{"description":"实验创建于2017/8/26","graph":{"edges":[{"to_node_id":"-647:features_ds","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-327:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-231:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-9185:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"},{"to_node_id":"-327:predict_ds","from_node_id":"-86:data"},{"to_node_id":"-238:input_data","from_node_id":"-231:data"},{"to_node_id":"-231:features","from_node_id":"-647:data"},{"to_node_id":"-238:features","from_node_id":"-647:data"},{"to_node_id":"-9185:options_data","from_node_id":"-216:sorted_data"},{"to_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:features_ds","from_node_id":"-8932:data"},{"to_node_id":"-302:input_1","from_node_id":"-173:data"},{"to_node_id":"-86:input_data","from_node_id":"-302:data_1"},{"to_node_id":"-216:input_ds","from_node_id":"-327:predictions"}],"nodes":[{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"shift(beta_csi500_90_0/group_sum(industry_sw_level2_0, beta_csi500_90_0-0.5),-5)\nshift(correlation(log(volume_0),abs(return_0-1),5),-5)\nshift(mean(mf_net_amount_xl_0,15),-5)\nshift(sum(mf_net_amount_xl_0,12)/market_cap_float_0,-5)\nshift(ta_willr_14_0,-5)\nshift(rank(((close_0-open_0)/open_0),6),-5)\n\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,"x":822,"y":-49},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2024-10-07","type":"Literal","bound_global_parameter":"交易日期"},{"name":"end_date","value":"2025-12-19","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":false,"x":678,"y":782},{"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,"x":1249,"y":559},{"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":"120","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,"x":1466,"y":135},{"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,"x":1570,"y":277},{"node_id":"-647","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\n \n fangb=ta_ema(((2*close_0+high_0+low_0)/4-ts_min(low_0, 34))/(ts_max(high_0, 34)-ts_min(low_0, 34))*100, 8)\nb1=ta_ema(fangb, 5)\n c1=fangb-b1 \n d1= ta_ema((sum(close_0-where(high_0<= close_1, high_0, close_1),7)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 7))*14*28+sum(close_0-where(high_0<= close_1, high_0, close_1),14)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 14))*7*28+sum(close_0-where(high_0<= close_1, high_0, close_1),28)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 28))*7*14)*100/(7*14+7*28+14*28), 6)\n\n#{STICKLINE(防线B-B1>0,防线B,B1,8,1),COLOR00FF00;}\n#妙趣横生:-一进一出,COLORRED;\n#{STICKLINE(防线B-B1<0,防线B,B1,8,1),COLORRED;}\n#卖出:(REF(一进一出,1)>0 AND 一进一出<=0) OR (一进一出<1 AND 一进一出>=0 AND C<O),COLORRED;\n\n#DRAWICON(卖出,36,1);\n#STICKLINE(卖出,0,28,1,0),COLORRED;\n#DRAWTEXT(卖出,30,'卖'),COLORMAGENTA;\n#买入:卖出=0 AND REF(一进一出,1)<0 AND 一进一出>0,COLORRED; \n# mairu= c1=0 shift(c1,1)<0 c1>0 \n\n#{STICKLINE(防线B-B1>0,防线B,B1,8,1),COLOR00FF00;}\n#妙趣横生:-一进一出,COLORRED;\n#{STICKLINE(防线B-B1<0,防线B,B1,8,1),COLORRED;}\n#卖出:(REF(一进一出,1)>0 AND 一进一出<=0) OR (一进一出<1 AND 一进一出>=0 AND C<O),COLORRED;\nmaichu1= where((shift(c1, 1)>0) & (((c1 >0))|(c1==0)),1,0)\nmaichu2=where((c1<1)&(((c1 >0))|(c1==0))&(close_1-close_0<0), 1, 0)\n_total_count=sum(maichu1+maichu1, 1)\n\n#DRAWICON(卖出,36,1);\n#STICKLINE(卖出,0,28,1,0),COLORRED;\n#DRAWTEXT(卖出,30,'卖'),COLORMAGENTA;\n#买入:卖出=0 AND REF(一进一出,1)<0 AND 一进一出>0,COLORRED; \n# mairu= c1=0 shift(c1,1)<0 c1>0 \ncon = where((c1.shift(1) < 0) ,1,0)\ncon3=where(((c1 >0))|(c1==0), 1, 0) \ntotal_count=con+con3\ncon2= where((_total_count<1), 1,0)\ntotal_count2= sum(con2,1)\n\n\n\n# 个股最近1日收益率 return_1 close_0/shift(close_0,1)\n# 大单净流入占比最近5日平均 mean(mf_net_pct_l_0,5) 收盘价的5日简单移动平均值 ta_sma_5_0 &(low_0<mean(close_0, 20)\n#收盘价的5日指数移动平均值 因子分析: ta_ema_5_0 过去5个交易日的平均换手率 avg_turn_5 close_0>mean(close_0, 15))&(close_0>mean(close_0, 10))&(close_0>mean(close_0, 5))&\n# 小单净流入占比最近5日平均 mean(mf_net_pct_s_0,5) 主力净流入占比最近5日平均值 mean(mf_net_pct_main_0,5) buy_cond_1==1&buy_cond_2==1&buy_cond_3==1&a3>0\n #收盘突破所有短期均线,收盘表现强势\nbuy_cond_1 = where((close_0<mean(close_0, 15))&(close_0<mean(close_0, 10))&(close_0<mean(close_0, 5))&(close_0<mean(close_0, -5)),1,0)\n#底部冲短线均线下方开始反弹\nbuy_cond_2 = where((low_0<mean(close_0, 5))&(low_0<mean(close_0, 10)), 1, 0)\n#确保当天为阳\nbuy_cond_3 = where((close_0>open_0), 1, 0)\n#资金流因子,近几天大单相对流通市值\na3 = sum(mf_net_amount_xl_0,10)/market_cap_float_0","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-647"}],"output_ports":[{"name":"data","node_id":"-647"}],"cacheable":true,"seq_num":4,"comment":"这里放置要过滤的条件","comment_collapsed":true,"x":908,"y":174},{"node_id":"-9185","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 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)\n # 设置每只股票占用的最大资金比例\n context.max_cash_per_instrument = 0.02\n context.options['hold_days'] = 100\n context.options['hold_days1'] = 10\n context.options['hold_days2'] = 50\n\n ","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\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 is_staging1 = context.trading_day_index < context.options['hold_days2']\n cash_avg = context.portfolio.portfolio_value / context.options['hold_days1']\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 \n # 赚9%且为可交易状态就止盈\n if stock_market_price/stock_cost-1>=2 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\n if len(current_stopwin_stock)>0:\n \n stock_sold += current_stopwin_stock\n\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(100) 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 \n stock_sold += current_stopdays_stock\n #------------------------- END:持有固定天数卖出-----------------------\n\n \n # 3. 生成轮仓卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰\n if not is_staging1 and cash_for_sell > 0:\n instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(\n lambda x: x in positions)])))\n \n for instrument in instruments:\n # 如果资金够了就不卖出了\n if cash_for_sell <= 0:\n break\n #防止多个止损条件同时满足,出现多次卖出产生空单\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 import random\n\n def select_stocks(ranker_prediction):\n \n # 选择前50名股票\n top_50_stocks = ranker_prediction.sort_values('position', ascending=False).head(20)\n # 随机选择2只股票\n selected_stocks = top_50_stocks.sample(n=2)\n return selected_stocks\n selected_stocks = select_stocks(ranker_prediction)\n\n # 计算所有禁止买入的股票池\n banned_list = stock_sold\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 context.order_value(context.symbol(instrument), cash)\n \n\n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"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 #判断一下如果当日涨停,则取消卖单\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","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":"100000000","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":"000300.SHA","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-9185"},{"name":"options_data","node_id":"-9185"},{"name":"history_ds","node_id":"-9185"},{"name":"benchmark_ds","node_id":"-9185"},{"name":"trading_calendar","node_id":"-9185"}],"output_ports":[{"name":"raw_perf","node_id":"-9185"}],"cacheable":false,"seq_num":20,"comment":"","comment_collapsed":true,"x":878,"y":1221},{"node_id":"-216","module_id":"BigQuantSpace.sort.sort-v4","parameters":[{"name":"sort_by","value":"prediction","type":"Literal","bound_global_parameter":null},{"name":"group_by","value":"date","type":"Literal","bound_global_parameter":null},{"name":"keep_columns","value":"--","type":"Literal","bound_global_parameter":null},{"name":"ascending","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_ds","node_id":"-216"},{"name":"sort_by_ds","node_id":"-216"}],"output_ports":[{"name":"sorted_data","node_id":"-216"}],"cacheable":true,"seq_num":21,"comment":"","comment_collapsed":true,"x":1028,"y":930},{"node_id":"-8932","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"shift(beta_csi500_90_0/group_sum(industry_sw_level2_0, beta_csi500_90_0-0.5),-5)\nshift(correlation(log(volume_0),abs(return_0-1),5),-5)\nshift(mean(mf_net_amount_xl_0,15),-5)\nshift(sum(mf_net_amount_xl_0,12)/market_cap_float_0,-5)\nshift(ta_willr_14_0,-5)","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-8932"}],"output_ports":[{"name":"data","node_id":"-8932"}],"cacheable":true,"seq_num":25,"comment":"","comment_collapsed":true,"x":797,"y":-212},{"node_id":"-173","module_id":"BigQuantSpace.chinaa_stock_filter.chinaa_stock_filter-v1","parameters":[{"name":"index_constituent_cond","value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22displayValue%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E4%B8%8A%E8%AF%8150%22%2C%22displayValue%22%3A%22%E4%B8%8A%E8%AF%8150%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%B2%AA%E6%B7%B1300%22%2C%22displayValue%22%3A%22%E6%B2%AA%E6%B7%B1300%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%AD%E8%AF%81500%22%2C%22displayValue%22%3A%22%E4%B8%AD%E8%AF%81500%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%AD%E8%AF%81800%22%2C%22displayValue%22%3A%22%E4%B8%AD%E8%AF%81800%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%8A%E8%AF%81180%22%2C%22displayValue%22%3A%22%E4%B8%8A%E8%AF%81180%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%AD%E8%AF%81100%22%2C%22displayValue%22%3A%22%E4%B8%AD%E8%AF%81100%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%B7%B1%E8%AF%81100%22%2C%22displayValue%22%3A%22%E6%B7%B1%E8%AF%81100%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%AD%E8%AF%811000%22%2C%22displayValue%22%3A%22%E4%B8%AD%E8%AF%811000%22%2C%22selected%22%3Afalse%7D%5D%7D","type":"Literal","bound_global_parameter":null},{"name":"board_cond","value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22displayValue%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%B8%8A%E8%AF%81%E4%B8%BB%E6%9D%BF%22%2C%22displayValue%22%3A%22%E4%B8%8A%E8%AF%81%E4%B8%BB%E6%9D%BF%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E6%B7%B1%E8%AF%81%E4%B8%BB%E6%9D%BF%22%2C%22displayValue%22%3A%22%E6%B7%B1%E8%AF%81%E4%B8%BB%E6%9D%BF%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E5%88%9B%E4%B8%9A%E6%9D%BF%22%2C%22displayValue%22%3A%22%E5%88%9B%E4%B8%9A%E6%9D%BF%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E7%A7%91%E5%88%9B%E6%9D%BF%22%2C%22displayValue%22%3A%22%E7%A7%91%E5%88%9B%E6%9D%BF%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%8C%97%E4%BA%A4%E6%89%80%22%2C%22displayValue%22%3A%22%E5%8C%97%E4%BA%A4%E6%89%80%22%2C%22selected%22%3Afalse%7D%5D%7D","type":"Literal","bound_global_parameter":null},{"name":"industry_cond","value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22displayValue%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22%E4%BA%A4%E9%80%9A%E8%BF%90%E8%BE%93%22%2C%22displayValue%22%3A%22%E4%BA%A4%E9%80%9A%E8%BF%90%E8%BE%93%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%BC%91%E9%97%B2%E6%9C%8D%E5%8A%A1%22%2C%22displayValue%22%3A%22%E4%BC%91%E9%97%B2%E6%9C%8D%E5%8A%A1%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E4%BC%A0%E5%AA%92%2F%E4%BF%A1%E6%81%AF%E6%9C%8D%E5%8A%A1%22%2C%22displayValue%22%3A%22%E4%BC%A0%E5%AA%92%2F%E4%BF%A1%E6%81%AF%E6%9C%8D%E5%8A%A1%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%85%AC%E7%94%A8%E4%BA%8B%E4%B8%9A%22%2C%22displayValue%22%3A%22%E5%85%AC%E7%94%A8%E4%BA%8B%E4%B8%9A%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%86%9C%E6%9E%97%E7%89%A7%E6%B8%94%22%2C%22displayValue%22%3A%22%E5%86%9C%E6%9E%97%E7%89%A7%E6%B8%94%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%8C%96%E5%B7%A5%22%2C%22displayValue%22%3A%22%E5%8C%96%E5%B7%A5%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%8C%BB%E8%8D%AF%E7%94%9F%E7%89%A9%22%2C%22displayValue%22%3A%22%E5%8C%BB%E8%8D%AF%E7%94%9F%E7%89%A9%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%95%86%E4%B8%9A%E8%B4%B8%E6%98%93%22%2C%22displayValue%22%3A%22%E5%95%86%E4%B8%9A%E8%B4%B8%E6%98%93%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%9B%BD%E9%98%B2%E5%86%9B%E5%B7%A5%22%2C%22displayValue%22%3A%22%E5%9B%BD%E9%98%B2%E5%86%9B%E5%B7%A5%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%AE%B6%E7%94%A8%E7%94%B5%E5%99%A8%22%2C%22displayValue%22%3A%22%E5%AE%B6%E7%94%A8%E7%94%B5%E5%99%A8%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%BB%BA%E7%AD%91%E6%9D%90%E6%96%99%2F%E5%BB%BA%E7%AD%91%E5%BB%BA%E6%9D%90%22%2C%22displayValue%22%3A%22%E5%BB%BA%E7%AD%91%E6%9D%90%E6%96%99%2F%E5%BB%BA%E7%AD%91%E5%BB%BA%E6%9D%90%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E5%BB%BA%E7%AD%91%E8%A3%85%E9%A5%B0%22%2C%22displayValue%22%3A%22%E5%BB%BA%E7%AD%91%E8%A3%85%E9%A5%B0%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%88%BF%E5%9C%B0%E4%BA%A7%22%2C%22displayValue%22%3A%22%E6%88%BF%E5%9C%B0%E4%BA%A7%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E%22%2C%22displayValue%22%3A%22%E6%9C%89%E8%89%B2%E9%87%91%E5%B1%9E%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%9C%BA%E6%A2%B0%E8%AE%BE%E5%A4%87%22%2C%22displayValue%22%3A%22%E6%9C%BA%E6%A2%B0%E8%AE%BE%E5%A4%87%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%B1%BD%E8%BD%A6%2F%E4%BA%A4%E8%BF%90%E8%AE%BE%E5%A4%87%22%2C%22displayValue%22%3A%22%E6%B1%BD%E8%BD%A6%2F%E4%BA%A4%E8%BF%90%E8%AE%BE%E5%A4%87%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E7%94%B5%E5%AD%90%22%2C%22displayValue%22%3A%22%E7%94%B5%E5%AD%90%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E7%94%B5%E6%B0%94%E8%AE%BE%E5%A4%87%22%2C%22displayValue%22%3A%22%E7%94%B5%E6%B0%94%E8%AE%BE%E5%A4%87%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E7%BA%BA%E7%BB%87%E6%9C%8D%E8%A3%85%22%2C%22displayValue%22%3A%22%E7%BA%BA%E7%BB%87%E6%9C%8D%E8%A3%85%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E7%BB%BC%E5%90%88%22%2C%22displayValue%22%3A%22%E7%BB%BC%E5%90%88%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E8%AE%A1%E7%AE%97%E6%9C%BA%22%2C%22displayValue%22%3A%22%E8%AE%A1%E7%AE%97%E6%9C%BA%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E8%BD%BB%E5%B7%A5%E5%88%B6%E9%80%A0%22%2C%22displayValue%22%3A%22%E8%BD%BB%E5%B7%A5%E5%88%B6%E9%80%A0%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%80%9A%E4%BF%A1%22%2C%22displayValue%22%3A%22%E9%80%9A%E4%BF%A1%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%87%87%E6%8E%98%22%2C%22displayValue%22%3A%22%E9%87%87%E6%8E%98%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%92%A2%E9%93%81%22%2C%22displayValue%22%3A%22%E9%92%A2%E9%93%81%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%93%B6%E8%A1%8C%22%2C%22displayValue%22%3A%22%E9%93%B6%E8%A1%8C%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%9D%9E%E9%93%B6%E9%87%91%E8%9E%8D%22%2C%22displayValue%22%3A%22%E9%9D%9E%E9%93%B6%E9%87%91%E8%9E%8D%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%A3%9F%E5%93%81%E9%A5%AE%E6%96%99%22%2C%22displayValue%22%3A%22%E9%A3%9F%E5%93%81%E9%A5%AE%E6%96%99%22%2C%22selected%22%3Afalse%7D%5D%7D","type":"Literal","bound_global_parameter":null},{"name":"st_cond","value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22displayValue%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%AD%A3%E5%B8%B8%22%2C%22displayValue%22%3A%22%E6%AD%A3%E5%B8%B8%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22ST%22%2C%22displayValue%22%3A%22ST%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22*ST%22%2C%22displayValue%22%3A%22*ST%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E6%9A%82%E5%81%9C%E4%B8%8A%E5%B8%82%22%2C%22displayValue%22%3A%22%E6%9A%82%E5%81%9C%E4%B8%8A%E5%B8%82%22%2C%22selected%22%3Afalse%7D%5D%7D","type":"Literal","bound_global_parameter":null},{"name":"delist_cond","value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22displayValue%22%3A%22%E5%85%A8%E9%83%A8%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%80%80%E5%B8%82%22%2C%22displayValue%22%3A%22%E9%80%80%E5%B8%82%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22%E9%9D%9E%E9%80%80%E5%B8%82%22%2C%22displayValue%22%3A%22%E9%9D%9E%E9%80%80%E5%B8%82%22%2C%22selected%22%3Atrue%7D%5D%7D","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":"-173"}],"output_ports":[{"name":"data","node_id":"-173"},{"name":"left_data","node_id":"-173"}],"cacheable":true,"seq_num":29,"comment":"","comment_collapsed":true,"x":1464,"y":377},{"node_id":"-302","module_id":"BigQuantSpace.filtet_st_stock_tomo.filtet_st_stock_tomo-v3","parameters":[],"input_ports":[{"name":"input_1","node_id":"-302"}],"output_ports":[{"name":"data_1","node_id":"-302"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true,"x":1715,"y":423},{"node_id":"-327","module_id":"BigQuantSpace.xgboost.xgboost-v1","parameters":[{"name":"num_boost_round","value":"150","type":"Literal","bound_global_parameter":null},{"name":"objective","value":"排序(map)","type":"Literal","bound_global_parameter":null},{"name":"booster","value":"gbtree","type":"Literal","bound_global_parameter":null},{"name":"max_depth","value":"6","type":"Literal","bound_global_parameter":null},{"name":"key_cols","value":"date,instrument","type":"Literal","bound_global_parameter":null},{"name":"group_col","value":"date","type":"Literal","bound_global_parameter":null},{"name":"nthread","value":1,"type":"Literal","bound_global_parameter":null},{"name":"n_gpus","value":-1,"type":"Literal","bound_global_parameter":null},{"name":"other_train_parameters","value":"{}","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"training_ds","node_id":"-327"},{"name":"features","node_id":"-327"},{"name":"model","node_id":"-327"},{"name":"predict_ds","node_id":"-327"}],"output_ports":[{"name":"output_model","node_id":"-327"},{"name":"predictions","node_id":"-327"}],"cacheable":true,"seq_num":6,"comment":"","comment_collapsed":true,"x":652,"y":646}],"node_layout":"<node_postions><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-24' Position='822,-49,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-62' Position='678,782,200,200'/><node_position Node='-86' Position='1249,559,200,200'/><node_position Node='-231' Position='1466,135,200,200'/><node_position Node='-238' Position='1570,277,200,200'/><node_position Node='-647' Position='908,174,200,200'/><node_position Node='-9185' Position='878,1221,200,200'/><node_position Node='-216' Position='1028,930,200,200'/><node_position Node='-8932' Position='797,-212,200,200'/><node_position Node='-173' Position='1464,377,200,200'/><node_position Node='-302' Position='1715,423,200,200'/><node_position Node='-327' Position='652,646,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [1]:
    # 本代码由可视化策略环境自动生成 2025年1月26日 11:56
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
     
    # 显式导入 BigQuant 相关 SDK 模块
    from bigdatasource.api import DataSource
    from bigdata.api.datareader import D
    from biglearning.api import M
    from biglearning.api import tools as T
    from biglearning.module2.common.data import Outputs
     
    import pandas as pd
    import numpy as np
    import math
    import warnings
    import datetime
     
    from zipline.finance.commission import PerOrder
    from zipline.api import get_open_orders
    from zipline.api import symbol
     
    from bigtrader.sdk import *
    from bigtrader.utils.my_collections import NumPyDeque
    from bigtrader.constant import OrderType
    from bigtrader.constant import Direction
    
    # <aistudiograph>
    
    # @param(id="m20", name="initialize")
    # 回测引擎:初始化函数,只执行一次
    def m20_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)])
        
        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)
        # 设置每只股票占用的最大资金比例
        context.max_cash_per_instrument = 0.02
        context.options['hold_days'] = 100
        context.options['hold_days1'] = 10
        context.options['hold_days2'] = 50
    
     
    # @param(id="m20", name="handle_data")
    # 回测引擎:每日数据处理函数,每天执行一次
    def m20_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 天)
        is_staging1 = context.trading_day_index < context.options['hold_days2']
        cash_avg = context.portfolio.portfolio_value / context.options['hold_days1']
        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')  
                
                # 赚9%且为可交易状态就止盈
                if stock_market_price/stock_cost-1>=2 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)
    
            if len(current_stopwin_stock)>0:
               
                stock_sold += current_stopwin_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(100) 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:持有固定天数卖出-----------------------
    
        
        # 3. 生成轮仓卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰
        if not is_staging1 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只股票
            import random
    
        def select_stocks(ranker_prediction):
        
        # 选择前50名股票
            top_50_stocks = ranker_prediction.sort_values('position', ascending=False).head(20)
        # 随机选择2只股票
            selected_stocks = top_50_stocks.sample(n=2)
            return selected_stocks
            selected_stocks = select_stocks(ranker_prediction)
    
        # 计算所有禁止买入的股票池
        banned_list = stock_sold
        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:
                context.order_value(context.symbol(instrument), cash)
        
    
    
    # @param(id="m20", name="prepare")
    # 回测引擎:准备数据,只执行一次
    def m20_prepare_bigquant_run(context):
        pass
    
    # @param(id="m20", name="before_trading_start")
    def m20_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:
                    #判断一下如果当日涨停,则取消卖单
                    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
    
    # @module(position="678,782", comment='预测数据,用于回测和模拟', comment_collapsed=False)
    m9 = M.instruments.v2(
        start_date=T.live_run_param('trading_date', '2024-10-07'),
        end_date=T.live_run_param('trading_date', '2025-12-19'),
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    # @module(position="797,-212", comment='', comment_collapsed=True)
    m25 = M.input_features.v1(
        features="""shift(beta_csi500_90_0/group_sum(industry_sw_level2_0, beta_csi500_90_0-0.5),-5)
    shift(correlation(log(volume_0),abs(return_0-1),5),-5)
    shift(mean(mf_net_amount_xl_0,15),-5)
    shift(sum(mf_net_amount_xl_0,12)/market_cap_float_0,-5)
    shift(ta_willr_14_0,-5)"""
    )
    
    # @module(position="822,-49", comment='', comment_collapsed=True)
    m3 = M.input_features.v1(
        features_ds=m25.data,
        features="""shift(beta_csi500_90_0/group_sum(industry_sw_level2_0, beta_csi500_90_0-0.5),-5)
    shift(correlation(log(volume_0),abs(return_0-1),5),-5)
    shift(mean(mf_net_amount_xl_0,15),-5)
    shift(sum(mf_net_amount_xl_0,12)/market_cap_float_0,-5)
    shift(ta_willr_14_0,-5)
    shift(rank(((close_0-open_0)/open_0),6),-5)
    
    """
    )
    
    # @module(position="908,174", comment='这里放置要过滤的条件', comment_collapsed=True)
    m4 = M.input_features.v1(
        features_ds=m3.data,
        features="""
        
         fangb=ta_ema(((2*close_0+high_0+low_0)/4-ts_min(low_0, 34))/(ts_max(high_0, 34)-ts_min(low_0, 34))*100, 8)
    b1=ta_ema(fangb, 5)
        c1=fangb-b1  
        d1= ta_ema((sum(close_0-where(high_0<= close_1, high_0, close_1),7)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 7))*14*28+sum(close_0-where(high_0<= close_1, high_0, close_1),14)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 14))*7*28+sum(close_0-where(high_0<= close_1, high_0, close_1),28)/(sum(where(high_0<= close_1, high_0, close_1)-where(low_0<=close_1, low_0, close_1), 28))*7*14)*100/(7*14+7*28+14*28), 6)
    
    #{STICKLINE(防线B-B1>0,防线B,B1,8,1),COLOR00FF00;}
    #妙趣横生:-一进一出,COLORRED;
    #{STICKLINE(防线B-B1<0,防线B,B1,8,1),COLORRED;}
    #卖出:(REF(一进一出,1)>0 AND 一进一出<=0) OR (一进一出<1 AND 一进一出>=0 AND C<O),COLORRED;
    
    #DRAWICON(卖出,36,1);
    #STICKLINE(卖出,0,28,1,0),COLORRED;
    #DRAWTEXT(卖出,30,'卖'),COLORMAGENTA;
    #买入:卖出=0 AND REF(一进一出,1)<0 AND 一进一出>0,COLORRED; 
    # mairu= c1=0    shift(c1,1)<0  c1>0  
    
    #{STICKLINE(防线B-B1>0,防线B,B1,8,1),COLOR00FF00;}
    #妙趣横生:-一进一出,COLORRED;
    #{STICKLINE(防线B-B1<0,防线B,B1,8,1),COLORRED;}
    #卖出:(REF(一进一出,1)>0 AND 一进一出<=0) OR (一进一出<1 AND 一进一出>=0 AND C<O),COLORRED;
    maichu1= where((shift(c1, 1)>0) & (((c1 >0))|(c1==0)),1,0)
    maichu2=where((c1<1)&(((c1 >0))|(c1==0))&(close_1-close_0<0), 1, 0)
    _total_count=sum(maichu1+maichu1, 1)
    
    #DRAWICON(卖出,36,1);
    #STICKLINE(卖出,0,28,1,0),COLORRED;
    #DRAWTEXT(卖出,30,'卖'),COLORMAGENTA;
    #买入:卖出=0 AND REF(一进一出,1)<0 AND 一进一出>0,COLORRED; 
    # mairu= c1=0    shift(c1,1)<0  c1>0  
    con = where((c1.shift(1) < 0) ,1,0)
    con3=where(((c1 >0))|(c1==0), 1, 0)               
    total_count=con+con3
    con2= where((_total_count<1), 1,0)
    total_count2= sum(con2,1)
    
    
    
    # 个股最近1日收益率 return_1 close_0/shift(close_0,1)
    # 大单净流入占比最近5日平均 mean(mf_net_pct_l_0,5)   收盘价的5日简单移动平均值 ta_sma_5_0 &(low_0<mean(close_0, 20)
    #收盘价的5日指数移动平均值 因子分析: ta_ema_5_0 过去5个交易日的平均换手率 avg_turn_5 close_0>mean(close_0, 15))&(close_0>mean(close_0, 10))&(close_0>mean(close_0, 5))&
    # 小单净流入占比最近5日平均 mean(mf_net_pct_s_0,5) 主力净流入占比最近5日平均值 mean(mf_net_pct_main_0,5) buy_cond_1==1&buy_cond_2==1&buy_cond_3==1&a3>0
     #收盘突破所有短期均线,收盘表现强势
    buy_cond_1 = where((close_0<mean(close_0, 15))&(close_0<mean(close_0, 10))&(close_0<mean(close_0, 5))&(close_0<mean(close_0, -5)),1,0)
    #底部冲短线均线下方开始反弹
    buy_cond_2 = where((low_0<mean(close_0, 5))&(low_0<mean(close_0, 10)), 1, 0)
    #确保当天为阳
    buy_cond_3 = where((close_0>open_0), 1, 0)
    #资金流因子,近几天大单相对流通市值
    a3 = sum(mf_net_amount_xl_0,10)/market_cap_float_0"""
    )
    
    # @module(position="1466,135", comment='', comment_collapsed=True)
    m17 = M.general_feature_extractor.v7(
        instruments=m9.data,
        features=m4.data,
        start_date='',
        end_date='',
        before_start_days=120
    )
    
    # @module(position="1570,277", comment='', comment_collapsed=True)
    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
    )
    
    # @module(position="1464,377", comment='', comment_collapsed=True)
    m29 = M.chinaa_stock_filter.v1(
        index_constituent_cond=['全部'],
        board_cond=['上证主板', '深证主板'],
        industry_cond=['全部'],
        st_cond=['正常'],
        delist_cond=['非退市'],
        output_left_data=False
    )
    
    # @module(position="1715,423", comment='', comment_collapsed=True)
    m1 = M.filtet_st_stock_tomo.v3(
        input_1=m29.data
    )
    
    # @module(position="1249,559", comment='', comment_collapsed=True)
    m14 = M.dropnan.v1(
        input_data=m1.data_1
    )
    
    # @module(position="652,646", comment='', comment_collapsed=True)
    m6 = M.xgboost.v1(
        features=m3.data,
        predict_ds=m14.data,
        num_boost_round=150,
        objective='排序(map)',
        booster='gbtree',
        max_depth=6,
        key_cols='date,instrument',
        group_col='date',
        nthread=1,
        n_gpus=-1,
        other_train_parameters={}
    )
    
    # @module(position="1028,930", comment='', comment_collapsed=True)
    m21 = M.sort.v4(
        input_ds=m6.predictions,
        sort_by='prediction',
        group_by='date',
        keep_columns='--',
        ascending=False
    )
    
    # @module(position="878,1221", comment='', comment_collapsed=True)
    m20 = M.trade.v4(
        instruments=m9.data,
        options_data=m21.sorted_data,
        start_date='',
        end_date='',
        initialize=m20_initialize_bigquant_run,
        handle_data=m20_handle_data_bigquant_run,
        prepare=m20_prepare_bigquant_run,
        before_trading_start=m20_before_trading_start_bigquant_run,
        volume_limit=0,
        order_price_field_buy='open',
        order_price_field_sell='close',
        capital_base=100000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='真实价格',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark='000300.SHA'
    )
    # </aistudiograph>
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    Cell In[1], line 131
        123 m31 = M.use_datasource.v1(
        124     instruments=m5.data,
        125     datasource_id='bar1d_CN_STOCK_A',
        126     start_date='',
        127     end_date=''
        128 )
        130 # @module(position="18,-125", comment='', comment_collapsed=True)
    --> 131 m15 = M.general_feature_extractor.v7(
        132     instruments=m5.data,
        133     start_date='',
        134     end_date='',
        135     before_start_days=120
        136 )
        138 # @module(position="7,-18", comment='', comment_collapsed=True)
        139 m16 = M.derived_feature_extractor.v3(
        140     input_data=m15.data,
        141     date_col='date',
       (...)
        144     remove_extra_columns=False
        145 )
    
    File module2/common/modulemanagerv2.py:88, in biglearning.module2.common.modulemanagerv2.BigQuantModuleVersion.__call__()
    
    File module2/common/moduleinvoker.py:370, in biglearning.module2.common.moduleinvoker.module_invoke()
    
    File module2/common/moduleinvoker.py:292, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
    
    File module2/common/moduleinvoker.py:253, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
    
    File module2/common/moduleinvoker.py:210, in biglearning.module2.common.moduleinvoker._module_run()
    
    File module2/modules/general_feature_extractor/v7/__init__.py:26, in biglearning.module2.modules.general_feature_extractor.v7.__init__.BigQuantModule.__init__()
    
    TypeError: __init__() takes at least 3 positional arguments (2 given)