复制链接
克隆策略

    {"description":"实验创建于2022/10/8","graph":{"edges":[{"to_node_id":"-2670:input_1","from_node_id":"-1681:data"},{"to_node_id":"-343:input_ds","from_node_id":"-5717:data"},{"to_node_id":"-603:input_data","from_node_id":"-343:sorted_data"},{"to_node_id":"-4290:instruments","from_node_id":"-2670:data_1"},{"to_node_id":"-5717:instruments","from_node_id":"-2670:data_2"},{"to_node_id":"-4290:options_data","from_node_id":"-1435:data"},{"to_node_id":"-1435:input_data","from_node_id":"-603:data"},{"to_node_id":"-603:features","from_node_id":"-393:data"}],"nodes":[{"node_id":"-1681","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2018-01-01","type":"Literal","bound_global_parameter":"交易日期"},{"name":"end_date","value":"2022-11-30","type":"Literal","bound_global_parameter":"交易日期"},{"name":"market","value":"CN_FUTURE","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-1681"}],"output_ports":[{"name":"data","node_id":"-1681"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-5717","module_id":"BigQuantSpace.use_datasource.use_datasource-v2","parameters":[{"name":"datasource_id","value":"bar1d_CN_FUTURE","type":"Literal","bound_global_parameter":null},{"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":"0","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-5717"},{"name":"features","node_id":"-5717"}],"output_ports":[{"name":"data","node_id":"-5717"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-343","module_id":"BigQuantSpace.sort.sort-v5","parameters":[{"name":"sort_by","value":"date","type":"Literal","bound_global_parameter":null},{"name":"group_by","value":"--","type":"Literal","bound_global_parameter":null},{"name":"keep_columns","value":"--","type":"Literal","bound_global_parameter":null},{"name":"ascending","value":"True","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_ds","node_id":"-343"},{"name":"sort_by_ds","node_id":"-343"}],"output_ports":[{"name":"sorted_data","node_id":"-343"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-2670","module_id":"BigQuantSpace.futures_forward_extractor.futures_forward_extractor-v11","parameters":[{"name":"before_days","value":"50","type":"Literal","bound_global_parameter":null},{"name":"product_filter","value":"[\"BB\", \"LR\", \"JR\", \"FB\", \"RI\",\n \"WR\", \"RS\", \"PM\", \"WT\", \"TC\",\n \"RO\", \"ER\", \"WS\", \"B\", \"FU\",\n \"LU\", \"SC\", \"L\", \"ME\", \"WH\",\n \"FB\", \"FBA\"]","type":"Literal","bound_global_parameter":null},{"name":"if_CFX","value":"True","type":"Literal","bound_global_parameter":null},{"name":"set_enable_trade","value":"False","type":"Literal","bound_global_parameter":null},{"name":"output_type","value":"主力连续","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-2670"}],"output_ports":[{"name":"data_1","node_id":"-2670"},{"name":"data_2","node_id":"-2670"},{"name":"data_3","node_id":"-2670"}],"cacheable":true,"seq_num":10,"comment":"","comment_collapsed":true},{"node_id":"-1435","module_id":"BigQuantSpace.dropnan.dropnan-v2","parameters":[],"input_ports":[{"name":"input_data","node_id":"-1435"},{"name":"features","node_id":"-1435"}],"output_ports":[{"name":"data","node_id":"-1435"}],"cacheable":true,"seq_num":19,"comment":"","comment_collapsed":true},{"node_id":"-603","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":"-603"},{"name":"features","node_id":"-603"}],"output_ports":[{"name":"data","node_id":"-603"}],"cacheable":true,"seq_num":4,"comment":"","comment_collapsed":true},{"node_id":"-393","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"alpha0001 = high / (ts_min(high, 5) / close)","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-393"}],"output_ports":[{"name":"data","node_id":"-393"}],"cacheable":true,"seq_num":7,"comment":"","comment_collapsed":true},{"node_id":"-4290","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":"def bigquant_run(context):\n msg = \"initialize:\" \n context.PRINT = 1\n context.write_log(msg, stdout=context.PRINT)\n print(\"initializing:\")\n context.all_data = context.options[\"data\"].read()\n context.all_data.set_index(\"instrument\", inplace=True)\n \n context.rebalance_period = 22 # 调仓周期设置\n context.long_short = 1 # 多空策略选择: 0为多空策略; 1为纯多头策略\n context.num_trades = 5 # 每层交易品种数量: 若context.long_short为0, 则总共交易标的有2*context.num_trades; 若为1, 则为context.num_trades\n context.mono = True\n context.lev = 1\n \n context.set_slippage_value(slippage_type=SlippageType.PERCENT, slippage_value=0) # 交易滑点设置","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"def bigquant_run(context, data):\n context.today = data.trading_day_dt.strftime('%Y-%m-%d')\n context.today_data = context.all_data[context.all_data.date==context.today]\n\n if context.trading_day_index % context.rebalance_period == 0:\n # print(\"check date, \", context.today)\n r1 = context.today_data\n r1.sort_values(by=[\"alpha0001\"], ascending=context.mono, inplace=True)\n context.ins_to_long = r1.index[:context.num_trades].tolist() # 做多因子排序后靠前的品种\n context.ins_to_short = r1.index[-context.num_trades:].tolist() # 做空因子排序后靠后的品种\n\n context.dominant_to_long = context.get_dominant(context.ins_to_long)\n context.dominant_to_short = context.get_dominant(context.ins_to_short)\n if context.trading_day_index == 0:\n context.extension.pre_dominant_to_long = context.dominant_to_long\n context.extension.pre_dominant_to_short = context.dominant_to_short\n else:\n context.ins_to_long = context.extension.pre_ins_to_long\n context.ins_to_short = context.extension.pre_ins_to_short\n\n context.dominant_to_long = context.get_dominant(context.ins_to_long)\n context.dominant_to_short = context.get_dominant(context.ins_to_short)\n \n context.ins = context.ins_to_long+context.ins_to_short\n if not context.long_short:\n context.cash_per_constract = context.portfolio.portfolio_value / (context.num_trades * 2)\n else:\n context.cash_per_constract = context.portfolio.portfolio_value / context.num_trades","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":"def bigquant_run(context, data):\n if len(context.today_data) == 0:\n return\n \n ##--------- 调整标的池之后, 未入选新标的池的合约进行平仓处理 ---------##\n if len(context.get_account_positions()) > 0:\n ins_pc = [i.split(\".\")[0][:-4] for i in context.ins] # 当前日期交易品种池的product_codes\n for instrument, _ in context.get_account_positions().items():\n pc = instrument.split(\".\")[0][:-4]\n if pc not in ins_pc:\n price = data.current(instrument, \"close\")\n rv = context.order_target(instrument, 0, price, order_type=OrderType.MARKET)\n ##--------- 调整标的池之后, 未入选新标的池的合约进行平仓处理 ---------##\n \n # if context.trading_day_index % context.rebalance_period == 0:\n for instrument in context.ins:\n pc = instrument.split(\".\")[0][:-4]\n dominant_code = [i for i in context.dominant_to_long+context.dominant_to_short if pc == i.split(\".\")[0][:-4]][0]\n pre_dominant_list = [i for i in context.extension.pre_dominant_to_long+context.extension.pre_dominant_to_short if pc == i.split(\".\")[0][:-4]]\n\n if not len(pre_dominant_list):\n pre_dominant_code = dominant_code\n else:\n pre_dominant_code = pre_dominant_list[0]\n \n price = data.current(instrument, \"close\") # 合约价格\n multiplier = context.get_contract(instrument).multiplier # 合约乘数\n long_position = context.get_account_position(pre_dominant_code, direction=Direction.LONG).avail_qty # 多头持仓\n short_position = context.get_account_position(pre_dominant_code, direction=Direction.SHORT).avail_qty # 空头持仓\n curr_position = short_position + long_position # 总持仓\n \n order_num = context.lev * (context.cash_per_constract // (price * multiplier))\n \n if curr_position==0 and context.trading_day_index % context.rebalance_period == 0:\n if not context.long_short:\n if instrument in context.ins_to_long:\n rv1 = context.order_target(dominant_code, order_num, price, order_type=OrderType.MARKET)\n elif instrument in context.ins_to_short:\n rv1 = context.order_target(dominant_code, -order_num, price, order_type=OrderType.MARKET)\n else:\n if instrument in context.ins_to_long:\n rv1 = context.order_target(dominant_code, order_num, price, order_type=OrderType.MARKET)\n else:\n if short_position > 0 and dominant_code != pre_dominant_code:\n rv1 = context.order_target(pre_dominant_code, 0, price, order_type=OrderType.MARKET)\n rv2 = context.order_target(dominant_code, -short_position, price, order_type=OrderType.MARKET)\n elif long_position > 0 and dominant_code != pre_dominant_code:\n rv1 = context.order_target(pre_dominant_code, 0, price, order_type=OrderType.MARKET)\n rv2 = context.order_target(dominant_code, long_position, price, order_type=OrderType.MARKET)","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=context.PRINT)\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_order","value":"# 交易引擎:委托回报处理函数,每个委托变化时执行一次\ndef bigquant_run(context, data):\n# msg = \"handle_order data:{}\".format(data.log_str())\n# context.write_log(msg, stdout=context.PRINT)\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"after_trading","value":"# 交易引擎:盘后处理函数,每日盘后执行一次\ndef bigquant_run(context, data):\n context.extension.pre_ins_to_long = context.ins_to_long\n context.extension.pre_ins_to_short = context.ins_to_short\n\n context.extension.pre_dominant_to_long = context.dominant_to_long\n context.extension.pre_dominant_to_short = context.dominant_to_short","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"20000000","type":"Literal","bound_global_parameter":null},{"name":"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":"before_start_days","value":"0","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":1,"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":"","type":"Literal","bound_global_parameter":null},{"name":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"disable_cache","value":"True","type":"Literal","bound_global_parameter":null},{"name":"replay_bdb","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":"-4290"},{"name":"options_data","node_id":"-4290"},{"name":"history_ds","node_id":"-4290"},{"name":"benchmark_ds","node_id":"-4290"}],"output_ports":[{"name":"raw_perf","node_id":"-4290"}],"cacheable":false,"seq_num":3,"comment":"交易到固定合约","comment_collapsed":false}],"node_layout":"<node_postions><node_position Node='-1681' Position='394,-10,200,200'/><node_position Node='-5717' Position='564,160,200,200'/><node_position Node='-343' Position='564,238,200,200'/><node_position Node='-2670' Position='395,57,200,200'/><node_position Node='-1435' Position='566,397,200,200'/><node_position Node='-603' Position='564,317,200,200'/><node_position Node='-393' Position='776,-10,200,200'/><node_position Node='-4290' Position='487.80291748046875,476.39422607421875,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [9]:
    # 本代码由可视化策略环境自动生成 2022年12月30日 17:01
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    def m3_initialize_bigquant_run(context):
        msg = "initialize:" 
        context.PRINT = 1
        context.write_log(msg, stdout=context.PRINT)
        print("initializing:")
        context.all_data = context.options["data"].read()
        context.all_data.set_index("instrument", inplace=True)
        
        context.rebalance_period = 22  # 调仓周期设置
        context.long_short = 1  # 多空策略选择: 0为多空策略; 1为纯多头策略
        context.num_trades = 5  # 每层交易品种数量: 若context.long_short为0, 则总共交易标的有2*context.num_trades; 若为1, 则为context.num_trades
        context.mono = True
        context.lev = 1
        
        context.set_slippage_value(slippage_type=SlippageType.PERCENT, slippage_value=0)  # 交易滑点设置
    def m3_before_trading_start_bigquant_run(context, data):
        context.today = data.trading_day_dt.strftime('%Y-%m-%d')
        context.today_data = context.all_data[context.all_data.date==context.today]
    
        if context.trading_day_index % context.rebalance_period == 0:
            # print("check date, ", context.today)
            r1 = context.today_data
            r1.sort_values(by=["alpha0001"], ascending=context.mono, inplace=True)
            context.ins_to_long = r1.index[:context.num_trades].tolist()  # 做多因子排序后靠前的品种
            context.ins_to_short = r1.index[-context.num_trades:].tolist()  # 做空因子排序后靠后的品种
    
            context.dominant_to_long = context.get_dominant(context.ins_to_long)
            context.dominant_to_short = context.get_dominant(context.ins_to_short)
            if context.trading_day_index == 0:
                context.extension.pre_dominant_to_long = context.dominant_to_long
                context.extension.pre_dominant_to_short = context.dominant_to_short
        else:
            context.ins_to_long = context.extension.pre_ins_to_long
            context.ins_to_short = context.extension.pre_ins_to_short
    
            context.dominant_to_long = context.get_dominant(context.ins_to_long)
            context.dominant_to_short = context.get_dominant(context.ins_to_short)
        
        context.ins = context.ins_to_long+context.ins_to_short
        if not context.long_short:
            context.cash_per_constract = context.portfolio.portfolio_value / (context.num_trades * 2)
        else:
            context.cash_per_constract = context.portfolio.portfolio_value / context.num_trades
    # 交易引擎:tick数据处理函数,每个tick执行一次
    def m3_handle_tick_bigquant_run(context, tick):
        pass
    
    def m3_handle_data_bigquant_run(context, data):
        if len(context.today_data) == 0:
            return
        
        ##--------- 调整标的池之后, 未入选新标的池的合约进行平仓处理 ---------##
        if len(context.get_account_positions()) > 0:
            ins_pc = [i.split(".")[0][:-4] for i in context.ins]  # 当前日期交易品种池的product_codes
            for instrument, _ in context.get_account_positions().items():
                pc = instrument.split(".")[0][:-4]
                if pc not in ins_pc:
                    price = data.current(instrument, "close")
                    rv = context.order_target(instrument, 0, price, order_type=OrderType.MARKET)
        ##--------- 调整标的池之后, 未入选新标的池的合约进行平仓处理 ---------##
        
        # if context.trading_day_index % context.rebalance_period == 0:
        for instrument in context.ins:
            pc = instrument.split(".")[0][:-4]
            dominant_code = [i for i in context.dominant_to_long+context.dominant_to_short if pc == i.split(".")[0][:-4]][0]
            pre_dominant_list = [i for i in context.extension.pre_dominant_to_long+context.extension.pre_dominant_to_short if pc == i.split(".")[0][:-4]]
    
            if not len(pre_dominant_list):
                pre_dominant_code = dominant_code
            else:
                pre_dominant_code = pre_dominant_list[0]
            
            price = data.current(instrument, "close")  # 合约价格
            multiplier = context.get_contract(instrument).multiplier  # 合约乘数
            long_position = context.get_account_position(pre_dominant_code, direction=Direction.LONG).avail_qty  # 多头持仓
            short_position = context.get_account_position(pre_dominant_code, direction=Direction.SHORT).avail_qty  # 空头持仓
            curr_position = short_position + long_position  # 总持仓
            
            order_num = context.lev * (context.cash_per_constract // (price * multiplier))
            
            if curr_position==0 and context.trading_day_index % context.rebalance_period == 0:
                if not context.long_short:
                    if instrument in context.ins_to_long:
                        rv1 = context.order_target(dominant_code, order_num, price, order_type=OrderType.MARKET)
                    elif instrument in context.ins_to_short:
                        rv1 = context.order_target(dominant_code, -order_num, price, order_type=OrderType.MARKET)
                else:
                    if instrument in context.ins_to_long:
                        rv1 = context.order_target(dominant_code, order_num, price, order_type=OrderType.MARKET)
            else:
                if short_position > 0 and dominant_code != pre_dominant_code:
                    rv1 = context.order_target(pre_dominant_code, 0, price, order_type=OrderType.MARKET)
                    rv2 = context.order_target(dominant_code, -short_position, price, order_type=OrderType.MARKET)
                elif long_position > 0 and dominant_code != pre_dominant_code:
                    rv1 = context.order_target(pre_dominant_code, 0, price, order_type=OrderType.MARKET)
                    rv2 = context.order_target(dominant_code, long_position, price, order_type=OrderType.MARKET)
    # 交易引擎:成交回报处理函数,每个成交发生时执行一次
    def m3_handle_trade_bigquant_run(context, data):
    #     msg = "handle_trade data:{}".format(data.log_str())
    #     context.write_log(msg, stdout=context.PRINT)
        pass
    
    # 交易引擎:委托回报处理函数,每个委托变化时执行一次
    def m3_handle_order_bigquant_run(context, data):
    #     msg = "handle_order data:{}".format(data.log_str())
    #     context.write_log(msg, stdout=context.PRINT)
        pass
    
    # 交易引擎:盘后处理函数,每日盘后执行一次
    def m3_after_trading_bigquant_run(context, data):
        context.extension.pre_ins_to_long = context.ins_to_long
        context.extension.pre_ins_to_short = context.ins_to_short
    
        context.extension.pre_dominant_to_long = context.dominant_to_long
        context.extension.pre_dominant_to_short = context.dominant_to_short
    
    m1 = M.instruments.v2(
        start_date=T.live_run_param('trading_date', '2018-01-01'),
        end_date=T.live_run_param('trading_date', '2022-11-30'),
        market='CN_FUTURE',
        instrument_list='',
        max_count=0
    )
    
    m10 = M.futures_forward_extractor.v11(
        input_1=m1.data,
        before_days=50,
        product_filter=["BB", "LR", "JR", "FB", "RI",
     "WR", "RS", "PM", "WT", "TC",
     "RO", "ER", "WS", "B", "FU",
     "LU", "SC", "L", "ME", "WH",
     "FB", "FBA"],
        if_CFX=True,
        set_enable_trade=False,
        output_type='主力连续'
    )
    
    m2 = M.use_datasource.v2(
        instruments=m10.data_2,
        datasource_id='bar1d_CN_FUTURE',
        start_date='',
        end_date='',
        before_start_days=0
    )
    
    m5 = M.sort.v5(
        input_ds=m2.data,
        sort_by='date',
        group_by='--',
        keep_columns='--',
        ascending=True
    )
    
    m7 = M.input_features.v1(
        features='alpha0001 = high / (ts_min(high, 5) / close)'
    )
    
    m4 = M.derived_feature_extractor.v3(
        input_data=m5.sorted_data,
        features=m7.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=False,
        remove_extra_columns=False,
        user_functions={}
    )
    
    m19 = M.dropnan.v2(
        input_data=m4.data
    )
    
    m3 = M.hftrade.v2(
        instruments=m10.data_1,
        options_data=m19.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=20000000,
        frequency='daily',
        price_type='真实价格',
        product_type='期货',
        before_start_days='0',
        volume_limit=1,
        order_price_field_buy='open',
        order_price_field_sell='open',
        benchmark='',
        plot_charts=True,
        disable_cache=True,
        replay_bdb=False,
        show_debug_info=False,
        backtest_only=False
    )
    
    2022-12-30 15:00:47.937579 strategy(bktfut,): initialize: 
    initializing:
    
    • 收益率118.07%
    • 年化收益率17.13%
    • 基准收益率0.0%
    • 阿尔法nan
    • 贝塔nan
    • 夏普比率0.94
    • 胜率0.63
    • 盈亏比2.59
    • 收益波动率15.73%
    • 最大回撤21.02%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-625c121e233b477cbb9f31e8d8f7a08b"}/bigcharts-data-end
    In [ ]: