克隆策略
In [7]:
from datetime import datetime,timedelta

STRATEGY_NAME = "STRATEGY_1"
    
def initialize(context):
    """初始化"""
    context.ins = context.get_conf_param("instruments") # 从传入参数中获取需要交易的合约
    print(context.ins)
    context.order_num = context.get_conf_param("order_num") # 下单手数
    context.set_universe(context.ins) # 设置需要处理的合约
    
    context.closetime_day = context.get_conf_param("closetime_day") # 日内策略白盘平仓时间,一般14:58
    context.closetime_night = context.get_conf_param("closetime_night") # 日内策略夜盘平仓时间,一般22:58,注意有些商品夜盘收盘时间不一样

def before_trading(context, data):
    """盘前处理"""
    context.subscribe(context.ins) # 注册合约
    context.flag = 1 # 用于获取今开
    context.count = 0 # 交易次数记录
    
    bar1d_df = data.history(context.ins, ["high","low",'close'], 1, "1d")
    context.high = bar1d_df.iloc[0]['high'] # 昨高
    context.low = bar1d_df.iloc[0]['low']  # 昨低
    
def handle_data(context, data):
    """Bar行情推送"""

    # 获取当天开盘价
    if context.flag == 1:
        open_price = data.history(context.ins, ["open"], 1, "1m")
        context.flag = context.flag + 1
        context.today_open = open_price.iloc[-1]['open'] 
        
    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=0) #输出关键日志
        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=0) #输出关键日志
        #尾盘不开新仓,直接返回
        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=0) 
        
    # 空头持仓,最新价大于开盘价 平空
    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=0) 
        
    # 建仓逻辑   
    # 当前的最新价大于前一天的最高价且没有持仓 开多
    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=0) 
    # 当前最新价小于前一天的最低价且没有持仓 开空
    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=0) 
        
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) 
    # 分别获取最新的多头持仓和空头持仓
    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 = "RB2110.SHF" 
#需要交易者传入的参数
strategy_setting = [{
        "instruments": instruments,
        "order_num": 2,
        "closetime_day": "14:58",
        "closetime_night": "22:58"
    }]

start_date = "2021-02-01"
end_date = "2021-03-01"
md = M.hfbacktest.v1(start_date=start_date,
                     end_date=end_date,
                     instruments=[instruments],  
                     capital_base=20000,
                     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,
                     volume_limit=0.0,
                     disable_cache=0,
                     show_debug_info=0,
                     strategy_setting=strategy_setting,
                     slippage_type=SlippageType.FIXED,#滑点固定模式
                     slippage_value=1.0,#买卖双向各1个滑点
                     m_deps=np.random.rand() # 模块依赖,值相同的话会命中缓存
                     )
2021-10-28 20:28:16.660896 run trading v1.7.8_sp1 
2021-10-28 20:28:16.661691 init history datas... 
2021-10-28 20:28:16.683129 init trading env... 
RB2110.SHF
  • 收益率1.95%
  • 年化收益率35.57%
  • 基准收益率0.02%
  • 阿尔法0.25
  • 贝塔0.73
  • 夏普比率0.83
  • 胜率0.19
  • 盈亏比1.14
  • 收益波动率44.57%
  • 最大回撤11.51%
bigcharts-data-start/{"__type":"tabs","__id":"bigchart-75d79b49a3084433ac93d4110bd8f516"}/bigcharts-data-end