修复翻倍出场/翻倍提醒可能重复推微信:done状态停扫,提醒标记立即提交。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-20 18:04:40 +08:00
parent 440778e9e6
commit 36724a902a
2 changed files with 52 additions and 10 deletions
+5
View File
@@ -138,6 +138,11 @@ def run_options_profit_alerts(
f"UPDATE options_trades SET profit_alert_sent = 1 WHERE id IN ({','.join('?' * len(bucket['ids']))})",
tuple(bucket["ids"]),
)
# 立即提交,避免后续目标/翻倍/同步异常回滚后每轮重推
try:
conn.commit()
except Exception:
pass
sent += 1
except Exception:
pass
+47 -10
View File
@@ -125,10 +125,7 @@ def profit_exit_by_inst(conn: sqlite3.Connection) -> dict[str, dict[str, Any]]:
SELECT inst_id, profit_exit_enabled, profit_exit_mult, profit_exit_state
FROM options_trades
WHERE status = 'open'
AND (
CAST(COALESCE(profit_exit_enabled, 0) AS INTEGER) = 1
OR COALESCE(profit_exit_state, 'idle') IN ('active', 'closing')
)
AND COALESCE(profit_exit_state, 'idle') IN ('active', 'closing')
ORDER BY id DESC
"""
).fetchall()
@@ -139,14 +136,17 @@ def profit_exit_by_inst(conn: sqlite3.Connection) -> dict[str, dict[str, Any]]:
continue
enabled = int(r["profit_exit_enabled"] or 0) == 1
state = str(r["profit_exit_state"] or "idle")
if not enabled and state not in ("active", "closing"):
if state not in ("active", "closing"):
continue
# closing 需续跑直到全平;active 需仍开启
if state == "active" and not enabled:
continue
mult = normalize_profit_exit_mult(r["profit_exit_mult"], default=1.0)
out[inst] = {
"inst_id": inst,
"profit_exit_enabled": enabled or state in ("active", "closing"),
"profit_exit_enabled": enabled or state == "closing",
"profit_exit_mult": mult,
"profit_exit_state": state if state in ("active", "closing") else ("active" if enabled else "idle"),
"profit_exit_state": state,
"required_recycle": None,
}
for inst, info in out.items():
@@ -318,9 +318,7 @@ def run_options_profit_exits(
continue
pos = pos_by_inst.get(inst_id)
if not pos:
# 持仓已平:收尾
_mark_state(conn, inst_id, "done")
_commit(conn)
# 本轮暂无持仓:不改状态(避免接口抖动误标 done);真正平完由 sync 收尾
continue
state = str(info.get("profit_exit_state") or "active")
@@ -329,10 +327,25 @@ def run_options_profit_exits(
if prem is None or prem <= 0:
continue
# done/idle 不再扫描(查询层已过滤;此处双保险)
if state in ("done", "idle"):
continue
if state == "closing":
result = close_fn(inst_id)
if result.get("already_flat") or _result_fully_done(result):
_mark_state(conn, inst_id, "done")
try:
conn.execute(
"""
UPDATE options_trades
SET profit_exit_enabled = 0
WHERE inst_id = ? AND status = 'open'
""",
(inst_id,),
)
except Exception:
pass
_commit(conn)
else:
_mark_state(conn, inst_id, "closing")
@@ -356,6 +369,17 @@ def run_options_profit_exits(
result = close_fn(inst_id)
if result.get("already_flat"):
_mark_state(conn, inst_id, "done")
try:
conn.execute(
"""
UPDATE options_trades
SET profit_exit_enabled = 0
WHERE inst_id = ? AND status = 'open'
""",
(inst_id,),
)
except Exception:
pass
_commit(conn)
continue
if not result.get("ok"):
@@ -365,6 +389,19 @@ def run_options_profit_exits(
done = _result_fully_done(result)
_mark_state(conn, inst_id, "done" if done else "closing")
if done:
try:
conn.execute(
"""
UPDATE options_trades
SET profit_exit_enabled = 0
WHERE inst_id = ? AND status = 'open'
""",
(inst_id,),
)
except Exception:
pass
# 先落库再推送:同一笔只推一次;closing 重试不再进本分支
_commit(conn)
triggered += 1
_notify_profit_exit_close(