复制链接
克隆策略

30分钟K线移动平均策略的交易规则

版本 v1.0

目录

策略交易规则

策略构建步骤

正文

一、30分钟K线移动平均策略的交易规则

交易逻辑在HFTrade模块中实现: 1.在初始化函数中,设置需要处理的合约,并初始化分钟以及30分钟大周期K线序号,最后设置 30分钟大周期K线的最短移动平均周期数,这里默认值为26; 2.在K线处理函数中,通过合并30个分钟K线的信息,得到一个30分钟K线信息,合并原理为:取30个分钟K线的最高价和最低价为该30分钟K线的最高价与最低价,取第一根分钟K线的开盘价与最后一根K线的收盘价为该30分钟K线的对应价; 3.求30分钟大周期K线的默认周期(此处默认周期为26)移动平均的均值; 4.最后,通过传统的金叉死叉原则确定买卖出逻辑,具体为:在无持仓的时候,如果最后一根大周期K线收盘价大于大周期K线的平均收盘价(金叉),则下单买入; 在有持仓,且最后一根分钟K线收盘价小于大周期K线的平均收盘价(死叉),则下单卖出。

二、策略构建步骤

1、确定股票池和回测时间

通过证券代码列表输入要回测的股票,这里以贵州茅台(600519.SHA)为例,以及回测的起止日期。

2、确定买卖原则

通过传统的金叉死叉原则确定买卖逻辑,具体为:在无持仓的时候,如果最后一根大周期K线收盘价大于大周期K线的平均收盘价(金叉),则下单买入; 在有持仓,且最后一根分钟K线收盘价小于大周期K线的平均收盘价(死叉),则下单卖出。

3、模拟回测

HFTrade模块中的初始化函数已经设置了默认的交易手续费和滑点,要修改手续费可在初始化函数内修改;

