Эх сурвалжийг харах

feat(MAPatternStrategy): 更新开仓逻辑以支持单手保证金限制检查

- 修改 `open_position` 函数,增加 `single_hand_exceeds_limit` 参数以处理单手保证金超过最大限制的情况
- 更新 `calculate_target_hands` 函数,返回目标开仓手数及单手保证金是否超过限制
- 优化开仓时的下单逻辑,根据单手保证金情况选择不同的下单方式,提升交易灵活性和安全性
maxfeng 1 сар өмнө
parent
commit
ed21be3563

+ 40 - 13
Lib/future/MAPatternStrategy_v002.py

@@ -657,11 +657,21 @@ def check_open_and_stop(context):
                             continue
                     # 执行开仓
                     log.info(f"  准备开仓: {symbol} {direction}")
-                    target_hands, single_hand_margin = calculate_target_hands(context, dominant_future, direction)
+                    target_hands, single_hand_margin, single_hand_exceeds_limit = calculate_target_hands(
+                        context, dominant_future, direction)
                     
                     if target_hands > 0:
-                        success = open_position(context, dominant_future, target_hands, direction, single_hand_margin,
-                                              f'均线形态开仓', crossed_ma_details=score_details, entry_snapshot=entry_snapshot)
+                        success = open_position(
+                            context,
+                            dominant_future,
+                            target_hands,
+                            direction,
+                            single_hand_margin,
+                            single_hand_exceeds_limit,
+                            f'均线形态开仓',
+                            crossed_ma_details=score_details,
+                            entry_snapshot=entry_snapshot
+                        )
                         if success:
                             log.info(f"  ✓✓ {symbol} 开仓成功,从候选列表移除")
                             candidates_to_remove.append(dominant_future)
@@ -1170,15 +1180,27 @@ def check_historical_ma_pattern_consistency(historical_data, direction, lookback
 
 ############################ 交易执行函数 ###################################
 
-def open_position(context, security, target_hands, direction, single_hand_margin, reason='',
+def open_position(context, security, target_hands, direction, single_hand_margin,
+                  single_hand_exceeds_limit, reason='',
                   crossed_ma_details=None, entry_snapshot=None):
-    """开仓并可选地在成交后校验保证金"""
+    """开仓并可选地在成交后校验保证金
+    
+    Args:
+        single_hand_exceeds_limit: bool,当单手保证金超过最大限制时为True
+    """
     try:
         # 记录交易前的可用资金
         cash_before = context.portfolio.available_cash
         
-        # 使用order_target按手数开仓
-        order = order_target(security, target_hands, side=direction)
+        # 根据单手保证金情况选择下单方式
+        use_value_order = (not single_hand_exceeds_limit) and getattr(g, 'max_margin_per_position', 0) > 0
+        if use_value_order:
+            target_value = g.max_margin_per_position
+            order = order_target_value(security, target_value, side=direction)
+            log.debug(f"使用order_target_value下单: {security} {direction} 目标价值 {target_value}")
+        else:
+            order = order_target(security, target_hands, side=direction)
+            log.debug(f"使用order_target按手数下单: {security} {direction} 目标手数 {target_hands}")
         log.debug(f"order: {order}")
         
         # 检查订单状态,如果为'new'说明当晚没有夜盘
@@ -1266,8 +1288,8 @@ def open_position(context, security, target_hands, direction, single_hand_margin
                     f"保证金: {margin_change:.0f}, 资金变化: {cash_change:.0f}, 原因: {reason}, "
                     f"穿越均线: {crossed_ma_str}")
             
-            log.debug(f"开仓后检查并补足保证金占用,使其满足最小要求")
-            verify_position_margin_requirement(context, security)
+            # log.debug(f"开仓后检查并补足保证金占用,使其满足最小要求")
+            # verify_position_margin_requirement(context, security)
             
             return True
             
@@ -1508,7 +1530,11 @@ def has_reached_trading_start(current_dt, trading_start_time_str, has_night_sess
     return True
 
 def calculate_target_hands(context, security, direction):
-    """计算目标开仓手数"""
+    """计算目标开仓手数
+    
+    Returns:
+        tuple: (target_hands, single_hand_margin, single_hand_exceeds_limit)
+    """
     current_price = get_current_data()[security].last_price
     underlying_symbol = security.split('.')[0][:-4]
     
@@ -1525,8 +1551,9 @@ def calculate_target_hands(context, security, direction):
     
     # 根据单个标的最大持仓保证金限制计算开仓数量
     max_margin = g.max_margin_per_position
+    single_hand_exceeds_limit = single_hand_margin > max_margin
     
-    if single_hand_margin <= max_margin:
+    if not single_hand_exceeds_limit:
         # 如果单手保证金不超过最大限制,计算最大可开仓手数
         max_hands = int(max_margin / single_hand_margin)
         max_hands_by_cash = int(available_cash / single_hand_margin)
@@ -1539,14 +1566,14 @@ def calculate_target_hands(context, security, direction):
         
         log.info(f"单手保证金: {single_hand_margin:.0f}, 目标开仓手数: {actual_hands}")
         
-        return actual_hands, single_hand_margin
+        return actual_hands, single_hand_margin, single_hand_exceeds_limit
     else:
         # 如果单手保证金超过最大限制,默认开仓1手
         actual_hands = 1
         
         log.info(f"单手保证金: {single_hand_margin:.0f} 超过最大限制: {max_margin}, 默认开仓1手")
         
-        return actual_hands, single_hand_margin
+        return actual_hands, single_hand_margin, single_hand_exceeds_limit
 
 def check_symbol_prefix_match(symbol, context, hold_symbols):
     """检查是否有相似的持仓品种"""