Преглед изворни кода

优化MAPatternStrategy_v002.py,简化开仓条件检查逻辑,仅依赖均线穿越得分,更新得分计算函数以返回得分详情,增强日志信息以便于调试。

maxfeng пре 1 месец
родитељ
комит
1e9e7e0761
1 измењених фајлова са 33 додато и 58 уклоњено
  1. 33 58
      Lib/future/MAPatternStrategy_v002.py

+ 33 - 58
Lib/future/MAPatternStrategy_v002.py

@@ -204,7 +204,7 @@ def initialize(context):
     
     # 策略品种选择策略配置
     # 方案1:全品种策略 - 考虑所有配置的期货品种
-    g.strategy_focus_symbols = ['AU']  # 空列表表示考虑所有品种
+    g.strategy_focus_symbols = []  # 空列表表示考虑所有品种
     
     # 方案2:精选品种策略 - 只交易流动性较好的特定品种(如需使用请取消下行注释)
     # g.strategy_focus_symbols = ['RM', 'CJ', 'CY', 'JD', 'L', 'LC', 'SF', 'SI']
@@ -603,60 +603,13 @@ def check_open_and_stop(context):
                 log.info(f"  方向: {direction}, 开盘价: {open_price:.2f}, 当前价: {current_price:.2f}, "
                         f"当天价差: {intraday_diff:.2f}, 变化比例: {intraday_diff_ratio:.2%}")
                 
-                # 判断是否满足开仓条件
-                should_open = False
-                
-                if g.ma_gap_strategy_mode == 1:
-                    # 方案1:根据参数决定是否检查日内价差
-                    if not g.check_intraday_spread:
-                        log.info(f"  方案1跳过日内价差检查(check_intraday_spread=False)")
-                        should_open = True
-                    elif direction == 'long' and intraday_diff > 0:
-                        log.info(f"  ✓ 方案1多头当天价差检查通过 ({intraday_diff:.2f} > 0)")
-                        should_open = True
-                    elif direction == 'short' and intraday_diff < 0:
-                        log.info(f"  ✓ 方案1空头当天价差检查通过 ({intraday_diff:.2f} < 0)")
-                        should_open = True
-                    else:
-                        log.info(f"  ✗ 方案1当天价差不符合{direction}方向要求")
-                        
-                elif g.ma_gap_strategy_mode == 2:
-                    # 方案2:强制检查日内变化,使用专用阈值
-                    if direction == 'long' and intraday_diff_ratio >= g.ma_intraday_threshold_scheme2:
-                        log.info(f"  ✓ 方案2多头日内变化检查通过 ({intraday_diff_ratio:.2%} >= {g.ma_intraday_threshold_scheme2:.2%})")
-                        should_open = True
-                    elif direction == 'short' and intraday_diff_ratio <= -g.ma_intraday_threshold_scheme2:
-                        log.info(f"  ✓ 方案2空头日内变化检查通过 ({intraday_diff_ratio:.2%} <= {-g.ma_intraday_threshold_scheme2:.2%})")
-                        should_open = True
-                    else:
-                        log.info(f"  ✗ 方案2日内变化不符合{direction}方向要求(阈值: ±{g.ma_intraday_threshold_scheme2:.2%})")
-                        
-                elif g.ma_gap_strategy_mode == 3:
-                    # 方案3:下跳后上涨(多头)或上跳后下跌(空头),并检查当前价格与前一日开盘收盘均值的关系
-                    if yesterday_open is not None and yesterday_close is not None:
-                        prev_day_avg = (yesterday_open + yesterday_close) / 2
-                        log.debug(f"  前一日开盘价: {yesterday_open:.2f}, 前一日收盘价: {yesterday_close:.2f}, 前一日开盘收盘均值: {prev_day_avg:.2f}")
-                        
-                        if direction == 'long':
-                            # 多头:当前价格 >= 前一日开盘收盘均值
-                            if current_price >= prev_day_avg:
-                                log.info(f"  ✓ 方案3多头入场条件通过: 当前价 {current_price:.2f} >= 前日均值 {prev_day_avg:.2f}")
-                                should_open = True
-                            else:
-                                log.info(f"  ✗ 方案3多头入场条件未通过: 当前价 {current_price:.2f} < 前日均值 {prev_day_avg:.2f}")
-                        elif direction == 'short':
-                            # 空头:当前价格 <= 前一日开盘收盘均值
-                            if current_price <= prev_day_avg:
-                                log.info(f"  ✓ 方案3空头入场条件通过: 当前价 {current_price:.2f} <= 前日均值 {prev_day_avg:.2f}")
-                                should_open = True
-                            else:
-                                log.info(f"  ✗ 方案3空头入场条件未通过: 当前价 {current_price:.2f} > 前日均值 {prev_day_avg:.2f}")
-                    else:
-                        log.info(f"  ✗ 方案3缺少前一日开盘或收盘价数据")
+                # 判断是否满足开仓条件 - 仅检查均线穿越得分
+                should_open = True
+                log.info(f"  开仓条件简化:仅检查均线穿越得分,跳过策略1,2,3的判断")
                 
                 if should_open:
                     ma_values = candidate_info.get('ma_values') or {}
-                    cross_score = calculate_ma_cross_score(open_price, current_price, ma_values, direction)
+                    cross_score, score_details = calculate_ma_cross_score(open_price, current_price, ma_values, direction)
 
                     # 根据当前时间调整所需的均线穿越得分阈值
                     current_time_str = str(context.current_dt.time())[:5]  # HH:MM格式
@@ -665,9 +618,26 @@ def check_open_and_stop(context):
                         # 在14:55以外的时间,需要更高的得分阈值
                         required_cross_score = g.ma_cross_threshold + 1
 
-                    log.info(f"  均线穿越得分: {cross_score}, 当前时间: {current_time_str}, 所需阈值: {required_cross_score}")
-                    if cross_score < required_cross_score:
-                        log.info(f"  ✗ 均线穿越得分不足({cross_score} < {required_cross_score}),跳过开仓")
+                    log.info(f"  均线穿越得分: {cross_score}, 得分详情: {score_details}, 当前时间: {current_time_str}, 所需阈值: {required_cross_score}")
+
+                    # 检查得分是否满足条件
+                    score_passed = False
+                    if cross_score >= required_cross_score:
+                        # 如果得分达到阈值,检查特殊情况:只有1分且来自MA5
+                        if cross_score == 1 and required_cross_score == 1:
+                            # 检查这一分是否来自MA5
+                            from_ma5_only = len(score_details) == 1 and score_details[0]['period'] == 5
+                            if not from_ma5_only:
+                                score_passed = True
+                                log.info(f"  ✓ 均线穿越得分检查通过:1分且非来自MA5")
+                            else:
+                                log.info(f"  ✗ 均线穿越得分检查未通过:1分且仅来自MA5")
+                        else:
+                            score_passed = True
+                            log.info(f"  ✓ 均线穿越得分检查通过")
+
+                    if not score_passed:
+                        log.info(f"  ✗ 均线穿越得分不足或不符合条件({cross_score} < {required_cross_score} 或 1分来自MA5),跳过开仓")
                         continue
                     # 执行开仓
                     log.info(f"  准备开仓: {symbol} {direction}")
@@ -903,11 +873,15 @@ def calculate_ma_values(data, periods):
 
 
 def calculate_ma_cross_score(open_price, current_price, ma_values, direction):
-    """根据开盘价与当前价统计多周期均线穿越得分"""
+    """根据开盘价与当前价统计多周期均线穿越得分
+    返回: (总得分, 得分详情列表)
+    得分详情: [{'period': 5, 'delta': 1}, {'period': 10, 'delta': 1}, ...]
+    """
     if not ma_values:
-        return 0
+        return 0, []
     assert direction in ('long', 'short')
     score = 0
+    score_details = []
     for period in g.ma_periods:
         key = f'MA{period}'
         ma_value = ma_values.get(key)
@@ -922,11 +896,12 @@ def calculate_ma_cross_score(open_price, current_price, ma_values, direction):
         else:
             delta = -1 if cross_up else 1
         score += delta
+        score_details.append({'period': period, 'delta': delta})
         log.debug(
             f"  均线穿越[{key}] - 开盘 {open_price:.2f}, 当前 {current_price:.2f}, "
             f"均线 {ma_value:.2f}, 方向 {direction}, 增量 {delta}, 当前得分 {score}"
         )
-    return score
+    return score, score_details
 
 
 def calculate_ma_proximity_counts(data, periods, lookback_days):