fix(gate-bot): PnL colors, sync exchange TP/SL to plan display
Color floating PnL on position cards, mirror exchange stop/take prices in the grid and DB, and purge false external-close records on monitor relink.
This commit is contained in:
@@ -54,6 +54,7 @@ from form_submit_lib import check_duplicate_submit, submit_scope_add_key, submit
|
||||
from order_monitor_display_lib import (
|
||||
apply_order_price_display_fields,
|
||||
enrich_order_display_fields,
|
||||
tpsl_slot_trigger_price,
|
||||
)
|
||||
from journal_chart_lib import (
|
||||
JOURNAL_CHART_DEFAULT_LIMIT,
|
||||
@@ -5799,7 +5800,6 @@ def api_price_snapshot():
|
||||
order_rows = conn.execute(
|
||||
"SELECT id,symbol,exchange_symbol,direction,trigger_price,stop_loss,initial_stop_loss,take_profit,margin_capital,leverage FROM order_monitors WHERE status='active'"
|
||||
).fetchall()
|
||||
conn.close()
|
||||
|
||||
symbol_set = set()
|
||||
for r in key_rows:
|
||||
@@ -5927,17 +5927,51 @@ def api_price_snapshot():
|
||||
except Exception:
|
||||
exchange_tpsl = {"sl": None, "tp": None}
|
||||
payload["exchange_tpsl"] = exchange_tpsl
|
||||
live_sl = tpsl_slot_trigger_price(exchange_tpsl.get("sl"))
|
||||
live_tp = tpsl_slot_trigger_price(exchange_tpsl.get("tp"))
|
||||
disp_sl = live_sl if live_sl is not None else r["stop_loss"]
|
||||
disp_tp = live_tp if live_tp is not None else r["take_profit"]
|
||||
sym = r["symbol"]
|
||||
payload["stop_loss_raw"] = disp_sl
|
||||
payload["take_profit_raw"] = disp_tp
|
||||
payload["stop_loss_display"] = (
|
||||
format_price_for_symbol(sym, disp_sl) if disp_sl not in (None, "") else "—"
|
||||
)
|
||||
payload["take_profit_display"] = (
|
||||
format_price_for_symbol(sym, disp_tp) if disp_tp not in (None, "") else "—"
|
||||
)
|
||||
apply_order_price_display_fields(
|
||||
payload,
|
||||
direction=r["direction"],
|
||||
entry_price=entry,
|
||||
initial_stop_loss=r["initial_stop_loss"],
|
||||
stop_loss=r["stop_loss"],
|
||||
take_profit=r["take_profit"],
|
||||
stop_loss=disp_sl,
|
||||
take_profit=disp_tp,
|
||||
calc_rr_ratio_fn=calc_rr_ratio,
|
||||
exchange_tpsl=exchange_tpsl,
|
||||
)
|
||||
order_prices.append(payload)
|
||||
if live_sl is not None or live_tp is not None:
|
||||
try:
|
||||
cur_sl = float(r["stop_loss"] or 0)
|
||||
cur_tp = float(r["take_profit"] or 0)
|
||||
except (TypeError, ValueError):
|
||||
cur_sl, cur_tp = 0.0, 0.0
|
||||
new_sl = live_sl if live_sl is not None else cur_sl
|
||||
new_tp = live_tp if live_tp is not None else cur_tp
|
||||
if (live_sl is not None and abs(new_sl - cur_sl) > 1e-12) or (
|
||||
live_tp is not None and abs(new_tp - cur_tp) > 1e-12
|
||||
):
|
||||
conn.execute(
|
||||
"UPDATE order_monitors SET stop_loss=?, take_profit=? WHERE id=?",
|
||||
(new_sl, new_tp, int(r["id"])),
|
||||
)
|
||||
|
||||
try:
|
||||
conn.commit()
|
||||
except Exception:
|
||||
pass
|
||||
conn.close()
|
||||
|
||||
from hub_position_metrics import build_position_marks_list
|
||||
|
||||
@@ -6113,11 +6147,19 @@ def api_order_relink_orphan():
|
||||
"msg": "未找到可恢复的历史监控记录,请在中控核对持仓或联系管理员",
|
||||
}
|
||||
), 404
|
||||
opened_at = get_opened_at_value(row)
|
||||
purged = conn.execute(
|
||||
"DELETE FROM trade_records WHERE symbol=? AND direction=? AND opened_at=? AND result LIKE ?",
|
||||
(symbol, direction, opened_at, "%外部平仓%"),
|
||||
).rowcount
|
||||
conn.execute("UPDATE order_monitors SET status='active' WHERE id=?", (int(row["id"]),))
|
||||
conn.commit()
|
||||
oid = int(row["id"])
|
||||
conn.close()
|
||||
return jsonify({"ok": True, "msg": "已恢复本地监控", "order_id": oid})
|
||||
msg = "已恢复本地监控"
|
||||
if purged:
|
||||
msg += f"(已清除 {purged} 条误记的外部平仓记录)"
|
||||
return jsonify({"ok": True, "msg": msg, "order_id": oid, "purged_trade_records": purged})
|
||||
|
||||
|
||||
@app.route("/api/order_defaults")
|
||||
|
||||
Reference in New Issue
Block a user