fix(key-monitor): repair trigger entry bugs in four exchange apps

Restore missing check_fib_key_monitors, fix gate preview and OKX add_key,
and unify trigger execution error handling to avoid duplicate history writes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-14 01:06:53 +08:00
parent edf4bb835d
commit 4573ccca9a
4 changed files with 179 additions and 130 deletions
+60 -56
View File
@@ -5421,18 +5421,30 @@ def _execute_trigger_entry_cross(conn, row):
conn.execute("DELETE FROM key_monitors WHERE id=?", (kid,))
conn.commit()
ok, err, det = _market_open_for_trigger_entry(
conn,
symbol,
direction,
ex_sym,
entry,
sl,
tp,
breakeven_enabled=be_en,
time_close_enabled=tc_en,
time_close_hours=tc_h,
)
try:
ok, err, det = _market_open_for_trigger_entry(
conn,
symbol,
direction,
ex_sym,
entry,
sl,
tp,
breakeven_enabled=be_en,
time_close_enabled=tc_en,
time_close_hours=tc_h,
)
except Exception as e:
fail_msg = friendly_exchange_error(e)
send_wechat_msg(
f"# ❌ {symbol} 触价开仓异常\n"
f"**账户:{_wechat_account_label()}**\n"
f"- 计划入场:{format_price_for_symbol(symbol, entry)}\n"
f"- 原因:{fail_msg}\n"
)
insert_key_monitor_history(conn, row, 0, fail_msg, TRIGGER_ENTRY_CLOSE_EXCHANGE_FAILED)
return False, fail_msg
if ok and det:
rr_txt = format_wechat_scalar_2dp(det.get("planned_rr_fill")) if det.get("planned_rr_fill") is not None else "-"
msg = (
@@ -5498,22 +5510,12 @@ def check_trigger_entry_key_monitors():
_finalize_key_monitor_one_shot(conn, r, msg, TRIGGER_ENTRY_CLOSE_TP_INVALIDATE)
continue
if trigger_entry_reached(direction, mark, entry):
try:
_execute_trigger_entry_cross(conn, r)
except Exception as e:
fail_msg = friendly_exchange_error(e)
try:
insert_key_monitor_history(conn, r, 0, fail_msg, TRIGGER_ENTRY_CLOSE_EXCHANGE_FAILED)
except Exception:
pass
send_wechat_msg(
f"# ❌ {symbol} 触价开仓异常\n**账户:{_wechat_account_label()}**\n- {fail_msg}\n"
)
_execute_trigger_entry_cross(conn, r)
conn.commit()
conn.close()
def check_fib_key_monitors():
conn = get_db()
rows = conn.execute("SELECT * FROM key_monitors").fetchall()
for r in rows:
@@ -6857,6 +6859,7 @@ def api_price_snapshot():
gate_metrics = ""
fib_gate_ok = True
fb_gate_ok = True
te_gate_ok = True
if is_fib:
direction = (r["direction"] or "long").lower()
inval = fib_invalidate_by_mark(direction, price, r["upper"], r["lower"])
@@ -6895,7 +6898,7 @@ def api_price_snapshot():
)
gate_summary = prev.get("summary") or "-"
gate_metrics = prev.get("metrics") or ""
fib_gate_ok = bool(prev.get("gate_ok"))
te_gate_ok = bool(prev.get("gate_ok"))
elif (r["monitor_type"] or "").strip() in KEY_MONITOR_RS_TYPES:
try:
prev = _key_rs_gate_preview(r["symbol"], r["upper"], r["lower"])
@@ -6951,6 +6954,7 @@ def api_price_snapshot():
"gate_ok": (
fib_gate_ok if is_fib
else fb_gate_ok if is_fb
else te_gate_ok if is_te
else bool(gate and gate.get("ok"))
),
"gate_metrics": gate_metrics,
@@ -7512,40 +7516,40 @@ def add_key():
if tc_en and not tc_h:
tc_en = 0
if is_trigger_entry_key_monitor_type(mt):
if direction_sel not in ("long", "short"):
conn.close()
conn = None
flash("触价开仓请选择做多或做空")
return redirect("/key_monitor")
try:
entry_px = float(d.get("trigger_entry") or 0)
sl_px = float(d.get("trigger_sl") or 0)
tp_px = float(d.get("trigger_tp") or 0)
except (TypeError, ValueError):
entry_px = sl_px = tp_px = 0
if entry_px <= 0 or sl_px <= 0 or tp_px <= 0:
conn.close()
conn = None
flash("触价开仓须填写有效的入场价、止损价、止盈价")
return redirect("/key_monitor")
ok_te, err_te = _add_trigger_entry_key_monitor(
conn, symbol, direction_sel, entry_px, sl_px, tp_px, breakeven_enabled=be_flag,
time_close_enabled=tc_en, time_close_hours=tc_h,
)
conn.commit()
if direction_sel not in ("long", "short"):
conn.close()
conn = None
if not ok_te:
flash(err_te or "触价开仓监控添加失败")
return redirect("/key_monitor")
flash(
f"触价开仓已添加({symbol} 日成交量排名 {rank}/{total}"
f"|有效期 {TRIGGER_ENTRY_VALIDITY_HOURS}h"
f"|标记价触达入场价后下一轮询市价开仓"
f"|移动保本:{'' if be_flag else ''}"
+ (f"{time_close_label(tc_h)}" if tc_en else "")
)
flash("触价开仓请选择做多或做空")
return redirect("/key_monitor")
try:
entry_px = float(d.get("trigger_entry") or 0)
sl_px = float(d.get("trigger_sl") or 0)
tp_px = float(d.get("trigger_tp") or 0)
except (TypeError, ValueError):
entry_px = sl_px = tp_px = 0
if entry_px <= 0 or sl_px <= 0 or tp_px <= 0:
conn.close()
conn = None
flash("触价开仓须填写有效的入场价、止损价、止盈价")
return redirect("/key_monitor")
ok_te, err_te = _add_trigger_entry_key_monitor(
conn, symbol, direction_sel, entry_px, sl_px, tp_px, breakeven_enabled=be_flag,
time_close_enabled=tc_en, time_close_hours=tc_h,
)
conn.commit()
conn.close()
conn = None
if not ok_te:
flash(err_te or "触价开仓监控添加失败")
return redirect("/key_monitor")
flash(
f"触价开仓已添加({symbol} 日成交量排名 {rank}/{total}"
f"|有效期 {TRIGGER_ENTRY_VALIDITY_HOURS}h"
f"|标记价触达入场价后下一轮询市价开仓"
f"|移动保本:{'' if be_flag else ''}"
+ (f"{time_close_label(tc_h)}" if tc_en else "")
)
return redirect("/key_monitor")
if is_false_breakout_key_monitor_type(mt):
fb_sym = normalize_false_breakout_symbol(symbol)
if not fb_sym: