克隆策略

策略逻辑:

分钟均线突破策略。以20日均线为标准,当价格上穿20日均线时,平空做多1手;若价格下穿20日均线,则平多做空1手。

交易日历:

后台会自动根据所需要交易的标的,进行交易时间的辨别。无需手动导入交易日历。

In [27]:
from bigtrader.constant import Direction, OrderType

#给每个策略取一个名字
STRATEGY_NAME = "STRATEGY_1"

def initialize(context):
    """策略初始化函数,只触发一次。可以在该函数中初始化一些变量,如读取配置和全局使用数据"""
    #输出关键日志
    msg = "initialize:" 
    context.write_log(msg, stdout=1)
    
    #从传入参数中获取需要字段
    context.my_instrument = context.get_conf_param("instrument")
    context.opentime_day = context.get_conf_param('opentime_day')
    context.closetime_day = context.get_conf_param('closetime_day')
    context.closetime_night = context.get_conf_param('closetime_night')

    #设置需要处理的股票池或者合约集合
    context.set_universe(context.my_instrument)
    
    
        
def before_trading(context, data):
    """盘前处理,策略盘前交易函数,每日盘前触发一次。可以在该函数中一些启动前的准备,如订阅行情等"""
    # 输出关键日志
    msg = "before_trading"
    context.write_log(msg, stdout=1)
    
    # 订阅要交易的合约的行情
    context.subscribe(context.my_instrument)
    
    # 如果需要处理tick数据,需要添加tick处理函数:handle_tick(context, tick):

def handle_data(context, data):
    """Bars行情通知函数,每个bar时间周期会触发,包括日线和分钟"""
    print("handle_data:", data.current_dt)
   
    # 分别获取多头持仓,和空头持仓,主要使用 current_qty 和 avail_qty 两个属性
    position_long = context.get_position(context.my_instrument, Direction.LONG)
    position_short = context.get_position(context.my_instrument, Direction.SHORT)

    # 获取账户资金,主要使用 balance 和 available 两个属性
    trading_account = context.get_trading_account()

    # 获取当前k线最新收盘价格
    price = data.current(context.my_instrument, "close")

    #获取30根1m历史数据数据
    hist = context.history_data(context.my_instrument, ["open","high","low","close"], 30, "1m")

    #计算20均线
    hist['ma'] = hist['close'].rolling(20).mean()
    
      
    cur_hm = data.current_dt.strftime('%H:%M')

    #价格向上穿越20均线
#     if cur_hm <= context.closetime_day and cur_hm >= context.opentime_day:
    if(hist.iloc[-2]['close']<hist.iloc[-2]['ma'] and price>=hist.iloc[-1]['ma']):
        #有空单的先平掉
        if (position_short.avail_qty != 0):
            rv = context.buy_close(context.my_instrument, position_short.avail_qty, price, order_type=OrderType.MARKET)
            if rv != 0:
                context.write_log("buy_close error={}".format(context.get_error_msg(rv)), stdout=1)
            msg = str(data.current_dt) +  " 平空 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
            context.write_log(msg, stdout=1)
        #没有多单则开多1手
        if (position_long.current_qty == 0):
            rv = context.buy_open(context.my_instrument, 1, price, order_type=OrderType.MARKET)
            msg = str(data.current_dt) +  " 开多 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
            context.write_log(msg, stdout=1) 
    #价格向下穿越20均线
    if (hist.iloc[-2]['close']>hist.iloc[-2]['ma'] and price<hist.iloc[-1]['ma']):
        #有多单的先平掉
        if (position_long.avail_qty != 0):
            rv = context.sell_close(context.my_instrument, position_long.avail_qty, price, order_type=OrderType.MARKET)
            msg = str(data.current_dt) +  " 平多 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
            context.write_log(msg, stdout=1)
        #没有空单则开空1手    
        if (position_short.current_qty == 0):
            rv = context.sell_open(context.my_instrument, 1, price, order_type=OrderType.MARKET)
            msg = str(data.current_dt) +  " 开空 for " + context.my_instrument + " 最新价=" + str(price) + " rv:" + str(rv)
            context.write_log(msg, stdout=1)    
    

def handle_order(context, order):
    """委托回报通知函数,每个订单状态有变化时会触发"""
    #输出关键日志
    msg = "handle_order data:{}".format(order.log_str())
    context.write_log(msg, stdout=1) 
    
        
def handle_trade(context, trade):
    """成交回报通知函数,有成交时会触发"""
    #输出关键日志
    msg = "handle_trade data:{}".format(trade.log_str())
    context.write_log(msg, stdout=1) 
In [ ]:
instrument = "AU2110.SHF"
# 需要交易者传入的参数(一般回测时不需要,但实盘时,通常是传配置的方式给运行策略,从而不需要改动策略代码)
strategy_setting = [
    {
        "instrument": instrument,
        "opentime_day": "9:00",
        "closetime_day": "15:00",
        "closetime_night": "22:58"
    }    
    
]
start_date = "2021-05-11"
end_date = "2021-05-13"
md = M.hfbacktest.v1(start_date=start_date, #回测开始时间
                     end_date=end_date, #回测结束时间
                     instruments=[instrument], #合约列表
                     capital_base=100000, #初始资金
                     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日志
                     strategy_setting=strategy_setting, #配置参数
                     slippage_type=SlippageType.FIXED,#滑点固定模式
                     slippage_value=1.0,#买卖双向各1个滑点
                     )