From da1e0242d661f5fa45bd0e9559148cd6ab6d5ac0 Mon Sep 17 00:00:00 2001 From: hmo Date: Wed, 29 Jul 2026 09:30:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B8=AF=E8=82=A1=E9=80=9A=E8=B5=9B?= =?UTF-8?q?=E9=81=93=E2=80=94=E2=80=94HSI=E5=85=A8=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E5=85=A5=E5=BA=93+29=E5=8F=AA=E6=B8=AF=E8=82=A1=E9=80=9A?= =?UTF-8?q?=E6=B1=A0=E5=9B=9E=E5=A1=AB+=E5=88=86=E5=B8=82=E5=9C=BA?= =?UTF-8?q?=E6=83=85=E6=99=AF=E5=88=A4=E6=96=AD(A=E8=82=A1=E7=9C=8B?= =?UTF-8?q?=E4=B8=8A=E8=AF=81/=E6=B8=AF=E8=82=A1=E7=9C=8B=E6=81=92?= =?UTF-8?q?=E6=8C=87)+13=E4=B8=AA=E6=B8=AF=E8=82=A1=E8=87=AA=E5=BB=BA?= =?UTF-8?q?=E6=9D=BF=E5=9D=97=E6=8C=87=E6=95=B0+=E6=B8=AF=E8=82=A1?= =?UTF-8?q?=E8=A1=8C=E4=B8=9A=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/profile-scripts/v71_gate.py | 2 +- strategy_lab.py | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/deploy/profile-scripts/v71_gate.py b/deploy/profile-scripts/v71_gate.py index 85825d5d..6a0ba49c 100644 --- a/deploy/profile-scripts/v71_gate.py +++ b/deploy/profile-scripts/v71_gate.py @@ -63,7 +63,7 @@ def check_entry_gate(code, price=None): factors = calc_factors(bars, len(bars) - 1) date = bars[-1]['date'] - mk = mkt_ctx(date) + mk = mkt_ctx(date, code) sec = sector_ctx(code, date) factors['mkt_above_ma20'] = mk.get('above_ma20') factors['mkt_slope'] = mk.get('ma20_slope') diff --git a/strategy_lab.py b/strategy_lab.py index 839ce2e3..c7065ac2 100644 --- a/strategy_lab.py +++ b/strategy_lab.py @@ -275,12 +275,16 @@ _SECTOR_CTX = {} _STOCK_SECTOR = {} def prepare_market_context(start_date, end_date): - """大盘指数(sh000001)每日状态: 是否在MA20上、MA20斜率、ROC""" - global _MKT_CTX - _MKT_CTX = {} - bars = prepare_bars('sh000001', start_date, end_date) + """大盘指数每日状态: A股用上证(sh000001),港股用恒生(hkHSI)""" + global _MKT_CTX, _MKT_CTX_HK + _MKT_CTX = _load_index_ctx('sh000001', start_date, end_date) + _MKT_CTX_HK = _load_index_ctx('hkHSI', start_date, end_date) + +def _load_index_ctx(index_code, start_date, end_date): + ctx = {} + bars = prepare_bars(index_code, start_date, end_date) if not bars: - return + return ctx for i, b in enumerate(bars): slope = None if i >= 5: @@ -288,11 +292,15 @@ def prepare_market_context(start_date, end_date): if m0 and m1: slope = round((m1 - m0) / m0 * 100, 3) ma20 = b.get('ma20') or 0 - _MKT_CTX[b['date']] = { + ctx[b['date']] = { 'above_ma20': (b.get('close') or 0) > ma20 if ma20 > 0 else None, 'ma20_slope': slope, 'roc': b.get('roc'), } + return ctx + +def is_hk_code(code): + return len(code) == 5 and code.startswith('0') def prepare_sector_context(start_date, end_date): """行业上下文: sector_index_daily(全历史) 提供板块趋势; sector_snapshots(近期) 补充净流入""" @@ -353,7 +361,10 @@ def prepare_sector_context(start_date, end_date): finally: conn.close() -def mkt_ctx(date): +def mkt_ctx(date, code=None): + """按市场取大盘情景:港股用恒指,A股用上证""" + if code and is_hk_code(code): + return _MKT_CTX_HK.get(date, {}) return _MKT_CTX.get(date, {}) def sector_ctx(code, date): @@ -614,9 +625,9 @@ def run_backtest(strategy_version, start_date, end_date, capital=1000000, save=T if total_score >= entry_cfg['min_score'] and comp['momentum'] >= entry_cfg['min_momentum']: factors = calc_factors(bars, i) - # 附加大盘/行业上下文 + # 附加大盘/行业上下文(港股用恒指,A股用上证) date = last.get('date') - mk = mkt_ctx(date) + mk = mkt_ctx(date, code) sc_ctx = sector_ctx(code, date) factors['mkt_above_ma20'] = mk.get('above_ma20') factors['mkt_slope'] = mk.get('ma20_slope')