复制链接
克隆策略

    {"description":"实验创建于2019/4/20","graph":{"edges":[{"to_node_id":"-299:instruments","from_node_id":"-290:data"},{"to_node_id":"-32:instruments","from_node_id":"-290:data"},{"to_node_id":"-299:features","from_node_id":"-286:data"},{"to_node_id":"-606:input_ds","from_node_id":"-299:data"},{"to_node_id":"-53:input_data","from_node_id":"-606:sorted_data"},{"to_node_id":"-58:input_1","from_node_id":"-32:raw_perf"},{"to_node_id":"-32:options_data","from_node_id":"-53:data"}],"nodes":[{"node_id":"-290","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2018-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2021-11-01","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_STOCK_A","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":"-290"}],"output_ports":[{"name":"data","node_id":"-290"}],"cacheable":true,"seq_num":1,"comment":"输入证券","comment_collapsed":true},{"node_id":"-286","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"market_cap_float_0\namount_0","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-286"}],"output_ports":[{"name":"data","node_id":"-286"}],"cacheable":true,"seq_num":2,"comment":"输入特征","comment_collapsed":true},{"node_id":"-299","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":"60","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-299"},{"name":"features","node_id":"-299"}],"output_ports":[{"name":"data","node_id":"-299"}],"cacheable":true,"seq_num":3,"comment":"","comment_collapsed":true},{"node_id":"-606","module_id":"BigQuantSpace.sort.sort-v4","parameters":[{"name":"sort_by","value":"market_cap_float_0","type":"Literal","bound_global_parameter":null},{"name":"group_by","value":"instrument","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":"-606"},{"name":"sort_by_ds","node_id":"-606"}],"output_ports":[{"name":"sorted_data","node_id":"-606"}],"cacheable":true,"seq_num":4,"comment":"依据某个因子排序","comment_collapsed":true},{"node_id":"-32","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 # 加载股票指标数据,数据继承自m6模块\n context.indicator_data = context.options['data'].read_df()\n\n # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n \n # 设置股票数量\n context.stock_num = 30\n \n # 调仓天数,22个交易日大概就是一个月。可以理解为一个月换仓一次\n context.rebalance_days = 22\n \n # 如果策略运行中,需要将数据进行保存,可以借用extension这个对象,类型为dict\n # 比如当前运行的k线的索引,比如个股持仓天数、买入均价\n if 'index' not in context.extension:\n context.extension['index'] = 0\n \n \n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n \n context.extension['index'] += 1\n # 不在换仓日就return,相当于后面的代码只会一个月运行一次,买入的股票会持有1个月\n if context.extension['index'] % context.rebalance_days != 0:\n return \n \n # 当前的日期\n date = data.current_dt.strftime('%Y-%m-%d')\n \n cur_data = context.indicator_data[context.indicator_data['date'] == date]\n # 根据日期获取调仓需要买入的股票的列表\n stock_to_buy = list(cur_data.instrument[:context.stock_num])\n # 通过positions对象,使用列表生成式的方法获取目前持仓的股票列表\n stock_hold_now = [equity.symbol for equity in context.portfolio.positions]\n # 继续持有的股票:调仓时,如果买入的股票已经存在于目前的持仓里,那么应继续持有\n no_need_to_sell = [i for i in stock_hold_now if i in stock_to_buy]\n # 需要卖出的股票\n stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]\n \n # 卖出\n for stock in stock_to_sell:\n # 如果该股票停牌,则没法成交。因此需要用can_trade方法检查下该股票的状态\n # 如果返回真值,则可以正常下单,否则会出错\n # 因为stock是字符串格式,我们用symbol方法将其转化成平台可以接受的形式:Equity格式\n\n if data.can_trade(context.symbol(stock)):\n # order_target_percent是平台的一个下单接口,表明下单使得该股票的权重为0,\n # 即卖出全部股票,可参考回测文档\n context.order_target_percent(context.symbol(stock), 0)\n \n # 如果当天没有买入的股票,就返回\n if len(stock_to_buy) == 0:\n return\n\n # 等权重买入 \n weight = 1 / len(stock_to_buy)\n \n # 买入\n for stock in stock_to_buy:\n if data.can_trade(context.symbol(stock)):\n # 下单使得某只股票的持仓权重达到weight,因为\n # weight大于0,因此是等权重买入\n context.order_target_percent(context.symbol(stock), weight)\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":"open","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":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-32"},{"name":"options_data","node_id":"-32"},{"name":"history_ds","node_id":"-32"},{"name":"benchmark_ds","node_id":"-32"},{"name":"trading_calendar","node_id":"-32"}],"output_ports":[{"name":"raw_perf","node_id":"-32"}],"cacheable":false,"seq_num":5,"comment":"回测","comment_collapsed":true},{"node_id":"-53","module_id":"BigQuantSpace.filter.filter-v3","parameters":[{"name":"expr","value":"amount_0 > 10000","type":"Literal","bound_global_parameter":null},{"name":"output_left_data","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-53"}],"output_ports":[{"name":"data","node_id":"-53"},{"name":"left_data","node_id":"-53"}],"cacheable":true,"seq_num":6,"comment":"过滤掉不需要的股票数据","comment_collapsed":true},{"node_id":"-58","module_id":"BigQuantSpace.strategy_ret_risk_analysis.strategy_ret_risk_analysis-v2","parameters":[{"name":"analysis_flag","value":"absolute","type":"Literal","bound_global_parameter":null},{"name":"benchmark_index","value":"000906.HIX","type":"Literal","bound_global_parameter":null},{"name":"terms","value":"long","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-58"}],"output_ports":[{"name":"data_1","node_id":"-58"},{"name":"data_2","node_id":"-58"}],"cacheable":true,"seq_num":7,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-290' Position='-40,17,200,200'/><node_position Node='-286' Position='343,15,200,200'/><node_position Node='-299' Position='225,137,200,200'/><node_position Node='-606' Position='229,224,200,200'/><node_position Node='-32' Position='177,399,200,200'/><node_position Node='-53' Position='215,304,200,200'/><node_position Node='-58' Position='247.71270751953125,474.77527618408203,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [1]:
    # 本代码由可视化策略环境自动生成 2021年12月20日 14:04
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:初始化函数,只执行一次
    def m5_initialize_bigquant_run(context):
        # 加载股票指标数据,数据继承自m6模块
        context.indicator_data = context.options['data'].read_df()
    
        # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        
        # 设置股票数量
        context.stock_num = 30
        
        # 调仓天数,22个交易日大概就是一个月。可以理解为一个月换仓一次
        context.rebalance_days = 22
        
        # 如果策略运行中,需要将数据进行保存,可以借用extension这个对象,类型为dict
        # 比如当前运行的k线的索引,比如个股持仓天数、买入均价
        if 'index' not in context.extension:
            context.extension['index'] = 0
     
        
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m5_handle_data_bigquant_run(context, data):
        
        
        context.extension['index'] += 1
        # 不在换仓日就return,相当于后面的代码只会一个月运行一次,买入的股票会持有1个月
        if  context.extension['index'] % context.rebalance_days != 0:
            return 
        
        # 当前的日期
        date = data.current_dt.strftime('%Y-%m-%d')
        
        cur_data = context.indicator_data[context.indicator_data['date'] == date]
        # 根据日期获取调仓需要买入的股票的列表
        stock_to_buy = list(cur_data.instrument[:context.stock_num])
        # 通过positions对象,使用列表生成式的方法获取目前持仓的股票列表
        stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
        # 继续持有的股票:调仓时,如果买入的股票已经存在于目前的持仓里,那么应继续持有
        no_need_to_sell = [i for i in stock_hold_now if i in stock_to_buy]
        # 需要卖出的股票
        stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
      
        # 卖出
        for stock in stock_to_sell:
            # 如果该股票停牌,则没法成交。因此需要用can_trade方法检查下该股票的状态
            # 如果返回真值,则可以正常下单,否则会出错
            # 因为stock是字符串格式,我们用symbol方法将其转化成平台可以接受的形式:Equity格式
    
            if data.can_trade(context.symbol(stock)):
                # order_target_percent是平台的一个下单接口,表明下单使得该股票的权重为0,
                #   即卖出全部股票,可参考回测文档
                context.order_target_percent(context.symbol(stock), 0)
        
        # 如果当天没有买入的股票,就返回
        if len(stock_to_buy) == 0:
            return
    
        # 等权重买入 
        weight =  1 / len(stock_to_buy)
        
        # 买入
        for stock in stock_to_buy:
            if data.can_trade(context.symbol(stock)):
                # 下单使得某只股票的持仓权重达到weight,因为
                # weight大于0,因此是等权重买入
                context.order_target_percent(context.symbol(stock), weight)
     
    # 回测引擎:准备数据,只执行一次
    def m5_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m5_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m1 = M.instruments.v2(
        start_date='2018-01-01',
        end_date='2021-11-01',
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    m2 = M.input_features.v1(
        features="""market_cap_float_0
    amount_0"""
    )
    
    m3 = M.general_feature_extractor.v7(
        instruments=m1.data,
        features=m2.data,
        start_date='',
        end_date='',
        before_start_days=60
    )
    
    m4 = M.sort.v4(
        input_ds=m3.data,
        sort_by='market_cap_float_0',
        group_by='instrument',
        keep_columns='--',
        ascending=True
    )
    
    m6 = M.filter.v3(
        input_data=m4.sorted_data,
        expr='amount_0 > 10000',
        output_left_data=False
    )
    
    m5 = M.trade.v4(
        instruments=m1.data,
        options_data=m6.data,
        start_date='',
        end_date='',
        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.025,
        order_price_field_buy='open',
        order_price_field_sell='open',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='后复权',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark=''
    )
    
    m7 = M.strategy_ret_risk_analysis.v2(
        input_1=m5.raw_perf,
        analysis_flag='absolute',
        benchmark_index='000906.HIX',
        terms='long'
    )
    
    • 收益率72.12%
    • 年化收益率15.87%
    • 基准收益率21.33%
    • 阿尔法0.13
    • 贝塔0.6
    • 夏普比率0.62
    • 胜率0.57
    • 盈亏比2.22
    • 收益波动率23.23%
    • 信息比率0.03
    • 最大回撤30.81%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-8e3eba590ecf49b6b49359188d972ddf"}/bigcharts-data-end
    In [5]:
    m7.data_2.read()
    
    Out[5]:
    {'weights':             2018-02-01  2018-02-02  2018-02-05  2018-02-06  2018-02-07  \
     300665.SZA         0.0    0.033126    0.033495    0.033066    0.032599   
     300538.SZA         0.0    0.033124    0.033159    0.033330    0.033460   
     300669.SZA         0.0    0.033485    0.033867    0.034038    0.033646   
     603580.SHA         0.0    0.032910    0.033163    0.033232    0.032700   
     603330.SHA         0.0    0.033055    0.033073    0.033941    0.033834   
     ...                ...         ...         ...         ...         ...   
     605155.SHA         0.0    0.000000    0.000000    0.000000    0.000000   
     605333.SHA         0.0    0.000000    0.000000    0.000000    0.000000   
     688501.SHA         0.0    0.000000    0.000000    0.000000    0.000000   
     688701.SHA         0.0    0.000000    0.000000    0.000000    0.000000   
     688681.SHA         0.0    0.000000    0.000000    0.000000    0.000000   
     
                 2018-02-08  2018-02-09  2018-02-12  2018-02-13  2018-02-14  ...  \
     300665.SZA    0.033012    0.032628    0.032499    0.032493    0.031990  ...   
     300538.SZA    0.033129    0.032771    0.032419    0.032557    0.032659  ...   
     300669.SZA    0.033715    0.033333    0.033094    0.033080    0.032816  ...   
     603580.SHA    0.032814    0.032608    0.032338    0.032280    0.032626  ...   
     603330.SHA    0.033701    0.034301    0.034103    0.033700    0.033792  ...   
     ...                ...         ...         ...         ...         ...  ...   
     605155.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  ...   
     605333.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  ...   
     688501.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  ...   
     688701.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  ...   
     688681.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  ...   
     
                 2021-10-19  2021-10-20  2021-10-21  2021-10-22  2021-10-25  \
     300665.SZA    0.000000    0.000000    0.000000    0.000000    0.000000   
     300538.SZA    0.000000    0.000000    0.000000    0.000000    0.000000   
     300669.SZA    0.000000    0.000000    0.000000    0.000000    0.000000   
     603580.SHA    0.000000    0.000000    0.000000    0.000000    0.000000   
     603330.SHA    0.000000    0.000000    0.000000    0.000000    0.000000   
     ...                ...         ...         ...         ...         ...   
     605155.SHA    0.003682    0.003662    0.003629    0.003615    0.003636   
     605333.SHA    0.000000    0.000000    0.000000    0.000000    0.000000   
     688501.SHA    0.031050    0.030938    0.030493    0.030143    0.029815   
     688701.SHA    0.000000    0.000000    0.000000    0.000000    0.000000   
     688681.SHA    0.000000    0.000000    0.000000    0.000000    0.000000   
     
                 2021-10-26  2021-10-27  2021-10-28  2021-10-29  2021-11-01  
     300665.SZA    0.000000    0.000000    0.000000    0.000000    0.000000  
     300538.SZA    0.000000    0.000000    0.000000    0.000000    0.000000  
     300669.SZA    0.000000    0.000000    0.000000    0.000000    0.000000  
     603580.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  
     603330.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  
     ...                ...         ...         ...         ...         ...  
     605155.SHA    0.003642    0.003619    0.003541    0.003562    0.003581  
     605333.SHA    0.000000    0.000000    0.000000    0.000000    0.000000  
     688501.SHA    0.029775    0.033215    0.032371    0.031608    0.031866  
     688701.SHA    0.000000    0.033094    0.032039    0.031095    0.031475  
     688681.SHA    0.000000    0.023194    0.022539    0.022483    0.022766  
     
     [208 rows x 907 columns]}