From 816f17ae053dc3df1a3433f622ed0a23aa6c7b44 Mon Sep 17 00:00:00 2001 From: hmo Date: Sat, 15 Aug 2026 01:44:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mr=E6=A1=86=E6=9E=B6=E5=8F=8C=E8=BE=B9?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=A2=9E=E5=BC=BA=E2=80=94=E2=80=94rsi=5Fmin?= =?UTF-8?q?/mom20=5Fmin/vol=5Fratio=5Fmin=E4=B8=8B=E9=99=90+mom20=5Fmax?= =?UTF-8?q?=E6=94=B9is=20not=20None(=E6=B8=AF=E8=82=A1=E8=B6=8B=E5=8A=BF?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E9=9C=80=E8=A6=81,A=E8=82=A1=E6=9C=AA?= =?UTF-8?q?=E8=AE=BE=E4=B8=8D=E5=BD=B1=E5=93=8D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strategy_lab.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/strategy_lab.py b/strategy_lab.py index 79836635..50a99ec7 100644 --- a/strategy_lab.py +++ b/strategy_lab.py @@ -2258,7 +2258,7 @@ def run_mr_backtest(strategy_version, start_date, end_date, capital=913000, trades = [] screened = 0 skip_stats = {'no_bars': 0, 'bias': 0, 'rsi': 0, 'ret60': 0, 'mom20': 0, - 'amount': 0, 'rsi_delta': 0, 'mkt': 0, 'next_open': 0} + 'amount': 0, 'rsi_delta': 0, 'vol_ratio': 0, 'mkt': 0, 'next_open': 0} for code, name in stocks: screened += 1 @@ -2289,7 +2289,9 @@ def run_mr_backtest(strategy_version, start_date, end_date, capital=913000, if bmax is not None and bias60 > bmax: skip_stats['bias'] += 1; i += 1; continue - # 2. RSI 超卖 + # 2. RSI 超卖(rsi_max 上限);2026-08-14 港股趋势策略需 rsi_min 下限(双边对称) + if mr.get('rsi_min') is not None and rsi < mr['rsi_min']: + skip_stats['rsi'] += 1; i += 1; continue if rsi > mr.get('rsi_max', 50): skip_stats['rsi'] += 1; i += 1; continue @@ -2306,10 +2308,12 @@ def run_mr_backtest(strategy_version, start_date, end_date, capital=913000, if rmax is not None and prev_ret60 > rmax: skip_stats['ret60'] += 1; i += 1; continue - # 4. 低动量 + # 4. 低动量(mom20_max 上限;2026-08-14 港股趋势策略需 mom20_min 下限,双边对称,None=不限) prev20 = bars[i-20].get('close') or 0 mom20 = (close - prev20) / prev20 * 100 if prev20 > 0 else 0 - if mom20 > mr.get('mom20_max', 5): + if mr.get('mom20_min') is not None and mom20 < mr['mom20_min']: + skip_stats['mom20'] += 1; i += 1; continue + if mr.get('mom20_max') is not None and mom20 > mr['mom20_max']: skip_stats['mom20'] += 1; i += 1; continue # 5. 小盘(20日均成交额,百万元) @@ -2320,6 +2324,14 @@ def run_mr_backtest(strategy_version, start_date, end_date, capital=913000, if mr.get('amount_max') is not None and amount_ma20_m > mr['amount_max']: skip_stats['amount'] += 1; i += 1; continue + # 5.5 量比(放量确认,2026-08-14 港股趋势策略;A股未设 vol_ratio_min 不生效) + if mr.get('vol_ratio_min') is not None: + _vols = [bars[j].get('volume') or 0 for j in range(max(0, i-19), i+1)] + _vv = [v for v in _vols[:-1] if v > 0] + _vol_ratio = (_vols[-1] / (sum(_vv)/len(_vv))) if _vv and _vols[-1] else 0 + if _vol_ratio < mr['vol_ratio_min']: + skip_stats['vol_ratio'] += 1; i += 1; continue + # 6. 止跌回升确认(RSI 5日回升) if i >= 5: rsi0 = bars[i-5].get('rsi')