# 导入相应包
from biglearning.api import M
import math
from bigtrader.sdk import *
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
def initialize(context):
"""策略初始化函数,只触发一次。可以在该函数中初始化一些变量,如读取配置和全局使用数据"""
#输出关键日志
msg = "initialize:"
context.write_log(msg, stdout=1)
#从传入参数中获取需要交易的合约
context.ins = context.instruments[0] # 从传入参数中获取需要交易的合约
context.order_num = 2 # 下单手数
context.closetime_day = "14:58" # 日内策略白盘平仓时间,一般14:58
context.closetime_night = "22:58" # 日内策略夜盘平仓时间,一般22:58,注意有些商品夜盘收盘时间不一样
def before_trading(context, data):
"""盘前处理,策略盘前交易函数,每日盘前触发一次。可以在该函数中一些启动前的准备,如订阅行情等"""
# 盘前处理,订阅行情等
context.subscribe_bar(context.ins,'1m') # 注册合约
context.flag = 0 # 用于获取今开
context.count = 0 # 交易次数记录
bar1d_df = data.history(context.ins, ["high","low",'close'], 1, "1d")
context.high = bar1d_df['high'][0] # 昨高
context.low = bar1d_df['low'][0] # 昨低
def handle_data(context, data):
# 获取当天开盘价
from datetime import datetime,timedelta
if context.flag == 0:
open_price = data.history(context.ins, ["open"], 1, "1m")
context.flag += 1
context.today_open = open_price['open'][0]
# 当前k线时间,具体到分
cur_date = data.current_dt
cur_hm = cur_date.strftime('%H:%M')
# 部分品种夜盘收盘时间不一样,此时间表示指定的尾盘平仓时间往后偏移30分钟,这段时间内不能开新仓,只能平仓。给30分钟是为了足够的冗余
closetime_nightshift = (datetime.strptime(context.closetime_night,'%H:%M') + timedelta(minutes = 30)).strftime('%H:%M')
# 分别获取多头持和空头持仓
position_long = context.get_position(context.ins, Direction.LONG)
position_short = context.get_position(context.ins, Direction.SHORT)
# 获取当前价格
price = data.current(context.ins, "close")
# 尾盘平仓
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 position_long.current_qty != 0 and price < context.today_open:
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)
# 空头持仓,最新价大于开盘价 平空
elif position_short.current_qty != 0 and price > context.today_open:
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)
# 当前的最新价大于前一天的最高价且没有持仓 开多
if (position_long.current_qty == 0) and (price > context.high) and (context.count<=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.count += 1 #只开仓一次的判断
context.write_log(msg, stdout=1)
# 当前最新价小于前一天的最低价且没有持仓 开空
elif (position_short.current_qty == 0) and (price < context.low) and (context.count<=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.count += 1
context.write_log(msg, stdout=1)
def handle_order(context, order):
"""委托回报通知函数,每个订单状态有变化时会触发"""
msg = "handle_order data:{}".format(order.log_str())
context.write_log(msg, stdout=0)
def handle_trade(context, trade):
"""成交回报通知函数,有成交时会触发"""
msg = "handle_trade data:{}".format(trade.log_str())
context.write_log(msg, stdout=0) # stdout=0表示不打印
# 分别获取最新的多头持仓和空头持仓
position_long = context.get_position(trade.symbol, Direction.LONG)
position_short = context.get_position(trade.symbol, Direction.SHORT)
msg = "当前多头持仓:{} 当前空头持仓:{}".format(str(position_long),str(position_short))
context.write_log(msg, stdout=0)
# 回测标的
instruments = ["RU2309.SHF"]
start_date = "2023-04-01"
end_date = "2023-05-01"
md = M.hftrade.v2(start_date=start_date, #回测开始时间
end_date=end_date, #回测结束时间
instruments=instruments, #合约列表
capital_base=200000, #初始资金
product_type=Product.FUTURE,
frequency=Frequency.MINUTE, #回测频率
initialize=initialize,
before_trading_start=before_trading,
handle_data=handle_data,
handle_order=handle_order,
handle_trade=handle_trade,
plot_charts=True, #画出回测结果分析图
disable_cache=0, #启用缓存加速
show_debug_info=1, #打印debug日志
before_start_days=10
)