复制链接
克隆策略

    {"description":"实验创建于2017/8/26","graph":{"edges":[{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-106:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-773:input_1","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15:data"},{"to_node_id":"-132:features_ds","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-768:input_2","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-778:input_2","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-243:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-3895:input_2","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-251:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-3907:input_2","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-243:input_data","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data"},{"to_node_id":"-122:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-1918:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-224:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-175:input_1","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-113:input_data","from_node_id":"-106:data"},{"to_node_id":"-768:input_1","from_node_id":"-113:data"},{"to_node_id":"-129:input_data","from_node_id":"-122:data"},{"to_node_id":"-778:input_1","from_node_id":"-129:data"},{"to_node_id":"-2680:inputs","from_node_id":"-160:data"},{"to_node_id":"-3880:inputs","from_node_id":"-160:data"},{"to_node_id":"-1540:trained_model","from_node_id":"-1098:data"},{"to_node_id":"-2431:input_1","from_node_id":"-1540:data"},{"to_node_id":"-202:data1","from_node_id":"-2431:data_1"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data2","from_node_id":"-768:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data1","from_node_id":"-773:data"},{"to_node_id":"-251:input_data","from_node_id":"-778:data"},{"to_node_id":"-2431:input_2","from_node_id":"-778:data"},{"to_node_id":"-3895:input_1","from_node_id":"-243:data"},{"to_node_id":"-3907:input_1","from_node_id":"-251:data"},{"to_node_id":"-2712:inputs","from_node_id":"-2680:data"},{"to_node_id":"-3840:inputs","from_node_id":"-2712:data"},{"to_node_id":"-3784:inputs","from_node_id":"-3773:data"},{"to_node_id":"-3880:outputs","from_node_id":"-3784:data"},{"to_node_id":"-3872:inputs","from_node_id":"-3840:data"},{"to_node_id":"-3773:inputs","from_node_id":"-3872:data"},{"to_node_id":"-1098:input_model","from_node_id":"-3880:data"},{"to_node_id":"-1098:training_data","from_node_id":"-3895:data_1"},{"to_node_id":"-1540:input_data","from_node_id":"-3907:data_1"},{"to_node_id":"-106:features","from_node_id":"-132:data"},{"to_node_id":"-122:features","from_node_id":"-132:data"},{"to_node_id":"-113:features","from_node_id":"-132:data"},{"to_node_id":"-129:features","from_node_id":"-132:data"},{"to_node_id":"-224:features","from_node_id":"-148:data"},{"to_node_id":"-189:data1","from_node_id":"-224:data"},{"to_node_id":"-202:data2","from_node_id":"-189:data"},{"to_node_id":"-1918:options_data","from_node_id":"-202:data"},{"to_node_id":"-175:input_2","from_node_id":"-12762:data"},{"to_node_id":"-196:input_ds","from_node_id":"-175:data_1"},{"to_node_id":"-189:data2","from_node_id":"-196:data"}],"nodes":[{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2010-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2017-12-31","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":"287d2cb0-f53c-4101-bdf8-104b137c8601-8"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15","module_id":"BigQuantSpace.advanced_auto_labeler.advanced_auto_labeler-v2","parameters":[{"name":"label_expr","value":"# #号开始的表示注释\n# 0. 每行一个,顺序执行,从第二个开始,可以使用label字段\n# 1. 可用数据字段见 https://bigquant.com/docs/data_history_data.html\n# 添加benchmark_前缀,可使用对应的benchmark数据\n# 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/big_expr.html>`_\n\n# 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)\nshift(close, -2) / shift(open, -1)-1\n\n# 极值处理:用1%和99%分位的值做clip\nclip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))\n\n# 过滤掉一字涨停的情况 (设置label为NaN,在后续处理和训练中会忽略NaN的label)\nwhere(shift(high, -1) == shift(low, -1), NaN, label)\n","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":"benchmark","value":"000300.SHA","type":"Literal","bound_global_parameter":null},{"name":"drop_na_label","value":"True","type":"Literal","bound_global_parameter":null},{"name":"cast_label_int","value":"False","type":"Literal","bound_global_parameter":null},{"name":"user_functions","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"high_0\nhigh_1\nhigh_2\nhigh_3\nhigh_4\nlow_0\nlow_1\nlow_2\nlow_3\nlow_4\n# 5日平均换手率\navg_turn_5 \n# 5日平均振幅\n(high_0-low_0+high_1-low_1+high_2-low_2+high_3-low_3+high_4-low_4)/5 \n# 市盈率LYR\npe_lyr_0\n# 5日净主动买入额\nmf_net_amount_5 \n# 10日净主动买入额\nmf_net_amount_10 \n# 20日净主动买入额\nmf_net_amount_20\n","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24"}],"cacheable":true,"seq_num":3,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53","module_id":"BigQuantSpace.join.join-v3","parameters":[{"name":"on","value":"date,instrument","type":"Literal","bound_global_parameter":null},{"name":"how","value":"inner","type":"Literal","bound_global_parameter":null},{"name":"sort","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"data1","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53"},{"name":"data2","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53"}],"cacheable":true,"seq_num":7,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2018-01-01","type":"Literal","bound_global_parameter":"交易日期"},{"name":"end_date","value":"2021-12-12","type":"Literal","bound_global_parameter":"交易日期"},{"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":"287d2cb0-f53c-4101-bdf8-104b137c8601-62"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62"}],"cacheable":true,"seq_num":9,"comment":"预测数据,用于回测和模拟","comment_collapsed":true},{"node_id":"-106","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":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-106"},{"name":"features","node_id":"-106"}],"output_ports":[{"name":"data","node_id":"-106"}],"cacheable":true,"seq_num":15,"comment":"","comment_collapsed":true},{"node_id":"-113","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":"True","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":"-113"},{"name":"features","node_id":"-113"}],"output_ports":[{"name":"data","node_id":"-113"}],"cacheable":true,"seq_num":16,"comment":"","comment_collapsed":true},{"node_id":"-122","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":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-122"},{"name":"features","node_id":"-122"}],"output_ports":[{"name":"data","node_id":"-122"}],"cacheable":true,"seq_num":17,"comment":"","comment_collapsed":true},{"node_id":"-129","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":"True","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":"-129"},{"name":"features","node_id":"-129"}],"output_ports":[{"name":"data","node_id":"-129"}],"cacheable":true,"seq_num":18,"comment":"","comment_collapsed":true},{"node_id":"-160","module_id":"BigQuantSpace.dl_layer_input.dl_layer_input-v1","parameters":[{"name":"shape","value":"16,5","type":"Literal","bound_global_parameter":null},{"name":"batch_shape","value":"","type":"Literal","bound_global_parameter":null},{"name":"dtype","value":"float32","type":"Literal","bound_global_parameter":null},{"name":"sparse","value":"False","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-160"}],"output_ports":[{"name":"data","node_id":"-160"}],"cacheable":false,"seq_num":6,"comment":"","comment_collapsed":true},{"node_id":"-1098","module_id":"BigQuantSpace.dl_model_train.dl_model_train-v1","parameters":[{"name":"optimizer","value":"RMSprop","type":"Literal","bound_global_parameter":null},{"name":"user_optimizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"loss","value":"mean_squared_error","type":"Literal","bound_global_parameter":null},{"name":"user_loss","value":"","type":"Literal","bound_global_parameter":null},{"name":"metrics","value":"mae","type":"Literal","bound_global_parameter":null},{"name":"batch_size","value":"256","type":"Literal","bound_global_parameter":null},{"name":"epochs","value":"20","type":"Literal","bound_global_parameter":null},{"name":"earlystop","value":"","type":"Literal","bound_global_parameter":null},{"name":"custom_objects","value":"# 用户的自定义层需要写到字典中,比如\n# {\n# \"MyLayer\": MyLayer\n# }\nbigquant_run = {\n \n}\n","type":"Literal","bound_global_parameter":null},{"name":"n_gpus","value":0,"type":"Literal","bound_global_parameter":null},{"name":"verbose","value":"2:每个epoch输出一行记录","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_model","node_id":"-1098"},{"name":"training_data","node_id":"-1098"},{"name":"validation_data","node_id":"-1098"}],"output_ports":[{"name":"data","node_id":"-1098"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-1540","module_id":"BigQuantSpace.dl_model_predict.dl_model_predict-v1","parameters":[{"name":"batch_size","value":"1024","type":"Literal","bound_global_parameter":null},{"name":"n_gpus","value":0,"type":"Literal","bound_global_parameter":null},{"name":"verbose","value":"2:每个epoch输出一行记录","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"trained_model","node_id":"-1540"},{"name":"input_data","node_id":"-1540"}],"output_ports":[{"name":"data","node_id":"-1540"}],"cacheable":true,"seq_num":11,"comment":"","comment_collapsed":true},{"node_id":"-2431","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n pred_label = input_1.read_pickle()\n df = input_2.read_df()\n df = pd.DataFrame({'pred_label':pred_label[:,0], 'instrument':df.instrument, 'date':df.date})\n df.sort_values(['date','pred_label'],inplace=True, ascending=[True,False])\n return Outputs(data_1=DataSource.write_df(df), data_2=None, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-2431"},{"name":"input_2","node_id":"-2431"},{"name":"input_3","node_id":"-2431"}],"output_ports":[{"name":"data_1","node_id":"-2431"},{"name":"data_2","node_id":"-2431"},{"name":"data_3","node_id":"-2431"}],"cacheable":true,"seq_num":24,"comment":"","comment_collapsed":true},{"node_id":"-768","module_id":"BigQuantSpace.standardlize.standardlize-v8","parameters":[{"name":"columns_input","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-768"},{"name":"input_2","node_id":"-768"}],"output_ports":[{"name":"data","node_id":"-768"}],"cacheable":true,"seq_num":14,"comment":"","comment_collapsed":true},{"node_id":"-773","module_id":"BigQuantSpace.standardlize.standardlize-v8","parameters":[{"name":"columns_input","value":"label","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-773"},{"name":"input_2","node_id":"-773"}],"output_ports":[{"name":"data","node_id":"-773"}],"cacheable":true,"seq_num":13,"comment":"","comment_collapsed":true},{"node_id":"-778","module_id":"BigQuantSpace.standardlize.standardlize-v8","parameters":[{"name":"columns_input","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-778"},{"name":"input_2","node_id":"-778"}],"output_ports":[{"name":"data","node_id":"-778"}],"cacheable":true,"seq_num":25,"comment":"","comment_collapsed":true},{"node_id":"-243","module_id":"BigQuantSpace.dl_convert_to_bin.dl_convert_to_bin-v2","parameters":[{"name":"window_size","value":"5","type":"Literal","bound_global_parameter":null},{"name":"feature_clip","value":5,"type":"Literal","bound_global_parameter":null},{"name":"flatten","value":"True","type":"Literal","bound_global_parameter":null},{"name":"window_along_col","value":"instrument","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-243"},{"name":"features","node_id":"-243"}],"output_ports":[{"name":"data","node_id":"-243"}],"cacheable":true,"seq_num":26,"comment":"","comment_collapsed":true},{"node_id":"-251","module_id":"BigQuantSpace.dl_convert_to_bin.dl_convert_to_bin-v2","parameters":[{"name":"window_size","value":"5","type":"Literal","bound_global_parameter":null},{"name":"feature_clip","value":5,"type":"Literal","bound_global_parameter":null},{"name":"flatten","value":"True","type":"Literal","bound_global_parameter":null},{"name":"window_along_col","value":"instrument","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-251"},{"name":"features","node_id":"-251"}],"output_ports":[{"name":"data","node_id":"-251"}],"cacheable":true,"seq_num":27,"comment":"","comment_collapsed":true},{"node_id":"-2680","module_id":"BigQuantSpace.dl_layer_conv1d.dl_layer_conv1d-v1","parameters":[{"name":"filters","value":"20","type":"Literal","bound_global_parameter":null},{"name":"kernel_size","value":"3","type":"Literal","bound_global_parameter":null},{"name":"strides","value":"1","type":"Literal","bound_global_parameter":null},{"name":"padding","value":"valid","type":"Literal","bound_global_parameter":null},{"name":"dilation_rate","value":1,"type":"Literal","bound_global_parameter":null},{"name":"activation","value":"relu","type":"Literal","bound_global_parameter":null},{"name":"user_activation","value":"","type":"Literal","bound_global_parameter":null},{"name":"use_bias","value":"True","type":"Literal","bound_global_parameter":null},{"name":"kernel_initializer","value":"glorot_uniform","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_initializer","value":"Zeros","type":"Literal","bound_global_parameter":null},{"name":"user_bias_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_kernel_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_bias_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_activity_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_bias_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-2680"}],"output_ports":[{"name":"data","node_id":"-2680"}],"cacheable":false,"seq_num":10,"comment":"","comment_collapsed":true},{"node_id":"-2712","module_id":"BigQuantSpace.dl_layer_maxpooling1d.dl_layer_maxpooling1d-v1","parameters":[{"name":"pool_size","value":"1","type":"Literal","bound_global_parameter":null},{"name":"strides","value":"","type":"Literal","bound_global_parameter":null},{"name":"padding","value":"valid","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-2712"}],"output_ports":[{"name":"data","node_id":"-2712"}],"cacheable":false,"seq_num":12,"comment":"","comment_collapsed":true},{"node_id":"-3773","module_id":"BigQuantSpace.dl_layer_globalmaxpooling1d.dl_layer_globalmaxpooling1d-v1","parameters":[{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-3773"}],"output_ports":[{"name":"data","node_id":"-3773"}],"cacheable":false,"seq_num":28,"comment":"","comment_collapsed":true},{"node_id":"-3784","module_id":"BigQuantSpace.dl_layer_dense.dl_layer_dense-v1","parameters":[{"name":"units","value":"1","type":"Literal","bound_global_parameter":null},{"name":"activation","value":"linear","type":"Literal","bound_global_parameter":null},{"name":"user_activation","value":"","type":"Literal","bound_global_parameter":null},{"name":"use_bias","value":"True","type":"Literal","bound_global_parameter":null},{"name":"kernel_initializer","value":"glorot_uniform","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_initializer","value":"Zeros","type":"Literal","bound_global_parameter":null},{"name":"user_bias_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_kernel_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_bias_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_activity_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_bias_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-3784"}],"output_ports":[{"name":"data","node_id":"-3784"}],"cacheable":false,"seq_num":30,"comment":"","comment_collapsed":true},{"node_id":"-3840","module_id":"BigQuantSpace.dl_layer_conv1d.dl_layer_conv1d-v1","parameters":[{"name":"filters","value":"20","type":"Literal","bound_global_parameter":null},{"name":"kernel_size","value":"3","type":"Literal","bound_global_parameter":null},{"name":"strides","value":"1","type":"Literal","bound_global_parameter":null},{"name":"padding","value":"valid","type":"Literal","bound_global_parameter":null},{"name":"dilation_rate","value":1,"type":"Literal","bound_global_parameter":null},{"name":"activation","value":"relu","type":"Literal","bound_global_parameter":null},{"name":"user_activation","value":"","type":"Literal","bound_global_parameter":null},{"name":"use_bias","value":"True","type":"Literal","bound_global_parameter":null},{"name":"kernel_initializer","value":"glorot_uniform","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_initializer","value":"Zeros","type":"Literal","bound_global_parameter":null},{"name":"user_bias_initializer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"kernel_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_kernel_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"bias_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_bias_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer","value":"None","type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l1","value":0,"type":"Literal","bound_global_parameter":null},{"name":"activity_regularizer_l2","value":0,"type":"Literal","bound_global_parameter":null},{"name":"user_activity_regularizer","value":"","type":"Literal","bound_global_parameter":null},{"name":"kernel_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_kernel_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"bias_constraint","value":"None","type":"Literal","bound_global_parameter":null},{"name":"user_bias_constraint","value":"","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-3840"}],"output_ports":[{"name":"data","node_id":"-3840"}],"cacheable":false,"seq_num":32,"comment":"","comment_collapsed":true},{"node_id":"-3872","module_id":"BigQuantSpace.dl_layer_maxpooling1d.dl_layer_maxpooling1d-v1","parameters":[{"name":"pool_size","value":"1","type":"Literal","bound_global_parameter":null},{"name":"strides","value":"","type":"Literal","bound_global_parameter":null},{"name":"padding","value":"valid","type":"Literal","bound_global_parameter":null},{"name":"name","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"inputs","node_id":"-3872"}],"output_ports":[{"name":"data","node_id":"-3872"}],"cacheable":false,"seq_num":33,"comment":"","comment_collapsed":true},{"node_id":"-3880","module_id":"BigQuantSpace.dl_model_init.dl_model_init-v1","parameters":[],"input_ports":[{"name":"inputs","node_id":"-3880"},{"name":"outputs","node_id":"-3880"}],"output_ports":[{"name":"data","node_id":"-3880"}],"cacheable":false,"seq_num":34,"comment":"","comment_collapsed":true},{"node_id":"-3895","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n df = input_1.read_pickle()\n feature_len = len(input_2.read_pickle())\n \n \n df['x'] = df['x'].reshape(df['x'].shape[0], int(feature_len), int(df['x'].shape[1]/feature_len))\n \n data_1 = DataSource.write_pickle(df)\n return Outputs(data_1=data_1)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-3895"},{"name":"input_2","node_id":"-3895"},{"name":"input_3","node_id":"-3895"}],"output_ports":[{"name":"data_1","node_id":"-3895"},{"name":"data_2","node_id":"-3895"},{"name":"data_3","node_id":"-3895"}],"cacheable":true,"seq_num":4,"comment":"","comment_collapsed":true},{"node_id":"-3907","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"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_pickle()\n feature_len = len(input_2.read_pickle())\n \n \n df['x'] = df['x'].reshape(df['x'].shape[0], int(feature_len), int(df['x'].shape[1]/feature_len))\n \n data_1 = DataSource.write_pickle(df)\n return Outputs(data_1=data_1)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-3907"},{"name":"input_2","node_id":"-3907"},{"name":"input_3","node_id":"-3907"}],"output_ports":[{"name":"data_1","node_id":"-3907"},{"name":"data_2","node_id":"-3907"},{"name":"data_3","node_id":"-3907"}],"cacheable":true,"seq_num":8,"comment":"","comment_collapsed":true},{"node_id":"-132","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"# #号开始的表示注释\n# 多个特征,每行一个,可以包含基础特征和衍生特征\nclose_0\nhigh_1\nopen_0\nlow_0\nst_status_0","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-132"}],"output_ports":[{"name":"data","node_id":"-132"}],"cacheable":true,"seq_num":22,"comment":"","comment_collapsed":true},{"node_id":"-148","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nname","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-148"}],"output_ports":[{"name":"data","node_id":"-148"}],"cacheable":true,"seq_num":21,"comment":"","comment_collapsed":true},{"node_id":"-224","module_id":"BigQuantSpace.use_datasource.use_datasource-v1","parameters":[{"name":"datasource_id","value":"instruments_CN_STOCK_A","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}],"input_ports":[{"name":"instruments","node_id":"-224"},{"name":"features","node_id":"-224"}],"output_ports":[{"name":"data","node_id":"-224"}],"cacheable":true,"seq_num":23,"comment":"","comment_collapsed":true},{"node_id":"-189","module_id":"BigQuantSpace.join.join-v3","parameters":[{"name":"on","value":"date","type":"Literal","bound_global_parameter":null},{"name":"how","value":"left","type":"Literal","bound_global_parameter":null},{"name":"sort","value":"True","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"data1","node_id":"-189"},{"name":"data2","node_id":"-189"}],"output_ports":[{"name":"data","node_id":"-189"}],"cacheable":true,"seq_num":31,"comment":"","comment_collapsed":true},{"node_id":"-202","module_id":"BigQuantSpace.join.join-v3","parameters":[{"name":"on","value":"date,instrument","type":"Literal","bound_global_parameter":null},{"name":"how","value":"left","type":"Literal","bound_global_parameter":null},{"name":"sort","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"data1","node_id":"-202"},{"name":"data2","node_id":"-202"}],"output_ports":[{"name":"data","node_id":"-202"}],"cacheable":true,"seq_num":35,"comment":"","comment_collapsed":true},{"node_id":"-1918","module_id":"BigQuantSpace.trade.trade-v4","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n # 加载预测数据\n context.ranker_prediction = context.options['data'].read_df()\n\n # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n # 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)\n # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只\n stock_count = 5\n # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]\n context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])\n # 设置每只股票占用的最大资金比例\n context.max_cash_per_instrument =0.1\n context.options['hold_days'] = 5\n \n # 这一段感觉是在为盘前准备函数写的,当order.amount>0时,认为是买入,<0卖出。\n from zipline.finance.slippage import SlippageModel\n class FixedPriceSlippage(SlippageModel):\n def process_order(self, data, order, bar_volume=0, trigger_check_price=0):\n if order.limit is None:\n price_field = self._price_field_buy if order.amount > 0 else self._price_field_sell\n price = data.current(order.asset, price_field)\n else:\n price = data.current(order.asset, self._price_field_buy)\n # 返回希望成交的价格和数量\n return (price, order.amount)\n # 设置price_field,默认是开盘买入,收盘卖出\n context.fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='close')\n context.set_slippage(us_equities=context.fix_slippage)","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n # 获取当前持仓\n positions = {e.symbol: p.amount * p.last_sale_price\n for e, p in context.portfolio.positions.items()}\n \n today = data.current_dt.strftime('%Y-%m-%d')\n # 按日期过滤得到今日的预测数据\n ranker_prediction = context.ranker_prediction[\n context.ranker_prediction.date == today]\n try:\n #大盘风控模块,读取风控数据 \n # 利用沪深300的dif下穿dea作为大盘风控的条件\n benckmark_risk=ranker_prediction['bm_0'].values[0]\n if benckmark_risk > 0 and len(positions) > 0:\n for instrument in positions.keys():\n context.order_target(context.symbol(instrument), 0)\n print(today,'大盘风控止损触发,全仓卖出')\n return\n except:\n print('缺失风控数据!')\n \n today_date = data.current_dt.strftime('%Y-%m-%d')\n positions_all = [equity.symbol for equity in context.portfolio.positions]\n dataprediction=context.dataprediction\n today_prediction=dataprediction[dataprediction.date==today_date].direction.values[0]\n # 满足空仓条件\n if today_prediction<0:\t\n if len(positions_all)>0:\n # 全部卖出后返回\n for i in positions_all:\n if data.can_trade(context.symbol(i)):\n context.order_target_percent(context.symbol(i), 0)\n print('风控执行',today_date)\n return\n #运行风控后当日结束,不再执行后续的买卖订单\n \n \n # 1. 资金分配\n # 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金\n # 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)\n is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)\n cash_avg = context.portfolio.portfolio_value / context.options['hold_days']\n cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)\n cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)\n \n \n # 2. 根据需要加入移动止赢止损模块、固定天数卖出模块、ST或退市股卖出模块\n stock_sold = [] # 记录卖出的股票,防止多次卖出出现空单\n \n #------------------------START:止赢止损模块(含建仓期)---------------\n current_stopwin_stock=[]\n current_stoploss_stock = [] \n positions_cost={e.symbol:p.cost_basis for e,p in context.portfolio.positions.items()}\n if len(positions)>0:\n for instrument in positions.keys():\n stock_cost=positions_cost[instrument] \n stock_market_price=data.current(context.symbol(instrument),'price') \n volume_since_buy = data.history(context.symbol(instrument), 'volume', 6, '1d')\n # 赚60%且为可交易状态就止盈\n if stock_market_price/stock_cost-1>=0.5 and data.can_trade(context.symbol(instrument)):\n context.order_target_percent(context.symbol(instrument),0)\n cash_for_sell -= positions[instrument]\n current_stopwin_stock.append(instrument)\n # 亏5%并且为可交易状态就止损\n if stock_market_price/stock_cost-1 <= -0.05 and data.can_trade(context.symbol(instrument)): \n context.order_target_percent(context.symbol(instrument),0)\n cash_for_sell -= positions[instrument]\n current_stoploss_stock.append(instrument)\n # 放天量 止损:\n# if (volume_since_buy[0]>1.5*volume_since_buy[1]) |(volume_since_buy[0]>1.5*(volume_since_buy[1]+volume_since_buy[2]+volume_since_buy[3]+volume_since_buy[4]+volume_since_buy[5])/5):\n# context.order_target_percent(context.symbol(instrument),0)\n# cash_for_sell -= positions[instrument]\n# current_stoploss_stock.append(instrument)\n if len(current_stopwin_stock)>0:\n print(today,'止盈股票列表',current_stopwin_stock)\n stock_sold += current_stopwin_stock\n if len(current_stoploss_stock)>0:\n print(today,'止损股票列表',current_stoploss_stock)\n stock_sold += current_stoploss_stock\n #--------------------------END: 止赢止损模块--------------------------\n \n #--------------------------START:持有固定天数卖出(不含建仓期)-----------\n current_stopdays_stock = []\n positions_lastdate = {e.symbol:p.last_sale_date for e,p in context.portfolio.positions.items()}\n # 不是建仓期(在前hold_days属于建仓期)\n if not is_staging:\n for instrument in positions.keys():\n #如果上面的止盈止损已经卖出过了,就不要重复卖出以防止产生空单\n if instrument in stock_sold:\n continue\n # 今天和上次交易的时间相隔hold_days就全部卖出 datetime.timedelta(context.options['hold_days'])也可以换成自己需要的天数,比如datetime.timedelta(5)\n if data.current_dt - positions_lastdate[instrument]>=datetime.timedelta(22) and data.can_trade(context.symbol(instrument)):\n context.order_target_percent(context.symbol(instrument), 0)\n current_stopdays_stock.append(instrument)\n cash_for_sell -= positions[instrument]\n if len(current_stopdays_stock)>0: \n print(today,'固定天数卖出列表',current_stopdays_stock)\n stock_sold += current_stopdays_stock\n #------------------------- END:持有固定天数卖出-----------------------\n \n #-------------------------- START: ST和退市股卖出 --------------------- \n st_stock_list = []\n for instrument in positions.keys():\n try:\n instrument_name = ranker_prediction[ranker_prediction.instrument==instrument].name.values[0]\n # 如果股票状态变为了st或者退市 则卖出\n if 'ST' in instrument_name or '退' in instrument_name:\n if instrument in stock_sold:\n continue\n if data.can_trade(context.symbol(instrument)):\n context.order_target(context.symbol(instrument), 0)\n st_stock_list.append(instrument)\n cash_for_sell -= positions[instrument]\n except:\n continue\n if st_stock_list!=[]:\n print(today,'持仓出现st股/退市股',st_stock_list,'进行卖出处理') \n stock_sold += st_stock_list\n\n #-------------------------- END: ST和退市股卖出 --------------------- \n \n \n # 3. 生成轮仓卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰\n if not is_staging and cash_for_sell > 0:\n instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(\n lambda x: x in positions)])))\n for instrument in instruments:\n # 如果资金够了就不卖出了\n if cash_for_sell <= 0:\n break\n #防止多个止损条件同时满足,出现多次卖出产生空单\n if instrument in stock_sold:\n continue\n context.order_target(context.symbol(instrument), 0)\n cash_for_sell -= positions[instrument]\n stock_sold.append(instrument)\n\n # 4. 生成轮仓买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票\n # 计算今日跌停的股票\n #dt_list = list(ranker_prediction[ranker_prediction.price_limit_status_0==1].instrument)\n # 计算今日ST/退市的股票\n st_list = list(ranker_prediction[ranker_prediction.name.str.contains('ST')|ranker_prediction.name.str.contains('退')].instrument)\n # 计算所有禁止买入的股票池\n banned_list = stock_sold+st_list\n buy_cash_weights = context.stock_weights\n buy_instruments=[k for k in list(ranker_prediction.instrument) if k not in banned_list][:len(buy_cash_weights)]\n max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument\n for i, instrument in enumerate(buy_instruments):\n cash = cash_for_buy * buy_cash_weights[i]\n if cash > max_cash_per_instrument - positions.get(instrument, 0):\n # 确保股票持仓量不会超过每次股票最大的占用资金量\n cash = max_cash_per_instrument - positions.get(instrument, 0)\n if cash > 0:\n current_price = data.current(context.symbol(instrument), 'price')\n amount = math.floor(cash / current_price - cash / current_price % 100)\n context.order(context.symbol(instrument), amount)\n \n\n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n context.status_df = D.features(instruments =context.instruments,start_date = context.start_date, end_date = context.end_date, \n fields=['st_status_0','price_limit_status_0','price_limit_status_1'])\n seq_len=5 #每个input的长度\n # 导入包 \n from tensorflow.keras.layers import Activation, Dropout\n from tensorflow.keras.models import Sequential\n from tensorflow.keras import optimizers\n import tensorflow.keras as tf \n from sklearn.preprocessing import scale\n from tensorflow.keras.layers import Input, Dense, LSTM\n from tensorflow.keras.models import Model\n # 基础参数配置\n instrument = '000300.SHA' #股票代码\n #设置用于训练和回测的开始/结束日期\n train_length=seq_len*10\n # 多取几天的数据,这里前100天\n start_date_temp= (pd.to_datetime(context.start_date) - datetime.timedelta(days=2*train_length)).strftime('%Y-%m-%d')\n print(start_date_temp)\n len1=len(D.trading_days(start_date=start_date_temp, end_date=context.end_date)) \n print(len1)\n len2=len(D.trading_days(start_date=context.start_date, end_date=context.end_date))\n print(len2)\n distance=len1-len2\n print(distance)\n trade_day=D.trading_days(start_date=start_date_temp, end_date=context.end_date)\n print(trade_day)\n start_date = trade_day.iloc[distance-train_length][0].strftime('%Y-%m-%d')\n print(start_date)\n split_date = trade_day.iloc[distance-1][0].strftime('%Y-%m-%d')\n print(split_date)\n # features因子\n fields = ['close', 'open', 'high', 'low', 'amount', 'volume'] \n #整数,指定进行梯度下降时每个batch包含的样本数,训练时一个batch的样本会被计算一次梯度下降,使目标函数优化一步\n batch = 100\n \n # 数据导入以及初步处理\n data1 = D.history_data(instrument, start_date, context.end_date, fields)\n data1['return'] = data1['close'].shift(-5) / data1['open'].shift(-1) - 1 #计算未来5日收益率(未来第五日的收盘价/明日的开盘价)\n data1=data1[data1.amount>0]\n datatime = data1['date'][data1.date>split_date] #记录predictions的时间,回测要用\n data1['return'] = data1['return']\n data1['return'] = data1['return']*10 # 适当增大return(收益)范围,利于LSTM模型训练\n data1.reset_index(drop=True, inplace=True)\n scaledata = data1[fields]\n traindata = data1[data1.date<=split_date]\n \n # 数据处理:设定每个input(series×6features)以及数据标准化\n train_input = []\n train_output = []\n test_input = []\n for i in range(seq_len-1, len(traindata)):\n a = scale(scaledata[i+1-seq_len:i+1])\n train_input.append(a)\n c = data1['return'][i]\n train_output.append(c)\n for j in range(len(traindata), len(data1)):\n b = scale(scaledata[j+1-seq_len:j+1])\n test_input.append(b)\n\n\n # LSTM接受数组类型的输入\n train_x = np.array(train_input)\n train_y = np.array(train_output)\n test_x = np.array(test_input) \n\n # 自定义激活函数\n import tensorflow.keras as tf\n def atan(x): \n return tf.atan(x)\n # 构建神经网络层 1层LSTM层+3层Dense层\n # 用于1个输入情况\n lstm_input = Input(shape=(seq_len,len(fields)), name='lstm_input')\n lstm_output = LSTM(32,input_shape=(seq_len,len(fields)))(lstm_input)\n Dense_output_1 = Dense(16, activation='linear')(lstm_output)\n Dense_output_2 = Dense(4, activation='linear')(Dense_output_1)\n predictions = Dense(1)(Dense_output_2)\n model = Model(inputs=lstm_input, outputs=predictions)\n model.compile(optimizer='adam', loss='mse', metrics=['mse'])\n model.fit(train_x, train_y, batch_size=batch, epochs=5, verbose=0)\n # 预测\n predictions = model.predict(test_x)\n # 如果预测值>0,取为1;如果预测值<=0,取为-1.为回测做准备\n for i in range(len(predictions)):\n if predictions[i]>0:\n predictions[i]=1\n elif predictions[i]<=0:\n predictions[i]=-1\n \n # 将预测值与时间整合作为回测数据\n cc = np.reshape(predictions,len(predictions), )\n dataprediction = pd.DataFrame()\n dataprediction['date'] = datatime\n dataprediction['direction']=np.round(cc)\n context.dataprediction=dataprediction\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"def bigquant_run(context, data):\n # 获取涨跌停状态数据\n df_price_limit_status = context.ranker_prediction.set_index('date')\n today=data.current_dt.strftime('%Y-%m-%d')\n # 得到当前未完成订单\n for orders in get_open_orders().values():\n # 循环,撤销订单\n for _order in orders:\n ins=str(_order.sid.symbol)\n try:\n #判断一下如果当日涨停(3),则取消卖单\n if df_price_limit_status[df_price_limit_status.instrument==ins].price_limit_status_0.ix[today]>2 and _order.amount<0:\n cancel_order(_order)\n print(today,'尾盘涨停取消卖单',ins) \n except:\n continue","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":0.025,"type":"Literal","bound_global_parameter":null},{"name":"order_price_field_buy","value":"open","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_sell","value":"close","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"1000001","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":"-1918"},{"name":"options_data","node_id":"-1918"},{"name":"history_ds","node_id":"-1918"},{"name":"benchmark_ds","node_id":"-1918"},{"name":"trading_calendar","node_id":"-1918"}],"output_ports":[{"name":"raw_perf","node_id":"-1918"}],"cacheable":false,"seq_num":37,"comment":"","comment_collapsed":true},{"node_id":"-12762","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\n#bm_0 = where(close/shift(close,5)-1<-0.05,1,0)\n# 如果macd中的dif下穿macd中的dea,则bm_0等于1,否则等于0\nbm_0=where(ta_macd_dif(close,2,4,4)-ta_macd_dea(close,2,4,4)<0,1,0)","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-12762"}],"output_ports":[{"name":"data","node_id":"-12762"}],"cacheable":true,"seq_num":19,"comment":"卖出条件","comment_collapsed":true},{"node_id":"-175","module_id":"BigQuantSpace.index_feature_extract.index_feature_extract-v3","parameters":[{"name":"before_days","value":100,"type":"Literal","bound_global_parameter":null},{"name":"index","value":"000300.HIX","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-175"},{"name":"input_2","node_id":"-175"}],"output_ports":[{"name":"data_1","node_id":"-175"},{"name":"data_2","node_id":"-175"}],"cacheable":true,"seq_num":20,"comment":"","comment_collapsed":true},{"node_id":"-196","module_id":"BigQuantSpace.select_columns.select_columns-v3","parameters":[{"name":"columns","value":"date,bm_0","type":"Literal","bound_global_parameter":null},{"name":"reverse_select","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_ds","node_id":"-196"},{"name":"columns_ds","node_id":"-196"}],"output_ports":[{"name":"data","node_id":"-196"}],"cacheable":true,"seq_num":39,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-8' Position='642,152,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-15' Position='642,224,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-24' Position='950,80,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-53' Position='779,424,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-62' Position='1250,133,200,200'/><node_position Node='-106' Position='940,219,200,200'/><node_position Node='-113' Position='945,293,200,200'/><node_position Node='-122' Position='1254,205,200,200'/><node_position Node='-129' Position='1258,276,200,200'/><node_position Node='-160' Position='346,127,200,200'/><node_position Node='-1098' Position='347,662,200,200'/><node_position Node='-1540' Position='352,722,200,200'/><node_position Node='-2431' Position='343,802,200,200'/><node_position Node='-768' Position='943,360,200,200'/><node_position Node='-773' Position='644,290,200,200'/><node_position Node='-778' Position='1248,367,200,200'/><node_position Node='-243' Position='779,547,200,200'/><node_position Node='-251' Position='1251,485,200,200'/><node_position Node='-2680' Position='352,190,200,200'/><node_position Node='-2712' Position='348,263,200,200'/><node_position Node='-3773' Position='348,454,200,200'/><node_position Node='-3784' Position='347,529,200,200'/><node_position Node='-3840' Position='346,326,200,200'/><node_position Node='-3872' Position='350,389,200,200'/><node_position Node='-3880' Position='350,599,200,200'/><node_position Node='-3895' Position='779,613,200,200'/><node_position Node='-3907' Position='1244,552,200,200'/><node_position Node='-132' Position='947,144,200,200'/><node_position Node='-148' Position='1559,327,200,200'/><node_position Node='-224' Position='1558,402,200,200'/><node_position Node='-189' Position='1571,488,200,200'/><node_position Node='-202' Position='1079,731,200,200'/><node_position Node='-1918' Position='966,905,200,200'/><node_position Node='-12762' Position='1892,183,200,200'/><node_position Node='-175' Position='1897,290,200,200'/><node_position Node='-196' Position='1878,390,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [1]:
    # 本代码由可视化策略环境自动生成 2021年12月17日 14:03
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m4_run_bigquant_run(input_1, input_2, input_3):
        df =  input_1.read_pickle()
        feature_len = len(input_2.read_pickle())
        
        
        df['x'] = df['x'].reshape(df['x'].shape[0], int(feature_len), int(df['x'].shape[1]/feature_len))
        
        data_1 = DataSource.write_pickle(df)
        return Outputs(data_1=data_1)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m4_post_run_bigquant_run(outputs):
        return outputs
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m8_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        df =  input_1.read_pickle()
        feature_len = len(input_2.read_pickle())
        
        
        df['x'] = df['x'].reshape(df['x'].shape[0], int(feature_len), int(df['x'].shape[1]/feature_len))
        
        data_1 = DataSource.write_pickle(df)
        return Outputs(data_1=data_1)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m8_post_run_bigquant_run(outputs):
        return outputs
    
    # 用户的自定义层需要写到字典中,比如
    # {
    #   "MyLayer": MyLayer
    # }
    m5_custom_objects_bigquant_run = {
        
    }
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m24_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        pred_label = input_1.read_pickle()
        df = input_2.read_df()
        df = pd.DataFrame({'pred_label':pred_label[:,0], 'instrument':df.instrument, 'date':df.date})
        df.sort_values(['date','pred_label'],inplace=True, ascending=[True,False])
        return Outputs(data_1=DataSource.write_df(df), data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m24_post_run_bigquant_run(outputs):
        return outputs
    
    # 回测引擎:初始化函数,只执行一次
    def m37_initialize_bigquant_run(context):
        # 加载预测数据
        context.ranker_prediction = context.options['data'].read_df()
    
        # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        # 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
        # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
        stock_count = 5
        # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
        context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
        # 设置每只股票占用的最大资金比例
        context.max_cash_per_instrument =0.1
        context.options['hold_days'] = 5
        
        # 这一段感觉是在为盘前准备函数写的,当order.amount>0时,认为是买入,<0卖出。
        from zipline.finance.slippage import SlippageModel
        class FixedPriceSlippage(SlippageModel):
            def process_order(self, data, order, bar_volume=0, trigger_check_price=0):
                if order.limit is None:
                    price_field = self._price_field_buy if order.amount > 0 else self._price_field_sell
                    price = data.current(order.asset, price_field)
                else:
                    price = data.current(order.asset, self._price_field_buy)
                # 返回希望成交的价格和数量
                return (price, order.amount)
        # 设置price_field,默认是开盘买入,收盘卖出
        context.fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='close')
        context.set_slippage(us_equities=context.fix_slippage)
    # 回测引擎:每日数据处理函数,每天执行一次
    def m37_handle_data_bigquant_run(context, data):
        # 获取当前持仓
        positions = {e.symbol: p.amount * p.last_sale_price
                     for e, p in context.portfolio.positions.items()}
        
        today = data.current_dt.strftime('%Y-%m-%d')
        # 按日期过滤得到今日的预测数据
        ranker_prediction = context.ranker_prediction[
            context.ranker_prediction.date == today]
        try:
        #大盘风控模块,读取风控数据  
            # 利用沪深300的dif下穿dea作为大盘风控的条件
            benckmark_risk=ranker_prediction['bm_0'].values[0]
            if benckmark_risk > 0 and len(positions) > 0:
                for instrument in positions.keys():
                    context.order_target(context.symbol(instrument), 0)
                    print(today,'大盘风控止损触发,全仓卖出')
                    return
        except:
            print('缺失风控数据!')
        
        today_date = data.current_dt.strftime('%Y-%m-%d')
        positions_all = [equity.symbol for equity in context.portfolio.positions]
        dataprediction=context.dataprediction
        today_prediction=dataprediction[dataprediction.date==today_date].direction.values[0]
        # 满足空仓条件
        if today_prediction<0:	
            if len(positions_all)>0:
                # 全部卖出后返回
                for i in positions_all:
                    if data.can_trade(context.symbol(i)):
                        context.order_target_percent(context.symbol(i), 0)
                        print('风控执行',today_date)
                        return
                    #运行风控后当日结束,不再执行后续的买卖订单
         
        
        # 1. 资金分配
        # 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金
        # 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)
        is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)
        cash_avg = context.portfolio.portfolio_value / context.options['hold_days']
        cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
        cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
       
        
        # 2. 根据需要加入移动止赢止损模块、固定天数卖出模块、ST或退市股卖出模块
        stock_sold = [] # 记录卖出的股票,防止多次卖出出现空单
        
        #------------------------START:止赢止损模块(含建仓期)---------------
        current_stopwin_stock=[]
        current_stoploss_stock = []   
        positions_cost={e.symbol:p.cost_basis for e,p in context.portfolio.positions.items()}
        if len(positions)>0:
            for instrument in positions.keys():
                stock_cost=positions_cost[instrument]  
                stock_market_price=data.current(context.symbol(instrument),'price')  
                volume_since_buy = data.history(context.symbol(instrument), 'volume', 6, '1d')
                # 赚60%且为可交易状态就止盈
                if stock_market_price/stock_cost-1>=0.5 and data.can_trade(context.symbol(instrument)):
                    context.order_target_percent(context.symbol(instrument),0)
                    cash_for_sell -= positions[instrument]
                    current_stopwin_stock.append(instrument)
                # 亏5%并且为可交易状态就止损
                if stock_market_price/stock_cost-1 <= -0.05 and data.can_trade(context.symbol(instrument)):   
                    context.order_target_percent(context.symbol(instrument),0)
                    cash_for_sell -= positions[instrument]
                    current_stoploss_stock.append(instrument)
                # 放天量  止损:
    #             if  (volume_since_buy[0]>1.5*volume_since_buy[1]) |(volume_since_buy[0]>1.5*(volume_since_buy[1]+volume_since_buy[2]+volume_since_buy[3]+volume_since_buy[4]+volume_since_buy[5])/5):
    #                 context.order_target_percent(context.symbol(instrument),0)
    #                 cash_for_sell -= positions[instrument]
    #                 current_stoploss_stock.append(instrument)
            if len(current_stopwin_stock)>0:
                print(today,'止盈股票列表',current_stopwin_stock)
                stock_sold += current_stopwin_stock
            if len(current_stoploss_stock)>0:
                print(today,'止损股票列表',current_stoploss_stock)
                stock_sold += current_stoploss_stock
        #--------------------------END: 止赢止损模块--------------------------
        
        #--------------------------START:持有固定天数卖出(不含建仓期)-----------
        current_stopdays_stock = []
        positions_lastdate = {e.symbol:p.last_sale_date for e,p in context.portfolio.positions.items()}
        # 不是建仓期(在前hold_days属于建仓期)
        if not is_staging:
            for instrument in positions.keys():
                #如果上面的止盈止损已经卖出过了,就不要重复卖出以防止产生空单
                if instrument in stock_sold:
                    continue
                # 今天和上次交易的时间相隔hold_days就全部卖出 datetime.timedelta(context.options['hold_days'])也可以换成自己需要的天数,比如datetime.timedelta(5)
                if data.current_dt - positions_lastdate[instrument]>=datetime.timedelta(22) and data.can_trade(context.symbol(instrument)):
                    context.order_target_percent(context.symbol(instrument), 0)
                    current_stopdays_stock.append(instrument)
                    cash_for_sell -= positions[instrument]
            if len(current_stopdays_stock)>0:        
                print(today,'固定天数卖出列表',current_stopdays_stock)
                stock_sold += current_stopdays_stock
        #-------------------------  END:持有固定天数卖出-----------------------
        
        #-------------------------- START: ST和退市股卖出 ---------------------  
        st_stock_list = []
        for instrument in positions.keys():
            try:
                instrument_name = ranker_prediction[ranker_prediction.instrument==instrument].name.values[0]
                # 如果股票状态变为了st或者退市 则卖出
                if 'ST' in instrument_name or '退' in instrument_name:
                    if instrument in stock_sold:
                        continue
                    if data.can_trade(context.symbol(instrument)):
                        context.order_target(context.symbol(instrument), 0)
                        st_stock_list.append(instrument)
                        cash_for_sell -= positions[instrument]
            except:
                continue
        if st_stock_list!=[]:
            print(today,'持仓出现st股/退市股',st_stock_list,'进行卖出处理')    
            stock_sold += st_stock_list
    
        #-------------------------- END: ST和退市股卖出 --------------------- 
        
        
        # 3. 生成轮仓卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰
        if not is_staging and cash_for_sell > 0:
            instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(
                    lambda x: x in positions)])))
            for instrument in instruments:
                # 如果资金够了就不卖出了
                if cash_for_sell <= 0:
                    break
                #防止多个止损条件同时满足,出现多次卖出产生空单
                if instrument in stock_sold:
                    continue
                context.order_target(context.symbol(instrument), 0)
                cash_for_sell -= positions[instrument]
                stock_sold.append(instrument)
    
        # 4. 生成轮仓买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
        # 计算今日跌停的股票
        #dt_list = list(ranker_prediction[ranker_prediction.price_limit_status_0==1].instrument)
        # 计算今日ST/退市的股票
        st_list = list(ranker_prediction[ranker_prediction.name.str.contains('ST')|ranker_prediction.name.str.contains('退')].instrument)
        # 计算所有禁止买入的股票池
        banned_list = stock_sold+st_list
        buy_cash_weights = context.stock_weights
        buy_instruments=[k for k in list(ranker_prediction.instrument) if k not in banned_list][:len(buy_cash_weights)]
        max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
        for i, instrument in enumerate(buy_instruments):
            cash = cash_for_buy * buy_cash_weights[i]
            if cash > max_cash_per_instrument - positions.get(instrument, 0):
                # 确保股票持仓量不会超过每次股票最大的占用资金量
                cash = max_cash_per_instrument - positions.get(instrument, 0)
            if cash > 0:
                current_price = data.current(context.symbol(instrument), 'price')
                amount = math.floor(cash / current_price - cash / current_price % 100)
                context.order(context.symbol(instrument), amount)
        
    
    
    # 回测引擎:准备数据,只执行一次
    def m37_prepare_bigquant_run(context):
        context.status_df = D.features(instruments =context.instruments,start_date = context.start_date, end_date = context.end_date, 
                                       fields=['st_status_0','price_limit_status_0','price_limit_status_1'])
        seq_len=5    #每个input的长度
        # 导入包 
        from tensorflow.keras.layers import Activation, Dropout
        from tensorflow.keras.models import Sequential
        from tensorflow.keras import optimizers
        import tensorflow.keras as tf   
        from sklearn.preprocessing import scale
        from tensorflow.keras.layers import Input, Dense, LSTM
        from tensorflow.keras.models import Model
        # 基础参数配置
        instrument = '000300.SHA'  #股票代码
        #设置用于训练和回测的开始/结束日期
        train_length=seq_len*10
        # 多取几天的数据,这里前100天
        start_date_temp= (pd.to_datetime(context.start_date) - datetime.timedelta(days=2*train_length)).strftime('%Y-%m-%d')
        print(start_date_temp)
        len1=len(D.trading_days(start_date=start_date_temp, end_date=context.end_date)) 
        print(len1)
        len2=len(D.trading_days(start_date=context.start_date, end_date=context.end_date))
        print(len2)
        distance=len1-len2
        print(distance)
        trade_day=D.trading_days(start_date=start_date_temp, end_date=context.end_date)
        print(trade_day)
        start_date = trade_day.iloc[distance-train_length][0].strftime('%Y-%m-%d')
        print(start_date)
        split_date = trade_day.iloc[distance-1][0].strftime('%Y-%m-%d')
        print(split_date)
        # features因子
        fields = ['close', 'open', 'high', 'low', 'amount', 'volume'] 
        #整数,指定进行梯度下降时每个batch包含的样本数,训练时一个batch的样本会被计算一次梯度下降,使目标函数优化一步
        batch = 100
        
        # 数据导入以及初步处理
        data1 = D.history_data(instrument, start_date, context.end_date, fields)
        data1['return'] = data1['close'].shift(-5) / data1['open'].shift(-1) - 1 #计算未来5日收益率(未来第五日的收盘价/明日的开盘价)
        data1=data1[data1.amount>0]
        datatime = data1['date'][data1.date>split_date]  #记录predictions的时间,回测要用
        data1['return'] = data1['return']
        data1['return'] = data1['return']*10  # 适当增大return(收益)范围,利于LSTM模型训练
        data1.reset_index(drop=True, inplace=True)
        scaledata = data1[fields]
        traindata = data1[data1.date<=split_date]
        
        # 数据处理:设定每个input(series×6features)以及数据标准化
        train_input = []
        train_output = []
        test_input = []
        for i in range(seq_len-1, len(traindata)):
            a = scale(scaledata[i+1-seq_len:i+1])
            train_input.append(a)
            c = data1['return'][i]
            train_output.append(c)
        for j in range(len(traindata), len(data1)):
            b = scale(scaledata[j+1-seq_len:j+1])
            test_input.append(b)
    
    
        # LSTM接受数组类型的输入
        train_x = np.array(train_input)
        train_y = np.array(train_output)
        test_x = np.array(test_input) 
    
        # 自定义激活函数
        import tensorflow.keras as tf
        def atan(x): 
            return tf.atan(x)
        # 构建神经网络层 1层LSTM层+3层Dense层
        # 用于1个输入情况
        lstm_input = Input(shape=(seq_len,len(fields)), name='lstm_input')
        lstm_output = LSTM(32,input_shape=(seq_len,len(fields)))(lstm_input)
        Dense_output_1 = Dense(16, activation='linear')(lstm_output)
        Dense_output_2 = Dense(4, activation='linear')(Dense_output_1)
        predictions = Dense(1)(Dense_output_2)
        model = Model(inputs=lstm_input, outputs=predictions)
        model.compile(optimizer='adam', loss='mse', metrics=['mse'])
        model.fit(train_x, train_y, batch_size=batch, epochs=5, verbose=0)
        # 预测
        predictions = model.predict(test_x)
        # 如果预测值>0,取为1;如果预测值<=0,取为-1.为回测做准备
        for i in range(len(predictions)):
            if predictions[i]>0:
                predictions[i]=1
            elif predictions[i]<=0:
                predictions[i]=-1
                
        # 将预测值与时间整合作为回测数据
        cc = np.reshape(predictions,len(predictions), )
        dataprediction = pd.DataFrame()
        dataprediction['date'] = datatime
        dataprediction['direction']=np.round(cc)
        context.dataprediction=dataprediction
    
    def m37_before_trading_start_bigquant_run(context, data):
        # 获取涨跌停状态数据
        df_price_limit_status = context.ranker_prediction.set_index('date')
        today=data.current_dt.strftime('%Y-%m-%d')
        # 得到当前未完成订单
        for orders in get_open_orders().values():
            # 循环,撤销订单
            for _order in orders:
                ins=str(_order.sid.symbol)
                try:
                    #判断一下如果当日涨停(3),则取消卖单
                    if  df_price_limit_status[df_price_limit_status.instrument==ins].price_limit_status_0.ix[today]>2 and _order.amount<0:
                        cancel_order(_order)
                        print(today,'尾盘涨停取消卖单',ins) 
                except:
                    continue
    
    m1 = M.instruments.v2(
        start_date='2010-01-01',
        end_date='2017-12-31',
        market='CN_STOCK_A',
        instrument_list=' ',
        max_count=0
    )
    
    m2 = M.advanced_auto_labeler.v2(
        instruments=m1.data,
        label_expr="""# #号开始的表示注释
    # 0. 每行一个,顺序执行,从第二个开始,可以使用label字段
    # 1. 可用数据字段见 https://bigquant.com/docs/data_history_data.html
    #   添加benchmark_前缀,可使用对应的benchmark数据
    # 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/big_expr.html>`_
    
    # 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)
    shift(close, -2) / shift(open, -1)-1
    
    # 极值处理:用1%和99%分位的值做clip
    clip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))
    
    # 过滤掉一字涨停的情况 (设置label为NaN,在后续处理和训练中会忽略NaN的label)
    where(shift(high, -1) == shift(low, -1), NaN, label)
    """,
        start_date='',
        end_date='',
        benchmark='000300.SHA',
        drop_na_label=True,
        cast_label_int=False
    )
    
    m13 = M.standardlize.v8(
        input_1=m2.data,
        columns_input='label'
    )
    
    m3 = M.input_features.v1(
        features="""high_0
    high_1
    high_2
    high_3
    high_4
    low_0
    low_1
    low_2
    low_3
    low_4
    # 5日平均换手率
    avg_turn_5   
    # 5日平均振幅
    (high_0-low_0+high_1-low_1+high_2-low_2+high_3-low_3+high_4-low_4)/5 
    # 市盈率LYR
    pe_lyr_0
    # 5日净主动买入额
    mf_net_amount_5 
    # 10日净主动买入额
    mf_net_amount_10 
    # 20日净主动买入额
    mf_net_amount_20
    """
    )
    
    m22 = M.input_features.v1(
        features_ds=m3.data,
        features="""# #号开始的表示注释
    # 多个特征,每行一个,可以包含基础特征和衍生特征
    close_0
    high_1
    open_0
    low_0
    st_status_0"""
    )
    
    m15 = M.general_feature_extractor.v7(
        instruments=m1.data,
        features=m22.data,
        start_date='',
        end_date='',
        before_start_days=0
    )
    
    m16 = M.derived_feature_extractor.v3(
        input_data=m15.data,
        features=m22.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=True,
        remove_extra_columns=False
    )
    
    m14 = M.standardlize.v8(
        input_1=m16.data,
        input_2=m3.data,
        columns_input=''
    )
    
    m7 = M.join.v3(
        data1=m13.data,
        data2=m14.data,
        on='date,instrument',
        how='inner',
        sort=False
    )
    
    m26 = M.dl_convert_to_bin.v2(
        input_data=m7.data,
        features=m3.data,
        window_size=5,
        feature_clip=5,
        flatten=True,
        window_along_col='instrument'
    )
    
    m4 = M.cached.v3(
        input_1=m26.data,
        input_2=m3.data,
        run=m4_run_bigquant_run,
        post_run=m4_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m9 = M.instruments.v2(
        start_date=T.live_run_param('trading_date', '2018-01-01'),
        end_date=T.live_run_param('trading_date', '2021-12-12'),
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    m17 = M.general_feature_extractor.v7(
        instruments=m9.data,
        features=m22.data,
        start_date='',
        end_date='',
        before_start_days=0
    )
    
    m18 = M.derived_feature_extractor.v3(
        input_data=m17.data,
        features=m22.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=True,
        remove_extra_columns=False
    )
    
    m25 = M.standardlize.v8(
        input_1=m18.data,
        input_2=m3.data,
        columns_input=''
    )
    
    m27 = M.dl_convert_to_bin.v2(
        input_data=m25.data,
        features=m3.data,
        window_size=5,
        feature_clip=5,
        flatten=True,
        window_along_col='instrument'
    )
    
    m8 = M.cached.v3(
        input_1=m27.data,
        input_2=m3.data,
        run=m8_run_bigquant_run,
        post_run=m8_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m6 = M.dl_layer_input.v1(
        shape='16,5',
        batch_shape='',
        dtype='float32',
        sparse=False,
        name=''
    )
    
    m10 = M.dl_layer_conv1d.v1(
        inputs=m6.data,
        filters=20,
        kernel_size='3',
        strides='1',
        padding='valid',
        dilation_rate=1,
        activation='relu',
        use_bias=True,
        kernel_initializer='glorot_uniform',
        bias_initializer='Zeros',
        kernel_regularizer='None',
        kernel_regularizer_l1=0,
        kernel_regularizer_l2=0,
        bias_regularizer='None',
        bias_regularizer_l1=0,
        bias_regularizer_l2=0,
        activity_regularizer='None',
        activity_regularizer_l1=0,
        activity_regularizer_l2=0,
        kernel_constraint='None',
        bias_constraint='None',
        name=''
    )
    
    m12 = M.dl_layer_maxpooling1d.v1(
        inputs=m10.data,
        pool_size=1,
        padding='valid',
        name=''
    )
    
    m32 = M.dl_layer_conv1d.v1(
        inputs=m12.data,
        filters=20,
        kernel_size='3',
        strides='1',
        padding='valid',
        dilation_rate=1,
        activation='relu',
        use_bias=True,
        kernel_initializer='glorot_uniform',
        bias_initializer='Zeros',
        kernel_regularizer='None',
        kernel_regularizer_l1=0,
        kernel_regularizer_l2=0,
        bias_regularizer='None',
        bias_regularizer_l1=0,
        bias_regularizer_l2=0,
        activity_regularizer='None',
        activity_regularizer_l1=0,
        activity_regularizer_l2=0,
        kernel_constraint='None',
        bias_constraint='None',
        name=''
    )
    
    m33 = M.dl_layer_maxpooling1d.v1(
        inputs=m32.data,
        pool_size=1,
        padding='valid',
        name=''
    )
    
    m28 = M.dl_layer_globalmaxpooling1d.v1(
        inputs=m33.data,
        name=''
    )
    
    m30 = M.dl_layer_dense.v1(
        inputs=m28.data,
        units=1,
        activation='linear',
        use_bias=True,
        kernel_initializer='glorot_uniform',
        bias_initializer='Zeros',
        kernel_regularizer='None',
        kernel_regularizer_l1=0,
        kernel_regularizer_l2=0,
        bias_regularizer='None',
        bias_regularizer_l1=0,
        bias_regularizer_l2=0,
        activity_regularizer='None',
        activity_regularizer_l1=0,
        activity_regularizer_l2=0,
        kernel_constraint='None',
        bias_constraint='None',
        name=''
    )
    
    m34 = M.dl_model_init.v1(
        inputs=m6.data,
        outputs=m30.data
    )
    
    m5 = M.dl_model_train.v1(
        input_model=m34.data,
        training_data=m4.data_1,
        optimizer='RMSprop',
        loss='mean_squared_error',
        metrics='mae',
        batch_size=256,
        epochs=20,
        custom_objects=m5_custom_objects_bigquant_run,
        n_gpus=0,
        verbose='2:每个epoch输出一行记录'
    )
    
    m11 = M.dl_model_predict.v1(
        trained_model=m5.data,
        input_data=m8.data_1,
        batch_size=1024,
        n_gpus=0,
        verbose='2:每个epoch输出一行记录'
    )
    
    m24 = M.cached.v3(
        input_1=m11.data,
        input_2=m25.data,
        run=m24_run_bigquant_run,
        post_run=m24_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m21 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    name"""
    )
    
    m23 = M.use_datasource.v1(
        instruments=m9.data,
        features=m21.data,
        datasource_id='instruments_CN_STOCK_A',
        start_date='',
        end_date=''
    )
    
    m19 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    #bm_0 = where(close/shift(close,5)-1<-0.05,1,0)
    # 如果macd中的dif下穿macd中的dea,则bm_0等于1,否则等于0
    bm_0=where(ta_macd_dif(close,2,4,4)-ta_macd_dea(close,2,4,4)<0,1,0)"""
    )
    
    m20 = M.index_feature_extract.v3(
        input_1=m9.data,
        input_2=m19.data,
        before_days=100,
        index='000300.HIX'
    )
    
    m39 = M.select_columns.v3(
        input_ds=m20.data_1,
        columns='date,bm_0',
        reverse_select=False
    )
    
    m31 = M.join.v3(
        data1=m23.data,
        data2=m39.data,
        on='date',
        how='left',
        sort=True
    )
    
    m35 = M.join.v3(
        data1=m24.data_1,
        data2=m31.data,
        on='date,instrument',
        how='left',
        sort=False
    )
    
    m37 = M.trade.v4(
        instruments=m9.data,
        options_data=m35.data,
        start_date='',
        end_date='',
        initialize=m37_initialize_bigquant_run,
        handle_data=m37_handle_data_bigquant_run,
        prepare=m37_prepare_bigquant_run,
        before_trading_start=m37_before_trading_start_bigquant_run,
        volume_limit=0.025,
        order_price_field_buy='open',
        order_price_field_sell='close',
        capital_base=1000001,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='后复权',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark=''
    )
    
    3502/3502 - 32s
    DataSource(76a93c53cef8429182de0392bc52c613T)
    
    2017-09-23
    1023
    958
    65
               date
    3094 2017-09-25
    3095 2017-09-26
    3096 2017-09-27
    3097 2017-09-28
    3098 2017-09-29
    ...         ...
    4112 2021-12-06
    4113 2021-12-07
    4114 2021-12-08
    4115 2021-12-09
    4116 2021-12-10
    
    [1023 rows x 1 columns]
    2017-10-23
    2017-12-29
    
    ---------------------------------------------------------------------------
    NotImplementedError                       Traceback (most recent call last)
    <ipython-input-1-45432c3447b1> in <module>
        720 )
        721 
    --> 722 m37 = M.trade.v4(
        723     instruments=m9.data,
        724     options_data=m35.data,
    
    <ipython-input-1-45432c3447b1> in m37_prepare_bigquant_run(context)
        319     # 用于1个输入情况
        320     lstm_input = Input(shape=(seq_len,len(fields)), name='lstm_input')
    --> 321     lstm_output = LSTM(32,input_shape=(seq_len,len(fields)))(lstm_input)
        322     Dense_output_1 = Dense(16, activation='linear')(lstm_output)
        323     Dense_output_2 = Dense(4, activation='linear')(Dense_output_1)
    
    NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported