feat: v_next/v_next3正式注册进引擎——conviction多因子信念缩放(平铺/叠乘封顶x4)+sector_adx因子+sizing=3+完整说明; 补跑2y+5y回测(复现54.8%/48.3%); UI仓位列显示信念模型

This commit is contained in:
hmo
2026-07-30 23:41:20 +08:00
parent 5e9de28966
commit 17d07f06f9
2 changed files with 79 additions and 5 deletions
+1 -1
View File
@@ -2153,7 +2153,7 @@ function renderStrategyTable(strategies) {
html += '<tr class="' + rowCls + '" onclick="showStrategyDetail(\'' + s.version + '\')">' +
'<td class="px-2 py-1.5 font-mono font-bold ' + (isCurrent ? 'text-emerald-400' : 'text-blue-400') + '">' + s.version + (isCurrent ? ' <span class="text-[10px] bg-emerald-500/20 text-emerald-300 px-1 rounded">当前</span>' : '') + ((s.market && s.market !== 'all') ? ' <span class="text-[10px] bg-cyan-500/20 text-cyan-300 px-1 rounded">' + (s.market === 'hk' ? '港' : 'A') + '</span>' : '') + '</td>' +
'<td class="px-2 py-1.5" title="' + (s.hypothesis || s.summary || '').replace(/"/g, '&quot;') + '">' + (s.name || '') + (smallSample ? ' <span class="text-amber-500" title="样本<40笔">⚠️</span>' : '') + '</td>' +
'<td class="text-center px-2 py-1.5 font-mono text-cyan-300">' + (st.sizing_slots ? st.sizing_slots + '仓' : '10仓') + '</td>' +
'<td class="text-center px-2 py-1.5 font-mono text-cyan-300"' + (st.conviction_model ? ' title="信念分级仓位: ' + st.conviction_model.replace(/"/g, '&quot;') + '(基准' + (st.sizing_slots||10) + '仓, 单票按信念因子放大)"' : '') + '>' + (st.sizing_slots ? st.sizing_slots + '仓' : '10仓') + (st.conviction_model ? '<span class="text-amber-400" style="cursor:help">⚡</span>' : '') + '</td>' +
'<td class="text-center px-2 py-1.5">' + ((s.description && s.description.title) ? '<button onclick="event.stopPropagation();showDesc(\'' + s.version + '\')" class="text-blue-400 hover:text-blue-300" title="查看策略说明">📖</button>' : '<span class="text-slate-700">—</span>') + '</td>' +
cell('composite', s._composite, v => v + (s._confidence != null && s._confidence < 1 ? '<span class="text-slate-500 text-[10px]">×' + s._confidence.toFixed(2) + '</span>' : ''), 'font-bold text-amber-300') +
cell('universality_score', (st.universality || {}).score, v => v + '<span class="text-slate-500">/' + (st.universality || {}).months + '月</span>') +
+78 -4
View File
@@ -494,6 +494,47 @@ def get_strategy(version):
# 各策略的最优仓位模型(仓位扫描实证,2026-07-29)
# 波段/结构出场适合大仓少股,固定出场适合小仓多股
def _v81_conviction(version, name, summary, hypothesis, conviction):
"""v8.1波段基座 + 信念分级仓位配置(2026-07-30 正式注册,替代临时脚本)"""
s = _v40_branch(version, name, summary, hypothesis,
entry_overrides={"vol_ratio_min": 0.9, "vol_ratio_max": 2.0, "sector_slope_max": 1.0,
"hl_only": True, "rsi_delta_min": 6},
exit_overrides={"tp_pct": None, "exit_mode": "swing", "sl_atr": 1.5,
"max_hold_days": 60, "reentry_days": 10})
s['config']['conviction'] = conviction
s['created'] = '2026-07-30'
return s
STRATEGIES.update({
"v_next": _v81_conviction("v_next", "v8.1+三重信念×2(平铺)",
"v8.1波段基座; 任一信念因子命中(DNA/行业ADX>=20/资金加速度)仓位×2, 不叠乘",
"v8.1波段单笔最优(均赢+21.78%), 信念因子区分好坏票——命中即加倍, 简单稳健",
{"model": "平铺: DNA or 行业ADX>=20 or flow_delta>0 → ×2",
"stack": False, "dna_mult": 2.0, "sector_adx_min": 20, "sector_mult": 2.0,
"flow_delta_min": 0, "flow_mult": 2.0}),
"v_next3": _v81_conviction("v_next3", "v8.1+信念叠乘+行业牛杠杆",
"v8.1波段基座; DNA×2 + 行业ADX>25×2 + flow_delta>0×2 叠乘, 封顶×4",
"多因子共振的票才是极品配最重仓; 行业ADX>25=行业级确认牛, 比>=20更精准",
{"model": "叠乘封顶×4: DNA×2 + 行业ADX>25×2 + flow_delta>0×2",
"stack": True, "cap": 4.0, "dna_mult": 2.0, "sector_adx_min": 25, "sector_mult": 2.0,
"flow_delta_min": 0, "flow_mult": 2.0}),
})
STRATEGY_DESCRIPTIONS.update({
"v_next": {
"title": "v8.1+三重信念×2 平铺版(DNA/行业ADX≥20/资金加速度, 任一命中即×2)",
"algorithm": "v8.1波段出场基座 + 三重信念信号平铺重仓: 动量基因DNA、行业趋势强(行业ADX≥20)、资金加速(flow_delta>0)——任一命中仓位×2, 多命中不叠乘。基准3仓。",
"rationale": "v8.1波段单笔最优(均赢+21.78%), 信念因子区分好坏票——命中即加倍, 规则简单稳健。与v_next3的区别: 平铺只分'有没有信念', 不区分'信念有多强'",
"evidence": "5年全参与+48.3%(年化8.8%)/回撤4.1%。×2票69%胜率/+14.23% vs ×1票48%/+5.99%。规则经逆向验证103/103笔精确复现(平铺×2)。",
},
"v_next3": {
"title": "v8.1+信念叠乘+行业牛杠杆(DNA×2·行业ADX>25×2·资金加速度×2, 封顶×4)【当前最优】",
"algorithm": "v8.1波段出场基座 + 信念因子叠乘重仓: 动量基因DNA×2、行业确认牛(行业ADX>25)×2、资金加速度(flow_delta>0)×2; 多因子同时命中则叠乘, 封顶×4; 均不命中×1。基准3仓, 单票最大4倍基准仓。",
"rationale": "v_next平铺只区分'有没有信念', 叠乘区分'信念有多强'——多因子共振的票是极品, 配最重仓位。行业ADX>25是行业级确认牛(比≥20更严格), 对应生产端行业牛杠杆(ADX>25升一档仓位)。",
"evidence": "5年103笔/57.3%胜率, 全参与+55.6%(年化9.1%)/回撤4.1%, 收益/回撤比12.4全场最优。boost分布×1:56笔/×2:37笔/×4:10笔。规则经逆向验证102/103笔精确复现。",
},
})
STRATEGY_SIZING = {
'v7.1': 4, # 固定15%出场,4仓+74.6%最优(10仓+59.8%)
'v7.2': 3, # 分批止盈,3仓+60.7%
@@ -505,6 +546,8 @@ STRATEGY_SIZING = {
'v7.1b': 4, # 同v7.14仓
'v11.0': 3, # 枢轴波段,3仓+116.4%
'v11.1': 3, # 枢轴强压/弱撑,3仓+55.8%
'v_next': 3, # 信念平铺×2,同v8.1基座3仓
'v_next3': 3, # 信念叠乘封顶×4,同v8.1基座3仓
}
@@ -937,6 +980,7 @@ def run_backtest(strategy_version, start_date, end_date, capital=913000, save=Tr
factors['sector_inflow'] = sc_ctx.get('inflow')
factors['sector_above_ma20'] = sc_ctx.get('above_ma20')
factors['sector_slope'] = sc_ctx.get('slope')
factors['sector_adx'] = sc_ctx.get('adx')
# 资金面因子
fl = flow_ctx(code, date, None, i)
factors.update(fl)
@@ -1236,10 +1280,40 @@ def run_backtest(strategy_version, start_date, end_date, capital=913000, save=Tr
_y0 = datetime.strptime(start_date, '%Y-%m-%d')
_y1 = datetime.strptime(end_date, '%Y-%m-%d')
_bt_years = max((_y1 - _y0).days / 365.0, 0.5)
# 信念缩放(通用,2026-07-29验证全策略+7~16pp:动量基因票默认×2.5
boost_k = cfg.get('exit', {}).get('dna_boost', 2.5)
for t in trades:
t['boost'] = boost_k if t.get('dna') else 1.0
# 信念缩放:优先 conviction 多因子配置,否则默认动量基因×2.52026-07-29验证全策略+7~16pp
conv = cfg.get('conviction')
if conv:
_dna_m = conv.get('dna_mult', 2.0)
_sec_t = conv.get('sector_adx_min', 25)
_sec_m = conv.get('sector_mult', 2.0)
_flo_t = conv.get('flow_delta_min', 0)
_flo_m = conv.get('flow_mult', 2.0)
_cap = conv.get('cap')
_stack = conv.get('stack', True)
for t in trades:
_f = t.get('factors') or {}
_sa = _f.get('sector_adx')
_sec_hit = _sa is not None and _sa > _sec_t
_fd = _f.get('flow_delta')
_flo_hit = _fd is not None and _fd > _flo_t
if _stack:
b = 1.0
if t.get('dna'):
b *= _dna_m
if _sec_hit:
b *= _sec_m
if _flo_hit:
b *= _flo_m
if _cap:
b = min(b, _cap)
else:
b = _dna_m if (t.get('dna') or _sec_hit or _flo_hit) else 1.0
t['boost'] = b
summary['conviction_model'] = conv.get('model', '')
else:
boost_k = cfg.get('exit', {}).get('dna_boost', 2.5)
for t in trades:
t['boost'] = boost_k if t.get('dna') else 1.0
# 集中仓位(该策略最优激进仓位)
slots = STRATEGY_SIZING.get(strategy_version, 10)
summary['portfolio'] = portfolio_sim(trades, capital, slots)