From 9c6ce434765a4d6f190d5d9400a4a0b282e571f9 Mon Sep 17 00:00:00 2001 From: xxm Date: Mon, 17 Aug 2026 00:47:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=99=AE=E9=80=82=E6=8C=87=E6=A0=87?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E5=8C=96=E2=80=94=E2=80=94trades=E6=9C=88?= =?UTF-8?q?=E4=BB=BD=E5=8E=BB=E9=87=8D/=E6=B8=A9=E5=8C=BA=E6=80=BB?= =?UTF-8?q?=E6=9C=88=E4=BB=BD(=E5=8E=9F=E4=BF=A1=E5=8F=B7=C3=B73=E4=BC=B0?= =?UTF-8?q?=E7=AE=97=E4=BD=BFs2=5Fpanic=E8=99=9A=E9=AB=98100=E5=88=86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/profile-scripts/regime_perf_by_period.py | 15 ++++++++++++--- server.py | 14 ++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/deploy/profile-scripts/regime_perf_by_period.py b/deploy/profile-scripts/regime_perf_by_period.py index 2af55711..d38d64cb 100644 --- a/deploy/profile-scripts/regime_perf_by_period.py +++ b/deploy/profile-scripts/regime_perf_by_period.py @@ -56,6 +56,8 @@ def create_table(conn): positions_taken INTEGER, sharpe_ratio REAL, profit_factor REAL, + universality_months INTEGER, + universality_score REAL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (strategy, market, regime, period_tag) ) @@ -158,17 +160,24 @@ def process_period(conn, market, period_tag): cagr = round(((1 + ret / 100) ** (365 / span_days) - 1) * 100, 1) else: cagr = None + # 普适:该温区 trades 的 entry_date 去重月份数 / 该温区总月份数(2026-08-16 修复: + # 原 server 端信号数÷3估算 → s2_panic 2255信号估算751月=100分,实际只2个月) + _uniq_months = len({t.get("entry_date", "")[:7] for t in reg_trades if t.get("entry_date")}) + _regime_months_all = {d[:7] for d, r in rmap.items() if r == reg} + _regime_total_months = len(_regime_months_all) + _univ_score = round(min(_uniq_months / max(_regime_total_months, 1) * 100, 100)) if _uniq_months else 0 conn.execute( """INSERT OR REPLACE INTO strategy_regime_perf_by_period (strategy, market, regime, period_tag, trades, win_rate, avg_pnl, avg_hold_days, total_return_pct, cagr_pct, portfolio_max_dd_pct, capital_final, - positions_taken, sharpe_ratio, profit_factor, updated_at) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + positions_taken, sharpe_ratio, profit_factor, universality_months, universality_score, updated_at) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", (v, market, reg, period_tag, len(reg_trades), extra.get("win_rate"), extra.get("avg_pnl"), extra.get("avg_hold_days"), ret, cagr, sim.get("portfolio_max_dd_pct"), sim.get("capital_final"), sim.get("positions_taken"), - extra.get("sharpe_ratio"), extra.get("profit_factor"), now)) + extra.get("sharpe_ratio"), extra.get("profit_factor"), + _uniq_months, _univ_score, now)) written += 1 return written diff --git a/server.py b/server.py index aeb7f8de..470a4628 100644 --- a/server.py +++ b/server.py @@ -60,7 +60,8 @@ def _compute_regime_winrates_cached(pt, _approx_univ): for _r in _c.execute( "SELECT strategy, market, regime, period_tag, trades, win_rate, avg_pnl, " "avg_hold_days, total_return_pct, cagr_pct, portfolio_max_dd_pct, capital_final, " - "positions_taken, sharpe_ratio, profit_factor FROM strategy_regime_perf_by_period " + "positions_taken, sharpe_ratio, profit_factor, universality_months, universality_score " + "FROM strategy_regime_perf_by_period " "WHERE period_tag=? ORDER BY strategy, market, regime", (_pt_use,)).fetchall(): _ver, _mkt, _reg = _r[0], _r[1], _r[2] @@ -71,6 +72,8 @@ def _compute_regime_winrates_cached(pt, _approx_univ): _pt_v = _r[12] _sh_v = _r[13] _pf_v = _r[14] + _umon = _r[15] + _uscore = _r[16] _regime_winrates.setdefault(_ver, {})[_reg] = { "trades": _r[4], "win_rate": _r[5], "avg_pnl": _r[6], "avg_hold_days": _r[7], @@ -83,7 +86,7 @@ def _compute_regime_winrates_cached(pt, _approx_univ): "portfolio_max_dd_pct": _dd_v, "capital_final": _cf_v, "positions_taken": _pt_v, "sharpe_ratio": _sh_v, "profit_factor": _pf_v}, - "universality": _approx_univ(_ver, _reg, _r[4]), + "universality": _approx_univ(_ver, _reg, _r[4], _umon, _uscore), } _c.close() except Exception: @@ -625,8 +628,11 @@ def get_tracking(): @app.route("/api/research/strategies") def api_research_strategies(): """策略版本列表(含回测结果摘要,支持 period_tag 区间过滤)""" - def _approx_regime_universality(strategy, regime, trades): - """温区级普适近似:温区内信号月份≈trades/温区月均笔数,温区总月份占比(避免逐笔遍历性能问题)""" + def _approx_regime_universality(strategy, regime, trades, umon=None, uscore=None): + """温区级普适:优先用预计算真实值(trades entry_date 去重月份/温区总月份), + 缺失时退回旧近似(信号数÷3估算,2026-08-16 修复——原估算对集中信号虚高)""" + if umon is not None and uscore is not None: + return {"months": umon, "score": uscore, "regime_total_months": 0} try: import sqlite3 as _sq6 _c6 = _sq6.connect(str(DATA_DIR / "mofin.db"), timeout=10)