3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(JoinQuant)平台上进行 IM(中证1000)股指期货交易时,由于股指期货具有高杠杆、高波动的特性,合理设置交易手数和风控机制是策略长期存活的关键。本文将详细介绍如何实现一个分钟级突破趋势策略,并进行严格的手数与风控管理。
set_subportfolios 显式创建 type='futures' 的期货子账户。context.subportfolios[i].is_dangerous(margin_rate) 监控账户整体保证金风险。import jqdata
import numpy as np
def initialize(context):
# 1. 开启真实价格模式
set_option('use_real_price', True)
# 2. 初始化期货账户,设置初始资金
init_cash = context.portfolio.starting_cash
set_subportfolios([SubPortfolioConfig(cash=init_cash, type='futures')])
# 3. 设定策略参数
g.symbol = 'IM' # 中证1000股指期货品种
g.time_window = 30 # 突破的时间窗口(30分钟)
g.risk_ratio = 0.1 # 单次开仓占用资金比例上限(10%)
g.stop_loss_pct = 0.015 # 1.5% 止损
# 4. 设置运行频率:每分钟运行一次
run_daily(market_open, time='every_bar', reference_security='IM9999.CCFX')
def market_open(context):
# 获取当前主力合约
dominant_contract = get_dominant_future(g.symbol)
if not dominant_contract:
return
# 获取当前子账户信息
sub_portfolio = context.subportfolios[0]
# 1. 极端行情风控:检查保证金是否过高(若整体保证金占用超过 50%,触发预警并平仓)
if sub_portfolio.is_dangerous(0.5):
log.warn("账户整体保证金占用过高,触发风控平仓!")
close_all_positions(dominant_contract)
return
# 2. 获取历史数据计算突破区间
# 获取过去 N 根分钟 K 线(不含当前分钟)
bars = get_bars(dominant_contract, count=g.time_window, unit='1m', fields=['close', 'high', 'low'], include_now=False, df=True)
if len(bars) < g.time_window:
return
highest_price = bars['high'].max()
lowest_price = bars['low'].min()
current_price = get_bars(dominant_contract, count=1, unit='1m', fields=['close'], include_now=True)[0]['close']
# 3. 检查现有持仓并执行止损风控
manage_stop_loss(context, dominant_contract, current_price)
# 4. 突破信号判断与手数控制
long_positions = sub_portfolio.long_positions
short_positions = sub_portfolio.short_positions
if current_price > highest_price and dominant_contract not in long_positions:
# 向上突破,平空开多
if dominant_contract in short_positions:
order_target(dominant_contract, 0, side='short')
# 计算安全开仓手数
target_qty = calculate_safe_qty(context, dominant_contract, current_price)
if target_qty > 0:
order(dominant_contract, target_qty, side='long')
log.info("向上突破,买入开多 %s 手" % target_qty)
elif current_price < lowest_price and dominant_contract not in short_positions:
# 向下突破,平多开空
if dominant_contract in long_positions:
order_target(dominant_contract, 0, side='long')
# 计算安全开仓手数
target_qty = calculate_safe_qty(context, dominant_contract, current_price)
if target_qty > 0:
order(dominant_contract, target_qty, side='short')
log.info("向下突破,卖出开空 %s 手" % target_qty)
def calculate_safe_qty(context, contract, price):
"""根据资金规模与风险系数动态计算开仓手数"""
sub_portfolio = context.subportfolios[0]
available_cash = sub_portfolio.available_cash
# 获取合约保证金比例(若未设置,IM 默认约为 15%)
margin_rate = 0.15
# IM 合约乘数为 200 元/点
contract_multiplier = 200
# 单手保证金 = 价格 * 乘数 * 保证金比例
one_contract_margin = price * contract_multiplier * margin_rate
# 允许使用的最大保证金金额
allowed_margin = sub_portfolio.total_value * g.risk_ratio
# 计算安全手数(向下取整)
safe_qty = int(allowed_margin / one_contract_margin)
return safe_qty
def manage_stop_loss(context, contract, current_price):
"""个股持仓止损管理"""
sub_portfolio = context.subportfolios[0]
# 多头止损
if contract in sub_portfolio.long_positions:
pos = sub_portfolio.long_positions[contract]
# avg_cost 为开仓均价
if (pos.price - current_price) / pos.price > g.stop_loss_pct:
order_target(contract, 0, side='long')
log.warn("多头持仓触发止损,平仓!")
# 空头止损
if contract in sub_portfolio.short_positions:
pos = sub_portfolio.short_positions[contract]
if (current_price - pos.price) / pos.price > g.stop_loss_pct:
order_target(contract, 0, side='short')
log.warn("空头持仓触发止损,平仓!")
def close_all_positions(contract):
"""一键平仓"""
order_target(contract, 0, side='long')
order_target(contract, 0, side='short')
is_dangerous(margin_rate):context.subportfolios[0].is_dangerous(0.5) 用于判断当前子账户的保证金占用是否超过了总资产的 50%。在极端行情下,该函数能有效防止爆仓风险。get_dominant_future(underlying_symbol):IM9999 连续合约下单。必须在每日盘中通过该 API 获取当前持仓量最大的真实合约(如 IM2309.CCFX)进行交易。