fix(hub): sync TP/SL display after trend handoff to order monitor
Use order monitor plan prices on handoff cards and fill exchange TP/SL rows when Gate shows reduce-only orders without algo labels. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -697,28 +697,59 @@ def _tpsl_slots_to_conditional_orders(exchange_tpsl: dict, symbol: str) -> list[
|
||||
if not isinstance(slot, dict):
|
||||
continue
|
||||
trig = slot.get("trigger_price")
|
||||
oid = slot.get("order_id")
|
||||
if trig is None or oid is None:
|
||||
if trig is None:
|
||||
continue
|
||||
try:
|
||||
trig_f = float(trig)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
oid = slot.get("order_id")
|
||||
out.append(
|
||||
{
|
||||
"id": str(oid),
|
||||
"id": str(oid) if oid is not None else "",
|
||||
"symbol": symbol,
|
||||
"channel": "algo",
|
||||
"category": "conditional",
|
||||
"label": f"{label} {trig_f:g}",
|
||||
"trigger_price": trig_f,
|
||||
"amount": None,
|
||||
"amount": slot.get("amount"),
|
||||
"status": "open",
|
||||
}
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
def _exchange_tpsl_from_hub_order(hub_orders: list, symbol: str, side: str) -> dict | None:
|
||||
"""趋势保本移交后:用下单监控计划价补全 exchange_tpsl(与实例页一致)。"""
|
||||
side_l = (side or "").lower()
|
||||
for o in hub_orders:
|
||||
if not isinstance(o, dict):
|
||||
continue
|
||||
o_sym = o.get("exchange_symbol") or o.get("symbol") or ""
|
||||
if not _symbols_match(symbol, o_sym):
|
||||
continue
|
||||
if (o.get("direction") or "").lower() != side_l:
|
||||
continue
|
||||
sl = o.get("stop_loss")
|
||||
tp = o.get("take_profit")
|
||||
if sl in (None, "") and tp in (None, ""):
|
||||
continue
|
||||
slots: dict = {"sl": None, "tp": None}
|
||||
if sl not in (None, ""):
|
||||
try:
|
||||
slots["sl"] = {"trigger_price": float(sl), "order_id": None}
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if tp not in (None, ""):
|
||||
try:
|
||||
slots["tp"] = {"trigger_price": float(tp), "order_id": None}
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if slots["sl"] or slots["tp"]:
|
||||
return slots
|
||||
return None
|
||||
|
||||
|
||||
def _find_exchange_tpsl_for_position(
|
||||
symbol: str,
|
||||
side: str,
|
||||
@@ -946,12 +977,22 @@ def _merge_flask_exchange_tpsl(agent_row: dict, snap: dict | None, hub_mon: dict
|
||||
sym = p.get("symbol") or ""
|
||||
side = p.get("side") or ""
|
||||
et = _find_exchange_tpsl_for_position(sym, side, order_prices, hub_orders)
|
||||
if not et:
|
||||
et = _exchange_tpsl_from_hub_order(hub_orders, sym, side)
|
||||
if not et:
|
||||
continue
|
||||
p["exchange_tpsl"] = et
|
||||
cond = p.get("conditional_orders") or []
|
||||
merged = _tpsl_slots_to_conditional_orders(et, sym)
|
||||
if not cond:
|
||||
p["conditional_orders"] = _tpsl_slots_to_conditional_orders(et, sym)
|
||||
p["conditional_orders"] = merged
|
||||
elif merged:
|
||||
labels = {str(c.get("label") or "") for c in cond if isinstance(c, dict)}
|
||||
for row in merged:
|
||||
lbl = str(row.get("label") or "")
|
||||
if lbl and not any(lbl in x or x in lbl for x in labels):
|
||||
cond.append(row)
|
||||
p["conditional_orders"] = cond
|
||||
|
||||
|
||||
async def _fetch_exchange_flask_bundle(
|
||||
|
||||
Reference in New Issue
Block a user