复制链接
克隆策略

    {"description":"实验创建于2017/8/26","graph":{"edges":[{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data1","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-11425:features_ds","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60:model","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43:model"},{"to_node_id":"-11430:input_data","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data"},{"to_node_id":"-189:data1","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60:predictions"},{"to_node_id":"-1918:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-231: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":"287d2cb0-f53c-4101-bdf8-104b137c8601-43:training_ds","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-84:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60:data","from_node_id":"-86:data"},{"to_node_id":"-222:input_data","from_node_id":"-215:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-53:data2","from_node_id":"-222:data"},{"to_node_id":"-238:input_data","from_node_id":"-231:data"},{"to_node_id":"-3779:input_data","from_node_id":"-238:data"},{"to_node_id":"-215:features","from_node_id":"-11425:data"},{"to_node_id":"-222:features","from_node_id":"-11425:data"},{"to_node_id":"-238:features","from_node_id":"-11425:data"},{"to_node_id":"-231:features","from_node_id":"-11425:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-84:input_data","from_node_id":"-11430:data"},{"to_node_id":"-86:input_data","from_node_id":"-3779:data"},{"to_node_id":"-215:instruments","from_node_id":"-184:data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-15:instruments","from_node_id":"-184:data"},{"to_node_id":"-224:features","from_node_id":"-148:data"},{"to_node_id":"-189:data2","from_node_id":"-224:data"},{"to_node_id":"-1918:options_data","from_node_id":"-189:data"}],"nodes":[{"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/develop/datasource/deprecated/history_data.html\n# 添加benchmark_前缀,可使用对应的benchmark数据\n# 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/develop/bigexpr/usage.html>`_\n\n# 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)\nshift(close, -5) / shift(open, -1)\n\n# 极值处理:用1%和99%分位的值做clip\nclip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))\n\n# 将分数映射到分类,这里使用20个分类\nall_wbins(label, 20)\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.HIX","type":"Literal","bound_global_parameter":null},{"name":"drop_na_label","value":"True","type":"Literal","bound_global_parameter":null},{"name":"cast_label_int","value":"True","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":"# #号开始的表示注释\n# 多个特征,每行一个,可以包含基础特征和衍生特征\nvolume_0\n# 过去15个交易日的平均换手率/当天换手率\navg_turn_15/turn_0\n# 当天净主动买入额\nmf_net_amount_xl_0\n# 当天收盘价*当天的平均换手率+过去1个交易日的收盘价*过去1个交易日的平均换手率+过去2个交易日的收盘价*过去2个交易日的平均换手率\nalpha4=close_0*avg_turn_0+close_1*avg_turn_1+close_2*avg_turn_2\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-43","module_id":"BigQuantSpace.stock_ranker_train.stock_ranker_train-v5","parameters":[{"name":"learning_algorithm","value":"排序","type":"Literal","bound_global_parameter":null},{"name":"number_of_leaves","value":30,"type":"Literal","bound_global_parameter":null},{"name":"minimum_docs_per_leaf","value":1000,"type":"Literal","bound_global_parameter":null},{"name":"number_of_trees","value":20,"type":"Literal","bound_global_parameter":null},{"name":"learning_rate","value":0.1,"type":"Literal","bound_global_parameter":null},{"name":"max_bins","value":1023,"type":"Literal","bound_global_parameter":null},{"name":"feature_fraction","value":1,"type":"Literal","bound_global_parameter":null},{"name":"m_lazy_run","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"training_ds","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"},{"name":"features","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"},{"name":"test_ds","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"},{"name":"base_model","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"}],"output_ports":[{"name":"model","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"},{"name":"feature_gains","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"},{"name":"m_lazy_run","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-43"}],"cacheable":true,"seq_num":6,"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-60","module_id":"BigQuantSpace.stock_ranker_predict.stock_ranker_predict-v5","parameters":[{"name":"m_lazy_run","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"model","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60"},{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60"}],"output_ports":[{"name":"predictions","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60"},{"name":"m_lazy_run","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-60"}],"cacheable":true,"seq_num":8,"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-26","type":"Literal","bound_global_parameter":"交易日期"},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"300782.SZA\n605358.SHA\n603290.SHA\n603392.SHA\n601865.SHA\n300759.SZA\n300750.SZA\n300677.SZA\n002607.SZA\n603259.SHA\n300751.SZA\n603613.SHA\n601100.SHA\n300763.SZA\n002568.SZA\n300724.SZA\n603345.SHA\n600763.SHA\n603713.SHA\n300595.SZA\n300014.SZA\n603712.SHA\n300760.SZA\n603317.SHA\n002791.SZA\n601066.SHA\n002985.SZA\n300661.SZA\n300347.SZA\n300777.SZA\n603129.SHA\n300454.SZA\n601888.SHA\n605111.SHA\n603638.SHA\n300850.SZA\n600809.SHA\n002414.SZA\n603893.SHA\n002967.SZA\n600132.SHA\n603605.SHA\n300015.SZA\n603267.SHA\n300012.SZA\n600882.SHA\n300684.SZA\n300390.SZA\n300769.SZA\n\t\n300748.SZA\n000799.SZA\n300767.SZA\n300775.SZA\n603737.SHA\n300601.SZA\n601698.SHA\n300841.SZA\n002975.SZA\n603501.SHA\n300122.SZA\n300677.SZA\n603392.SHA\n002791.SZA\n601865.SHA\n300759.SZA\n002568.SZA\n603613.SHA\n300014.SZA\n601100.SHA\n300763.SZA\n300274.SZA\n601633.SHA\n603501.SHA\n002709.SZA\n603317.SHA\n300661.SZA\n002985.SZA\n600882.SHA\n300598.SZA\n300777.SZA\n300552.SZA\n300346.SZA\n002475.SZA\n605111.SHA\n300850.SZA\n300526.SZA\n601012.SHA\n603893.SHA\n002967.SZA\n000858.SZA\n603267.SHA\n000568.SZA\n603638.SHA\n000708.SZA\n603456.SHA\n000995.SZA\n600399.SHA\n300767.SZA\n300595.SZA\n300347.SZA\n600763.SHA\n300751.SZA\n600316.SHA\n300775.SZA\n603208.SHA\n600862.SHA\n002241.SZA\n002706.SZA\n300390.SZA\n601698.SHA\n002541.SZA\n002607.SZA\n000733.SZA\n000596.SZA\n603345.SHA\n300151.SZA\n300496.SZA\n002705.SZA\n002756.SZA\n603185.SHA\n002850.SZA\n000661.SZA\n002600.SZA\n300724.SZA\n600584.SHA\n002414.SZA\n300223.SZA\n002920.SZA\n603906.SHA\n002714.SZA\n600966.SHA\n300083.SZA\n300601.SZA\n600438.SHA\n002812.SZA\n002459.SZA\n603027.SHA\n300015.SZA\n300763.SZA\n002709.SZA\n688202.SHA\n000422.SZA\n300769.SZA\n300751.SZA\n300343.SZA\n605117.SHA\n300827.SZA\n601633.SHA\n603026.SHA\n002240.SZA\n002326.SZA\n002487.SZA\n000762.SZA\n300432.SZA\n603396.SHA\n300363.SZA\n603985.SHA\n000155.SZA\n002594.SZA\n600399.SHA\n600702.SHA\n300171.SZA\n002176.SZA\n000733.SZA\n300750.SZA\n601127.SHA\n002812.SZA\n603260.SHA\n600610.SHA\n601012.SHA\n003022.SZA\n603127.SHA\n000301.SZA\n002585.SZA\n688198.SHA\n002245.SZA\n300693.SZA\n600096.SHA\n300568.SZA\n300382.SZA\n300443.SZA\n003031.SZA\n605376.SHA\n603806.SHA\n603223.SHA\n688116.SHA\n002529.SZA\n600141.SHA\n600956.SHA\n300035.SZA\n300316.SZA\n002460.SZA\n600110.SHA\n300671.SZA\n002407.SZA\n600532.SHA\n688599.SHA\n002472.SZA\n600499.SHA\n600111.SHA\n600884.SHA\n300696.SZA\n603267.SHA","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":false},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-84","module_id":"BigQuantSpace.dropnan.dropnan-v1","parameters":[],"input_ports":[{"name":"input_data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-84"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-84"}],"cacheable":true,"seq_num":13,"comment":"","comment_collapsed":true},{"node_id":"-86","module_id":"BigQuantSpace.dropnan.dropnan-v1","parameters":[],"input_ports":[{"name":"input_data","node_id":"-86"}],"output_ports":[{"name":"data","node_id":"-86"}],"cacheable":true,"seq_num":14,"comment":"","comment_collapsed":true},{"node_id":"-215","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":90,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-215"},{"name":"features","node_id":"-215"}],"output_ports":[{"name":"data","node_id":"-215"}],"cacheable":true,"seq_num":15,"comment":"","comment_collapsed":true},{"node_id":"-222","module_id":"BigQuantSpace.derived_feature_extractor.derived_feature_extractor-v3","parameters":[{"name":"date_col","value":"date","type":"Literal","bound_global_parameter":null},{"name":"instrument_col","value":"instrument","type":"Literal","bound_global_parameter":null},{"name":"drop_na","value":"False","type":"Literal","bound_global_parameter":null},{"name":"remove_extra_columns","value":"False","type":"Literal","bound_global_parameter":null},{"name":"user_functions","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-222"},{"name":"features","node_id":"-222"}],"output_ports":[{"name":"data","node_id":"-222"}],"cacheable":true,"seq_num":16,"comment":"","comment_collapsed":true},{"node_id":"-231","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":90,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-231"},{"name":"features","node_id":"-231"}],"output_ports":[{"name":"data","node_id":"-231"}],"cacheable":true,"seq_num":17,"comment":"","comment_collapsed":true},{"node_id":"-238","module_id":"BigQuantSpace.derived_feature_extractor.derived_feature_extractor-v3","parameters":[{"name":"date_col","value":"date","type":"Literal","bound_global_parameter":null},{"name":"instrument_col","value":"instrument","type":"Literal","bound_global_parameter":null},{"name":"drop_na","value":"False","type":"Literal","bound_global_parameter":null},{"name":"remove_extra_columns","value":"False","type":"Literal","bound_global_parameter":null},{"name":"user_functions","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-238"},{"name":"features","node_id":"-238"}],"output_ports":[{"name":"data","node_id":"-238"}],"cacheable":true,"seq_num":18,"comment":"","comment_collapsed":true},{"node_id":"-11425","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"# #号开始的表示注释\n# 多个特征,每行一个,可以包含基础特征和衍生特征\n#周线金叉,择时思路\n# macd中的dif上穿dea,金叉,买入\ncond1=sum(ta_macd_dif(close_0,2,4,4),5)>sum(ta_macd_dea(close_0,2,4,4),5)\n# 当天收盘价大于过去25天收盘价的均值\ncond2=(close_0>ta_sma_10_0)&(close_0>ta_sma_20_0)&(close_0>ta_sma_30_0)&(close_0>ta_sma_60_0)\n# 当天股价在收盘时的涨跌停状态(1跌停,2未涨跌停,3涨停)\nprice_limit_status_0\n# 过滤st股票(0:正常股票,1:st,2:*st,11:暂停上市)\ncond4=st_status_0<1","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-11425"}],"output_ports":[{"name":"data","node_id":"-11425"}],"cacheable":true,"seq_num":4,"comment":"择时特征","comment_collapsed":true},{"node_id":"-11430","module_id":"BigQuantSpace.filter.filter-v3","parameters":[{"name":"expr","value":"cond2&cond4","type":"Literal","bound_global_parameter":null},{"name":"output_left_data","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-11430"}],"output_ports":[{"name":"data","node_id":"-11430"},{"name":"left_data","node_id":"-11430"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-3779","module_id":"BigQuantSpace.filter.filter-v3","parameters":[{"name":"expr","value":"cond2&cond4","type":"Literal","bound_global_parameter":null},{"name":"output_left_data","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-3779"}],"output_ports":[{"name":"data","node_id":"-3779"},{"name":"left_data","node_id":"-3779"}],"cacheable":true,"seq_num":10,"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 = 2\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.5\n context.options['hold_days'] = 1\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 \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_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(1) 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 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 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 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\n buy_cash_weights = context.stock_weights\n buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_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 cond1 = data.current(context.symbol(instrument), 'cond1')\n if cond1:\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","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":11,"comment":"","comment_collapsed":true},{"node_id":"-184","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2010-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2018-01-01","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"300782.SZA\n605358.SHA\n603290.SHA\n603392.SHA\n601865.SHA\n300759.SZA\n300750.SZA\n300677.SZA\n002607.SZA\n603259.SHA\n300751.SZA\n603613.SHA\n601100.SHA\n300763.SZA\n002568.SZA\n300724.SZA\n603345.SHA\n600763.SHA\n603713.SHA\n300595.SZA\n300014.SZA\n603712.SHA\n300760.SZA\n603317.SHA\n002791.SZA\n601066.SHA\n002985.SZA\n300661.SZA\n300347.SZA\n300777.SZA\n603129.SHA\n300454.SZA\n601888.SHA\n605111.SHA\n603638.SHA\n300850.SZA\n600809.SHA\n002414.SZA\n603893.SHA\n002967.SZA\n600132.SHA\n603605.SHA\n300015.SZA\n603267.SHA\n300012.SZA\n600882.SHA\n300684.SZA\n300390.SZA\n300769.SZA\n\t\n300748.SZA\n000799.SZA\n300767.SZA\n300775.SZA\n603737.SHA\n300601.SZA\n601698.SHA\n300841.SZA\n002975.SZA\n603501.SHA\n300122.SZA\n300677.SZA\n603392.SHA\n002791.SZA\n601865.SHA\n300759.SZA\n002568.SZA\n603613.SHA\n300014.SZA\n601100.SHA\n300763.SZA\n300274.SZA\n601633.SHA\n603501.SHA\n002709.SZA\n603317.SHA\n300661.SZA\n002985.SZA\n600882.SHA\n300598.SZA\n300777.SZA\n300552.SZA\n300346.SZA\n002475.SZA\n605111.SHA\n300850.SZA\n300526.SZA\n601012.SHA\n603893.SHA\n002967.SZA\n000858.SZA\n603267.SHA\n000568.SZA\n603638.SHA\n000708.SZA\n603456.SHA\n000995.SZA\n600399.SHA\n300767.SZA\n300595.SZA\n300347.SZA\n600763.SHA\n300751.SZA\n600316.SHA\n300775.SZA\n603208.SHA\n600862.SHA\n002241.SZA\n002706.SZA\n300390.SZA\n601698.SHA\n002541.SZA\n002607.SZA\n000733.SZA\n000596.SZA\n603345.SHA\n300151.SZA\n300496.SZA\n002705.SZA\n002756.SZA\n603185.SHA\n002850.SZA\n000661.SZA\n002600.SZA\n300724.SZA\n600584.SHA\n002414.SZA\n300223.SZA\n002920.SZA\n603906.SHA\n002714.SZA\n600966.SHA\n300083.SZA\n300601.SZA\n600438.SHA\n002812.SZA\n002459.SZA\n603027.SHA\n300015.SZA\n300763.SZA\n002709.SZA\n688202.SHA\n000422.SZA\n300769.SZA\n300751.SZA\n300343.SZA\n605117.SHA\n300827.SZA\n601633.SHA\n603026.SHA\n002240.SZA\n002326.SZA\n002487.SZA\n000762.SZA\n300432.SZA\n603396.SHA\n300363.SZA\n603985.SHA\n000155.SZA\n002594.SZA\n600399.SHA\n600702.SHA\n300171.SZA\n002176.SZA\n000733.SZA\n300750.SZA\n601127.SHA\n002812.SZA\n603260.SHA\n600610.SHA\n601012.SHA\n003022.SZA\n603127.SHA\n000301.SZA\n002585.SZA\n688198.SHA\n002245.SZA\n300693.SZA\n600096.SHA\n300568.SZA\n300382.SZA\n300443.SZA\n003031.SZA\n605376.SHA\n603806.SHA\n603223.SHA\n688116.SHA\n002529.SZA\n600141.SHA\n600956.SHA\n300035.SZA\n300316.SZA\n002460.SZA\n600110.SHA\n300671.SZA\n002407.SZA\n600532.SHA\n688599.SHA\n002472.SZA\n600499.SHA\n600111.SHA\n600884.SHA\n300696.SZA\n603267.SHA","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-184"}],"output_ports":[{"name":"data","node_id":"-184"}],"cacheable":true,"seq_num":27,"comment":"","comment_collapsed":true},{"node_id":"-148","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nname\ninstrument","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":1,"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":12,"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":19,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-15' Position='70,183,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-24' Position='743,-98,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-43' Position='661,607,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-53' Position='249,375,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-60' Position='853,683,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-62' Position='1092,-4,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-84' Position='424,523,200,200'/><node_position Node='-86' Position='1064,575,200,200'/><node_position Node='-215' Position='399,162,200,200'/><node_position Node='-222' Position='385,280,200,200'/><node_position Node='-231' Position='1086,184,200,200'/><node_position Node='-238' Position='1078,303,200,200'/><node_position Node='-11425' Position='633,40,200,200'/><node_position Node='-11430' Position='378,455,200,200'/><node_position Node='-3779' Position='1064,439,200,200'/><node_position Node='-1918' Position='944,917,200,200'/><node_position Node='-184' Position='168,23,200,200'/><node_position Node='-148' Position='1473,362,200,200'/><node_position Node='-224' Position='1442,466,200,200'/><node_position Node='-189' Position='1058,817,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [29]:
    # 本代码由可视化策略环境自动生成 2021年12月27日 17:07
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:初始化函数,只执行一次
    def m11_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 = 2
        # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[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.5
        context.options['hold_days'] = 1
        
        # 这一段感觉是在为盘前准备函数写的,当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 m11_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]
        
        # 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_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(1) 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:        
                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!=[]:  
            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 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
        buy_cash_weights = context.stock_weights
        buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_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:
                cond1 = data.current(context.symbol(instrument), 'cond1')
                if cond1:
                    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 m11_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'])
    
    def m11_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
    
    m3 = M.input_features.v1(
        features="""# #号开始的表示注释
    # 多个特征,每行一个,可以包含基础特征和衍生特征
    volume_0
    # 过去15个交易日的平均换手率/当天换手率
    avg_turn_15/turn_0
    # 当天净主动买入额
    mf_net_amount_xl_0
    # 当天收盘价*当天的平均换手率+过去1个交易日的收盘价*过去1个交易日的平均换手率+过去2个交易日的收盘价*过去2个交易日的平均换手率
    alpha4=close_0*avg_turn_0+close_1*avg_turn_1+close_2*avg_turn_2
    """
    )
    
    m4 = M.input_features.v1(
        features_ds=m3.data,
        features="""# #号开始的表示注释
    # 多个特征,每行一个,可以包含基础特征和衍生特征
    #周线金叉,择时思路
    # macd中的dif上穿dea,金叉,买入
    cond1=sum(ta_macd_dif(close_0,2,4,4),5)>sum(ta_macd_dea(close_0,2,4,4),5)
    # 当天收盘价大于过去25天收盘价的均值
    cond2=(close_0>ta_sma_10_0)&(close_0>ta_sma_20_0)&(close_0>ta_sma_30_0)&(close_0>ta_sma_60_0)
    # 当天股价在收盘时的涨跌停状态(1跌停,2未涨跌停,3涨停)
    price_limit_status_0
    # 过滤st股票(0:正常股票,1:st,2:*st,11:暂停上市)
    cond4=st_status_0<1"""
    )
    
    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-26'),
        market='CN_STOCK_A',
        instrument_list="""300782.SZA
    605358.SHA
    603290.SHA
    603392.SHA
    601865.SHA
    300759.SZA
    300750.SZA
    300677.SZA
    002607.SZA
    603259.SHA
    300751.SZA
    603613.SHA
    601100.SHA
    300763.SZA
    002568.SZA
    300724.SZA
    603345.SHA
    600763.SHA
    603713.SHA
    300595.SZA
    300014.SZA
    603712.SHA
    300760.SZA
    603317.SHA
    002791.SZA
    601066.SHA
    002985.SZA
    300661.SZA
    300347.SZA
    300777.SZA
    603129.SHA
    300454.SZA
    601888.SHA
    605111.SHA
    603638.SHA
    300850.SZA
    600809.SHA
    002414.SZA
    603893.SHA
    002967.SZA
    600132.SHA
    603605.SHA
    300015.SZA
    603267.SHA
    300012.SZA
    600882.SHA
    300684.SZA
    300390.SZA
    300769.SZA
    	
    300748.SZA
    000799.SZA
    300767.SZA
    300775.SZA
    603737.SHA
    300601.SZA
    601698.SHA
    300841.SZA
    002975.SZA
    603501.SHA
    300122.SZA
    300677.SZA
    603392.SHA
    002791.SZA
    601865.SHA
    300759.SZA
    002568.SZA
    603613.SHA
    300014.SZA
    601100.SHA
    300763.SZA
    300274.SZA
    601633.SHA
    603501.SHA
    002709.SZA
    603317.SHA
    300661.SZA
    002985.SZA
    600882.SHA
    300598.SZA
    300777.SZA
    300552.SZA
    300346.SZA
    002475.SZA
    605111.SHA
    300850.SZA
    300526.SZA
    601012.SHA
    603893.SHA
    002967.SZA
    000858.SZA
    603267.SHA
    000568.SZA
    603638.SHA
    000708.SZA
    603456.SHA
    000995.SZA
    600399.SHA
    300767.SZA
    300595.SZA
    300347.SZA
    600763.SHA
    300751.SZA
    600316.SHA
    300775.SZA
    603208.SHA
    600862.SHA
    002241.SZA
    002706.SZA
    300390.SZA
    601698.SHA
    002541.SZA
    002607.SZA
    000733.SZA
    000596.SZA
    603345.SHA
    300151.SZA
    300496.SZA
    002705.SZA
    002756.SZA
    603185.SHA
    002850.SZA
    000661.SZA
    002600.SZA
    300724.SZA
    600584.SHA
    002414.SZA
    300223.SZA
    002920.SZA
    603906.SHA
    002714.SZA
    600966.SHA
    300083.SZA
    300601.SZA
    600438.SHA
    002812.SZA
    002459.SZA
    603027.SHA
    300015.SZA
    300763.SZA
    002709.SZA
    688202.SHA
    000422.SZA
    300769.SZA
    300751.SZA
    300343.SZA
    605117.SHA
    300827.SZA
    601633.SHA
    603026.SHA
    002240.SZA
    002326.SZA
    002487.SZA
    000762.SZA
    300432.SZA
    603396.SHA
    300363.SZA
    603985.SHA
    000155.SZA
    002594.SZA
    600399.SHA
    600702.SHA
    300171.SZA
    002176.SZA
    000733.SZA
    300750.SZA
    601127.SHA
    002812.SZA
    603260.SHA
    600610.SHA
    601012.SHA
    003022.SZA
    603127.SHA
    000301.SZA
    002585.SZA
    688198.SHA
    002245.SZA
    300693.SZA
    600096.SHA
    300568.SZA
    300382.SZA
    300443.SZA
    003031.SZA
    605376.SHA
    603806.SHA
    603223.SHA
    688116.SHA
    002529.SZA
    600141.SHA
    600956.SHA
    300035.SZA
    300316.SZA
    002460.SZA
    600110.SHA
    300671.SZA
    002407.SZA
    600532.SHA
    688599.SHA
    002472.SZA
    600499.SHA
    600111.SHA
    600884.SHA
    300696.SZA
    603267.SHA""",
        max_count=0
    )
    
    m17 = M.general_feature_extractor.v7(
        instruments=m9.data,
        features=m4.data,
        start_date='',
        end_date='',
        before_start_days=90
    )
    
    m18 = M.derived_feature_extractor.v3(
        input_data=m17.data,
        features=m4.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=False,
        remove_extra_columns=False
    )
    
    m10 = M.filter.v3(
        input_data=m18.data,
        expr='cond2&cond4',
        output_left_data=False
    )
    
    m14 = M.dropnan.v1(
        input_data=m10.data
    )
    
    m27 = M.instruments.v2(
        start_date='2010-01-01',
        end_date='2018-01-01',
        market='CN_STOCK_A',
        instrument_list="""300782.SZA
    605358.SHA
    603290.SHA
    603392.SHA
    601865.SHA
    300759.SZA
    300750.SZA
    300677.SZA
    002607.SZA
    603259.SHA
    300751.SZA
    603613.SHA
    601100.SHA
    300763.SZA
    002568.SZA
    300724.SZA
    603345.SHA
    600763.SHA
    603713.SHA
    300595.SZA
    300014.SZA
    603712.SHA
    300760.SZA
    603317.SHA
    002791.SZA
    601066.SHA
    002985.SZA
    300661.SZA
    300347.SZA
    300777.SZA
    603129.SHA
    300454.SZA
    601888.SHA
    605111.SHA
    603638.SHA
    300850.SZA
    600809.SHA
    002414.SZA
    603893.SHA
    002967.SZA
    600132.SHA
    603605.SHA
    300015.SZA
    603267.SHA
    300012.SZA
    600882.SHA
    300684.SZA
    300390.SZA
    300769.SZA
    	
    300748.SZA
    000799.SZA
    300767.SZA
    300775.SZA
    603737.SHA
    300601.SZA
    601698.SHA
    300841.SZA
    002975.SZA
    603501.SHA
    300122.SZA
    300677.SZA
    603392.SHA
    002791.SZA
    601865.SHA
    300759.SZA
    002568.SZA
    603613.SHA
    300014.SZA
    601100.SHA
    300763.SZA
    300274.SZA
    601633.SHA
    603501.SHA
    002709.SZA
    603317.SHA
    300661.SZA
    002985.SZA
    600882.SHA
    300598.SZA
    300777.SZA
    300552.SZA
    300346.SZA
    002475.SZA
    605111.SHA
    300850.SZA
    300526.SZA
    601012.SHA
    603893.SHA
    002967.SZA
    000858.SZA
    603267.SHA
    000568.SZA
    603638.SHA
    000708.SZA
    603456.SHA
    000995.SZA
    600399.SHA
    300767.SZA
    300595.SZA
    300347.SZA
    600763.SHA
    300751.SZA
    600316.SHA
    300775.SZA
    603208.SHA
    600862.SHA
    002241.SZA
    002706.SZA
    300390.SZA
    601698.SHA
    002541.SZA
    002607.SZA
    000733.SZA
    000596.SZA
    603345.SHA
    300151.SZA
    300496.SZA
    002705.SZA
    002756.SZA
    603185.SHA
    002850.SZA
    000661.SZA
    002600.SZA
    300724.SZA
    600584.SHA
    002414.SZA
    300223.SZA
    002920.SZA
    603906.SHA
    002714.SZA
    600966.SHA
    300083.SZA
    300601.SZA
    600438.SHA
    002812.SZA
    002459.SZA
    603027.SHA
    300015.SZA
    300763.SZA
    002709.SZA
    688202.SHA
    000422.SZA
    300769.SZA
    300751.SZA
    300343.SZA
    605117.SHA
    300827.SZA
    601633.SHA
    603026.SHA
    002240.SZA
    002326.SZA
    002487.SZA
    000762.SZA
    300432.SZA
    603396.SHA
    300363.SZA
    603985.SHA
    000155.SZA
    002594.SZA
    600399.SHA
    600702.SHA
    300171.SZA
    002176.SZA
    000733.SZA
    300750.SZA
    601127.SHA
    002812.SZA
    603260.SHA
    600610.SHA
    601012.SHA
    003022.SZA
    603127.SHA
    000301.SZA
    002585.SZA
    688198.SHA
    002245.SZA
    300693.SZA
    600096.SHA
    300568.SZA
    300382.SZA
    300443.SZA
    003031.SZA
    605376.SHA
    603806.SHA
    603223.SHA
    688116.SHA
    002529.SZA
    600141.SHA
    600956.SHA
    300035.SZA
    300316.SZA
    002460.SZA
    600110.SHA
    300671.SZA
    002407.SZA
    600532.SHA
    688599.SHA
    002472.SZA
    600499.SHA
    600111.SHA
    600884.SHA
    300696.SZA
    603267.SHA""",
        max_count=0
    )
    
    m15 = M.general_feature_extractor.v7(
        instruments=m27.data,
        features=m4.data,
        start_date='',
        end_date='',
        before_start_days=90
    )
    
    m16 = M.derived_feature_extractor.v3(
        input_data=m15.data,
        features=m4.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=False,
        remove_extra_columns=False
    )
    
    m2 = M.advanced_auto_labeler.v2(
        instruments=m27.data,
        label_expr="""# #号开始的表示注释
    # 0. 每行一个,顺序执行,从第二个开始,可以使用label字段
    # 1. 可用数据字段见 https://bigquant.com/docs/develop/datasource/deprecated/history_data.html
    #   添加benchmark_前缀,可使用对应的benchmark数据
    # 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/develop/bigexpr/usage.html>`_
    
    # 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)
    shift(close, -5) / shift(open, -1)
    
    # 极值处理:用1%和99%分位的值做clip
    clip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))
    
    # 将分数映射到分类,这里使用20个分类
    all_wbins(label, 20)
    
    # 过滤掉一字涨停的情况 (设置label为NaN,在后续处理和训练中会忽略NaN的label)
    where(shift(high, -1) == shift(low, -1), NaN, label)
    """,
        start_date='',
        end_date='',
        benchmark='000300.HIX',
        drop_na_label=True,
        cast_label_int=True
    )
    
    m7 = M.join.v3(
        data1=m2.data,
        data2=m16.data,
        on='date,instrument',
        how='inner',
        sort=False
    )
    
    m5 = M.filter.v3(
        input_data=m7.data,
        expr='cond2&cond4',
        output_left_data=False
    )
    
    m13 = M.dropnan.v1(
        input_data=m5.data
    )
    
    m6 = M.stock_ranker_train.v5(
        training_ds=m13.data,
        features=m3.data,
        learning_algorithm='排序',
        number_of_leaves=30,
        minimum_docs_per_leaf=1000,
        number_of_trees=20,
        learning_rate=0.1,
        max_bins=1023,
        feature_fraction=1,
        m_lazy_run=False
    )
    
    m8 = M.stock_ranker_predict.v5(
        model=m6.model,
        data=m14.data,
        m_lazy_run=False
    )
    
    m1 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    name
    instrument"""
    )
    
    m12 = M.use_datasource.v1(
        instruments=m9.data,
        features=m1.data,
        datasource_id='instruments_CN_STOCK_A',
        start_date='',
        end_date=''
    )
    
    m19 = M.join.v3(
        data1=m8.predictions,
        data2=m12.data,
        on='date',
        how='left',
        sort=True
    )
    
    m11 = M.trade.v4(
        instruments=m9.data,
        options_data=m19.data,
        start_date='',
        end_date='',
        initialize=m11_initialize_bigquant_run,
        handle_data=m11_handle_data_bigquant_run,
        prepare=m11_prepare_bigquant_run,
        before_trading_start=m11_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=''
    )
    
    设置测试数据集,查看训练迭代过程的NDCG
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-f31fd28353b64a34899d2963d1d217c1"}/bigcharts-data-end
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-29-9c19775615ea> in <module>
        735 )
        736 
    --> 737 m11 = M.trade.v4(
        738     instruments=m9.data,
        739     options_data=m19.data,
    
    <ipython-input-29-9c19775615ea> in m11_handle_data_bigquant_run(context, data)
        114     banned_list = stock_sold
        115     buy_cash_weights = context.stock_weights
    --> 116     buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_weights)])
        117     #buy_instruments=[k for k in list(ranker_prediction.instrument) if k not in banned_list][:len(buy_cash_weights)]
        118     max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
    
    AttributeError: 'DataFrame' object has no attribute 'instrument'