通过HFTrade模块中K线处理函数实现交易规则,并打印交易日志。

    {"description":"实验创建于2022/3/7","graph":{"edges":[{"to_node_id":"-248:instruments","from_node_id":"-290:data"}],"nodes":[{"node_id":"-290","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2022-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2022-03-11","type":"Literal","bound_global_parameter":"交易日期"},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"600519.SHA","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":"0","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-290"}],"output_ports":[{"name":"data","node_id":"-290"}],"cacheable":false,"seq_num":1,"comment":"输入证券","comment_collapsed":true},{"node_id":"-248","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 # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.subscribe(context.instruments[0])\n context.set_universe(context.instruments[0]) # 设置需要处理的合约\n context.bar_series = NumPyDeque(200, dtype='object') # 20个分钟 K线 (包括OHLC)\n context.bar_index = 0 # 分钟K线序号\n context.big_cycle_bar_index = 0 #30分钟大周期K线序号\n context.ma_periods = 26 \n\n \n \n ","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 交易引擎:每个单位时间开盘前调用一次。\ndef bigquant_run(context, data):\n pass","type":"Literal","bound_global_parameter":null},{"name":"handle_tick","value":"# 交易引擎:tick数据处理函数,每个tick执行一次\ndef bigquant_run(context, tick):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n import talib as ta\n context.bar_index += 1\n cur_date = data.current_dt\n cur_hm = cur_date.strftime('%H:%M')\n \n \n if context.bar_index % 30 == 0: # 30m k线\n context.big_cycle_bar_index += 1\n \n sid = context.symbol(context.instruments[0])# 标的为字符串格式\n hist = data.history(sid, [\"open\",\"high\",\"low\",\"close\"], 30, \"1m\")\n big_cycle_bar_data = {'datetime':hist.index[-1],'high':hist.high.max(),'open':hist.open.values[0],'low':hist.low.min(),'close':hist.close.values[-1]}\n context.bar_series.append(big_cycle_bar_data)\n \n if context.big_cycle_bar_index > context.ma_periods : # 30分钟大周期K线的移动平均26个周期的均值 \n price_data = pd.DataFrame(list(context.bar_series))\n \n sma = talib.SMA(price_data['close'], timeperiod=context.ma_periods ).values[-1]\n cur_price = price_data['close'].values[-1]\n cur_position = context.portfolio.positions[sid].amount # 持仓 \n \n if cur_position==0 and cur_price>sma:\n context.order(sid, 100)\n print('buy'*5, cur_date)\n \n elif cur_position>0 and cur_price<sma:\n context.order_target_percent(sid, 0)\n print('sell'*5, cur_date)\n\n \n \n\n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n\n ","type":"Literal","bound_global_parameter":null},{"name":"handle_trade","value":"# 交易引擎:成交回报处理函数,每个成交发生时执行一次\ndef bigquant_run(context, trade):\n pass \n","type":"Literal","bound_global_parameter":null},{"name":"handle_order","value":"# 交易引擎:委托回报处理函数,每个委托变化时执行一次\ndef bigquant_run(context, order):\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":"500000","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":"order_price_field_buy","value":"open","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_sell","value":"open","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":"replay_bdb","value":"True","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":"-248"},{"name":"options_data","node_id":"-248"},{"name":"history_ds","node_id":"-248"},{"name":"benchmark_ds","node_id":"-248"}],"output_ports":[{"name":"raw_perf","node_id":"-248"}],"cacheable":false,"seq_num":3,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-290' Position='-75,-332,200,200'/><node_position Node='-248' Position='-67,-202,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [3]:
    # 本代码由可视化策略环境自动生成 2022年3月15日 15:08
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:初始化函数,只执行一次
    def m3_initialize_bigquant_run(context):
        # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
        context.subscribe(context.instruments[0])
        context.set_universe(context.instruments[0]) # 设置需要处理的合约
        context.bar_series =  NumPyDeque(200, dtype='object')  # 20个分钟 K线 (包括OHLC)
        context.bar_index = 0 # 分钟K线序号
        context.big_cycle_bar_index = 0 #30分钟大周期K线序号
        context.ma_periods  = 26 
    
         
     
     
    # 交易引擎:每个单位时间开盘前调用一次。
    def m3_before_trading_start_bigquant_run(context, data):
        pass
    # 交易引擎:tick数据处理函数,每个tick执行一次
    def m3_handle_tick_bigquant_run(context, tick):
        pass
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m3_handle_data_bigquant_run(context, data):
        
        import talib as ta
        context.bar_index += 1
        cur_date =  data.current_dt
        cur_hm = cur_date.strftime('%H:%M')
     
        
        if context.bar_index % 30 == 0:   # 30m k线
            context.big_cycle_bar_index += 1
                
            sid = context.symbol(context.instruments[0])# 标的为字符串格式
            hist = data.history(sid, ["open","high","low","close"], 30, "1m")
            big_cycle_bar_data = {'datetime':hist.index[-1],'high':hist.high.max(),'open':hist.open.values[0],'low':hist.low.min(),'close':hist.close.values[-1]}
            context.bar_series.append(big_cycle_bar_data)
           
            if context.big_cycle_bar_index > context.ma_periods :  # 30分钟大周期K线的移动平均26个周期的均值  
                price_data = pd.DataFrame(list(context.bar_series))
                
                sma = talib.SMA(price_data['close'], timeperiod=context.ma_periods ).values[-1]
                cur_price = price_data['close'].values[-1]
                cur_position = context.portfolio.positions[sid].amount # 持仓 
                
                if cur_position==0 and cur_price>sma:
                    context.order(sid, 100)
                    print('buy'*5, cur_date)
                    
                elif  cur_position>0 and cur_price<sma:
                    context.order_target_percent(sid, 0)
                    print('sell'*5, cur_date)
    
                
                
    
            
             
    
        
        
        
        
        
        
        
        
        
        
        
        
    
       
    # 交易引擎:成交回报处理函数,每个成交发生时执行一次
    def m3_handle_trade_bigquant_run(context, trade):
        pass 
    
    # 交易引擎:委托回报处理函数,每个委托变化时执行一次
    def m3_handle_order_bigquant_run(context, order):
        pass
    
    # 交易引擎:盘后处理函数,每日盘后执行一次
    def m3_after_trading_bigquant_run(context, data):
        pass
    
    
    m1 = M.instruments.v2(
        start_date='2022-01-01',
        end_date=T.live_run_param('trading_date', '2022-03-11'),
        market='CN_STOCK_A',
        instrument_list='600519.SHA',
        max_count=0,
        m_cached=False
    )
    
    m3 = M.hftrade.v2(
        instruments=m1.data,
        start_date='',
        end_date='',
        initialize=m3_initialize_bigquant_run,
        before_trading_start=m3_before_trading_start_bigquant_run,
        handle_tick=m3_handle_tick_bigquant_run,
        handle_data=m3_handle_data_bigquant_run,
        handle_trade=m3_handle_trade_bigquant_run,
        handle_order=m3_handle_order_bigquant_run,
        after_trading=m3_after_trading_bigquant_run,
        capital_base=500000,
        frequency='minute',
        price_type='真实价格',
        product_type='股票',
        before_start_days='0',
        order_price_field_buy='open',
        order_price_field_sell='open',
        benchmark='000300.HIX',
        plot_charts=True,
        disable_cache=False,
        replay_bdb=True,
        show_debug_info=False,
        backtest_only=False
    )
    
    • 收益率-2.41%
    • 年化收益率-12.56%
    • 基准收益率-12.43%
    • 阿尔法-0.1
    • 贝塔0.08
    • 夏普比率-2.91
    • 胜率0.2
    • 盈亏比0.4
    • 收益波动率5.77%
    • 信息比率0.23
    • 最大回撤3.93%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-f7d7b06e4f404f71982c7d8882ec1391"}/bigcharts-data-end