fix(gate_bot): exclude active trend plans from orphan position warning
Trend pullback plans manage positions before order_monitors handoff; treat them as covered and add a pre-deploy DB backup script. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3632,8 +3632,36 @@ def _active_monitor_position_keys(active_orders):
|
||||
return covered
|
||||
|
||||
|
||||
def collect_orphan_exchange_positions(active_orders):
|
||||
"""交易所有持仓但未匹配 order_monitors.status=active(与中控 Agent 持仓对齐提示)。"""
|
||||
def _active_trend_plan_position_keys(conn):
|
||||
"""运行中的趋势回调计划已开仓时,持仓由计划表管理而非 order_monitors。"""
|
||||
covered = set()
|
||||
if conn is None:
|
||||
return covered
|
||||
try:
|
||||
rows = conn.execute(
|
||||
"SELECT symbol, exchange_symbol, direction FROM trend_pullback_plans "
|
||||
"WHERE status='active' AND COALESCE(first_order_done, 0) != 0"
|
||||
).fetchall()
|
||||
except Exception:
|
||||
return covered
|
||||
for r in rows:
|
||||
sym = (r["symbol"] or "").strip()
|
||||
ex = (r["exchange_symbol"] or normalize_exchange_symbol(sym)).strip()
|
||||
direction = (r["direction"] or "long").lower()
|
||||
for s in (ex, sym, _unified_symbol_for_match(ex), _unified_symbol_for_match(sym)):
|
||||
if s:
|
||||
covered.add((s, direction))
|
||||
return covered
|
||||
|
||||
|
||||
def _strategy_managed_position_keys(active_orders, conn=None):
|
||||
covered = _active_monitor_position_keys(active_orders)
|
||||
covered |= _active_trend_plan_position_keys(conn)
|
||||
return covered
|
||||
|
||||
|
||||
def collect_orphan_exchange_positions(active_orders, conn=None):
|
||||
"""交易所有持仓但未匹配本地策略/监控(order_monitors 或运行中趋势计划)。"""
|
||||
from hub_position_metrics import (
|
||||
parse_position_mark_price,
|
||||
position_contracts,
|
||||
@@ -3643,7 +3671,7 @@ def collect_orphan_exchange_positions(active_orders):
|
||||
rows = _fetch_all_swap_positions_live()
|
||||
if not rows:
|
||||
return []
|
||||
covered = _active_monitor_position_keys(active_orders)
|
||||
covered = _strategy_managed_position_keys(active_orders, conn)
|
||||
orphans = []
|
||||
seen = set()
|
||||
for p in rows:
|
||||
@@ -5639,7 +5667,7 @@ def render_main_page(page="trade"):
|
||||
orphan_positions: list = []
|
||||
if page == "trade":
|
||||
try:
|
||||
orphan_positions = collect_orphan_exchange_positions(order_list)
|
||||
orphan_positions = collect_orphan_exchange_positions(order_list, conn)
|
||||
except Exception as exc:
|
||||
print(f"[render_main_page] orphan positions: {exc}")
|
||||
conn.close()
|
||||
@@ -6160,6 +6188,19 @@ def api_order_relink_orphan():
|
||||
if active:
|
||||
conn.close()
|
||||
return jsonify({"ok": True, "msg": "已有运行中的监控", "order_id": int(active["id"])})
|
||||
trend_plan = conn.execute(
|
||||
"SELECT id FROM trend_pullback_plans WHERE status='active' AND symbol=? AND direction=? "
|
||||
"AND COALESCE(first_order_done, 0) != 0 LIMIT 1",
|
||||
(symbol, direction),
|
||||
).fetchone()
|
||||
if trend_plan:
|
||||
conn.close()
|
||||
return jsonify(
|
||||
{
|
||||
"ok": False,
|
||||
"msg": f"该持仓由趋势回调计划 #{int(trend_plan['id'])} 管理,请在策略页操作",
|
||||
}
|
||||
), 400
|
||||
row = conn.execute(
|
||||
"""
|
||||
SELECT * FROM order_monitors
|
||||
|
||||
Reference in New Issue
Block a user