复制链接
克隆策略

通道突破策略——布林带指标

版本 v1.0

目录

布林带通道突破策略的交易规则

策略构建步骤

策略的实现

正文

一、布林带通道突破策略的交易规则

指标计算:
中轨 = N时间段的简单移动平均线
上轨 = 中轨 + K × N时间段的标准差
下轨 = 中轨 − K × N时间段的标准差
一般情况下,设定N=20和K=2,这两个数值也是在布林带当中使用最多的。在日线图里,N=20其实就是“月均线”(MA20)。依照正态分布规则,约有95%的数值会分布在距离平均值有正负2个标准差的范围内
交易规则:价格突破上轨(%b大于等于1),买入开仓,价格突破下轨(%b小于等于0),卖出开仓

二、策略构建步骤

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

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

2、确定买卖原则

当价格突破中轨全仓买入,突破上轨空仓卖出。

3、回测

通过 trade 模块中的初始化函数定义交易手续费和滑点;
通过 trade 模块中的主函数(handle函数)查看每日的买卖交易信号,按照买卖原则执行相应的买入/卖出/调仓操作。

三、策略的实现

可视化策略实现如下:

    {"description":"实验创建于2021/12/2","graph":{"edges":[{"to_node_id":"-1824:instruments","from_node_id":"-5:data"},{"to_node_id":"-3064:instruments","from_node_id":"-5:data"},{"to_node_id":"-62:features","from_node_id":"-13:data"},{"to_node_id":"-3064:features","from_node_id":"-13:data"},{"to_node_id":"-97:input_data","from_node_id":"-62:data"},{"to_node_id":"-1824:options_data","from_node_id":"-97:data"},{"to_node_id":"-62:input_data","from_node_id":"-3064:data"}],"nodes":[{"node_id":"-5","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2021-01-17","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2022-3-26","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"000001.SZA","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-5"}],"output_ports":[{"name":"data","node_id":"-5"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-13","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nbbands_up = ta_bbands_u(close_0, 20)\nbbands = ta_bbands_m(close_0, 20)\nbbands_low = ta_bbands_l(close_0, 20)\n\nclose_0\n\n\n\n\n","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-13"}],"output_ports":[{"name":"data","node_id":"-13"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-62","module_id":"BigQuantSpace.derived_feature_extractor.derived_feature_extractor-v3","parameters":[{"name":"date_col","value":"date","type":"Literal","bound_global_parameter":null},{"name":"instrument_col","value":"instrument","type":"Literal","bound_global_parameter":null},{"name":"drop_na","value":"False","type":"Literal","bound_global_parameter":null},{"name":"remove_extra_columns","value":"False","type":"Literal","bound_global_parameter":null},{"name":"user_functions","value":"{}","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-62"},{"name":"features","node_id":"-62"}],"output_ports":[{"name":"data","node_id":"-62"}],"cacheable":true,"seq_num":4,"comment":"","comment_collapsed":true},{"node_id":"-97","module_id":"BigQuantSpace.dropnan.dropnan-v2","parameters":[],"input_ports":[{"name":"input_data","node_id":"-97"},{"name":"features","node_id":"-97"}],"output_ports":[{"name":"data","node_id":"-97"}],"cacheable":true,"seq_num":3,"comment":"","comment_collapsed":true},{"node_id":"-1824","module_id":"BigQuantSpace.trade.trade-v4","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.ranker_prediction = context.options['data'].read_df()\n\n # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n # 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)\n # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只\n# stock_count = 5\n# # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]\n# context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])\n# # 设置每只股票占用的最大资金比例\n# context.max_cash_per_instrument = 0.2\n# context.hold_days = 5\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n # 按日期过滤得到今日的预测数据\n ranker_prediction = context.ranker_prediction[\n context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]\n \n sid = context.symbol(context.instruments[0])# 标的为字符串格式\n price = data.current(sid, 'price') # 最新价格\n \n cash = context.portfolio.cash # 现金\n cur_position = context.portfolio.positions[sid].amount # 持仓\n \n \n upperbond = ranker_prediction['bbands_up'].values\n middlebond = ranker_prediction['bbands'].values\n lowerbond = ranker_prediction['bbands_low'].values\n close = ranker_prediction['close_0'].values\n \n print(upperbond)\n \n# print(price)\n \n \n# for i in range(0,len(middlebond)):\n# if close[i] > middlebond[i]:\n# context.order(sid, cash) # 买入\n# print('{}全仓买入{}股票'.format(data.current_dt.strftime('%Y-%m-%d'),sid.symbol))\n# elif close[i] > upperbond[i]:\n# context.order_target_percent(sid, 0) # 全部卖出\n# print('{}卖出{}股票'.format(data.current_dt.strftime('%Y-%m-%d'),sid.symbol))\n# else:\n# return\n \n \n \n \n \n \n \n \n\n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":0.025,"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":"close","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":1000000,"type":"Literal","bound_global_parameter":null},{"name":"auto_cancel_non_tradable_orders","value":"True","type":"Literal","bound_global_parameter":null},{"name":"data_frequency","value":"daily","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":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"backtest_only","value":"False","type":"Literal","bound_global_parameter":null},{"name":"benchmark","value":"000300.HIX","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-1824"},{"name":"options_data","node_id":"-1824"},{"name":"history_ds","node_id":"-1824"},{"name":"benchmark_ds","node_id":"-1824"},{"name":"trading_calendar","node_id":"-1824"}],"output_ports":[{"name":"raw_perf","node_id":"-1824"}],"cacheable":false,"seq_num":7,"comment":"","comment_collapsed":true},{"node_id":"-3064","module_id":"BigQuantSpace.general_feature_extractor.general_feature_extractor-v7","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"before_start_days","value":90,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-3064"},{"name":"features","node_id":"-3064"}],"output_ports":[{"name":"data","node_id":"-3064"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-5' Position='293,113,200,200'/><node_position Node='-13' Position='601,108,200,200'/><node_position Node='-62' Position='420,280,200,200'/><node_position Node='-97' Position='406,357,200,200'/><node_position Node='-1824' Position='301,467,200,200'/><node_position Node='-3064' Position='308,198,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [7]:
    # 本代码由可视化策略环境自动生成 2022年3月27日 22:03
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:初始化函数,只执行一次
    def m7_initialize_bigquant_run(context):
        # 加载预测数据
        context.ranker_prediction = context.options['data'].read_df()
    
        # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        # 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
        # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
    #     stock_count = 5
    #     # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
    #     context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
    #     # 设置每只股票占用的最大资金比例
    #     context.max_cash_per_instrument = 0.2
    #     context.hold_days = 5
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m7_handle_data_bigquant_run(context, data):
        # 按日期过滤得到今日的预测数据
        ranker_prediction = context.ranker_prediction[
            context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
        
        sid = context.symbol(context.instruments[0])# 标的为字符串格式
        price = data.current(sid, 'price') # 最新价格
        
        cash = context.portfolio.cash  # 现金
        cur_position = context.portfolio.positions[sid].amount # 持仓
        
        
        upperbond = ranker_prediction['bbands_up'].values
        middlebond = ranker_prediction['bbands'].values
        lowerbond = ranker_prediction['bbands_low'].values
        close = ranker_prediction['close_0'].values
        
        print(upperbond)
        
    #     print(price)
        
        
    #     for i in range(0,len(middlebond)):
    #         if close[i] > middlebond[i]:
    #             context.order(sid, cash) # 买入
    #             print('{}全仓买入{}股票'.format(data.current_dt.strftime('%Y-%m-%d'),sid.symbol))
    #         elif close[i] > upperbond[i]:
    #             context.order_target_percent(sid, 0) # 全部卖出
    #             print('{}卖出{}股票'.format(data.current_dt.strftime('%Y-%m-%d'),sid.symbol))
    #         else:
    #             return
            
                
                
                
        
        
        
        
    
    
    # 回测引擎:准备数据,只执行一次
    def m7_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m7_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m1 = M.instruments.v2(
        start_date='2021-01-17',
        end_date='2022-3-26',
        market='CN_STOCK_A',
        instrument_list='000001.SZA',
        max_count=0
    )
    
    m2 = M.input_features.v1(
        features="""# #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    bbands_up = ta_bbands_u(close_0, 20)
    bbands = ta_bbands_m(close_0, 20)
    bbands_low = ta_bbands_l(close_0, 20)
    
    close_0
    
    
    
    
    """
    )
    
    m5 = M.general_feature_extractor.v7(
        instruments=m1.data,
        features=m2.data,
        start_date='',
        end_date='',
        before_start_days=90
    )
    
    m4 = M.derived_feature_extractor.v3(
        input_data=m5.data,
        features=m2.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=False,
        remove_extra_columns=False,
        user_functions={}
    )
    
    m3 = M.dropnan.v2(
        input_data=m4.data
    )
    
    m7 = M.trade.v4(
        instruments=m1.data,
        options_data=m3.data,
        start_date='',
        end_date='',
        initialize=m7_initialize_bigquant_run,
        handle_data=m7_handle_data_bigquant_run,
        prepare=m7_prepare_bigquant_run,
        before_trading_start=m7_before_trading_start_bigquant_run,
        volume_limit=0.025,
        order_price_field_buy='open',
        order_price_field_sell='close',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='真实价格',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark='000300.HIX'
    )
    
    [2436.079]
    [2484.7927]
    [2525.2532]
    [2552.8022]
    [2572.4075]
    [2592.579]
    [2612.5227]
    [2644.5657]
    [2665.585]
    [2688.1487]
    [2729.0933]
    [2719.9036]
    [2763.7441]
    [2792.1653]
    [2818.7183]
    [2840.502]
    [2858.1277]
    [2855.4412]
    [2841.3074]
    [2828.4695]
    [2829.9114]
    [2833.386]
    [2835.278]
    [2836.324]
    [2843.827]
    [2851.8767]
    [2856.4873]
    [2856.2498]
    [2856.4414]
    [2856.0269]
    [2842.2803]
    [2849.1448]
    [2830.996]
    [2805.2363]
    [2765.1326]
    [2721.3665]
    [2676.45]
    [2647.7847]
    [2596.4883]
    [2557.038]
    [2548.1663]
    [2544.7478]
    [2541.54]
    [2535.5525]
    [2534.9426]
    [2535.1824]
    [2538.253]
    [2514.5415]
    [2486.625]
    [2470.852]
    [2471.9163]
    [2474.6738]
    [2469.3708]
    [2469.436]
    [2471.2349]
    [2469.9749]
    [2467.844]
    [2472.3162]
    [2470.6143]
    [2469.056]
    [2471.078]
    [2510.139]
    [2539.428]
    [2573.253]
    [2593.9666]
    [2611.9075]
    [2634.8262]
    [2660.6084]
    [2678.9775]
    [2700.3308]
    [2730.7021]
    [2753.778]
    [2768.6978]
    [2781.322]
    [2780.8774]
    [2782.8528]
    [2782.3403]
    [2772.3066]
    [2737.9604]
    [2715.8362]
    [2689.6755]
    [2689.8809]
    [2716.5303]
    [2753.055]
    [2772.6204]
    [2781.0427]
    [2785.71]
    [2787.4172]
    [2786.8281]
    [2786.519]
    [2795.0437]
    [2799.6501]
    [2806.08]
    [2813.2698]
    [2805.558]
    [2804.9478]
    [2808.7952]
    [2812.0215]
    [2816.2935]
    [2826.4253]
    [2842.9211]
    [2845.1055]
    [2836.4033]
    [2817.388]
    [2800.4011]
    [2789.586]
    [2786.2476]
    [2782.1697]
    [2776.5474]
    [2780.7385]
    [2763.3857]
    [2744.9849]
    [2717.1106]
    [2688.7769]
    [2672.3667]
    [2673.2427]
    [2672.6504]
    [2672.6316]
    [2662.7263]
    [2659.5105]
    [2660.4438]
    [2656.3447]
    [2646.5881]
    [2634.3164]
    [2613.3865]
    [2623.4368]
    [2652.1921]
    [2659.2498]
    [2638.0784]
    [2639.2695]
    [2625.3728]
    [2590.571]
    [2553.7212]
    [2534.2104]
    [2513.0798]
    [2489.3525]
    [2469.0215]
    [2455.4602]
    [2422.136]
    [2393.4111]
    [2366.6294]
    [2349.7026]
    [2353.596]
    [2352.7588]
    [2342.6335]
    [2346.292]
    [2348.458]
    [2347.2441]
    [2344.9763]
    [2339.8462]
    [2342.6782]
    [2343.5488]
    [2342.8728]
    [2337.202]
    [2335.4448]
    [2334.976]
    [2329.815]
    [2323.194]
    [2313.3762]
    [2327.8906]
    [2332.7217]
    [2329.2822]
    [2307.8857]
    [2287.3652]
    [2281.4934]
    [2278.2437]
    [2275.0344]
    [2275.6614]
    [2277.724]
    [2277.5637]
    [2276.3743]
    [2275.8599]
    [2276.468]
    [2285.0723]
    [2291.836]
    [2301.4585]
    [2301.1335]
    [2306.9224]
    [2309.6406]
    [2287.788]
    [2269.349]
    [2281.1545]
    [2291.0857]
    [2307.3179]
    [2323.2366]
    [2333.1956]
    [2334.6045]
    [2323.8494]
    [2310.6545]
    [2307.2068]
    [2309.1685]
    [2310.3228]
    [2323.6338]
    [2335.8352]
    [2341.9883]
    [2344.0723]
    [2341.0981]
    [2332.4697]
    [2327.608]
    [2318.5823]
    [2313.071]
    [2294.4932]
    [2271.4763]
    [2242.8997]
    [2211.4915]
    [2178.179]
    [2145.0332]
    [2112.444]
    [2073.932]
    [2071.703]
    [2069.794]
    [2069.2695]
    [2069.2617]
    [2070.9736]
    [2079.5503]
    [2085.3855]
    [2093.5537]
    [2095.3164]
    [2092.616]
    [2090.3245]
    [2088.98]
    [2088.9143]
    [2086.4038]
    [2083.9856]
    [2083.343]
    [2083.4216]
    [2084.499]
    [2085.5215]
    [2087.0376]
    [2088.6702]
    [2095.041]
    [2098.8762]
    [2105.7632]
    [2103.0552]
    [2088.68]
    [2071.905]
    [2044.4966]
    [2023.1371]
    [2002.9331]
    [1998.3269]
    [1993.6996]
    [1991.5208]
    [1991.545]
    [1985.8447]
    [1977.0815]
    [1975.9586]
    [1976.4985]
    [1974.7797]
    [1971.3732]
    [1968.2723]
    [1970.6241]
    [1979.1766]
    [1979.5404]
    [1980.1953]
    [1977.1171]
    [1975.5242]
    [1974.0273]
    [1968.8419]
    [1959.033]
    [1955.4789]
    [1951.7294]
    [1952.837]
    [1951.8273]
    [1952.7538]
    [1953.7938]
    [1945.7682]
    [1934.4104]
    [1926.2435]
    [1921.8232]
    [1921.8406]
    [1923.547]
    [1929.5817]
    [1944.5862]
    [1955.6245]
    [1967.6897]
    [1956.9758]
    [1937.2273]
    [1928.6742]
    [1932.6024]
    [1922.1354]
    [1907.9988]
    [1882.2313]
    [1859.6575]
    [1843.3173]
    [1824.9866]
    [1813.5096]
    [1799.2848]
    
    • 收益率0.0%
    • 年化收益率0.0%
    • 基准收益率-23.52%
    • 阿尔法-0.03
    • 贝塔0.0
    • 夏普比率n/a
    • 胜率0.0
    • 盈亏比0.0
    • 收益波动率0.0%
    • 信息比率0.07
    • 最大回撤0.0%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-2f9744d4de5d4bf0bed459d08f60064b"}/bigcharts-data-end