diff --git a/evolution/evolution_api.py b/evolution/evolution_api.py index 2d24ae81..c47dd2c6 100644 --- a/evolution/evolution_api.py +++ b/evolution/evolution_api.py @@ -147,6 +147,33 @@ def get_combo_dashboard(): "positions_taken_full": pf.get("positions_taken"), } + # 3.5 策略家族 S2 卡片(s2_panic,2026-08-05 §39/§40 上线) + r = conn.execute( + "SELECT results_json FROM strategy_research" + " WHERE version='s2_panic' AND period_tag='10y' ORDER BY id DESC LIMIT 1" + ).fetchone() + if r: + res = json.loads(r[0]) + s2 = res.get("summary", {}) + pf = s2.get("portfolio_full", {}) + p5 = s2.get("portfolio", {}) + members["s2_panic"] = { + "role": "极端恐慌买超跌(RSI<25)", + "version": "s2_panic", + "is_sel": True, + "trades": s2.get("total_trades"), + "win_rate": s2.get("win_rate"), + "avg_profit_pct": s2.get("avg_profit_pct"), + "avg_hold_days": s2.get("avg_hold_days"), + "cagr_pct": p5.get("cagr_pct"), + "return_pct": p5.get("total_return_pct"), + "max_dd_pct": p5.get("portfolio_max_dd_pct"), + "slots": p5.get("slots") or 8, + "universality": s2.get("universality", {}), + "positions_taken_5slot": p5.get("positions_taken"), + "positions_taken_full": pf.get("positions_taken"), + } + conn.close() return { "regime": regime,