diff --git a/specs/strategy.json b/specs/strategy.json index e93e95cf..bb92b6d5 100644 --- a/specs/strategy.json +++ b/specs/strategy.json @@ -1,28 +1,40 @@ { "module": "strategy", - "version": "1.0", - "purpose": "策略研究模块。策略版本管理、回测、温区自适应路由、三状态模型,以及研究 Tab 的版本迭代对比表格(含综合/普适评分体系)。", + "version": "2.0", + "purpose": "策略研究模块。策略版本管理、回测、温区自适应路由、资格评估(标准A)、手动可用性把关、三状态模型,以及研究 Tab 的版本迭代对比表格(含综合/普适评分体系)。", "human_help": { "title": "策略研究(版本迭代对比)", "description": [ "本模块是 MoFin 的策略研究面板:管理所有策略版本的迭代历史、回测结果、温区自适应路由(A股/港股独立温区)。", - "策略版本按【适应温区】展开成多行——每行显示该策略在该温区的独立表现(胜率/平均收益/笔数来自 strategy_regime_perf,每日盘后自动重算)。", - "当前温区激活区块按温区分组:当前温区排最前并高亮,组内策略按该温区胜率降序。", - "策略有三种状态:🟢 激活(当前温区路由选中)/ 🔵 可用未激活(候选池内,温区切换即可激活)/ 📚 不可用(已证伪或历史版本,路由不会选中)。", - "数据每日自动更新:strategy_period_rollup(17:05 派生 1y/2y/5y 窗口统计)+ regime_perf_daily(17:15 重算各温区表现)。" + "策略版本按【适应温区】展开成 6 张表(A股当前市/港股当前市/A股其余2市/港股其余2市)——每个策略只在它的适应温区(best_regime)表显示一行,所有列(胜率/平均收益/笔数/均持仓/年化/综合/夏普/盈亏比/普适/回撤)都是该策略在【适应温区】的数据,与所选周期一致。", + "策略有三种状态:🟢 激活(当前温区匹配 + 手动可用 + 三项资格达标)/ 🔵 可用(手动可用 + 长期+近期达标,当下待观察)/ 📚 不可用(手动不可用或长期不合格或已证伪)。", + "数据每日自动更新:strategy_period_rollup(17:05 派生 1y/2y/5y 窗口统计)+ regime_perf_daily(17:15 重算各温区表现,含按周期预计算 regime_perf_by_period)。" ], "usage": [ - "选择周期(近1月/6月/1年/2年/5年/10年)— 筛选该窗口的回测统计;1m/6m/1y 从最长区间切窗派生,2y/5y/10y 读库(派生行带 derived_from 标记)", + "选择周期(近1月/6月/1年/2年/5年/10年)— 筛选该窗口的回测统计;1m/6m/1y 从最长区间切窗派生,2y/5y/10y 读库", "选择市场(全部/A股/港股)— 港股策略带「港」徽章,A股带「A」", "点击策略行 — 打开该策略的版本详情(含因子归因、交易明细)", "▶回测按钮 — 手动重跑该策略回测", - "综合列 — 整体行显示温区加权综合分(按温区时长占比加权),温区行显示该温区的综合分", - "普适列 — 显示普适性评分,格式:分数/信号月数(详见下方说明)" + "【资格列】三个符号 = 长期/近期/当下 三项达标(详见下方「资格评估」说明)", + "【可用列】勾选框 = 手动可用性开关(激活只能是可用的策略;取消勾选 → 立即降级为不可用)", + "表头【✅全可用/🚫全不可用】按钮 — 批量设置当前温区表所有策略的可用性", + "表头【大盘基准: 1y/2y/10y】— 显示当前大盘年化阈值(资格评估的对比基准)", + "⚠️警告文字(黄色)= 可用策略近期转差(2y 年化已跌破大盘),提示关注;🔄(绿色)= 不可用策略近期回升(1y 年化重回大盘上方),提示可考虑重新启用" + ], + "qualification": [ + "资格评估 = 策略在【适应温区】的年化 vs 大盘基准,分三个时间尺度:", + "✅/❌ 第一个符号(长期)= 适应温区 10y 年化 > 大盘 10y(当前约 2.4%)", + "✅/❌ 第二个符号(近期)= 适应温区 2y 年化 > 大盘 2y(当前约 16.8%)", + "✅/❌ 第三个符号(当下)= 适应温区 1y 年化 > 大盘 1y(当前约 5.3%)", + "悬停每个符号可看具体数值(该尺度年化 vs 大盘基准)", + "三项全过(✅✅✅)= 激活资格;长期+近期过(✅✅❌)= 可用;长期不过(❌❌❌)= 历史", + "当前温区是下跌市(trend_down)时,只有 best_regime=trend_down 的策略在下跌市表显示;其他温区的策略(如趋势市 v7.1)三项全过但在各自温区表显示" ], "troubleshooting": [ "某策略某些列空白 → 该周期窗口无数据或样本不足;激活策略缺失时系统自动用 10y 数据补全并标注", - "综合分偏低 → 该策略在适应温区内收益/胜率/夏普/盈亏比/回撤综合评分低,或样本量<40笔/信号月份<6导致置信系数打折", - "v_oversold 在趋势市/震荡市收益低但仍激活 → 激活只看当前温区(trend_down)匹配,其他温区行只是参考", + "某策略「激活」但被降级(显示 🔵可用 或 📚不可用)→ 查看 state_reason:可能是手动不可用,或资格未三项达标(如近期 2y 年化跌破大盘)", + "⚠️警告出现 → 该策略 2y 年化已低于大盘(近期转差),虽然长期仍合格,建议关注是否手动停用", + "v_oversold 在下跌市表当下❌(1y 年化负)但仍显示 → 它长期+近期达标(✅✅),当下样本少(2笔)待观察,状态为可用而非激活", "普适显示 X/? 月 → 该温区总月份数据缺失(港股温区总月份按港股 market_regime 统计)" ] }, @@ -31,8 +43,34 @@ { "method": "GET", "path": "/api/research/strategies?period_tag=<2y>&market=", - "returns": "{strategies[{version, name, summary_stats, regime_winrates, regime_weighted, deprecated, state, state_reason, current, market, period_tag, trades_count}], regime_active[], regime_state}", - "description": "策略版本列表。summary_stats 含 win_rate/portfolio/portfolio_full/universality;regime_winrates 为每策略每温区表现;regime_weighted 为温区加权整体综合;state 为三状态(active/available/unavailable);regime_state 为 A股当前温区" + "returns": "{strategies[{version, name, summary_stats, regime_winrates, regime_weighted, deprecated, state, state_reason, current, market, period_tag, best_regime, qualification, manual_available, qual_warning, trades_count}], regime_active[], regime_state}", + "description": "策略版本列表。summary_stats 含 win_rate/portfolio/portfolio_full/universality;regime_winrates 为每策略每温区表现(按 period_tag 从预计算表读);best_regime=适应温区;qualification={long_ok,mid_ok,short_ok,cagr_10y,cagr_2y,cagr_1y,bench_*};manual_available=手动可用性;qual_warning=警告文本;state 为三状态(active/available/unavailable)" + }, + { + "method": "GET", + "path": "/api/research/availability", + "returns": "{version: {available: bool, note, updated_at}}", + "description": "查询全部策略的手动可用性状态" + }, + { + "method": "POST", + "path": "/api/research/availability", + "body": "{version, available, note?}", + "returns": "{updated, entry}", + "description": "设置单个策略的手动可用性(激活只能是可用的策略)" + }, + { + "method": "POST", + "path": "/api/research/availability?batch=1", + "body": "{versions[], available, note?}", + "returns": "{updated: {version: entry}, count}", + "description": "批量设置策略可用性(前端「全可用/全不可用」按钮调用)" + }, + { + "method": "POST", + "path": "/api/research/availability?init=1", + "returns": "{initialized: [[version, available]...], count}", + "description": "按标准A自动初始化新策略可用性(长期合格→默认可用;长期不合格→默认不可用)。已存在的手动状态不动" }, { "method": "GET", @@ -55,38 +93,47 @@ ], "dependencies": [ "strategy_lab.py — calc_summary/portfolio_sim/list_strategies 核心计算", + "strategy_qualify.py — 资格评估(标准A) + 手动可用性 json 管理(data/strategy_availability.json)", "hk_strategies.py — 港股策略定义(HK_STRATEGIES + strategies_for_regime)", "strategy_router.py — 双市场路由(写 data/strategy_weights.json)", "strategy_period_rollup.py — 每日派生 1y/2y/5y 窗口统计(cron 17:05)", - "regime_perf.py / regime_perf_daily.sh — 温区表现重算(cron 17:15)", + "regime_perf.py / regime_perf_by_period.py / regime_perf_daily.sh — 温区表现重算(cron 17:15,按周期预计算)", "strategy_research 表 — 策略版本+回测结果存储(含 market/period_tag/deprecated 字段)", - "strategy_regime_perf 表 — 每策略每温区表现(含温区级组合模拟)", - "market_regime 表 — 温区归因(date→regime,market 维度)" + "strategy_regime_perf_by_period 表 — 每策略每温区每周期表现(含温区级组合模拟+线性年化)", + "market_regime 表 — 温区归因(date→regime,market 维度)+ 大盘基准年化", + "data/strategy_availability.json — 手动可用性状态(git 可追踪)" ], "constraints": [ "综合分公式(前端计算,整体行):min(ret,100)/100×30 + wr/100×20 + min(max(sharpe,0),20)/20×20 + min(pf,5)/5×15 + (1-min(dd,50)/50)×15,乘以置信系数 conf=min(1,n/40)×min(1,months/6)", - "综合分收益口径:MC 全参与(portfolio_full 优先,消除集中仓挑装运气);温区加权综合按温区时长占比加权各温区表现", - "普适性(strategy_lab.calc_summary):months=信号分布覆盖的月份数;peak_pct=信号最集中月份的占比%;score=信号月份分布香农熵归一化(0-100),分布越均匀越高", - "温区级普适(server._approx_regime_universality):信号月份≈trades/温区月均笔数,score=估算信号月份/温区总月份×100", - "激活判定(strategy_router.route):当前温区胜率≥50 且最佳温区胜率≥50,且未 deprecated", - "三状态派生(不存储):active=∈strategy_weights.active∪markets.hk.active;unavailable=已证伪(deprecated非空)或不在候选池;available=其余(候选池内未激活)", + "综合分收益口径:MC 全参与(portfolio_full 优先);温区加权综合按温区时长占比加权各温区表现", + "温区年化(线性放大,非复利):温区组合总收益 × (窗口交易日数 / 该温区窗口内天数)——体现『如果全年都是该温区,策略年化收益率』;消除 portfolio_sim 复利在短跨度时的爆炸(如 v_lurk_bull 5笔同日曾算成 463万%)", + "资格评估(标准A,strategy_qualify.evaluate_strategy):长期=10y适应温区年化>大盘10y;近期=2y>大盘2y;当下=1y>大盘1y。大盘基准从 market_regime 指数 close 现算", + "激活判定(strategy_router.route):三项资格达标(long_ok&&mid_ok&&short_ok)且手动可用(is_available)——替代旧『胜率≥50』标准", + "state 派生(server.py,不存储):active=∈active_set且手动可用且三项达标;available=手动可用且长期+近期达标;unavailable=手动不可用或长期不合格或已证伪或不在候选池", + "路由激活但资格不足的策略:降级为 available/unavailable,current 置 False(前端不高亮),state_reason 说明原因(如『路由激活但未三项达标(长期✓/近期✗/当下✗)』)", + "警告标记:可用策略 2y 年化<大盘 → ⚠️近期转差;不可用策略 1y 年化>大盘 → 🔄近期回升(提示可重新启用)", + "手动可用性(data/strategy_availability.json):新策略按标准A初始化(长期合格默认可用);未标记策略默认可用;激活只能是可用策略", "候选池:A股=regime_perf 有记录的策略;港股=HK_STRATEGIES 定义的策略", - "回测数据截止 2026-07-24,窗口派生锚定数据末端(非今天),避免回测未重跑时窗口缩水" + "1m/6m 周期温区数据映射到 1y 预计算表(_pt_chain);list_strategies 切窗版本集=静态字典∪strategy_research DISTINCT version(DB-only 策略如 s2_panic/v_lurk_*/v_mr* 不丢)", + "回测数据截止 2026-07-24,窗口派生锚定数据末端(非今天)" ], "must_not": [ "不要在策略代码里硬编码 deprecated 集合(必须从 strategy_research.deprecated 读)", - "不要在策略代码里硬编码激活策略列表(必须读 data/strategy_weights.json)", + "不要在策略代码里硬编码激活策略列表(必须读 data/strategy_weights.json + strategy_qualify 资格判定)", "不要给派生行(derived_from)覆盖真实研究记录", "不要用 period_tag 字典序排序取 trades(必须用 LENGTH 降序最长周期优先)", - "不要污染 A股温区(读 market_regime 必须带 market='a' 过滤)" + "不要污染 A股温区(读 market_regime 必须带 market='a' 过滤)", + "不要让手动不可用的策略成为 active(激活必须是可用的策略)", + "不要用 portfolio_sim 复利年化作为温区年化(必须用线性放大,否则短跨度爆炸)" ], "related_files": [ - "server.py — /api/research/* 路由 + 三状态派生 + regime_weighted", - "static/index.html — renderStrategyTable/renderGroupByRegime/renderRegimeRow", + "server.py — /api/research/* 路由 + 资格评估 + 三状态派生 + 手动可用性", + "static/index.html — renderStrategyTable/renderRegimeTable/renderRegimeRow + 资格列/可用性开关/批量按钮", + "strategy_qualify.py — 资格评估 + 可用性管理(deploy/profile-scripts/)", "strategy_lab.py — 核心计算", "hk_strategies.py — 港股策略", - "strategy_router.py — 双市场路由", - "strategy_period_rollup.py / regime_perf.py / regime_perf_daily.sh — 每日自动更新", + "strategy_router.py — 双市场路由(matched 用标准A)", + "strategy_period_rollup.py / regime_perf.py / regime_perf_by_period.py / regime_perf_daily.sh — 每日自动更新", "deploy/profile-scripts/health_monitor_daily.py — 健康度监控", "docs/decisions/2026-08-15-策略自我进化闭环重构.md — 进化闭环设计" ]