|
|
@@ -219,6 +219,10 @@ def initialize(context):
|
|
|
g.ma_checked_underlyings = {} # 记录各品种在交易日的均线检查状态 {symbol: trading_day}
|
|
|
g.last_ma_trading_day = None # 最近一次均线检查所属交易日
|
|
|
|
|
|
+ # 夜盘禁止操作标志
|
|
|
+ g.night_session_blocked = False # 标记是否禁止当晚操作
|
|
|
+ g.night_session_blocked_trading_day = None # 记录被禁止的交易日
|
|
|
+
|
|
|
# 定时任务设置
|
|
|
# 夜盘开始(21:05) - 均线和开盘价差检查
|
|
|
run_daily(check_ma_trend_and_open_gap, time='21:05:00', reference_security='IF1808.CCFX')
|
|
|
@@ -556,6 +560,14 @@ def check_open_and_stop(context):
|
|
|
# 判断是否为夜盘时间
|
|
|
is_night_session = (current_time in ['21', '22', '23', '00', '01', '02'])
|
|
|
|
|
|
+ # 检查是否禁止当晚操作
|
|
|
+ if is_night_session and g.night_session_blocked:
|
|
|
+ blocked_trading_day = normalize_trade_day_value(g.night_session_blocked_trading_day) if g.night_session_blocked_trading_day else None
|
|
|
+ current_trading_day_normalized = normalize_trade_day_value(current_trading_day)
|
|
|
+ if blocked_trading_day == current_trading_day_normalized:
|
|
|
+ log.info(f"当晚操作已被禁止(订单状态为'new',无夜盘),跳过所有操作")
|
|
|
+ return
|
|
|
+
|
|
|
# 第一步:检查开仓条件
|
|
|
log.info(f"检查开仓条件:")
|
|
|
if g.daily_ma_candidates:
|
|
|
@@ -780,12 +792,12 @@ def check_position_stop_loss_profit(context, position):
|
|
|
log.info(f"检查固定止损:")
|
|
|
log.info("=" * 60)
|
|
|
if profit_rate <= -g.fixed_stop_loss_rate:
|
|
|
- log.info(f"触发固定止损 {security} {direction}, 当前亏损率: {profit_rate:.3%}, "
|
|
|
+ log.info(f"{security} {direction} 触发固定止损 {g.fixed_stop_loss_rate:.3%}, 当前亏损率: {profit_rate:.3%}, "
|
|
|
f"成本价: {entry_price:.2f}, 当前价格: {current_price:.2f}")
|
|
|
close_position(context, security, direction)
|
|
|
return True
|
|
|
else:
|
|
|
- log.debug(f"未触发固定止损 {security} {direction}, 当前亏损率: {profit_rate:.3%}, "
|
|
|
+ log.debug(f"{security} {direction} 未触发固定止损 {g.fixed_stop_loss_rate:.3%}, 当前亏损率: {profit_rate:.3%}, "
|
|
|
f"成本价: {entry_price:.2f}, 当前价格: {current_price:.2f}")
|
|
|
|
|
|
if entry_trading_day is not None and entry_trading_day == current_trading_day:
|
|
|
@@ -1103,6 +1115,19 @@ def open_position(context, security, target_hands, direction, single_hand_margin
|
|
|
|
|
|
# 使用order_target按手数开仓
|
|
|
order = order_target(security, target_hands, side=direction)
|
|
|
+ log.debug(f"order: {order}")
|
|
|
+
|
|
|
+ # 检查订单状态,如果为'new'说明当晚没有夜盘
|
|
|
+ if order is not None:
|
|
|
+ order_status = str(order.status).lower()
|
|
|
+ if order_status == 'new':
|
|
|
+ # 取消订单
|
|
|
+ cancel_order(order)
|
|
|
+ current_trading_day = get_current_trading_day(context.current_dt)
|
|
|
+ g.night_session_blocked = True
|
|
|
+ g.night_session_blocked_trading_day = current_trading_day
|
|
|
+ log.warning(f"订单状态为'new',说明{current_trading_day}当晚没有夜盘,已取消订单: {security} {direction} {target_hands}手,并禁止当晚所有操作")
|
|
|
+ return False
|
|
|
|
|
|
if order is not None and order.filled > 0:
|
|
|
# 记录交易后的可用资金
|
|
|
@@ -1334,6 +1359,12 @@ def after_market_close(context):
|
|
|
log.info(f"清空排除缓存,共 {excluded_count} 个合约")
|
|
|
g.excluded_contracts = {}
|
|
|
|
|
|
+ # 重置夜盘禁止操作标志
|
|
|
+ if g.night_session_blocked:
|
|
|
+ log.info(f"重置夜盘禁止操作标志")
|
|
|
+ g.night_session_blocked = False
|
|
|
+ g.night_session_blocked_trading_day = None
|
|
|
+
|
|
|
# 只有当天有交易时才打印统计信息
|
|
|
if g.today_trades:
|
|
|
print_daily_trading_summary(context)
|