3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在期货交易中,临近交割日(Delivery Date)时,个人投资者或非套保客户通常会被交易所强制平仓,甚至面临流动性枯竭和额外的强平费用。因此,在量化策略中加入交割日监控与自动平仓风控逻辑至关重要。
在 ptrade 平台中,我们可以通过 get_instruments 接口获取期货合约的详细上市信息,其中包括交割日期 delivery_date。结合 context.blotter.current_dt(当前回测/交易时间),即可计算出距离交割日的剩余天数,并在满足条件时执行平仓。
get_instruments(contract)contract(str,期货合约代码,如 'CU2112.XSGE')。contract_code:合约代码delivery_date:交割日期(格式通常为 'YYYYMMDD' 或 'YYYY-MM-DD' 的字符串)trade_code:交易代码margin_rate:保证金比例context.portfolio.positions 遍历当前账户中的所有期货持仓。get_instruments(contract),获取其 delivery_date。sell_close 或 buy_close 进行平仓。以下是一个完整的 ptrade 策略示例,展示了如何在每日盘中(handle_data)或定时任务中监控持仓合约的交割日并执行风控平仓:
import datetime
def initialize(context):
# 设置操作的期货合约池(示例:沪铜与股指期货)
g.security = ['CU2412.XSGE', 'IF2412.CCFX']
set_universe(g.security)
# 每天 14:50 运行一次交割日风控检查
run_daily(context, delivery_risk_control, time='14:50')
def handle_data(context, data):
# 盘中常规交易逻辑(此处略,仅做风控演示)
pass
def delivery_risk_control(context):
"""
交割日风控函数:检查所有持仓,距离交割日 <= 5 天时强制平仓
"""
log.info("开始执行交割日风控检查...")
current_date = context.blotter.current_dt.date() # 获取当前交易日期
# 获取当前所有持仓
positions = context.portfolio.positions
if not positions:
log.info("当前无持仓,无需风控。")
return
for contract, pos in list(positions.items()):
# 过滤非期货品种(如股票等业务类型)
if pos.business_type != 'future':
continue
# 获取合约信息
instrument_info = get_instruments(contract)
if not instrument_info or not instrument_info.delivery_date:
log.warning("未能获取到合约 %s 的交割日信息" % contract)
continue
delivery_date_str = instrument_info.delivery_date
# 解析交割日字符串为 datetime.date 对象
try:
# 兼容处理不同的日期格式
if '-' in delivery_date_str:
delivery_date = datetime.datetime.strptime(delivery_date_str, '%Y-%m-%d').date()
else:
delivery_date = datetime.datetime.strptime(delivery_date_str, '%Y%m%d').date()
except Exception as e:
log.error("解析合约 %s 交割日 %s 失败: %s" % (contract, delivery_date_str, str(e)))
continue
# 计算距离交割日的剩余天数
days_to_delivery = (delivery_date - current_date).days
log.info("合约: %s, 当前日期: %s, 交割日期: %s, 距离交割日: %d 天" %
(contract, current_date, delivery_date, days_to_delivery))
# 触发风控阈值(<= 5天)
if days_to_delivery <= 5:
log.warning("【风控警报】合约 %s 距离交割日仅剩 %d 天,触发强制平仓!" % (contract, days_to_delivery))
# 1. 平多仓 (long_amount > 0)
if pos.long_amount > 0:
order_id = sell_close(contract, pos.long_amount)
if order_id:
log.info("已发送多头平仓单,合约: %s, 数量: %d" % (contract, pos.long_amount))
# 2. 平空仓 (short_amount > 0)
if pos.short_amount > 0:
order_id = buy_close(contract, pos.short_amount)
if order_id:
log.info("已发送空头平仓单,合约: %s, 数量: %d" % (contract, pos.short_amount))
delivery_date 格式可能存在 '20241225' 或 '2024-12-25' 的差异,代码中已使用 try-except 和条件判断进行了兼容处理。(delivery_date - current_date).days 计算的是自然日差值。如果交割日前有长假(如国庆、春节),建议将风控阈值适当调大(例如设为 7-10 天),以防假期休市无法平仓。close_today=True)与平昨仓的区分,ptrade 的 sell_close 和 buy_close 默认优先平昨仓。