From 022ead6d6cb8be97cbe0f45cbd6339e40b85134d Mon Sep 17 00:00:00 2001 From: root Date: Sat, 28 Feb 2026 13:45:26 +0000 Subject: [PATCH] feat: paper_trades store score_factors JSONB (direction/crowding/environment/confirmation/auxiliary breakdown) --- backend/db.py | 1 + backend/signal_engine.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/backend/db.py b/backend/db.py index 83616da..326a01c 100644 --- a/backend/db.py +++ b/backend/db.py @@ -247,6 +247,7 @@ CREATE TABLE IF NOT EXISTS paper_trades ( status TEXT DEFAULT 'active', pnl_r DOUBLE PRECISION DEFAULT 0, atr_at_entry DOUBLE PRECISION DEFAULT 0, + score_factors JSONB, created_at TIMESTAMP DEFAULT NOW() ); """ diff --git a/backend/signal_engine.py b/backend/signal_engine.py index 7f6eab1..3a6d21b 100644 --- a/backend/signal_engine.py +++ b/backend/signal_engine.py @@ -493,8 +493,9 @@ def save_indicator_1m(ts: int, symbol: str, result: dict): # ─── 模拟盘 ────────────────────────────────────────────────────── -def paper_open_trade(symbol: str, direction: str, price: float, score: int, tier: str, atr: float, now_ms: int): +def paper_open_trade(symbol: str, direction: str, price: float, score: int, tier: str, atr: float, now_ms: int, factors: dict = None): """模拟开仓""" + import json as _json3 risk_atr = 0.7 * atr if risk_atr <= 0: return @@ -510,9 +511,10 @@ def paper_open_trade(symbol: str, direction: str, price: float, score: int, tier with get_sync_conn() as conn: with conn.cursor() as cur: cur.execute( - "INSERT INTO paper_trades (symbol,direction,score,tier,entry_price,entry_ts,tp1_price,tp2_price,sl_price,atr_at_entry) " - "VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", - (symbol, direction, score, tier, price, now_ms, tp1, tp2, sl, atr) + "INSERT INTO paper_trades (symbol,direction,score,tier,entry_price,entry_ts,tp1_price,tp2_price,sl_price,atr_at_entry,score_factors) " + "VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", + (symbol, direction, score, tier, price, now_ms, tp1, tp2, sl, atr, + _json3.dumps(factors) if factors else None) ) conn.commit() logger.info(f"[{symbol}] 📝 模拟开仓: {direction} @ {price:.2f} score={score} tier={tier} TP1={tp1:.2f} TP2={tp2:.2f} SL={sl:.2f}") @@ -705,7 +707,8 @@ def main(): paper_open_trade( sym, result["signal"], result["price"], result["score"], tier, - result["atr"], now_ms + result["atr"], now_ms, + factors=result.get("factors") ) # 模拟盘持仓检查由paper_monitor.py通过WebSocket实时处理,这里不再检查