复制链接
克隆策略

R-Breaker日内期货交易策略-分钟

交易规则

  • 计算出六个指标,从大到小依次为:
  • 中心价位P = (H + C + L)/3
  • 突破买入价 = H + 2P -2L
  • 观察卖出价 = P + H - L
  • 反转卖出价 = 2P - L
  • 反转买入价 = 2P - H
  • 观察买入价 = P - (H - L)
  • 突破卖出价 = L - 2(H - P)

策略构建步骤

确定股票池和回测时间

  • 通过证券代码列表输入回测的起止日期

确定买卖原则

  • 空仓时:突破策略 空仓时,当盘中价格>突破买入价,则认为上涨的趋势还会继续,开仓做多; 空仓时,当盘中价格<突破卖出价,则认为下跌的趋势还会继续,开仓做空。

  • 持仓时:反转策略 持多单时:当日内最高价>观察卖出价后,盘中价格回落,跌破反转卖出价构成的支撑线时,采取反转策略,即做空; 持空单时:当日内最低价<观察买入价后,盘中价格反弹,超过反转买入价构成的阻力线时,采取反转策略,即做多。

回测

  • 通过 trade 模块中的初始化函数定义交易手续费和滑点;

  • 通过 trade 模块中的主函数(handle函数)查看每日的买卖交易信号,按照买卖原则执行相应的买入/卖出/调仓操作。

