Prevent duplicate strategy trade snapshots on plan close.
Finalize plans before writing snapshots, dedupe on startup and page load, and add a cleanup script for existing repeated rows. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+53
-10
@@ -667,6 +667,47 @@ def _trend_plan_trade_exists(conn, plan_id: int) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _bump_session_capital_no_commit(
|
||||
m, conn, session_date: str, pnl_amount: float
|
||||
) -> float | None:
|
||||
"""更新当日资金,不单独 commit(与 _finalize_plan 同一事务)。"""
|
||||
try:
|
||||
row = conn.execute(
|
||||
"SELECT current_capital FROM trading_sessions WHERE session_date = ?",
|
||||
(session_date,),
|
||||
).fetchone()
|
||||
if not row:
|
||||
start_cap = float(getattr(m, "DAILY_START_CAPITAL", 0) or 0)
|
||||
if start_cap <= 0:
|
||||
ensure = getattr(m, "ensure_session", None)
|
||||
if callable(ensure):
|
||||
ensured = ensure(conn, session_date)
|
||||
row = ensured
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO trading_sessions "
|
||||
"(session_date, start_capital, current_capital) VALUES (?,?,?)",
|
||||
(session_date, start_cap, start_cap),
|
||||
)
|
||||
row = conn.execute(
|
||||
"SELECT current_capital FROM trading_sessions WHERE session_date = ?",
|
||||
(session_date,),
|
||||
).fetchone()
|
||||
if not row:
|
||||
return None
|
||||
new_capital = float(row["current_capital"]) + float(pnl_amount)
|
||||
conn.execute(
|
||||
"UPDATE trading_sessions SET current_capital = ?, updated_at = CURRENT_TIMESTAMP "
|
||||
"WHERE session_date = ?",
|
||||
(round(new_capital, 4), session_date),
|
||||
)
|
||||
return round(new_capital, 4)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -> None:
|
||||
m = _m(cfg)
|
||||
plan_id = int(row["id"])
|
||||
@@ -700,6 +741,13 @@ def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
planned_rr = m.calc_rr_ratio(direction, avg_e, float(row["stop_loss"]), float(row["take_profit"]))
|
||||
st = _plan_stop_status(result_label)
|
||||
cur = conn.execute(
|
||||
"UPDATE trend_pullback_plans SET status=?, message=? WHERE id=? AND status='active'",
|
||||
(st, res, plan_id),
|
||||
)
|
||||
if not getattr(cur, "rowcount", 0):
|
||||
return
|
||||
try:
|
||||
from strategy_snapshot_lib import save_trend_plan_snapshot
|
||||
|
||||
@@ -710,6 +758,7 @@ def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -
|
||||
result_label=result_label,
|
||||
exit_price=float(exit_price) if exit_price is not None else None,
|
||||
pnl_amount=float(pnl_amount) if pnl_amount is not None else None,
|
||||
closed_at=closed_at,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -717,9 +766,12 @@ def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -
|
||||
cancel_symbol_orders(cfg, ex_sym)
|
||||
except Exception:
|
||||
pass
|
||||
session_capital = None
|
||||
if not _trend_plan_trade_exists(conn, plan_id):
|
||||
session_date = row["session_date"] or m.get_trading_day()
|
||||
session_capital = m.update_session_capital(conn, session_date, pnl_amount)
|
||||
session_capital = _bump_session_capital_no_commit(
|
||||
m, conn, session_date, pnl_amount
|
||||
)
|
||||
_call_insert_trade_record(
|
||||
m,
|
||||
plan_id,
|
||||
@@ -746,15 +798,6 @@ def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -
|
||||
entry_reason=ENTRY_REASON_TREND_PULLBACK,
|
||||
),
|
||||
)
|
||||
else:
|
||||
session_capital = None
|
||||
st = _plan_stop_status(result_label)
|
||||
cur = conn.execute(
|
||||
"UPDATE trend_pullback_plans SET status=?, message=? WHERE id=? AND status='active'",
|
||||
(st, res, plan_id),
|
||||
)
|
||||
if not getattr(cur, "rowcount", 0):
|
||||
return
|
||||
conn.commit()
|
||||
try:
|
||||
from strategy_wechat_notify import notify_trend_plan_ended
|
||||
|
||||
Reference in New Issue
Block a user