复制链接
克隆策略

目标

本示例旨在说明如何基于自定义的数据进行回测研究,例子以ETF回测为例,若是其他市场其他标的,同理即可。

策略逻辑

每日计算沪深300的5日均线和20日均线值

若5日均线大于20日均线,只持有a(注:a没有持仓就买入。b和c若有持仓就买出平仓),建仓20%;

若5日均线小于20日均线,只持有b(注:b没有持仓就买入。a和c若有持仓就买出平仓),建仓20%;

若5日均线小于20日均线,只持有c(注:c没有持仓就买入。a和b若有持仓就买出平仓),建仓20%。

模块介绍

m2,数据源模块,读取基金日线行情数据

m1,自定义Python模块,过滤出三只ETF基金数据

m4,数据源模块,读取指数日线行情数据

m3,自定义Python模块,过滤出沪深300指数行情数据

m6,自定义Python模块,将沪深300指数数据和回测标的的历史行情数据整理到一起

m8,代码列表模块,指定回测标的、起始结束时间

m7,自定义Python模块,读取基准数据

m5,Trade(回测/模拟),回测执行模块

    {"Description":"实验创建于2017/8/26","Summary":"","Graph":{"EdgesInternal":[{"DestinationInputPortId":"-2513:input_1","SourceOutputPortId":"-2431:data_1"},{"DestinationInputPortId":"-2431:input_1","SourceOutputPortId":"-2440:data"},{"DestinationInputPortId":"-2513:input_2","SourceOutputPortId":"-2450:data_1"},{"DestinationInputPortId":"-2450:input_1","SourceOutputPortId":"-2459:data"},{"DestinationInputPortId":"-2469:history_ds","SourceOutputPortId":"-2513:data_1"},{"DestinationInputPortId":"-2469:benchmark_ds","SourceOutputPortId":"-2525:data_1"},{"DestinationInputPortId":"-2469:instruments","SourceOutputPortId":"-3435:data"}],"ModuleNodes":[{"Id":"-2431","ModuleId":"BigQuantSpace.cached.cached-v3","ModuleParameters":[{"Name":"run","Value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n df = input_1.read()\n lt = ['518880.HOF','513600.HOF','512880.HOF']\n df = df[(df['instrument']==lt[0])|(df['instrument']==lt[1])|(df['instrument']==lt[2])]\n \n data_1 = DataSource.write_df(df)\n return Outputs(data_1=data_1, data_2=None, data_3=None)\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"post_run","Value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"input_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"params","Value":"{}","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"output_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-2431"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-2431"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-2431"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-2431","OutputType":null},{"Name":"data_2","NodeId":"-2431","OutputType":null},{"Name":"data_3","NodeId":"-2431","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":1,"Comment":"","CommentCollapsed":true},{"Id":"-2440","ModuleId":"BigQuantSpace.use_datasource.use_datasource-v1","ModuleParameters":[{"Name":"datasource_id","Value":"bar1d_CN_FUND","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"start_date","Value":"2017-11-27","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2018-09-05","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-2440"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-2440"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-2440","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":2,"Comment":"","CommentCollapsed":true},{"Id":"-2450","ModuleId":"BigQuantSpace.cached.cached-v3","ModuleParameters":[{"Name":"run","Value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n df = input_1.read()\n lt = '000300.HIX'\n df = df[df['instrument']==lt]\n \n data_1 = DataSource.write_df(df)\n return Outputs(data_1=data_1, data_2=None, data_3=None)\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"post_run","Value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"input_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"params","Value":"{}","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"output_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-2450"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-2450"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-2450"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-2450","OutputType":null},{"Name":"data_2","NodeId":"-2450","OutputType":null},{"Name":"data_3","NodeId":"-2450","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":3,"Comment":"","CommentCollapsed":true},{"Id":"-2459","ModuleId":"BigQuantSpace.use_datasource.use_datasource-v1","ModuleParameters":[{"Name":"datasource_id","Value":"bar1d_index_CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"start_date","Value":"2017-11-27","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2018-09-05","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-2459"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-2459"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-2459","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":4,"Comment":"","CommentCollapsed":true},{"Id":"-2469","ModuleId":"BigQuantSpace.trade.trade-v4","ModuleParameters":[{"Name":"start_date","Value":"2018-01-16","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2018-09-05","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"def bigquant_run(context):\n set_commission(futures_commission=PerContract(cost={'IC':(0.0023, 0.0015, 0.0023)}))\n set_need_settle(False)\n context.length_1 = 5\n context.length_2 = 20\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"def bigquant_run(context, data):\n \n #instrument = ['IC0000.CFX','IF0000.CFX','IH0000.CFX']\n instrument = ['518880.HOF','513600.HOF','512880.HOF']\n\n today = data.current_dt.strftime('%Y-%m-%d')\n \n sid_ind = symbol('000300.HIX')\n sid_a = future_symbol(instrument[0])\n sid_b = future_symbol(instrument[1])\n sid_c = future_symbol(instrument[2])\n \n # 最新价格\n #price = data.current(sid, 'price')\n position_a = context.portfolio.positions[sid_a]\n position_b = context.portfolio.positions[sid_b]\n position_c = context.portfolio.positions[sid_c]\n curr_position_a = position_a.amount\n curr_position_b = position_b.amount\n curr_position_c = position_c.amount\n ma5_ind_price = data.history(sid_ind, 'price', context.length_1, '1d').mean()\n ma20_ind_price = data.history(sid_ind, 'price', context.length_2, '1d').mean() \n\n\n if ma5_ind_price > ma20_ind_price:\n if data.can_trade(sid_a) and curr_position_a == 0 :\n order_target_percent(sid_a, 0.2)\n print(get_datetime(), 'buy_a')\n if data.can_trade(sid_b) and curr_position_b > 0:\n order_target_percent(sid_b, 0)\n print(get_datetime(), 'sell_b')\n elif data.can_trade(sid_c) and curr_position_c > 0:\n order_target_percent(sid_c, 0)\n print(get_datetime(), 'sell_c')\n \n elif ma5_ind_price < ma20_ind_price:\n if data.can_trade(sid_b) and curr_position_b == 0 :\n order_target_percent(sid_b, 0.2)\n print(get_datetime(), 'buy_b')\n if data.can_trade(sid_a) and curr_position_a > 0:\n order_target_percent(sid_a, 0)\n print('=='*10,curr_position_a)\n print(get_datetime(), 'sell_a')\n elif data.can_trade(sid_c) and curr_position_c > 0:\n order_target_percent(sid_c, 0)\n print(get_datetime(), 'sell_c')\n \n elif ma5_ind_price == ma20_ind_price:\n if data.can_trade(sid_c) and curr_position_c == 0 :\n order_target_percent(sid_c, 0.2)\n print(get_datetime(), 'buy_c')\n if data.can_trade(sid_a) and curr_position_a > 0:\n order_target_percent(sid_a, 0)\n print(get_datetime(), 'sell_a')\n elif data.can_trade(sid_b) and curr_position_b > 0:\n order_target_percent(sid_b, 0)\n print(get_datetime(), 'sell_b')","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"prepare","Value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"before_trading_start","Value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"volume_limit","Value":"0.026","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_buy","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_sell","Value":"close","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":"2000","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"auto_cancel_non_tradable_orders","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"data_frequency","Value":"daily","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"price_type","Value":"真实价格","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"product_type","Value":"股票","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"plot_charts","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"backtest_only","Value":"False","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-2469"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-2469"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"history_ds","NodeId":"-2469"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"benchmark_ds","NodeId":"-2469"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"trading_calendar","NodeId":"-2469"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-2469","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":5,"Comment":"","CommentCollapsed":true},{"Id":"-2513","ModuleId":"BigQuantSpace.cached.cached-v3","ModuleParameters":[{"Name":"run","Value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n datadf = input_1.read()\n datadf_ind = input_2.read() \n \n history_ds = DataSource.write_df(pd.concat([datadf,datadf_ind],axis=0))\n return Outputs(data_1=history_ds, data_2=None, data_3=None)\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"post_run","Value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"input_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"params","Value":"{}","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"output_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-2513"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-2513"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-2513"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-2513","OutputType":null},{"Name":"data_2","NodeId":"-2513","OutputType":null},{"Name":"data_3","NodeId":"-2513","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":6,"Comment":"","CommentCollapsed":true},{"Id":"-2525","ModuleId":"BigQuantSpace.cached.cached-v3","ModuleParameters":[{"Name":"run","Value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n start_date = '2017-11-27'\n end_date = '2018-09-05'\n bm_instruments = ['000300.HIX']\n start = pd.to_datetime(start_date)-datetime.timedelta(50)\n start = start.strftime('%Y-%m-%d')\n id_ohlc = 'bar1d_index_CN_STOCK_A'\n origin_fields=['open', 'high', 'low', 'close', 'volume', 'amount']\n ohlc_df = DataSource(id_ohlc).read(instruments=bm_instruments, start_date=start, end_date=end_date,\n fields=origin_fields)\n\n ohlc_df.rename({'s_dq_close':'close', 's_dq_high':'high', 's_dq_open':'open', 's_dq_low':'low', 's_dq_volume':'volume', 's_dq_amount':'amount'},axis=1, inplace=True)\n benchmark_ds = DataSource.write_df(ohlc_df)\n return Outputs(data_1=benchmark_ds, data_2=None, data_3=None)\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"post_run","Value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"input_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"params","Value":"{}","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"output_ports","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-2525"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-2525"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-2525"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-2525","OutputType":null},{"Name":"data_2","NodeId":"-2525","OutputType":null},{"Name":"data_3","NodeId":"-2525","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":7,"Comment":"","CommentCollapsed":true},{"Id":"-3435","ModuleId":"BigQuantSpace.instruments.instruments-v2","ModuleParameters":[{"Name":"start_date","Value":"2017-11-27","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2018-09-05","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"market","Value":"CN_FUND","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_list","Value":"['518880.HOF','513600.HOF','512880.HOF']","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_count","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"rolling_conf","NodeId":"-3435"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-3435","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":8,"Comment":"","CommentCollapsed":true}],"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions><NodePosition Node='-2431' Position='754.2525024414062,91.77722930908203,200,200'/><NodePosition Node='-2440' Position='602.9158325195312,-26.054458618164062,200,200'/><NodePosition Node='-2450' Position='1127,48.18316650390625,200,200'/><NodePosition Node='-2459' Position='1127.5989990234375,-29.504948139190674,200,200'/><NodePosition Node='-2469' Position='720.17822265625,436.5544738769531,200,200'/><NodePosition Node='-2513' Position='788.7574462890625,190.9851531982422,200,200'/><NodePosition Node='-2525' Position='1041.2178955078125,317.1435546875,200,200'/><NodePosition Node='-3435' Position='441.81683349609375,304.5940856933594,200,200'/></NodePositions><NodeGroups /></DataV1>"},"IsDraft":true,"ParentExperimentId":null,"WebService":{"IsWebServiceExperiment":false,"Inputs":[],"Outputs":[],"Parameters":[{"Name":"交易日期","Value":"","ParameterDefinition":{"Name":"交易日期","FriendlyName":"交易日期","DefaultValue":"","ParameterType":"String","HasDefaultValue":true,"IsOptional":true,"ParameterRules":[],"HasRules":false,"MarkupType":0,"CredentialDescriptor":null}}],"WebServiceGroupId":null,"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions></NodePositions><NodeGroups /></DataV1>"},"DisableNodesUpdate":false,"Category":"user","Tags":[],"IsPartialRun":true}
    In [4]:
    # 本代码由可视化策略环境自动生成 2021年5月8日20:38
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m1_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        df = input_1.read()
        lt = ['518880.HOF','513600.HOF','512880.HOF']
        df = df[(df['instrument']==lt[0])|(df['instrument']==lt[1])|(df['instrument']==lt[2])]
        
        data_1 = DataSource.write_df(df)
        return Outputs(data_1=data_1, data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m1_post_run_bigquant_run(outputs):
        return outputs
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m3_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        df = input_1.read()
        lt = '000300.HIX'
        df = df[df['instrument']==lt]
        
        data_1 = DataSource.write_df(df)
        return Outputs(data_1=data_1, data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m3_post_run_bigquant_run(outputs):
        return outputs
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m6_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        datadf = input_1.read()
        datadf_ind = input_2.read()   
        
        history_ds = DataSource.write_df(pd.concat([datadf,datadf_ind],axis=0))
        return Outputs(data_1=history_ds, data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m6_post_run_bigquant_run(outputs):
        return outputs
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m7_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        start_date = '2017-11-27'
        end_date = '2018-09-05'
        bm_instruments = ['000300.HIX']
        start = pd.to_datetime(start_date)-datetime.timedelta(50)
        start = start.strftime('%Y-%m-%d')
        id_ohlc = 'bar1d_index_CN_STOCK_A'
        origin_fields=['open', 'high', 'low', 'close', 'volume', 'amount']
        ohlc_df = DataSource(id_ohlc).read(instruments=bm_instruments, start_date=start, end_date=end_date,
                                      fields=origin_fields)
    
        ohlc_df.rename({'s_dq_close':'close', 's_dq_high':'high', 's_dq_open':'open', 's_dq_low':'low', 's_dq_volume':'volume', 's_dq_amount':'amount'},axis=1, inplace=True)
        benchmark_ds = DataSource.write_df(ohlc_df)
        return Outputs(data_1=benchmark_ds, data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m7_post_run_bigquant_run(outputs):
        return outputs
    
    def m5_initialize_bigquant_run(context):
        set_commission(futures_commission=PerContract(cost={'IC':(0.0023, 0.0015, 0.0023)}))
        set_need_settle(False)
        context.length_1 = 5
        context.length_2 = 20
    
    def m5_handle_data_bigquant_run(context, data):
        
        #instrument = ['IC0000.CFX','IF0000.CFX','IH0000.CFX']
        instrument = ['518880.HOF','513600.HOF','512880.HOF']
    
        today = data.current_dt.strftime('%Y-%m-%d')
        
        sid_ind = symbol('000300.HIX')
        sid_a = future_symbol(instrument[0])
        sid_b = future_symbol(instrument[1])
        sid_c = future_symbol(instrument[2])
        
        # 最新价格
        #price = data.current(sid, 'price')
        position_a = context.portfolio.positions[sid_a]
        position_b = context.portfolio.positions[sid_b]
        position_c = context.portfolio.positions[sid_c]
        curr_position_a = position_a.amount
        curr_position_b = position_b.amount
        curr_position_c = position_c.amount
        ma5_ind_price = data.history(sid_ind, 'price', context.length_1, '1d').mean()
        ma20_ind_price = data.history(sid_ind, 'price', context.length_2, '1d').mean() 
    
    
        if ma5_ind_price > ma20_ind_price:
            if data.can_trade(sid_a) and curr_position_a == 0 :
                order_target_percent(sid_a, 0.2)
                print(get_datetime(), 'buy_a')
                if data.can_trade(sid_b) and curr_position_b > 0:
                    order_target_percent(sid_b, 0)
                    print(get_datetime(), 'sell_b')
                elif data.can_trade(sid_c) and curr_position_c > 0:
                    order_target_percent(sid_c, 0)
                    print(get_datetime(), 'sell_c')
            
        elif ma5_ind_price < ma20_ind_price:
            if data.can_trade(sid_b) and curr_position_b == 0 :
                order_target_percent(sid_b, 0.2)
                print(get_datetime(), 'buy_b')
                if data.can_trade(sid_a) and curr_position_a > 0:
                    order_target_percent(sid_a, 0)
                    print('=='*10,curr_position_a)
                    print(get_datetime(), 'sell_a')
                elif data.can_trade(sid_c) and curr_position_c > 0:
                    order_target_percent(sid_c, 0)
                    print(get_datetime(), 'sell_c')
                
        elif ma5_ind_price == ma20_ind_price:
            if data.can_trade(sid_c) and curr_position_c == 0 :
                order_target_percent(sid_c, 0.2)
                print(get_datetime(), 'buy_c')
                if data.can_trade(sid_a) and curr_position_a > 0:
                    order_target_percent(sid_a, 0)
                    print(get_datetime(), 'sell_a')
                elif data.can_trade(sid_b) and curr_position_b > 0:
                    order_target_percent(sid_b, 0)
                    print(get_datetime(), 'sell_b')
    # 回测引擎:准备数据,只执行一次
    def m5_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m5_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m2 = M.use_datasource.v1(
        datasource_id='bar1d_CN_FUND',
        start_date='2017-11-27',
        end_date='2018-09-05'
    )
    
    m1 = M.cached.v3(
        input_1=m2.data,
        run=m1_run_bigquant_run,
        post_run=m1_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m4 = M.use_datasource.v1(
        datasource_id='bar1d_index_CN_STOCK_A',
        start_date='2017-11-27',
        end_date='2018-09-05'
    )
    
    m3 = M.cached.v3(
        input_1=m4.data,
        run=m3_run_bigquant_run,
        post_run=m3_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m6 = M.cached.v3(
        input_1=m1.data_1,
        input_2=m3.data_1,
        run=m6_run_bigquant_run,
        post_run=m6_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m7 = M.cached.v3(
        run=m7_run_bigquant_run,
        post_run=m7_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m8 = M.instruments.v2(
        start_date='2017-11-27',
        end_date='2018-09-05',
        market='CN_FUND',
        instrument_list='[\'518880.HOF\',\'513600.HOF\',\'512880.HOF\']',
        max_count=0
    )
    
    m5 = M.trade.v4(
        instruments=m8.data,
        history_ds=m6.data_1,
        benchmark_ds=m7.data_1,
        start_date='2018-01-16',
        end_date='2018-09-05',
        initialize=m5_initialize_bigquant_run,
        handle_data=m5_handle_data_bigquant_run,
        prepare=m5_prepare_bigquant_run,
        before_trading_start=m5_before_trading_start_bigquant_run,
        volume_limit=0.026,
        order_price_field_buy='open',
        order_price_field_sell='close',
        capital_base=2000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='真实价格',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark=''
    )
    
    2018-01-16 15:00:00+00:00 buy_a
    2018-02-02 15:00:00+00:00 buy_b
    ==================== 100
    2018-02-02 15:00:00+00:00 sell_a
    2018-03-09 15:00:00+00:00 buy_a
    2018-03-09 15:00:00+00:00 sell_b
    2018-03-22 15:00:00+00:00 buy_b
    ==================== 100
    2018-03-22 15:00:00+00:00 sell_a
    2018-05-09 15:00:00+00:00 buy_a
    2018-05-09 15:00:00+00:00 sell_b
    2018-05-28 15:00:00+00:00 buy_b
    ==================== 100
    2018-05-28 15:00:00+00:00 sell_a
    2018-07-18 15:00:00+00:00 buy_a
    2018-07-18 15:00:00+00:00 sell_b
    2018-08-02 15:00:00+00:00 buy_b
    ==================== 100
    2018-08-02 15:00:00+00:00 sell_a
    2018-08-28 15:00:00+00:00 buy_a
    2018-08-28 15:00:00+00:00 sell_b
    2018-09-05 15:00:00+00:00 buy_b
    ==================== 100
    2018-09-05 15:00:00+00:00 sell_a
    
    • 收益率-4.93%
    • 年化收益率-7.79%
    • 基准收益率-21.94%
    • 阿尔法-0.08
    • 贝塔0.08
    • 夏普比率-3.75
    • 胜率0.5
    • 盈亏比0.53
    • 收益波动率2.94%
    • 信息比率0.1
    • 最大回撤4.93%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-743cb34f121a4ff1b49ac85168b8b888"}/bigcharts-data-end