通过 trade 模块中的初始化函数定义交易手续费和滑点;
通过 trade 模块中的主函数(handle函数)查看每日的买卖交易信号,按照买卖原则执行相应的买入/卖出/调仓操作。
# 本代码由可视化策略环境自动生成 2021年12月10日 15:54
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 交易引擎:初始化函数,只执行一次
def m2_initialize_bigquant_run(context):
# 加载预测数据
print("initialize")
context.ins = context.instruments[0]#从传入参数中获取需要交易的合约
context.order_num = 2#下单手数
context.set_universe(context.ins)#设置需要处理的合约
context.N = 5 #基于N天的历史数据
context.k1 = 0.2 #上轨参数
context.k2 = 0.2 #下轨参数
context.today_open = 0 #当天开盘价
context.closetime_day = "14:58"#日内策略白盘平仓时间,一般14:58
context.closetime_night = "22:58"#日内策略夜盘平仓时间,一般22:58,注意有些商品夜盘收盘时间不一样
# 交易引擎:每个单位时间开盘前调用一次。
def m2_before_trading_start_bigquant_run(context, data):
context.subscribe(context.ins) #注册合约
context.index = 0
context.flag = 1 #用于获取今开
# 取历史数据
hist = data.history(context.ins, ["open","high","low","close"], context.N, "1d")
# 计算Dual Thrust 的上下轨
HH = hist['high'].max()
HC = hist['close'].max()
LC = hist['close'].min()
LL = hist['low'].min()
context.range = max(HH - LC, HC - LL)
# 交易引擎:tick数据处理函数,每个tick执行一次
def m2_handle_tick_bigquant_run(context, data):
pass
def m2_handle_data_bigquant_run(context, data):
from datetime import datetime,timedelta
#获取当天的开盘价
if context.flag == 1 :
history_data = data.history(context.ins, ["open"], 1, "1m")
context.today_open = history_data.iloc[-1]['open']
context.flag += 1
#获取当前时间
cur_date = data.current_dt
cur_hm = cur_date.strftime('%H:%M')
#计算上下轨
buy_line = context.today_open + context.range * context.k1
sell_line = context.today_open - context.range * context.k2
# 分别获取多头持仓和空头持仓
position_long = context.get_position(context.ins, Direction.LONG)
position_short = context.get_position(context.ins, Direction.SHORT)
# 获取当前价格
price = data.current(context.ins, "close")
#尾盘平仓
#部分品种夜盘收盘时间不一样,此时间表示指定的尾盘平仓时间往后偏移30分钟,这段时间内不能开新仓,只能平仓。给30分钟是为了足够的冗余
closetime_nightshift = (datetime.strptime(context.closetime_night,'%H:%M') + timedelta(minutes = 30)).strftime('%H:%M')
if((cur_hm>=context.closetime_day and cur_hm<="15:00") or (cur_hm>=context.closetime_night and cur_hm<=closetime_nightshift)):
if(position_long.current_qty != 0):
rv = context.sell_close(context.ins, position_long.avail_qty, price, order_type=OrderType.MARKET)
msg = "{} 尾盘平多 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
if(position_short.current_qty != 0):
rv = context.buy_close(context.ins, position_short.avail_qty, price, order_type=OrderType.MARKET)
msg = "{} 尾盘平空 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
#尾盘不开新仓,直接返回
return
#交易逻辑
if price > buy_line:
if position_long.current_qty != 0:
return
else:
if position_short.current_qty != 0:
rv = context.buy_close(context.ins, position_short.avail_qty, price, order_type=OrderType.MARKET)
msg = "{} 平空 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
rv = context.buy_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)
msg = "{} 开多 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
elif price < sell_line:
if position_short.current_qty != 0:
return
else:
if position_long.current_qty != 0:
rv = context.sell_close(context.ins, position_long.avail_qty, price, order_type=OrderType.MARKET)
msg = "{} 平多 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
rv = context.sell_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)
msg = "{} 开空 for {} 最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
context.write_log(msg, stdout=1)
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m2_handle_trade_bigquant_run(context, data):
msg = "handle_trade data:{}".format(data.log_str())
context.write_log(msg, stdout=1)
# 分别获取最新的多头持仓和空头持仓
position_long = context.get_position(data.symbol, Direction.LONG)
position_short = context.get_position(data.symbol, Direction.SHORT)
msg = "当前多头持仓:{} 当前空头持仓:{}".format(str(position_long),str(position_short))
context.write_log(msg, stdout=1)
# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m2_handle_order_bigquant_run(context, data):
pass
# 交易引擎:盘后处理函数,每日盘后执行一次
def m2_after_trading_bigquant_run(context, data):
pass
m1 = M.instruments.v2(
start_date='2021-08-21',
end_date='2021-09-27',
market='CN_FUTURE',
instrument_list='RU2201.SHF',
max_count=0
)
m2 = M.hftrade.v2(
instruments=m1.data,
start_date='',
end_date='',
initialize=m2_initialize_bigquant_run,
before_trading_start=m2_before_trading_start_bigquant_run,
handle_tick=m2_handle_tick_bigquant_run,
handle_data=m2_handle_data_bigquant_run,
handle_trade=m2_handle_trade_bigquant_run,
handle_order=m2_handle_order_bigquant_run,
after_trading=m2_after_trading_bigquant_run,
capital_base=50000,
frequency='minute',
price_type='真实价格',
product_type='期货',
before_start_days='0',
benchmark='000300.HIX',
plot_charts=True,
disable_cache=False,
show_debug_info=False,
backtest_only=False
)
[2021-12-10 15:54:46.625954] INFO: moduleinvoker: instruments.v2 开始运行..
[2021-12-10 15:54:46.637851] INFO: moduleinvoker: 命中缓存
[2021-12-10 15:54:46.639461] INFO: moduleinvoker: instruments.v2 运行完成[0.013494s].
[2021-12-10 15:54:46.666263] INFO: moduleinvoker: hfbacktest.v1 开始运行..
[2021-12-10 15:54:46.688065] INFO: moduleinvoker: 命中缓存
[2021-12-10 15:54:47.137889] INFO: moduleinvoker: hfbacktest.v1 运行完成[0.471635s].
[2021-12-10 15:54:47.139396] INFO: moduleinvoker: hftrade.v2 运行完成[0.494441s].