feat: 激活逻辑重构——按温区激活矩阵(老莫原则)

- route() matched改为任一温区三项达标(不只当前温区)
- main()生成regime_active矩阵(每温区独立择优,资格够就激活,不合格绝不激活)
- 当前温区active=regime_active[state](实盘闸门)
结果: trend_down=[b_td1_v3,v_lurk_v3,s2_panic_v2] choppy=[v_lurk_v2] trend_up=[v_next,v8.1]
This commit is contained in:
xxm
2026-08-18 01:25:12 +08:00
parent 8fc1367a60
commit ca08969a8d
+51 -12
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""strategy_router.py v5 — MoFin 策略动态路由(动态策略库,2026-08-13)
@@ -154,19 +154,31 @@ def route(regime, temp, perf):
best_wr = best[1].get("win_rate", 0)
cur_wr = cur.get("win_rate") if cur else None
# 2026-08-16 资格标准A(老莫):长期10y/近期2y/当下1y 适应温区年化>大盘 三项达标 + 手动可用
# (替代只看胜率≥50%的旧判定——旧标准会让年化-41%但胜率51%的策略激活)
# 2026-08-18 重构(老莫):matched 改为【任一温区三项达标】即可(不只当前温区)。
# 核心:资格够就必须能激活;当前温区是实盘闸门,但choppy/trend_up等温区达标策略也要备好激活。
# 不合格(如 v_lurk_v3 @ choppy ✅❌❌)绝不激活该温区;合格(v_lurk_v2 @ choppy)就激活。
try:
from strategy_qualify import evaluate_all_regimes, is_available, get_benchmarks
_qbench = get_benchmarks('a')
# 2026-08-17 择优激活:按当前温区评估资格(同 server.py 修复——best_regime 会让
# v_lurk_v3 在 trend_down 达标却被 choppy 评估误判不合格
_qev_all = evaluate_all_regimes(name, 'a', bench=_qbench)
_qev_cur = (_qev_all or {}).get(current_regime) or {}
_qual_ok = bool(_qev_cur.get("long_ok") and _qev_cur.get("mid_ok") and _qev_cur.get("short_ok"))
_qev_all = evaluate_all_regimes(name, 'a', bench=_qbench) or {}
# 达标温区列表(任一温区三项全达
_qual_regimes = []
for _rg in ("trend_down", "choppy", "trend_up"):
_q = (_qev_all or {}).get(_rg) or {}
if _q.get("long_ok") and _q.get("mid_ok") and _q.get("short_ok"):
_qual_regimes.append(_rg)
_manual_ok = is_available(name)
matched = _qual_ok and _manual_ok
matched = bool(_qual_regimes) and _manual_ok
_qual_cur_ok = False
if _qual_regimes:
_qev_cur = (_qev_all or {}).get(current_regime) or {}
_qual_cur_ok = bool(_qev_cur.get("long_ok") and _qev_cur.get("mid_ok") and _qev_cur.get("short_ok"))
except Exception:
matched = (best_wr >= 50) and (cur_wr is not None and cur_wr >= 50) # 兜底旧标准
_qual_regimes = [current_regime] if ((best_wr >= 50) and (cur_wr is not None and cur_wr >= 50)) else []
_qual_cur_ok = current_regime in _qual_regimes
matched = bool(_qual_regimes)
# ✓ 记录达标温区(供按温区激活矩阵)
qualifies = _qual_regimes if 'qualifies' in dir() else []
family = FAMILY_MAP.get(name, DEFAULT_FAMILY)
base = 1.0 if matched else 0.3
try:
@@ -180,11 +192,14 @@ def route(regime, temp, perf):
"temp_band": band,
"family": family,
"matched": matched,
"qualifies": qualifies, # 达标温区列表(2026-08-18
"qual_cur_ok": _qual_cur_ok, # 当前温区是否达标(2026-08-18)
"best_regime": best[0],
"best_win_rate": best[1].get("win_rate", 0),
"cur_win_rate": cur.get("win_rate") if cur else None,
"cur_avg_pnl": cur.get("avg_pnl") if cur else None,
"trades": cur.get("trades") if cur else 0,
"active_regimes": qualifies, # 别名(前端用)
}
return dict(sorted(weights.items(), key=lambda x: -x[1]["weight"]))
@@ -247,15 +262,39 @@ def main():
temp = load_temp() # A股温度
perf = load_regime_perf('a') # A股策略表现
weights = route(regime, temp, perf)
# 2026-08-18:按温区生成激活矩阵(老莫:资格够就激活,不合格绝不激活)
# - 每个温区,从"在该温区三项达标(qualifies含该温区)"里按质量分择优取前 MAX_ACTIVE
# - 当前温区 active = regime_active[当前温区](实盘闸门)
_all_regimes = ("trend_down", "choppy", "trend_up")
_cur_rg = regime.get("regime", "unknown")
regime_active = {}
for _rg in _all_regimes:
# 该温区达标策略(qualifies 含 rg
_rg_matched = [(k, v) for k, v in weights.items()
if v.get("matched") and _rg in v.get("qualifies", [])]
# 按质量分择优
_rg_scored = []
for name, v in _rg_matched:
q = _quality_score(name, 'a', _rg)
fam = FAMILY_MAP_ACT.get(name, name)
_rg_scored.append({"name": name, "quality": q, "family": fam})
_rg_scored.sort(key=lambda x: -x["quality"])
_used = set(); _sel = []
for s in _rg_scored:
if s["family"] in _used: continue
if len(_sel) >= MAX_ACTIVE: break
_used.add(s["family"]); _sel.append(s["name"])
regime_active[_rg] = _sel
out = {
"state": regime.get("regime", "unknown"),
"state": _cur_rg,
"state_date": regime.get("date", ""),
"temp_band": temp.get("band", "unknown"),
"temp_rsi": temp.get("rsi"),
"weights": weights,
"active": _select_active(weights, regime.get("regime", "unknown"), 'a'),
"active": regime_active.get(_cur_rg, []),
"regime_active": regime_active,
"updated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"note": "择优激活(2026-08-17): 每温区按质量分(综合分×普适有效年占比)排序+家族去重取前%d个; 温区(平滑K=5)选类型+温度乘数" % MAX_ACTIVE,
"note": "择优激活(2026-08-18): 按温区——任一温区三项达标即可激活该温区;当前温区实盘闸门;不合格绝不激活;合格就激活(择优排序)",
}
# 港股路由(2026-08-14 新增,不影响A股)——港股组合按温区调度(hk_strategies 定义)
try: