{"description":"实验创建于2017/8/26","graph":{"edges":[{"to_node_id":"-228:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-234:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-123:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-550:input_1","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-575:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8:data"},{"to_node_id":"-228:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-235:features","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24:data"},{"to_node_id":"-235:input_data","from_node_id":"-228:data"},{"to_node_id":"-253:data1","from_node_id":"-234:data"},{"to_node_id":"-582:data1","from_node_id":"-253:data"},{"to_node_id":"-253:data2","from_node_id":"-235:data"},{"to_node_id":"-234:features","from_node_id":"-270:data"},{"to_node_id":"-123:options_data","from_node_id":"-185:data_1"},{"to_node_id":"-123:benchmark_ds","from_node_id":"-550:data_1"},{"to_node_id":"-575:features","from_node_id":"-570:data"},{"to_node_id":"-582:data2","from_node_id":"-575:data"},{"to_node_id":"-121:input_1","from_node_id":"-582:data"},{"to_node_id":"-185:input_1","from_node_id":"-297:data_1"},{"to_node_id":"-185:input_2","from_node_id":"-297:data_2"},{"to_node_id":"-185:input_3","from_node_id":"-297:data_3"},{"to_node_id":"-297:input_1","from_node_id":"-121:data"}],"nodes":[{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2020-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2022-05-01","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8"}],"output_ports":[{"name":"data","node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-8"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-24","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\nin_csi300_0\nin_csi500_0\nin_sse50_0\nindustry_sw_level1_0\nst_status_0\n\n# 选股条件\ncond1=(ta_macd(close_0/adjust_factor_0, fastperiod=12, slowperiod=26, signalperiod=26, derive='golden_cross'))&\\\n(ta_cci(high_0/adjust_factor_0, low_0/adjust_factor_0, close_0/adjust_factor_0, timeperiod=14)>50)&\\\n(ta_rsi(close_0/adjust_factor_0, timeperiod=14)>50)\n\n# 排序选股\ncond2=1\n\n# 进场条件\ncond3=1\n \n# 卖出条件\ncond4=1\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":"-228","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":"300","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-228"},{"name":"features","node_id":"-228"}],"output_ports":[{"name":"data","node_id":"-228"}],"cacheable":true,"seq_num":15,"comment":"","comment_collapsed":true},{"node_id":"-234","module_id":"BigQuantSpace.use_datasource.use_datasource-v1","parameters":[{"name":"datasource_id","value":"industry_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":"-234"},{"name":"features","node_id":"-234"}],"output_ports":[{"name":"data","node_id":"-234"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-253","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":"-253"},{"name":"data2","node_id":"-253"}],"output_ports":[{"name":"data","node_id":"-253"}],"cacheable":true,"seq_num":7,"comment":"","comment_collapsed":true},{"node_id":"-235","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":"-235"},{"name":"features","node_id":"-235"}],"output_ports":[{"name":"data","node_id":"-235"}],"cacheable":true,"seq_num":16,"comment":"","comment_collapsed":true},{"node_id":"-270","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"concept\n","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-270"}],"output_ports":[{"name":"data","node_id":"-270"}],"cacheable":true,"seq_num":10,"comment":"获取股票概念,并匹配选中的概念","comment_collapsed":false},{"node_id":"-123","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 prepare_index_data(context):\n \"\"\"准备指数数据\"\"\"\n if context.market_risk_conf != []:\n if len(context.market_risk_conf) == 1:\n index_code = context.market_risk_conf[0]['params']['index_code']\n start_date = '2005-01-01'\n end_date = context.end_date\n index_data = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[index_code], start_date=start_date, end_date=end_date).set_index('date')\n \n if context.market_risk_conf[0]['method'] == 'market_ma_stoploss':\n ma_periods = int(context.market_risk_conf[0]['params']['ma_periods'])\n index_data['ma_%s'%ma_periods] = index_data['close'].rolling(ma_periods).mean()\n index_data['signal'] = np.where(index_data['close'] > index_data['ma_%s'%ma_periods], 'long', 'short')\n\n elif context.market_risk_conf[0]['method'] == 'market_fallrange_stoploss':\n days = context.market_risk_conf[0]['params']['days']\n fallrange = context.market_risk_conf[0]['params']['fallrange']\n index_data['signal'] = np.where(index_data['close']/index_data['close'].shift(days)-1 <= fallrange, 'long', 'short')\n context.index_signal_data = index_data \n \n if len(context.market_risk_conf) == 2:\n start_date = '2005-01-01'\n end_date = context.end_date \n if context.market_risk_conf[0]['method'] == 'market_ma_stoploss': \n index_code_1 = context.market_risk_conf[0]['params']['index_code']\n index_data_1 = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[index_code_1], start_date=start_date, end_date=end_date).set_index('date')\n ma_periods = int(context.market_risk_conf[0]['params']['ma_periods'])\n \n index_code_2 = context.market_risk_conf[1]['params']['index_code']\n index_data_2 = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[index_code_2], start_date=start_date, end_date=end_date).set_index('date')\n days = context.market_risk_conf[1]['params']['days']\n fallrange = context.market_risk_conf[1]['params']['fallrange']\n else:\n index_code_1 = context.market_risk_conf[1]['params']['index_code']\n index_data_1 = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[index_code_1], start_date=start_date, end_date=end_date).set_index('date')\n ma_periods = int(context.market_risk_conf[1]['params']['ma_periods'])\n \n index_code_2 = context.market_risk_conf[0]['params']['index_code']\n index_data_2 = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[index_code_2], start_date=start_date, end_date=end_date).set_index('date')\n days = context.market_risk_conf[0]['params']['days']\n fallrange = context.market_risk_conf[0]['params']['fallrange'] \n \n index_data_1['ma_%s'%ma_periods] = index_data_1['close'].rolling(ma_periods).mean()\n index_data_1['signal_1'] = np.where(index_data_1['close'] > index_data_1['ma_%s'%ma_periods], 1, 0)\n signal_1 = index_data_1[['signal_1']].reset_index() \n index_data_2['signal_2'] = np.where(index_data_2['close']/index_data_2['close'].shift(days)-1 <= fallrange, 1, 0)\n signal_2 = index_data_2[['signal_2']].reset_index()\n signal = pd.merge(signal_1,signal_2).set_index('date')\n signal['signal_sum'] = signal['signal_1'] + signal['signal_2']\n signal['signal'] = np.where(signal['signal_sum']>0,'long','short') \n context.index_signal_data = signal\n else:\n context.index_signal_data = None \n\ndef bigquant_run(context):\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n context.selected_stock = []\n context.trade_mode = '轮动'\n\n if context.trade_mode == '轮动':\n context.buy_frequency = 1\n context.sell_frequency = 1\n context.rebalance_periods = 1 # 调仓周期\n context.max_stock_count = 5 # 最大持仓股票数量\n context.order_weight_method = 'equal_weight' # 买入方式\n context.is_sell_willbuy_stock = False # 卖出欲买进股票 \n else:\n # 买入条件参数\n context.stock_select_frequency = 1 # 选股频率\n context.order_weight_method = 'equal_weight' # 买入方式\n context.buy_frequency = 2 # 买入频率\n context.can_duplication_buy = False # 是否可重复买入\n context.max_stock_count = 5 # 最大持仓股票数量\n context.max_stock_weight = 1 # 个股最大持仓比重\n\n # 卖出条件参数\n context.sell_frequency = 10 # 卖出频率\n context.is_sell_willbuy_stock = False # 卖出欲买进股票 \n\n # 风控参数 \n context.stock_risk_conf = [{'method':'stock_percent_stoploss', 'params':{'percent': 0.05}}] # 支持多选 无:[]\n context.strategy_risk_conf = [] # 支持多选 无:[]\n context.market_risk_conf = [] # 支持多选, 无: []\n \n prepare_index_data(context)\n slippage_type = 'price'\n from zipline.finance.slippage import SlippageModel\n class FixedPriceSlippage(SlippageModel):\n # 指定初始化函数\n def __init__(self, spreads, price_field_buy, price_field_sell):\n # 存储spread的字典,用股票代码作为key\n self.spreads = spreads\n self._price_field_buy = price_field_buy\n self._price_field_sell = price_field_sell\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_base = data.current(order.asset, price_field)\n if slippage_type == 'price':\n price = price_base + (self.spreads / 2) if order.amount > 0 else price_base - (self.spreads / 2)\n else:\n price = price_base * (1.0 + self.spreads / 2) if order.amount > 0 else price_base * (1.0 - self.spreads / 2)\n else:\n price = order.limit\n # 返回希望成交的价格和数量\n return (price, order.amount)\n # 设置price_field\n fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='open', spreads=0.02)\n context.set_slippage(us_equities=fix_slippage)","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"#--------------------------------------------------------------------\n# 卖出条件\n#-------------------------------------------------------------------- \ndef sell_action(context, data):\n date = data.current_dt.strftime('%Y-%m-%d')\n hit_stop_stock = context.stock_hit_stop \n \n try:\n today_enter_stock = context.enter_daily_df.loc[date] \n except KeyError as e:\n today_enter_stock = []\n try:\n today_exit_stock = context.exit_daily_df.loc[date] \n except KeyError as e:\n today_exit_stock = []\n \n target_stock_to_buy = [i for i in context.selected_stock if i in today_enter_stock ] \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions] # 当前持仓股票\n \n if context.trading_day_index % context.sell_frequency == 0:\n stock_to_sell = [i for i in stock_hold_now if i in today_exit_stock] # 要卖出的股票\n stock_buy_and_sell = [i for i in stock_to_sell if i in target_stock_to_buy]\n if context.is_sell_willbuy_stock == False: # 要买入的股票不卖出,但该票也不再买入\n stock_to_sell.extend(hit_stop_stock) # 将触发个股风控的股票融入到卖出票池\n stock_to_sell = [i for i in stock_to_sell if i not in stock_buy_and_sell] # 进行更新而已\n elif context.is_sell_willbuy_stock == True: # 要买入的股票依然要卖出,该票不再买入\n stock_to_sell.extend(hit_stop_stock)\n \n # 买入时需要过滤的股票\n context.cannot_buy_stock = stock_buy_and_sell\n \n for stock in stock_to_sell:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0)\n del context.portfolio.positions[context.symbol(stock)]\n\n\n#--------------------------------------------------------------------\n# 买入条件\n#-------------------------------------------------------------------- \ndef buy_action(context, data):\n date = data.current_dt.strftime('%Y-%m-%d')\n \n try:\n today_enter_stock = context.enter_daily_df.loc[date] \n except KeyError as e:\n today_enter_stock = []\n try:\n today_exit_stock = context.exit_daily_df.loc[date] \n except KeyError as e:\n today_exit_stock = []\n \n target_stock_to_buy = [i for i in context.selected_stock if i in today_enter_stock] \n target_stock_to_buy = [s for s in target_stock_to_buy if s not in context.cannot_buy_stock] # 进行更新,不能买入的股票要过滤\n \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions] # 当前持仓股票\n \n # 确定股票权重\n if context.order_weight_method == 'equal_weight':\n equal_weight = 1 / context.max_stock_count\n \n portfolio_value = context.portfolio.portfolio_value\n position_current_value = {pos.sid: pos.amount* pos.last_sale_price for i,pos in context.portfolio.positions.items()}\n \n # 买入\n if context.trading_day_index % context.buy_frequency == 0:\n if len(stock_hold_now) >= context.max_stock_count:\n return \n \n today_buy_count = 0\n if context.trade_mode == '轮动':\n for s in target_stock_to_buy:\n if today_buy_count + len(stock_hold_now) >= context.max_stock_count: # 超出最大持仓数量\n break\n if data.can_trade(context.symbol(s)):\n order_target_percent(context.symbol(s), equal_weight)\n today_buy_count += 1\n else:\n if context.can_duplication_buy == True: # 可以重复买入,多一份买入\n for s in target_stock_to_buy:\n if today_buy_count + len(stock_hold_now) >= context.max_stock_count: # 超出最大持仓数量\n break\n \n if data.can_trade(context.symbol(s)):\n if context.symbol(s) in position_current_weight:\n curr_value = position_current_value.get(context.symbol(s)) \n order_value(context.symbol(s), min(context.max_stock_weight * portfolio_value - curr_value, equal_weight*portfolio_value))\n else:\n order_value(context.symbol(s), equal_weight*portfolio_value)\n today_buy_count += 1\n\n elif context.can_duplication_buy == False: # 不可以重复买入,不买\n for s in target_stock_to_buy:\n if today_buy_count + len(stock_hold_now) >= context.max_stock_count: # 超出最大持仓数量\n break\n if s in stock_hold_now:\n continue\n else:\n if data.can_trade(context.symbol(s)):\n order_target_percent(context.symbol(s), equal_weight)\n today_buy_count += 1\n\n \n#--------------------------------------------------------------------\n# 风控体系\n#-------------------------------------------------------------------- \ndef market_risk_manage(context, data):\n \"\"\"大盘风控\"\"\"\n date = data.current_dt.strftime('%Y-%m-%d')\n if type(context.index_signal_data) == pd.DataFrame:\n current_signal = context.index_signal_data.loc[date]['signal']\n if current_signal == 'short': \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions] \n # 平掉所有股票\n for stock in stock_hold_now:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0) \n print('大盘出现止损信号, 平掉全部仓位,并关闭交易!')\n context.market_risk_signal = 'short'\n else:\n context.market_risk_signal = 'long'\n\n \n \ndef strategy_risk_manage(context, data):\n \"\"\"策略风控\"\"\"\n if context.strategy_risk_conf == []: # 没有设置策略风控\n context.strategy_risk_signal = 'long'\n \n else:\n for rm in context.strategy_risk_conf:\n if rm['method'] == 'strategy_percent_stopwin':\n pct = rm['params']['percent']\n portfolio_value = context.portfolio.portfolio_value \n if portfolio_value / context.capital_base - 1 > pct: \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions] \n # 平掉所有股票\n for stock in stock_hold_now:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0) \n print('策略出现止盈信号, 平掉全部仓位,并关闭交易!')\n context.strategy_risk_signal = 'short' \n \n \n if rm['method'] == 'strategy_percent_stoploss':\n pct = rm['params']['percent']\n portfolio_value = context.portfolio.portfolio_value \n if portfolio_value / context.capital_base -1 < pct:\n stock_hold_now = [equity.symbol for equity in context.portfolio.positions] \n # 平掉所有股票\n for stock in stock_hold_now:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0) \n print('策略出现止损信号, 平掉全部仓位,并关闭交易!')\n context.strategy_risk_signal = 'short'\n\n \ndef stock_risk_manage(context, data):\n \"\"\"个股风控\"\"\"\n position_current_pnl = {pos.sid: (pos.last_sale_price-pos.cost_basis)/pos.cost_basis for i,pos in context.portfolio.positions.items()}\n \n for rm in context.stock_risk_conf:\n params_pct = rm['params']['percent']\n if rm['method'] == 'stock_percent_stopwin':\n for sid,pnl_pct in position_current_pnl.items(): \n if pnl_pct > params_pct:\n context.stock_hit_stop.append(sid.symbol)\n \n if rm['method'] == 'stock_percent_stoploss':\n for sid,pnl_pct in position_current_pnl.items():\n if pnl_pct < params_pct:\n context.stock_hit_stop.append(sid.symbol)\n\n\n\n\n# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \"\"\"每日运行策略逻辑\"\"\"\n market_risk_manage(context, data)\n strategy_risk_manage(context, data)\n \n if context.market_risk_signal == 'short': return\n if context.strategy_risk_signal == 'short': return\n\n stock_risk_manage(context, data)\n if context.trading_day_index % context.rebalance_periods == 0:\n sell_action(context, data)\n buy_action(context, data)\n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n \n load_data = context.options['data'].read_pickle()\n context.signal_daily_stock = load_data['df1'].groupby('date').apply(lambda x:list(x.instrument))\n context.enter_daily_df = load_data['df2'].groupby('date').apply(lambda x:list(x.instrument))\n context.exit_daily_df = load_data['df3'].groupby('date').apply(lambda x:list(x.instrument))\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n \n \"\"\"每日盘前更新股票池\"\"\"\n frequency = context.rebalance_periods if context.trade_mode == '轮动' else context.stock_select_frequency\n if context.trading_day_index % frequency == 0:\n date = data.current_dt.strftime('%Y-%m-%d')\n try:\n context.selected_stock = context.signal_daily_stock[date] \n except KeyError as e:\n context.selected_stock = []\n \n \"\"\"初始化风控参数\"\"\"\n context.strategy_risk_signal = 'long'\n context.market_risk_signal = 'long' \n context.stock_hit_stop = []\n context.cannot_buy_stock = []\n","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":0.2,"type":"Literal","bound_global_parameter":null},{"name":"order_price_field_buy","value":"open","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_sell","value":"open","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"100000","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.HIX","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-123"},{"name":"options_data","node_id":"-123"},{"name":"history_ds","node_id":"-123"},{"name":"benchmark_ds","node_id":"-123"},{"name":"trading_calendar","node_id":"-123"}],"output_ports":[{"name":"raw_perf","node_id":"-123"}],"cacheable":false,"seq_num":4,"comment":"","comment_collapsed":true},{"node_id":"-185","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n df1 = input_1.read_df()\n df2 = input_2.read_df()\n df3 = input_3.read_df()\n\n if len(df1.index.names) == 2:\n df1.index.names = [None, None]\n else:\n df1.index.names = [None]\n \n df = {'df1':df1,'df2':df2,'df3':df3}\n ds = DataSource.write_pickle(df)\n return Outputs(data_1=ds)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-185"},{"name":"input_2","node_id":"-185"},{"name":"input_3","node_id":"-185"}],"output_ports":[{"name":"data_1","node_id":"-185"},{"name":"data_2","node_id":"-185"},{"name":"data_3","node_id":"-185"}],"cacheable":true,"seq_num":17,"comment":"","comment_collapsed":true},{"node_id":"-550","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_index):\n # 示例代码如下。在这里编写您的代码\n start_date=input_1.read_pickle()['start_date']\n end_date=input_1.read_pickle()['end_date']\n df = DataSource('bar1d_index_CN_STOCK_A').read(instruments=[input_index],start_date=start_date,end_date=end_date,fields=['close'])\n data_1 = DataSource.write_df(df)\n return Outputs(data_1=data_1, data_2=None, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"input_1","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{'input_index':'000300.HIX'}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"data_1","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-550"},{"name":"input_2","node_id":"-550"},{"name":"input_3","node_id":"-550"}],"output_ports":[{"name":"data_1","node_id":"-550"},{"name":"data_2","node_id":"-550"},{"name":"data_3","node_id":"-550"}],"cacheable":true,"seq_num":8,"comment":"","comment_collapsed":true},{"node_id":"-570","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"suspended","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-570"}],"output_ports":[{"name":"data","node_id":"-570"}],"cacheable":true,"seq_num":6,"comment":"获取股票停牌数据","comment_collapsed":false},{"node_id":"-575","module_id":"BigQuantSpace.use_datasource.use_datasource-v1","parameters":[{"name":"datasource_id","value":"stock_status_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":"-575"},{"name":"features","node_id":"-575"}],"output_ports":[{"name":"data","node_id":"-575"}],"cacheable":true,"seq_num":19,"comment":"","comment_collapsed":true},{"node_id":"-582","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":"-582"},{"name":"data2","node_id":"-582"}],"output_ports":[{"name":"data","node_id":"-582"}],"cacheable":true,"seq_num":20,"comment":"","comment_collapsed":true},{"node_id":"-297","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n df = input_1.read_df()\n # 缺失值处理\n # if len(df)!=0:\n # df.dropna(inplace=True)\n \n # 选股条件\n if len(df)!=0:\n df_filter1 = df[df['cond1']>0]\n else:\n df_filter1 = df\n \n # 指标排序\n if len(df_filter1)!=0:\n df_filter2 = df_filter1.groupby('date').apply(lambda x:x.sort_values(by=['cond2'],ascending=True))\n else:\n df_filter2 = df_filter1\n \n #输出条件过滤股票池\n data_1 = DataSource.write_df(df_filter2)\n\n \n # 进场条件\n if len(df)!=0:\n df_buy = df[df['cond3']>0]\n else:\n df_buy = df\n # 输出满足进场条件的股票池\n data_2 = DataSource.write_df(df_buy)\n\n \n # 出场条件\n if len(df)!=0:\n df_sell = df[df['cond4']>0]\n else:\n df_sell = df\n # 输出满足出场条件的股票池\n data_3 = DataSource.write_df(df_sell) \n \n return Outputs(data_1=data_1, data_2=data_2, data_3=data_3)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-297"},{"name":"input_2","node_id":"-297"},{"name":"input_3","node_id":"-297"}],"output_ports":[{"name":"data_1","node_id":"-297"},{"name":"data_2","node_id":"-297"},{"name":"data_3","node_id":"-297"}],"cacheable":true,"seq_num":22,"comment":"","comment_collapsed":true},{"node_id":"-121","module_id":"BigQuantSpace.stockpool_select.stockpool_select-v6","parameters":[{"name":"self_instruments","value":"[]","type":"Literal","bound_global_parameter":null},{"name":"input_concepts","value":"[]","type":"Literal","bound_global_parameter":null},{"name":"input_industrys","value":"[360000,710000,220000,460000,370000,330000,340000,720000,240000,630000,280000,420000,510000,640000,610000,620000,650000,230000,410000,350000,490000,110000,210000,480000,730000,450000,270000,430000]","type":"Literal","bound_global_parameter":null},{"name":"input_indexs","value":"['沪深300']","type":"Literal","bound_global_parameter":null},{"name":"input_st","value":"过滤","type":"Literal","bound_global_parameter":null},{"name":"input_suspend","value":"过滤","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-121"}],"output_ports":[{"name":"data","node_id":"-121"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-8' Position='473,-148,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-24' Position='697,-231,200,200'/><node_position Node='-228' Position='479,-22,200,200'/><node_position Node='-234' Position='145,-30,200,200'/><node_position Node='-253' Position='341,161,200,200'/><node_position Node='-235' Position='483,70,200,200'/><node_position Node='-270' Position='124,-149,200,200'/><node_position Node='-123' Position='563,687,200,200'/><node_position Node='-185' Position='454,575,200,200'/><node_position Node='-550' Position='878,511,200,200'/><node_position Node='-570' Position='960,-137,200,200'/><node_position Node='-575' Position='840,-16,200,200'/><node_position Node='-582' Position='557,241,200,200'/><node_position Node='-297' Position='453,455,200,200'/><node_position Node='-121' Position='457,355,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
[2022-05-06 09:19:31.306780] INFO: moduleinvoker: instruments.v2 开始运行..
[2022-05-06 09:19:31.451409] INFO: moduleinvoker: instruments.v2 运行完成[0.144636s].
[2022-05-06 09:19:31.472145] INFO: moduleinvoker: cached.v3 开始运行..
[2022-05-06 09:19:32.104732] INFO: moduleinvoker: cached.v3 运行完成[0.632567s].
[2022-05-06 09:19:32.120808] INFO: moduleinvoker: input_features.v1 开始运行..
[2022-05-06 09:19:32.186967] INFO: moduleinvoker: input_features.v1 运行完成[0.06616s].
[2022-05-06 09:19:32.217607] INFO: moduleinvoker: general_feature_extractor.v7 开始运行..
[2022-05-06 09:19:33.345354] INFO: 基础特征抽取: 年份 2009, 特征行数=313319
[2022-05-06 09:19:34.843158] INFO: 基础特征抽取: 年份 2010, 特征行数=431567
[2022-05-06 09:19:36.357881] INFO: 基础特征抽取: 年份 2011, 特征行数=511455
[2022-05-06 09:19:37.944204] INFO: 基础特征抽取: 年份 2012, 特征行数=565675
[2022-05-06 09:19:40.023012] INFO: 基础特征抽取: 年份 2013, 特征行数=564168
[2022-05-06 09:19:41.930581] INFO: 基础特征抽取: 年份 2014, 特征行数=569948
[2022-05-06 09:19:44.342696] INFO: 基础特征抽取: 年份 2015, 特征行数=569698
[2022-05-06 09:19:47.868262] INFO: 基础特征抽取: 年份 2016, 特征行数=641546
[2022-05-06 09:19:50.289173] INFO: 基础特征抽取: 年份 2017, 特征行数=743233
[2022-05-06 09:19:53.209433] INFO: 基础特征抽取: 年份 2018, 特征行数=816987
[2022-05-06 09:19:55.821109] INFO: 基础特征抽取: 年份 2019, 特征行数=884867
[2022-05-06 09:19:58.651259] INFO: 基础特征抽取: 年份 2020, 特征行数=945961
[2022-05-06 09:20:02.666431] INFO: 基础特征抽取: 年份 2021, 特征行数=1061527
[2022-05-06 09:20:03.679345] INFO: 基础特征抽取: 年份 2022, 特征行数=363977
[2022-05-06 09:20:03.821502] INFO: 基础特征抽取: 总行数: 8983928
[2022-05-06 09:20:03.830377] INFO: moduleinvoker: general_feature_extractor.v7 运行完成[31.61277s].
[2022-05-06 09:20:03.854475] INFO: moduleinvoker: derived_feature_extractor.v3 开始运行..
[2022-05-06 09:21:00.986667] INFO: derived_feature_extractor: 提取完成 cond1=(ta_macd(close_0/adjust_factor_0, fastperiod=12, slowperiod=26, signalperiod=26, derive='golden_cross'))&(ta_cci(high_0/adjust_factor_0, low_0/adjust_factor_0, close_0/adjust_factor_0, timeperiod=14)>50)&(ta_rsi(close_0/adjust_factor_0, timeperiod=14)>50), 41.140s
[2022-05-06 09:21:00.999646] INFO: derived_feature_extractor: 提取完成 cond2=1, 0.011s
[2022-05-06 09:21:01.025756] INFO: derived_feature_extractor: 提取完成 cond3=1, 0.025s
[2022-05-06 09:21:01.052530] INFO: derived_feature_extractor: 提取完成 cond4=1, 0.025s
[2022-05-06 09:21:02.061024] INFO: derived_feature_extractor: /y_2009, 313319
[2022-05-06 09:21:02.813574] INFO: derived_feature_extractor: /y_2010, 431567
[2022-05-06 09:21:03.700597] INFO: derived_feature_extractor: /y_2011, 511455
[2022-05-06 09:21:04.675274] INFO: derived_feature_extractor: /y_2012, 565675
[2022-05-06 09:21:05.687148] INFO: derived_feature_extractor: /y_2013, 564168
[2022-05-06 09:21:06.715288] INFO: derived_feature_extractor: /y_2014, 569948
[2022-05-06 09:21:07.819727] INFO: derived_feature_extractor: /y_2015, 569698
[2022-05-06 09:21:08.908134] INFO: derived_feature_extractor: /y_2016, 641546
[2022-05-06 09:21:10.272182] INFO: derived_feature_extractor: /y_2017, 743233
[2022-05-06 09:21:11.690063] INFO: derived_feature_extractor: /y_2018, 816987
[2022-05-06 09:21:13.231913] INFO: derived_feature_extractor: /y_2019, 884867
[2022-05-06 09:21:15.394870] INFO: derived_feature_extractor: /y_2020, 945961
[2022-05-06 09:21:17.475429] INFO: derived_feature_extractor: /y_2021, 1061527
[2022-05-06 09:21:18.704100] INFO: derived_feature_extractor: /y_2022, 363977
[2022-05-06 09:21:19.008439] INFO: moduleinvoker: derived_feature_extractor.v3 运行完成[75.153961s].
[2022-05-06 09:21:19.013514] INFO: moduleinvoker: input_features.v1 开始运行..
[2022-05-06 09:21:19.026677] INFO: moduleinvoker: 命中缓存
[2022-05-06 09:21:19.028276] INFO: moduleinvoker: input_features.v1 运行完成[0.01477s].
[2022-05-06 09:21:19.038569] INFO: moduleinvoker: use_datasource.v1 开始运行..
[2022-05-06 09:21:27.466508] INFO: moduleinvoker: use_datasource.v1 运行完成[8.427938s].
[2022-05-06 09:21:27.489057] INFO: moduleinvoker: join.v3 开始运行..
[2022-05-06 09:22:03.403306] INFO: join: /y_2009, 行数=0/313319, 耗时=4.341606s
[2022-05-06 09:22:07.708945] INFO: join: /y_2010, 行数=431567/431567, 耗时=4.303091s
[2022-05-06 09:22:13.172494] INFO: join: /y_2011, 行数=511455/511455, 耗时=5.457941s
[2022-05-06 09:22:17.557473] INFO: join: /y_2012, 行数=565675/565675, 耗时=4.379337s
[2022-05-06 09:22:22.285088] INFO: join: /y_2013, 行数=564168/564168, 耗时=4.72124s
[2022-05-06 09:22:26.978697] INFO: join: /y_2014, 行数=569948/569948, 耗时=4.687507s
[2022-05-06 09:22:31.699074] INFO: join: /y_2015, 行数=569698/569698, 耗时=4.71427s
[2022-05-06 09:22:36.516353] INFO: join: /y_2016, 行数=641546/641546, 耗时=4.810868s
[2022-05-06 09:22:41.808613] INFO: join: /y_2017, 行数=743233/743233, 耗时=5.285436s
[2022-05-06 09:22:47.502123] INFO: join: /y_2018, 行数=816987/816987, 耗时=5.684907s
[2022-05-06 09:22:52.898047] INFO: join: /y_2019, 行数=884867/884867, 耗时=5.386509s
[2022-05-06 09:22:58.452002] INFO: join: /y_2020, 行数=945960/945961, 耗时=5.542411s
[2022-05-06 09:23:04.933197] INFO: join: /y_2021, 行数=1061527/1061527, 耗时=6.465447s
[2022-05-06 09:23:10.494839] INFO: join: /y_2022, 行数=363977/363977, 耗时=5.545842s
[2022-05-06 09:23:10.634185] INFO: join: 最终行数: 8670608
[2022-05-06 09:23:10.807346] INFO: moduleinvoker: join.v3 运行完成[103.318282s].
[2022-05-06 09:23:10.812881] INFO: moduleinvoker: input_features.v1 开始运行..
[2022-05-06 09:23:10.826013] INFO: moduleinvoker: 命中缓存
[2022-05-06 09:23:10.827642] INFO: moduleinvoker: input_features.v1 运行完成[0.014771s].
[2022-05-06 09:23:10.832532] INFO: moduleinvoker: use_datasource.v1 开始运行..
[2022-05-06 09:23:13.590093] INFO: moduleinvoker: use_datasource.v1 运行完成[2.757547s].
[2022-05-06 09:23:13.599188] INFO: moduleinvoker: join.v3 开始运行..
[2022-05-06 09:23:30.383154] INFO: join: /y_2009, 行数=0/0, 耗时=2.545489s
[2022-05-06 09:23:34.740839] INFO: join: /y_2010, 行数=431567/431567, 耗时=4.356109s
[2022-05-06 09:23:40.078588] INFO: join: /y_2011, 行数=511455/511455, 耗时=5.331383s
[2022-05-06 09:23:45.132239] INFO: join: /y_2012, 行数=565675/565675, 耗时=5.046864s
[2022-05-06 09:23:50.083506] INFO: join: /y_2013, 行数=564168/564168, 耗时=4.943123s
[2022-05-06 09:23:55.111615] INFO: join: /y_2014, 行数=569948/569948, 耗时=5.019088s
[2022-05-06 09:24:00.149793] INFO: join: /y_2015, 行数=569698/569698, 耗时=5.02861s
[2022-05-06 09:24:05.284119] INFO: join: /y_2016, 行数=641546/641546, 耗时=5.125708s
[2022-05-06 09:24:10.656817] INFO: join: /y_2017, 行数=743233/743233, 耗时=5.361616s
[2022-05-06 09:24:16.500483] INFO: join: /y_2018, 行数=816987/816987, 耗时=5.831628s
[2022-05-06 09:24:22.980140] INFO: join: /y_2019, 行数=884867/884867, 耗时=6.466431s
[2022-05-06 09:24:30.774146] INFO: join: /y_2020, 行数=945960/945960, 耗时=7.775277s
[2022-05-06 09:24:38.517425] INFO: join: /y_2021, 行数=1061527/1061527, 耗时=7.695269s
[2022-05-06 09:24:43.336104] INFO: join: /y_2022, 行数=363977/363977, 耗时=4.771877s
[2022-05-06 09:24:43.523794] INFO: join: 最终行数: 8670608
[2022-05-06 09:24:43.566360] INFO: moduleinvoker: join.v3 运行完成[89.967034s].
[2022-05-06 09:24:43.584777] INFO: moduleinvoker: stockpool_select.v6 开始运行..
[2022-05-06 09:42:42.985103] INFO: moduleinvoker: stockpool_select.v6 运行完成[1079.400319s].
[2022-05-06 09:42:43.003281] INFO: moduleinvoker: cached.v3 开始运行..
[2022-05-06 09:42:48.107996] INFO: moduleinvoker: cached.v3 运行完成[5.104732s].
[2022-05-06 09:42:48.124790] INFO: moduleinvoker: cached.v3 开始运行..
[2022-05-06 09:42:49.372632] INFO: moduleinvoker: cached.v3 运行完成[1.247849s].
[2022-05-06 09:42:51.497452] INFO: moduleinvoker: backtest.v8 开始运行..
[2022-05-06 09:42:51.503579] INFO: backtest: biglearning backtest:V8.6.2
[2022-05-06 09:42:53.468209] INFO: backtest: product_type:stock by specified
[2022-05-06 09:42:53.544412] INFO: moduleinvoker: cached.v2 开始运行..
[2022-05-06 09:43:40.275372] INFO: backtest: 读取股票行情完成:10393941
[2022-05-06 09:44:04.040411] INFO: moduleinvoker: cached.v2 运行完成[70.495953s].
[2022-05-06 09:44:13.622156] INFO: algo: TradingAlgorithm V1.8.7
[2022-05-06 09:44:17.511040] INFO: algo: trading transform...
[2022-05-06 09:44:22.817272] ERROR: moduleinvoker: module name: backtest, module version: v8, trackeback: KeyError: Equity(4423 [000060.SZA])
[2022-05-06 09:44:22.832341] ERROR: moduleinvoker: module name: trade, module version: v4, trackeback: KeyError: Equity(4423 [000060.SZA])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-1-50e4937832b6> in <module>
537 )
538
--> 539 m4 = M.trade.v4(
540 instruments=m1.data,
541 options_data=m17.data_1,
<ipython-input-1-50e4937832b6> in m4_handle_data_bigquant_run(context, data)
379 stock_risk_manage(context, data)
380 if context.trading_day_index % context.rebalance_periods == 0:
--> 381 sell_action(context, data)
382 buy_action(context, data)
383
<ipython-input-1-50e4937832b6> in sell_action(context, data)
226 if data.can_trade(context.symbol(stock)):
227 context.order_target_percent(context.symbol(stock), 0)
--> 228 del context.portfolio.positions[context.symbol(stock)]
229
230
KeyError: Equity(4423 [000060.SZA])