feat: 枢轴S/R注入回测引擎+v11系列——枢轴波段(v11.0)4仓+86.3%/回撤1.3%碾压MA10波段,证明复合强弱支撑优于简单均线;固定15%/ATR仍优于裸枢轴强压止盈

This commit is contained in:
hmo
2026-07-29 13:21:28 +08:00
parent dfdd7490f2
commit ff54d37915
2 changed files with 93 additions and 8 deletions
+68 -7
View File
@@ -258,6 +258,19 @@ STRATEGIES.update({
"v9归因反用:v7.1交易中weekly_up=False胜率78.4% vs True 60.9%——周线级回调中的日线动量回归正是本策略的核心边缘",
entry_overrides={"vol_ratio_min": 0.9, "vol_ratio_max": 2.0, "sector_slope_max": 1.0,
"hl_only": True, "rsi_delta_min": 6, "weekly_down_only": True}),
# I组: 枢轴S/R出场(与实盘technical_analysis同算法)
"v11.0": _v40_branch("v11.0", "波段·枢轴版",
"v8.1入场;出场改枢轴体系:破弱支撑先出,收复弱压且创新高再进",
"v8.1的MA10只是弱支撑的粗糙代理——用实盘同款枢轴S/R验证复合技术位是否优于简单均线",
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_pivot", "sl_atr": 1.5, "max_hold_days": 60, "reentry_days": 10}),
"v11.1": _v40_branch("v11.1", "强压止盈弱撑止损",
"v7.1入场;出场改实盘口径:强压止盈+弱支撑止损(枢轴点体系,替代固定15%/1.5ATR",
"实盘策略的真实出场方式就是枢轴S/R——回测必须验证这个口径而非固定百分比",
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, "use_pivot_sr": True, "max_hold_days": 20}),
# ── 港股专用版本(港股通宇宙归因推导,2026-07-29)──
"h1.0": {
"version": "h1.0",
@@ -694,7 +707,13 @@ def run_backtest(strategy_version, start_date, end_date, capital=1000000, save=T
if pass_filters(factors, filters):
atr_val = last.get('atr') or 0
if exit_cfg.get('tp_pct'):
if exit_cfg.get('use_pivot_sr'):
# 实盘口径:强压止盈 + 弱支撑止损(枢轴点体系)
target = last.get('strong_resist') if (last.get('strong_resist') or 0) > close else None
stop = last.get('weak_support') if (last.get('weak_support') or 0) < close else (close - atr_val * exit_cfg.get('sl_atr', 1.5) if atr_val > 0 else close * 0.93)
if target is None:
target = close * (1 + exit_cfg.get('tp_pct', 0.15))
elif exit_cfg.get('tp_pct'):
target = close * (1 + exit_cfg['tp_pct'])
elif exit_cfg.get('tp_atr') and atr_val > 0:
target = close + atr_val * exit_cfg['tp_atr']
@@ -702,12 +721,13 @@ def run_backtest(strategy_version, start_date, end_date, capital=1000000, save=T
target = None # 移动止盈模式无固定目标
else:
target = close * 1.10
if exit_cfg.get('sl_atr') and atr_val > 0:
stop = close - atr_val * exit_cfg['sl_atr']
elif exit_cfg.get('sl_pct'):
stop = close * (1 - exit_cfg['sl_pct'])
else:
stop = close * 0.93
if not exit_cfg.get('use_pivot_sr'):
if exit_cfg.get('sl_atr') and atr_val > 0:
stop = close - atr_val * exit_cfg['sl_atr']
elif exit_cfg.get('sl_pct'):
stop = close * (1 - exit_cfg['sl_pct'])
else:
stop = close * 0.93
kelly = 0
if cfg['sizing'].get('kelly'):
@@ -832,6 +852,47 @@ def run_backtest(strategy_version, start_date, end_date, capital=1000000, save=T
pnl = (total_ret - 1) * 100
exit_price = close * total_ret
hold_days = len(future) if future else 0
elif exit_cfg.get('exit_mode') == 'swing_pivot':
# ── 波段·枢轴版:破弱支撑先出,收复弱压且创新高再进 ──
reentry_window = exit_cfg.get('reentry_days', 10)
legs = []
in_pos = True
entry_p = close
stop_cur = stop
wait = 0
exit_reason = 'keep'
for k, fb in enumerate(future):
fh, fl, fc = fb.get('high') or 0, fb.get('low') or 0, fb.get('close') or 0
fws, fwr = fb.get('weak_support') or 0, fb.get('weak_resist') or 0
if in_pos:
if fl <= stop_cur:
legs.append(fc/entry_p - 1)
exit_reason = 'stop'
in_pos = False
break
if fws > 0 and fc < fws:
legs.append(fc/entry_p - 1)
in_pos = False
wait = reentry_window
exit_reason = 'swing_out'
else:
wait -= 1
if wait < 0:
break
prev_high = future[k-1].get('high') or 0 if k > 0 else 0
if fwr > 0 and fc > fwr and fh > prev_high:
in_pos = True
entry_p = fc
stop_cur = fb.get('weak_support') or (fc - atr_val * exit_cfg.get('sl_atr', 1.5) if atr_val > 0 else fc * 0.93)
exit_reason = 'swing_re'
if in_pos:
legs.append((future[-1].get('close') if future else entry_p)/entry_p - 1)
total_ret = 1.0
for l in legs:
total_ret *= (1 + l)
pnl = (total_ret - 1) * 100
exit_price = close * total_ret
hold_days = len(future) if future else 0
else:
exit_price = exit_reason = None
hold_days = 0