策略详情

    {"description":"实验创建于2021/12/6","graph":{"edges":[{"to_node_id":"-227:instruments","from_node_id":"-216:data"}],"nodes":[{"node_id":"-216","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2021-08-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2021-10-15","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_FUTURE","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"RB2201.SHF","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-216"}],"output_ports":[{"name":"data","node_id":"-216"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-227","module_id":"BigQuantSpace.hftrade.hftrade-v2","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 交易引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n print(\"initialize\") \n context.symbol = context.instruments[0]\n context.ins = context.instruments[0] #从传入参数中获取需要交易的合约\n context.order_num = 2 #下单手数\n context.set_universe(context.ins) #设置需要处理的合约\n \n context.closetime_day = \"14:58\"#日内策略白盘平仓时间,一般14:58\n context.closetime_night = \"22:58\" #日内策略夜盘平仓时间,一般22:58,注意有些商品夜盘收盘时间不一样","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 交易引擎:每个单位时间开盘前调用一次。\ndef bigquant_run(context, data):\n context.subscribe(context.ins) #注册合约\n context.max_high = 0 #当日最高价\n context.max_low = 0 #当日最低价\n hist = data.history(context.ins, [\"high\",\"low\",\"open\",\"close\"], 1, \"1d\")\n high = hist['high'].iloc[0] # 前一日的最高价\n low = hist['low'].iloc[0] # 前一日的最低价\n close = hist['close'].iloc[0] # 前一日的收盘价\n pivot = (high + low + close) / 3 # 枢轴点\n price_multi = 2 # 参数\n context.bBreak = np.round(high + price_multi * (pivot - low), 2) # 突破买入价 \n context.sSetup = np.round(pivot + (high - low), 2) # 观察卖出价\n context.sEnter = np.round(price_multi * pivot - low, 2) # 反转卖出价\n \n context.bEnter = np.round(price_multi * pivot - high, 2) # 反转买入价\n context.bSetup = np.round(pivot - (high - low), 2) # 观察买入价\n context.sBreak = np.round(low - price_multi * (high - pivot), 2) # 突破卖出价\n cur_date = data.current_dt\n print(cur_date, context.bBreak, context.sSetup, context.sEnter,context.bEnter , context.bSetup,context.sBreak)","type":"Literal","bound_global_parameter":null},{"name":"handle_tick","value":"# 交易引擎:tick数据处理函数,每个tick执行一次\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"def bigquant_run(context, data):\n \"\"\"Bar行情推送\"\"\"\n from datetime import datetime,timedelta\n cur_date = data.current_dt\n cur_hm = cur_date.strftime('%H:%M') \n \n #获取当日最高价和最低价\n today_high = data.current(context.ins,'high')\n today_low = data.current(context.ins,'low')\n context.max_high = max(context.max_high,today_high)\n context.max_low = max(context.max_high,today_low) \n \n # 分别获取多头持仓,和空头持仓\n position_long = context.get_position(context.ins, Direction.LONG)\n position_short = context.get_position(context.ins, Direction.SHORT)\n \n # 获取当前价格\n price = data.current(context.ins, \"close\")\n \n #部分品种夜盘收盘时间不一样,此时间表示指定的尾盘平仓时间往后偏移30分钟,这段时间内不能开新仓,只能平仓。给30分钟是为了足够的冗余\n closetime_nightshift = (datetime.strptime(context.closetime_night,'%H:%M') + timedelta(minutes = 30)).strftime('%H:%M')\n #尾盘平仓\n if((cur_hm>=context.closetime_day and cur_hm<=\"15:00\") or (cur_hm>=context.closetime_night and cur_hm<=closetime_nightshift)):\n if(position_long.current_qty != 0):\n rv = context.sell_close(context.ins, position_long.avail_qty, price, order_type=OrderType.MARKET)\n msg = \"{} 尾盘平多 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n if(position_short.current_qty != 0):\n rv = context.buy_close(context.ins, position_short.avail_qty, price, order_type=OrderType.MARKET)\n msg = \"{} 尾盘平空 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n #尾盘不开新仓,直接返回\n return\n \n # 突破策略\n if position_long.current_qty == 0 and position_short.current_qty == 0: # 空仓条件下\n if price > context.bBreak:\n # 在空仓的情况下,如果盘中价格超过突破买入价,则采取趋势策略,即在该点位开仓做多\n rv = context.buy_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)\n msg = \"buybuybuy{} 开多 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n context.open_position_price = price\n elif price < context.sBreak:\n # 在空仓的情况下,如果盘中价格跌破突破卖出价,则采取趋势策略,即在该点位开仓做空\n rv = context.sell_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)\n msg = \"sellsellsell{} 开空 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n context.open_position_price = price\n # 设置止损条件\n else: \n # 反转策略:\n if position_long.current_qty != 0: # 多仓条件下\n if context.max_high > context.sSetup and price < context.sEnter:\n # 多头持仓,当日内最高价超过观察卖出价后\n # 盘中价格出现回落,且进一步跌破反转卖出价构成的支撑线时\n # 采取反转策略,即在该点位反手做空\n context.write_log('多头持仓,当日内最高价超过观察卖出价后跌破反转卖出价: 反手做空', stdout=1) #输出关键日志\n rv = context.sell_close(context.ins, position_long.avail_qty, price, order_type=OrderType.MARKET)\n msg = '平===多'*5+\"{} 平多 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n \n rv = context.sell_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)\n context.open_position_price = price\n msg = '开===空'*5 +\"{} 开空 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志 \n \n elif position_short.current_qty != 0: # 空头持仓\n if context.max_low < context.bSetup and price > context.bEnter:\n # 空头持仓,当日内最低价低于观察买入价后,\n # 盘中价格出现反弹,且进一步超过反转买入价构成的阻力线时,\n # 采取反转策略,即在该点位反手做多\n context.write_log('空头持仓,当日最低价低于观察买入价后超过反转买入价: 反手做多', stdout=1) #输出关键日志\n rv = context.buy_close(context.ins, position_short.avail_qty, price, order_type=OrderType.MARKET)\n msg = \"{} 平空 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志\n \n rv = context.buy_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)\n context.open_position_price = price\n msg = \"{} 开多 for {} 最新价={} 下单函数返回={}\".format(str(data.current_dt),context.ins,str(price),str(rv))\n context.write_log(msg, stdout=1) #输出关键日志 \n ","type":"Literal","bound_global_parameter":null},{"name":"handle_trade","value":"# 交易引擎:成交回报处理函数,每个成交发生时执行一次\ndef bigquant_run(context, data):\n msg = \"handle_trade data:{}\".format(data.log_str())\n context.write_log(msg, stdout=1) \n # 分别获取最新的多头持仓和空头持仓\n position_long = context.get_position(data.symbol, Direction.LONG)\n position_short = context.get_position(data.symbol, Direction.SHORT)\n msg = \"当前多头持仓:{} 当前空头持仓:{}\".format(str(position_long),str(position_short))\n context.write_log(msg, stdout=1)\n","type":"Literal","bound_global_parameter":null},{"name":"handle_order","value":"# 交易引擎:委托回报处理函数,每个委托变化时执行一次\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"after_trading","value":"# 交易引擎:盘后处理函数,每日盘后执行一次\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"50000","type":"Literal","bound_global_parameter":null},{"name":"frequency","value":"minute","type":"Literal","bound_global_parameter":null},{"name":"price_type","value":"真实价格","type":"Literal","bound_global_parameter":null},{"name":"product_type","value":"期货","type":"Literal","bound_global_parameter":null},{"name":"before_start_days","value":"0","type":"Literal","bound_global_parameter":null},{"name":"benchmark","value":"000300.HIX","type":"Literal","bound_global_parameter":null},{"name":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"disable_cache","value":"False","type":"Literal","bound_global_parameter":null},{"name":"show_debug_info","value":"False","type":"Literal","bound_global_parameter":null},{"name":"backtest_only","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-227"},{"name":"options_data","node_id":"-227"},{"name":"history_ds","node_id":"-227"},{"name":"benchmark_ds","node_id":"-227"}],"output_ports":[{"name":"raw_perf","node_id":"-227"}],"cacheable":false,"seq_num":2,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-216' Position='35,120,200,200'/><node_position Node='-227' Position='21,209.5,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [1]:
    # 本代码由可视化策略环境自动生成 2021年12月10日 15:57
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 交易引擎:初始化函数,只执行一次
    def m2_initialize_bigquant_run(context):
        print("initialize")  
        context.symbol = context.instruments[0]
        context.ins = context.instruments[0] #从传入参数中获取需要交易的合约
        context.order_num = 2 #下单手数
        context.set_universe(context.ins) #设置需要处理的合约
        
        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.max_high = 0 #当日最高价
        context.max_low = 0 #当日最低价
        hist = data.history(context.ins, ["high","low","open","close"], 1, "1d")
        high = hist['high'].iloc[0]  # 前一日的最高价
        low = hist['low'].iloc[0]  # 前一日的最低价
        close = hist['close'].iloc[0]  # 前一日的收盘价
        pivot = (high + low + close) / 3  # 枢轴点
        price_multi = 2  #  参数
        context.bBreak = np.round(high + price_multi * (pivot - low), 2)  # 突破买入价 
        context.sSetup = np.round(pivot + (high - low), 2)  # 观察卖出价
        context.sEnter = np.round(price_multi * pivot - low, 2)  # 反转卖出价
        
        context.bEnter = np.round(price_multi * pivot - high, 2)  # 反转买入价
        context.bSetup = np.round(pivot - (high - low), 2)  # 观察买入价
        context.sBreak = np.round(low - price_multi * (high - pivot), 2)  # 突破卖出价
        cur_date =  data.current_dt
        print(cur_date, context.bBreak, context.sSetup, context.sEnter,context.bEnter , context.bSetup,context.sBreak)
    # 交易引擎:tick数据处理函数,每个tick执行一次
    def m2_handle_tick_bigquant_run(context, data):
        pass
    
    def m2_handle_data_bigquant_run(context, data):
        """Bar行情推送"""
        from datetime import datetime,timedelta
        cur_date =  data.current_dt
        cur_hm = cur_date.strftime('%H:%M') 
        
        #获取当日最高价和最低价
        today_high = data.current(context.ins,'high')
        today_low = data.current(context.ins,'low')
        context.max_high = max(context.max_high,today_high)
        context.max_low = max(context.max_high,today_low) 
        
        # 分别获取多头持仓,和空头持仓
        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 position_long.current_qty == 0 and position_short.current_qty == 0:  # 空仓条件下
            if price > context.bBreak:
                # 在空仓的情况下,如果盘中价格超过突破买入价,则采取趋势策略,即在该点位开仓做多
                rv = context.buy_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)
                msg = "buybuybuy{} 开多 for {}  最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
                context.write_log(msg, stdout=1) #输出关键日志
                context.open_position_price = price
            elif price < context.sBreak:
                # 在空仓的情况下,如果盘中价格跌破突破卖出价,则采取趋势策略,即在该点位开仓做空
                rv = context.sell_open(context.ins, context.order_num, price, order_type=OrderType.MARKET)
                msg = "sellsellsell{} 开空 for {}  最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
                context.write_log(msg, stdout=1) #输出关键日志
                context.open_position_price = price
        # 设置止损条件
        else:   
            # 反转策略:
            if position_long.current_qty != 0:  # 多仓条件下
                if context.max_high > context.sSetup and price < context.sEnter:
                    # 多头持仓,当日内最高价超过观察卖出价后
                    # 盘中价格出现回落,且进一步跌破反转卖出价构成的支撑线时
                    # 采取反转策略,即在该点位反手做空
                    context.write_log('多头持仓,当日内最高价超过观察卖出价后跌破反转卖出价: 反手做空', stdout=1) #输出关键日志
                    rv = context.sell_close(context.ins, position_long.avail_qty, price, order_type=OrderType.MARKET)
                    msg = '平===多'*5+"{} 平多 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)
                    context.open_position_price = price
                    msg = '开===空'*5 +"{} 开空 for {}  最新价={} 下单函数返回={}".format(str(data.current_dt),context.ins,str(price),str(rv))
                    context.write_log(msg, stdout=1) #输出关键日志  
                    
            elif position_short.current_qty != 0:  # 空头持仓
                if context.max_low < context.bSetup and price > context.bEnter:
                    # 空头持仓,当日内最低价低于观察买入价后,
                    # 盘中价格出现反弹,且进一步超过反转买入价构成的阻力线时,
                    # 采取反转策略,即在该点位反手做多
                    context.write_log('空头持仓,当日最低价低于观察买入价后超过反转买入价: 反手做多', stdout=1) #输出关键日志
                    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)
                    context.open_position_price = price
                    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-01',
        end_date='2021-10-15',
        market='CN_FUTURE',
        instrument_list='RB2201.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
    )
    
    • 收益率13.79%
    • 年化收益率97.03%
    • 基准收益率-0.03%
    • 阿尔法0.87
    • 贝塔0.36
    • 夏普比率3.49
    • 胜率0.5
    • 盈亏比0.0
    • 收益波动率19.13%
    • 最大回撤0.0%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-1a7b6dd7da294211a3f10fd726729482"}/bigcharts-data-end