Explorar el Código

feat(MAPatternStrategy): 增加开盘价差过滤功能并重构相关逻辑

- 新增enable_open_gap_filter配置开关控制开盘价差过滤是否启用
- 在初始化函数添加开盘价差过滤开关参数和日志记录
- 将开盘价差检查逻辑提取为独立函数check_open_gap_filter,简化主流程代码
- 根据不同策略模式及方向,分别判断开盘价差是否满足阈值要求
- 不满足开盘价差条件的合约加入排除列表,防止后续选入候选
- 开启开盘价差过滤时调用专用函数,关闭时跳过该检查并记录日志
maxfeng hace 1 mes
padre
commit
bc1a23f456
Se han modificado 1 ficheros con 77 adiciones y 27 borrados
  1. 77 27
      Lib/future/MAPatternStrategy_v002.py

+ 77 - 27
Lib/future/MAPatternStrategy_v002.py

@@ -61,6 +61,7 @@ def initialize(context):
     g.ma_distribution_min_ratio = 0.4  # MA5分布满足比例阈值
     g.enable_ma_distribution_filter = True  # 是否启用MA5分布过滤
     g.ma_cross_threshold = 1  # 均线穿越数量阈值
+    g.enable_open_gap_filter = True  # 是否启用开盘价差过滤
     
     # 均线价差策略方案选择
     g.ma_gap_strategy_mode = 3  # 策略模式选择(1: 原方案, 2: 新方案, 3: 方案3)
@@ -89,6 +90,7 @@ def initialize(context):
     log.info(f"  启用MA5分布过滤: {g.enable_ma_distribution_filter}")
     log.info(f"  是否检查日内价差: {g.check_intraday_spread}")
     log.info(f"  均线穿越阈值: {g.ma_cross_threshold}")
+    log.info(f"  是否启用开盘价差过滤: {g.enable_open_gap_filter}")
     log.info(f"  固定止损: {g.fixed_stop_loss_rate:.1%}")
     log.info(f"  均线跟踪止盈常规偏移: {g.ma_offset_ratio_normal:.1%}")
     log.info(f"  均线跟踪止盈收盘前偏移: {g.ma_offset_ratio_close:.1%}")
@@ -496,33 +498,20 @@ def check_ma_trend_and_open_gap(context):
                 log.info(f"  {symbol}({dominant_future}) ✓ 历史均线模式一致性检查通过 "
                         f"({consistency_ratio:.1%} >= {g.ma_pattern_consistency_threshold:.1%})")
             
