diff --git a/deploy/profile-scripts/mofin_db.py b/deploy/profile-scripts/mofin_db.py index 88fb8820..98318e1c 100644 --- a/deploy/profile-scripts/mofin_db.py +++ b/deploy/profile-scripts/mofin_db.py @@ -1635,14 +1635,24 @@ def check_strategy_outcomes(conn): mid = mid or price # fallback closed = False + # ── 持仓成本感知(2026-07-29 老爸抓包:策略版"止盈"可能远低于真实成本,必须区分语义)── + _hc = conn.execute("SELECT cost, shares FROM holdings WHERE code=? AND is_active=1 AND shares>0", (code,)).fetchone() + _cost = float(_hc[0]) if _hc and _hc[0] else 0.0 + _real_pnl = round((price - _cost) / _cost * 100, 1) if _cost > 0 else None if tp and tp > 0 and price >= tp: pnl_pct = round((tp - mid) / mid * 100, 1) if mid > 0 else 0 + _reason = '止盈触发' if (_real_pnl is None or _real_pnl > 0) else '反弹减仓触发' conn.execute(""" UPDATE strategy_tracking SET status='hit_tp', closed_at=datetime('now','localtime'), - close_price=?, close_reason='止盈触发', theoretical_pnl=? + close_price=?, close_reason=?, theoretical_pnl=? WHERE id=? - """, (price, pnl_pct, tid)) - print(f" [TRACK] {code} v{tid} 止盈! {price}≥{tp} +{pnl_pct}%", flush=True) + """, (price, _reason, pnl_pct, tid)) + if _real_pnl is not None and _real_pnl <= 0: + print(f" [TRACK] {code} v{tid} 反弹减仓位! {price}≥{tp},成本{_cost},浮亏{_real_pnl}%(减仓窗口,非止盈)", flush=True) + elif _real_pnl is not None: + print(f" [TRACK] {code} v{tid} 止盈! {price}≥{tp} 实际盈利+{_real_pnl}%(成本{_cost})", flush=True) + else: + print(f" [TRACK] {code} v{tid} 追踪版本止盈 {price}≥{tp} +{pnl_pct}%(未持仓)", flush=True) closed = True elif sl and sl > 0 and price <= sl: pnl_pct = round((sl - mid) / mid * 100, 1) if mid > 0 else -5 @@ -1651,7 +1661,10 @@ def check_strategy_outcomes(conn): close_price=?, close_reason='止损触发', theoretical_pnl=? WHERE id=? """, (price, pnl_pct, tid)) - print(f" [TRACK] {code} v{tid} 止损! {price}≤{sl} {pnl_pct}%", flush=True) + if _real_pnl is not None: + print(f" [TRACK] {code} v{tid} 止损! {price}≤{sl},成本{_cost},实际{_real_pnl}%", flush=True) + else: + print(f" [TRACK] {code} v{tid} 止损! {price}≤{sl} {pnl_pct}%", flush=True) closed = True if closed: