用自定义数据进行因子分析

策略分享
标签: #<Tag:0x00007fd3217dedc0>

(Nolamebrand) #1

简单构造了一个动量因子进行分析和简单的回测,和直接用Bigquant的表达式引擎来进行因子分析的结果有些差异,但结果影响不大,应该是在计算因子时和表达式引擎略有区别。

克隆策略

    {"Description":"实验创建于2017/8/26","Summary":"","Graph":{"EdgesInternal":[{"DestinationInputPortId":"-1972:instruments","SourceOutputPortId":"-184:data"},{"DestinationInputPortId":"-32:instruments","SourceOutputPortId":"-184:data"},{"DestinationInputPortId":"-1972:features","SourceOutputPortId":"-271:data"},{"DestinationInputPortId":"-1566:features","SourceOutputPortId":"-1598:data"},{"DestinationInputPortId":"-6207:input_1","SourceOutputPortId":"-1972:data"},{"DestinationInputPortId":"-32:options_data","SourceOutputPortId":"-2165:sorted_data"},{"DestinationInputPortId":"-2165:input_ds","SourceOutputPortId":"-4620:data"},{"DestinationInputPortId":"-4620:input_data","SourceOutputPortId":"-6207:data_1"},{"DestinationInputPortId":"-1566:user_factor_data","SourceOutputPortId":"-6207:data_1"}],"ModuleNodes":[{"Id":"-184","ModuleId":"BigQuantSpace.instruments.instruments-v2","ModuleParameters":[{"Name":"start_date","Value":"2020-01-01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2021-01-01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"market","Value":"CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_list","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_count","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"rolling_conf","NodeId":"-184"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-184","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":1,"Comment":"","CommentCollapsed":true},{"Id":"-271","ModuleId":"BigQuantSpace.input_features.input_features-v1","ModuleParameters":[{"Name":"features","Value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nclose_0","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features_ds","NodeId":"-271"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-271","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":3,"Comment":"表达式引擎因子计算5日收益率","CommentCollapsed":true},{"Id":"-1566","ModuleId":"BigQuantSpace.factorlens.factorlens-v1","ModuleParameters":[{"Name":"title","Value":"因子分析: {factor_name}","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"start_date","Value":"2020-01-01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2021-01-01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"rebalance_period","Value":"22","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"delay_rebalance_days","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"rebalance_price","Value":"close_0","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"stock_pool","Value":"全市场","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"quantile_count","Value":"5","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"commission_rate","Value":0.0016,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"returns_calculation_method","Value":"累乘","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"无","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"drop_price_limit_stocks","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"drop_st_stocks","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"drop_new_stocks","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"normalization","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"neutralization","Value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E8%A1%8C%E4%B8%9A%22%2C%22displayValue%22%3A%22%E8%A1%8C%E4%B8%9A%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%B8%82%E5%80%BC%22%2C%22displayValue%22%3A%22%E5%B8%82%E5%80%BC%22%2C%22selected%22%3Afalse%7D%5D%7D","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"metrics","Value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E8%A1%A8%E7%8E%B0%E6%A6%82%E8%A7%88%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E8%A1%A8%E7%8E%B0%E6%A6%82%E8%A7%88%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E5%88%86%E5%B8%83%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E5%88%86%E5%B8%83%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E8%A1%8C%E4%B8%9A%E5%88%86%E5%B8%83%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E8%A1%8C%E4%B8%9A%E5%88%86%E5%B8%83%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E5%B8%82%E5%80%BC%E5%88%86%E5%B8%83%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E5%B8%82%E5%80%BC%E5%88%86%E5%B8%83%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22IC%E5%88%86%E6%9E%90%22%2C%22displayValue%22%3A%22IC%E5%88%86%E6%9E%90%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E4%B9%B0%E5%85%A5%E4%BF%A1%E5%8F%B7%E9%87%8D%E5%90%88%E5%88%86%E6%9E%90%22%2C%22displayValue%22%3A%22%E4%B9%B0%E5%85%A5%E4%BF%A1%E5%8F%B7%E9%87%8D%E5%90%88%E5%88%86%E6%9E%90%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E4%BC%B0%E5%80%BC%E5%88%86%E6%9E%90%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E4%BC%B0%E5%80%BC%E5%88%86%E6%9E%90%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E6%8B%A5%E6%8C%A4%E5%BA%A6%E5%88%86%E6%9E%90%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E6%8B%A5%E6%8C%A4%E5%BA%A6%E5%88%86%E6%9E%90%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%9B%A0%E5%AD%90%E5%80%BC%E6%9C%80%E5%A4%A7%2F%E6%9C%80%E5%B0%8F%E8%82%A1%E7%A5%A8%22%2C%22displayValue%22%3A%22%E5%9B%A0%E5%AD%90%E5%80%BC%E6%9C%80%E5%A4%A7%2F%E6%9C%80%E5%B0%8F%E8%82%A1%E7%A5%A8%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%9B%A0%E5%AD%90%E5%80%BC%22%2C%22displayValue%22%3A%22%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%9B%A0%E5%AD%90%E5%80%BC%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%A4%9A%E5%9B%A0%E5%AD%90%E7%9B%B8%E5%85%B3%E6%80%A7%E5%88%86%E6%9E%90%22%2C%22displayValue%22%3A%22%E5%A4%9A%E5%9B%A0%E5%AD%90%E7%9B%B8%E5%85%B3%E6%80%A7%E5%88%86%E6%9E%90%22%2C%22selected%22%3Atrue%7D%5D%7D","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"factor_coverage","Value":"0.5","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"user_data_merge","Value":"left","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-1566"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"user_factor_data","NodeId":"-1566"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-1566","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":4,"Comment":"","CommentCollapsed":true},{"Id":"-1598","ModuleId":"BigQuantSpace.input_features.input_features-v1","ModuleParameters":[{"Name":"features","Value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nfactor\n","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features_ds","NodeId":"-1598"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-1598","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":6,"Comment":"","CommentCollapsed":true},{"Id":"-1972","ModuleId":"BigQuantSpace.general_feature_extractor.general_feature_extractor-v7","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"before_start_days","Value":90,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-1972"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-1972"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-1972","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":7,"Comment":"","CommentCollapsed":true},{"Id":"-2165","ModuleId":"BigQuantSpace.sort.sort-v4","ModuleParameters":[{"Name":"sort_by","Value":"factor","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"group_by","Value":"date","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"keep_columns","Value":"--","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"ascending","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_ds","NodeId":"-2165"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"sort_by_ds","NodeId":"-2165"}],"OutputPortsInternal":[{"Name":"sorted_data","NodeId":"-2165","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":8,"Comment":"","CommentCollapsed":true},{"Id":"-4620","ModuleId":"BigQuantSpace.dropnan.dropnan-v2","ModuleParameters":[],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_data","NodeId":"-4620"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-4620"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-4620","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":9,"Comment":"","CommentCollapsed":true},{"Id":"-32","ModuleId":"BigQuantSpace.trade.trade-v4","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n context.indicator_data = context.options['data'].read_df()\n context.set_commission(PerOrder(buy_cost=0.0001, sell_cost=0.001, min_cost=5))\n context.stock_num = 50\n context.rebalance_days = 22\n if 'index' not in context.extension:\n context.extension['index'] = 0\n \n \n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n #------------------------------------------止损模块START--------------------------------------------\n date = data.current_dt.strftime('%Y-%m-%d')\n positions = {e.symbol: p.cost_basis for e, p in context.portfolio.positions.items()}\n current_stoploss_stock = [] \n if len(positions) > 0:\n for i in positions.keys():\n stock_cost = positions[i] \n stock_market_price = data.current(context.symbol(i), 'price') \n if (stock_market_price - stock_cost) / stock_cost <= -0.1: \n context.order_target_percent(context.symbol(i),0) \n current_stoploss_stock.append(i)\n print('日期:',date,'股票:',i,'出现止损状况')\n #-------------------------------------------止损模块END-------------------------------------------------- \n context.extension['index'] += 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 if stock in current_stoploss_stock:\n continue\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0)\n \n # 如果当天没有买入的股票,就返回\n if len(stock_to_buy) == 0:\n return\n \n weight = 1 / len(stock_to_buy) \n # 买入\n for stock in stock_to_buy:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), weight)\n ","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.025,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_buy","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_sell","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":1000000,"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":"-32"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-32"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"history_ds","NodeId":"-32"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"benchmark_ds","NodeId":"-32"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"trading_calendar","NodeId":"-32"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-32","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":10,"Comment":"回测","CommentCollapsed":true},{"Id":"-6207","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 dt = input_1.read_df().sort_values(by='date',ascending=False).reset_index(drop=True)\n dt1 = dt.groupby('instrument')\n stock_list = dt['instrument'].value_counts().index\n dt2 = pd.DataFrame()\n for stock in stock_list:\n dd = dt1.get_group(stock)\n dd1 = ((dd['close_0'].rolling(44).mean() / dd['close_0'])-1)\n dt2 = pd.concat([dt2,dd1],ignore_index=True)\n dt2.columns=['factor']\n dt3 = pd.concat([dt,dt2],axis=1)\n dt3 = dt3[['factor','date','instrument']]\n data_1 = DataSource.write_df(dt3)\n return Outputs(data_1=data_1, data_2=None, data_3=None)","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":"-6207"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-6207"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-6207"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-6207","OutputType":null},{"Name":"data_2","NodeId":"-6207","OutputType":null},{"Name":"data_3","NodeId":"-6207","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":11,"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='-184' Position='-1006,-93,200,200'/><NodePosition Node='-271' Position='-634,-94,200,200'/><NodePosition Node='-1566' Position='-1028.4246826171875,440.84942626953125,200,200'/><NodePosition Node='-1598' Position='-1214,296,200,200'/><NodePosition Node='-1972' Position='-843,20,200,200'/><NodePosition Node='-2165' Position='-665,439,200,200'/><NodePosition Node='-4620' Position='-741,295,200,200'/><NodePosition Node='-32' Position='-824,579,200,200'/><NodePosition Node='-6207' Position='-782,151,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 [520]:
    # 本代码由可视化策略环境自动生成 2021年4月26日18:02
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m11_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        dt = input_1.read_df().sort_values(by='date',ascending=False).reset_index(drop=True)
        dt1 = dt.groupby('instrument')
        stock_list = dt['instrument'].value_counts().index
        dt2 = pd.DataFrame()
        for stock in stock_list:
            dd = dt1.get_group(stock)
            dd1 = ((dd['close_0'].rolling(44).mean() / dd['close_0'])-1)
            dt2 = pd.concat([dt2,dd1],ignore_index=True)
        dt2.columns=['factor']
        dt3 = pd.concat([dt,dt2],axis=1)
        dt3 = dt3[['factor','date','instrument']]
        data_1 = DataSource.write_df(dt3)
        return Outputs(data_1=data_1, data_2=None, data_3=None)
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m11_post_run_bigquant_run(outputs):
        return outputs
    
    # 回测引擎:初始化函数,只执行一次
    def m10_initialize_bigquant_run(context):
        context.indicator_data = context.options['data'].read_df()
        context.set_commission(PerOrder(buy_cost=0.0001, sell_cost=0.001, min_cost=5))
        context.stock_num = 50
        context.rebalance_days = 22
        if 'index' not in context.extension:
            context.extension['index'] = 0
     
        
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m10_handle_data_bigquant_run(context, data):
        #------------------------------------------止损模块START--------------------------------------------
        date = data.current_dt.strftime('%Y-%m-%d')
        positions = {e.symbol: p.cost_basis  for e, p in context.portfolio.positions.items()}
        current_stoploss_stock = [] 
        if len(positions) > 0:
            for i in positions.keys():
                stock_cost = positions[i] 
                stock_market_price = data.current(context.symbol(i), 'price') 
                if (stock_market_price - stock_cost) / stock_cost <= -0.1:   
                    context.order_target_percent(context.symbol(i),0)     
                    current_stoploss_stock.append(i)
                    print('日期:',date,'股票:',i,'出现止损状况')
        #-------------------------------------------止损模块END--------------------------------------------------    
        context.extension['index'] += 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:
            if stock in current_stoploss_stock:
                continue
            if data.can_trade(context.symbol(stock)):
                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)):
                context.order_target_percent(context.symbol(stock), weight)
     
    # 回测引擎:准备数据,只执行一次
    def m10_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m10_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m1 = M.instruments.v2(
        start_date='2020-01-01',
        end_date='2021-01-01',
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    m3 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    close_0"""
    )
    
    m7 = M.general_feature_extractor.v7(
        instruments=m1.data,
        features=m3.data,
        start_date='',
        end_date='',
        before_start_days=90
    )
    
    m11 = M.cached.v3(
        input_1=m7.data,
        run=m11_run_bigquant_run,
        post_run=m11_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m9 = M.dropnan.v2(
        input_data=m11.data_1
    )
    
    m8 = M.sort.v4(
        input_ds=m9.data,
        sort_by='factor',
        group_by='date',
        keep_columns='--',
        ascending=True
    )
    
    m10 = M.trade.v4(
        instruments=m1.data,
        options_data=m8.sorted_data,
        start_date='',
        end_date='',
        initialize=m10_initialize_bigquant_run,
        handle_data=m10_handle_data_bigquant_run,
        prepare=m10_prepare_bigquant_run,
        before_trading_start=m10_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=''
    )
    
    m6 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    factor
    """
    )
    
    m4 = M.factorlens.v1(
        features=m6.data,
        user_factor_data=m11.data_1,
        title='因子分析: {factor_name}',
        start_date='2020-01-01',
        end_date='2021-01-01',
        rebalance_period=22,
        delay_rebalance_days=0,
        rebalance_price='close_0',
        stock_pool='全市场',
        quantile_count=5,
        commission_rate=0.0016,
        returns_calculation_method='累乘',
        benchmark='无',
        drop_price_limit_stocks=True,
        drop_st_stocks=True,
        drop_new_stocks=True,
        normalization=True,
        neutralization=[],
        metrics=['因子表现概览', '因子分布', '因子行业分布', '因子市值分布', 'IC分析', '买入信号重合分析', '因子估值分析', '因子拥挤度分析', '因子值最大/最小股票', '表达式因子值', '多因子相关性分析'],
        factor_coverage=0.5,
        user_data_merge='left'
    )
    
    日期: 2020-02-11 股票: 688100.SHA 出现止损状况
    日期: 2020-02-14 股票: 300718.SZA 出现止损状况
    日期: 2020-02-21 股票: 600721.SHA 出现止损状况
    日期: 2020-02-25 股票: 300187.SZA 出现止损状况
    日期: 2020-02-26 股票: 300459.SZA 出现止损状况
    日期: 2020-03-16 股票: 000626.SZA 出现止损状况
    日期: 2020-03-16 股票: 688198.SHA 出现止损状况
    日期: 2020-03-16 股票: 603318.SHA 出现止损状况
    日期: 2020-03-16 股票: 601155.SHA 出现止损状况
    日期: 2020-03-16 股票: 002103.SZA 出现止损状况
    日期: 2020-03-16 股票: 300325.SZA 出现止损状况
    日期: 2020-03-17 股票: 300494.SZA 出现止损状况
    日期: 2020-03-17 股票: 600847.SHA 出现止损状况
    日期: 2020-03-17 股票: 002930.SZA 出现止损状况
    日期: 2020-03-17 股票: 300752.SZA 出现止损状况
    日期: 2020-03-17 股票: 000790.SZA 出现止损状况
    日期: 2020-03-18 股票: 001914.SZA 出现止损状况
    日期: 2020-03-18 股票: 002378.SZA 出现止损状况
    日期: 2020-03-18 股票: 000413.SZA 出现止损状况
    日期: 2020-03-18 股票: 600183.SHA 出现止损状况
    日期: 2020-03-18 股票: 000040.SZA 出现止损状况
    日期: 2020-03-19 股票: 300552.SZA 出现止损状况
    日期: 2020-03-19 股票: 603886.SHA 出现止损状况
    日期: 2020-03-19 股票: 600156.SHA 出现止损状况
    日期: 2020-03-23 股票: 603636.SHA 出现止损状况
    日期: 2020-03-23 股票: 002586.SZA 出现止损状况
    日期: 2020-03-23 股票: 000918.SZA 出现止损状况
    日期: 2020-03-27 股票: 688080.SHA 出现止损状况
    日期: 2020-03-30 股票: 002147.SZA 出现止损状况
    日期: 2020-03-30 股票: 000801.SZA 出现止损状况
    日期: 2020-03-30 股票: 300392.SZA 出现止损状况
    日期: 2020-04-01 股票: 300563.SZA 出现止损状况
    日期: 2020-04-01 股票: 300126.SZA 出现止损状况
    日期: 2020-04-13 股票: 300471.SZA 出现止损状况
    日期: 2020-04-13 股票: 300163.SZA 出现止损状况
    日期: 2020-04-22 股票: 300178.SZA 出现止损状况
    日期: 2020-04-24 股票: 300273.SZA 出现止损状况
    日期: 2020-04-24 股票: 300795.SZA 出现止损状况
    日期: 2020-04-28 股票: 002864.SZA 出现止损状况
    日期: 2020-04-28 股票: 000632.SZA 出现止损状况
    日期: 2020-04-28 股票: 002909.SZA 出现止损状况
    日期: 2020-04-28 股票: 002565.SZA 出现止损状况
    日期: 2020-04-28 股票: 300779.SZA 出现止损状况
    日期: 2020-04-29 股票: 002875.SZA 出现止损状况
    日期: 2020-04-29 股票: 000638.SZA 出现止损状况
    日期: 2020-05-20 股票: 300712.SZA 出现止损状况
    日期: 2020-05-25 股票: 688066.SHA 出现止损状况
    日期: 2020-05-25 股票: 600242.SHA 出现止损状况
    日期: 2020-05-28 股票: 600133.SHA 出现止损状况
    日期: 2020-05-28 股票: 002481.SZA 出现止损状况
    日期: 2020-05-29 股票: 600801.SHA 出现止损状况
    日期: 2020-06-15 股票: 002757.SZA 出现止损状况
    日期: 2020-06-15 股票: 300222.SZA 出现止损状况
    日期: 2020-06-23 股票: 601005.SHA 出现止损状况
    日期: 2020-07-03 股票: 688466.SHA 出现止损状况
    日期: 2020-07-15 股票: 688004.SHA 出现止损状况
    日期: 2020-07-24 股票: 688233.SHA 出现止损状况
    日期: 2020-07-24 股票: 688116.SHA 出现止损状况
    日期: 2020-07-27 股票: 300095.SZA 出现止损状况
    日期: 2020-08-10 股票: 605108.SHA 出现止损状况
    日期: 2020-08-11 股票: 601116.SHA 出现止损状况
    日期: 2020-08-11 股票: 300499.SZA 出现止损状况
    日期: 2020-08-12 股票: 300314.SZA 出现止损状况
    日期: 2020-08-20 股票: 300724.SZA 出现止损状况
    日期: 2020-08-21 股票: 603321.SHA 出现止损状况
    日期: 2020-08-25 股票: 002286.SZA 出现止损状况
    日期: 2020-08-26 股票: 300758.SZA 出现止损状况
    日期: 2020-09-01 股票: 600773.SHA 出现止损状况
    日期: 2020-09-07 股票: 002234.SZA 出现止损状况
    日期: 2020-09-07 股票: 002370.SZA 出现止损状况
    日期: 2020-09-08 股票: 002916.SZA 出现止损状况
    日期: 2020-09-09 股票: 601609.SHA 出现止损状况
    日期: 2020-09-09 股票: 600638.SHA 出现止损状况
    日期: 2020-09-09 股票: 002810.SZA 出现止损状况
    日期: 2020-09-10 股票: 000050.SZA 出现止损状况
    日期: 2020-09-10 股票: 000056.SZA 出现止损状况
    日期: 2020-09-10 股票: 300768.SZA 出现止损状况
    日期: 2020-09-10 股票: 600960.SHA 出现止损状况
    日期: 2020-09-11 股票: 600890.SHA 出现止损状况
    日期: 2020-09-16 股票: 300498.SZA 出现止损状况
    日期: 2020-09-17 股票: 002238.SZA 出现止损状况
    日期: 2020-09-23 股票: 600273.SHA 出现止损状况
    日期: 2020-09-24 股票: 603348.SHA 出现止损状况
    日期: 2020-09-28 股票: 600468.SHA 出现止损状况
    日期: 2020-09-28 股票: 300224.SZA 出现止损状况
    日期: 2020-09-28 股票: 688301.SHA 出现止损状况
    日期: 2020-10-22 股票: 000697.SZA 出现止损状况
    日期: 2020-10-26 股票: 600860.SHA 出现止损状况
    日期: 2020-10-26 股票: 600198.SHA 出现止损状况
    日期: 2020-10-27 股票: 600247.SHA 出现止损状况
    日期: 2020-10-29 股票: 688313.SHA 出现止损状况
    日期: 2020-11-02 股票: 688222.SHA 出现止损状况
    日期: 2020-11-02 股票: 300246.SZA 出现止损状况
    日期: 2020-11-02 股票: 000425.SZA 出现止损状况
    日期: 2020-11-13 股票: 002468.SZA 出现止损状况
    日期: 2020-11-16 股票: 600517.SHA 出现止损状况
    日期: 2020-11-24 股票: 600648.SHA 出现止损状况
    日期: 2020-12-09 股票: 300085.SZA 出现止损状况
    日期: 2020-12-09 股票: 002283.SZA 出现止损状况
    日期: 2020-12-09 股票: 002816.SZA 出现止损状况
    日期: 2020-12-10 股票: 600239.SHA 出现止损状况
    日期: 2020-12-10 股票: 688028.SHA 出现止损状况
    日期: 2020-12-11 股票: 300041.SZA 出现止损状况
    日期: 2020-12-14 股票: 000552.SZA 出现止损状况
    日期: 2020-12-15 股票: 002413.SZA 出现止损状况
    日期: 2020-12-16 股票: 688520.SHA 出现止损状况
    日期: 2020-12-16 股票: 688060.SHA 出现止损状况
    日期: 2020-12-16 股票: 002075.SZA 出现止损状况
    日期: 2020-12-16 股票: 002417.SZA 出现止损状况
    日期: 2020-12-17 股票: 603332.SHA 出现止损状况
    日期: 2020-12-18 股票: 603332.SHA 出现止损状况
    日期: 2020-12-21 股票: 603332.SHA 出现止损状况
    日期: 2020-12-22 股票: 603332.SHA 出现止损状况
    日期: 2020-12-22 股票: 600061.SHA 出现止损状况
    日期: 2020-12-23 股票: 603332.SHA 出现止损状况
    日期: 2020-12-24 股票: 000010.SZA 出现止损状况
    日期: 2020-12-24 股票: 300020.SZA 出现止损状况
    日期: 2020-12-24 股票: 603608.SHA 出现止损状况
    日期: 2020-12-24 股票: 003003.SZA 出现止损状况
    
    • 收益率20.95%
    • 年化收益率21.81%
    • 基准收益率27.21%
    • 阿尔法0.03
    • 贝塔0.65
    • 夏普比率0.92
    • 胜率0.5
    • 盈亏比1.47
    • 收益波动率20.48%
    • 信息比率-0.02
    • 最大回撤11.9%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-b85998d0fbb24118aa74d96c3f880834"}/bigcharts-data-end

    因子分析: factor

    { "type": "factor-track", "data": { "exprs": ["factor"], "options": {"BacktestInterval": ["2020-01-01", "2021-01-01"], "Benchmark": "none", "StockPool": "all", "UserDataMerge": "left", "DropSTStocks": 1, "DropPriceLimitStocks": 1, "DropNewStocks": 1, "QuantileCount": 5, "CommissionRates": 0.0016, "Normalization": 1, "Neutralization": "", "RebalancePrice": "close_0", "DelayRebalanceDays": 0, "RebalancePeriod": 22, "ReturnsCalculationMethod": "cumprod", "FactorCoverage": 0.5, "_HASH": "ab26db45ea3d74e87196c70a42fcd977"} } }

    因子表现概览

      累计收益 近1年收益 近3月收益 近1月收益 近1周收益 昨日收益 最大回撤 盈亏比 胜率 夏普比率 收益波动率
    最小分位 -8.89% -8.89% -9.87% -7.04% 0.99% 1.36% 18.98% 0.89 0.51 -0.49 21.80%
    最大分位 -8.25% -8.25% -9.79% -7.39% 1.00% 1.38% 19.73% 0.89 0.51 -0.46 21.79%
    多空组合 -0.35% -0.35% -0.04% 0.19% -0.00% -0.01% 1.30% 0.86 0.52 -3.74 1.03%

    基本特征分析

    IC分析

    IC均值

    -0.00

    IC标准差

    0.02

    IR值

    -0.20

    |IC| > 0.02比率

    40.00%

    买入信号重合分析

    因子估值分析

    因子拥挤度分析

    因子值最小的20只股票 (2020-12-31)

    股票名称 股票代码 因子值
    高测股份 688556.SHA -0.4870
    民和股份 002234.SZA -0.4813
    长电科技 600584.SHA -0.4774
    塔牌集团 002233.SZA -0.4574
    大东南 002263.SZA -0.4361
    江河集团 601886.SHA -0.4329
    鱼跃医疗 002223.SZA -0.4142
    天地科技 600582.SHA -0.4045
    水晶光电 002273.SZA -0.3852
    联化科技 002250.SZA -0.3824
    中国出版 601949.SHA -0.3766
    华昌化工 002274.SZA -0.3267
    安妮股份 002235.SZA -0.3247
    奇精机械 603677.SHA -0.3139
    香飘飘 603711.SHA -0.3074
    建设银行 601939.SHA -0.3032
    卧龙电驱 600580.SHA -0.2939
    桂林三金 002275.SZA -0.2938
    达意隆 002209.SZA -0.2920
    龙溪股份 600592.SHA -0.2808

    因子值最大的20只股票 (2020-12-31)

    股票名称 股票代码 因子值
    东百集团 600693.SHA 0.3885
    我爱我家 000560.SZA 0.3891
    中国高科 600730.SHA 0.3902
    济南高新 600807.SHA 0.3969
    江苏有线 600959.SHA 0.3981
    莱茵体育 000558.SZA 0.3986
    渝三峡A 000565.SZA 0.3992
    福建水泥 600802.SHA 0.4154
    新天绿能 600956.SHA 0.4154
    宁波海运 600798.SHA 0.4194
    华新水泥 600801.SHA 0.4261
    浙大网新 600797.SHA 0.4264
    供销大集 000564.SZA 0.4353
    百联股份 600827.SHA 0.4405
    钱江生化 600796.SHA 0.4461
    兰生股份 600826.SHA 0.4512
    中芯国际-U 688981.SHA 0.4544
    茂业商业 600828.SHA 0.4609
    鹏博士 600804.SHA 0.5360
    悦达投资 600805.SHA 0.5782

    (Eddie123) #2

    感谢分享,学习学习