-            # 步骤9:计算开盘价差并检查(合并优化)
-            open_gap_ratio = (today_open - yesterday_close) / yesterday_close
-            log.info(f"  开盘价差检查: 昨收 {yesterday_close:.2f}, 今开 {today_open:.2f}, "
-                    f"价差比例 {open_gap_ratio:.2%}")
-            
-            # 检查开盘价差是否符合方向要求
-            gap_check_passed = False
-            if g.ma_gap_strategy_mode == 1:
-                # 方案1:多头检查上跳,空头检查下跳
-                if direction == 'long' and open_gap_ratio >= g.ma_open_gap_threshold:
-                    log.info(f"  {symbol}({dominant_future}) ✓ 方案1多头开盘价差检查通过 ({open_gap_ratio:.2%} >= {g.ma_open_gap_threshold:.2%})")
-                    gap_check_passed = True
-                elif direction == 'short' and open_gap_ratio <= -g.ma_open_gap_threshold:
-                    log.info(f"  {symbol}({dominant_future}) ✓ 方案1空头开盘价差检查通过 ({open_gap_ratio:.2%} <= {-g.ma_open_gap_threshold:.2%})")
-                    gap_check_passed = True
-            elif g.ma_gap_strategy_mode == 2 or g.ma_gap_strategy_mode == 3:
-                # 方案2和方案3:多头检查下跳,空头检查上跳
-                if direction == 'long' and open_gap_ratio <= -g.ma_open_gap_threshold2:
-                    log.info(f"  {symbol}({dominant_future}) ✓ 方案{g.ma_gap_strategy_mode}多头开盘价差检查通过 ({open_gap_ratio:.2%} <= {-g.ma_open_gap_threshold2:.2%})")
-                    gap_check_passed = True
-                elif direction == 'short' and open_gap_ratio >= g.ma_open_gap_threshold2:
-                    log.info(f"  {symbol}({dominant_future}) ✓ 方案{g.ma_gap_strategy_mode}空头开盘价差检查通过 ({open_gap_ratio:.2%} >= {g.ma_open_gap_threshold2:.2%})")
-                    gap_check_passed = True
-            
-            if not gap_check_passed:
-                add_to_excluded_contracts(dominant_future, 'open_gap', current_trading_day)
-                continue
+            # 步骤9:检查开盘价差(可配置开关)
+            if g.enable_open_gap_filter:
+                gap_check_passed = check_open_gap_filter(
+                    symbol=symbol,
+                    dominant_future=dominant_future,
+                    direction=direction,
+                    yesterday_close=yesterday_close,
+                    today_open=today_open,
+                    current_trading_day=current_trading_day
+                )
+                if not gap_check_passed:
+                    continue
+            else:
+                log.info("  已关闭开盘价差过滤(enable_open_gap_filter=False),跳过该检查")
             
             # 步骤10:将通过检查的品种加入候选列表
             g.daily_ma_candidates[dominant_future] = {
@@ -1006,6 +995,67 @@ def check_ma5_distribution_filter(data, lookback_days, direction, min_ratio):
     return stats['qualified_days'] >= stats['required_days'], stats
 
 
+def check_open_gap_filter(symbol, dominant_future, direction, yesterday_close, today_open, current_trading_day):
+    """开盘价差过滤辅助函数
+
+    根据当前策略模式(`g.ma_gap_strategy_mode`)和对应阈值检查开盘价差是否符合方向要求。
+
+    Args:
+        symbol: 品种代码(如 'AO')
+        dominant_future: 主力合约代码(如 'AO2502.XSGE')
+        direction: 方向,'long' 或 'short'
+        yesterday_close: 前一交易日收盘价
+        today_open: 当日开盘价
+        current_trading_day: 当前期货交易日
+
+    Returns:
+        bool: True 表示通过开盘价差过滤,False 表示未通过(并已加入排除缓存)
+    """
+    open_gap_ratio = (today_open - yesterday_close) / yesterday_close
+    log.info(
+        f"  开盘价差检查: 昨收 {yesterday_close:.2f}, 今开 {today_open:.2f}, "
+        f"价差比例 {open_gap_ratio:.2%}"
+    )
+
+    gap_check_passed = False
+
+    if g.ma_gap_strategy_mode == 1:
+        # 方案1:多头检查上跳,空头检查下跳
+        if direction == 'long' and open_gap_ratio >= g.ma_open_gap_threshold:
+            log.info(
+                f"  {symbol}({dominant_future}) ✓ 方案1多头开盘价差检查通过 "
+                f"({open_gap_ratio:.2%} >= {g.ma_open_gap_threshold:.2%})"
+            )
+            gap_check_passed = True
+        elif direction == 'short' and open_gap_ratio <= -g.ma_open_gap_threshold:
+            log.info(
+                f"  {symbol}({dominant_future}) ✓ 方案1空头开盘价差检查通过 "
+                f"({open_gap_ratio:.2%} <= {-g.ma_open_gap_threshold:.2%})"
+            )
+            gap_check_passed = True
+    elif g.ma_gap_strategy_mode == 2 or g.ma_gap_strategy_mode == 3:
+        # 方案2和方案3:多头检查下跳,空头检查上跳
+        if direction == 'long' and open_gap_ratio <= -g.ma_open_gap_threshold2:
+            log.info(
+                f"  {symbol}({dominant_future}) ✓ 方案{g.ma_gap_strategy_mode}多头开盘价差检查通过 "
+                f"({open_gap_ratio:.2%} <= {-g.ma_open_gap_threshold2:.2%})"
+            )
+            gap_check_passed = True
+        elif direction == 'short' and open_gap_ratio >= g.ma_open_gap_threshold2:
+            log.info(
+                f"  {symbol}({dominant_future}) ✓ 方案{g.ma_gap_strategy_mode}空头开盘价差检查通过 "
+                f"({open_gap_ratio:.2%} >= {g.ma_open_gap_threshold2:.2%})"
+            )
+            gap_check_passed = True
+
+    if not gap_check_passed:
+        add_to_excluded_contracts(dominant_future, 'open_gap', current_trading_day)
+        return False
+
+    return True
+
+
+
 def check_ma_pattern(ma_values, direction):
     """检查均线排列模式是否符合方向要求