{"description":"实验创建于2021/11/25","graph":{"edges":[{"to_node_id":"-16:instruments","from_node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62:data"}],"nodes":[{"node_id":"-16","module_id":"BigQuantSpace.trade.trade-v4","parameters":[{"name":"start_date","value":"2022-01-03","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2022-04-28","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n # 获取今日的日期\n today = data.current_dt.strftime('%Y-%m-%d')\n # 通过positions对象,使用列表生成式的方法获取目前持仓的股票列表\n stock_hold_now = {e.symbol: p.amount * p.last_sale_price\n for e, p in context.perf_tracker.position_tracker.positions.items()}\n\n # //////////////////////////////////计算20日收益率动量拟合取斜率最大的标的\n rank = []\n for stock in context.instruments:\n # 标的为字符串格式\n stock_1 = context.symbol(stock) # 标的为字符串格\n data_1 = data.history(stock_1, ['close', 'open'], 20, '1d') # 获取前20天的历史收盘价\n score = np.polyfit(np.arange(len(data_1)), data_1.close / data_1.close[0], 1)[0]\n rank.append([stock, score])\n rank.sort(key=lambda x: x[-1], reverse=True) # 排序\n check_out_list = rank[0]\n print(data_1['close'].tail(3))\n # /////////////////////////////////计算20日收益率动量拟合取斜率最大的标的\n\n \n # /////////////////////////////////RSRS相关公式\n def get_ols(x, y):\n slope, intercept = np.polyfit(x, y, 1)\n r2 = 1 - (sum((y - (slope * x + intercept)) ** 2) / ((len(y) - 1) * np.var(y, ddof=1)))\n return intercept, slope, r2\n\n def initial_slope_series():\n data_1 = data.history(context.symbol('510300.HOF'), ['high', 'low'], 618, '1d') # 获取基准历史最高价 最低价\n return [get_ols(data_1.low[i:i + 18], data_1.high[i:i + 18])[1] for i in range(600)]\n\n # 因子标准化\n def get_zscore(slope_series):\n mean = np.mean(slope_series)\n std = np.std(slope_series)\n return (slope_series[-1] - mean) / std\n # /////////////////////////////////RSRS相关公式\n\n \n # /////////////////////////////////// 只看RSRS因子值作为买入、持有和清仓依据\n # 只看RSRS因子值作为买入、持有和清仓依据,前版本还加入了移动均线的上行作为条件\n def get_timing_signal(context, stock):\n slope_series = initial_slope_series()[:-1]\n high_low_data = data.history(context.symbol('510300.HOF'), ['high', 'low'], 18, '1d') # 获取基准历史最高价 最低价\n intercept, slope, r2 = get_ols(high_low_data.low, high_low_data.high)\n slope_series.append(slope)\n rsrs_score = get_zscore(slope_series[-600:]) * r2\n\n if rsrs_score > 0.7:\n return \"BUY\"\n elif rsrs_score < -0.7:\n return \"SELL\"\n else:\n return \"KEEP\"\n # /////////////////////////////////// 只看RSRS因子值作为买入、持有和清仓依据\n \n \n\n # ///////////////////////////////////买卖主函数\n # 交易主函数,先确定ETF最强的是谁,然后再根据择时信号判断是否需要切换或者清仓\n timing_signal = get_timing_signal(context, '510300.HOF') # 获取买\\卖\\持有信号\n print('今日自选及择时信号:{} {}'.format(check_out_list[0], timing_signal)) # 打印\n\n if timing_signal == 'SELL': # 如果信息为卖,执行卖出\n for stock in stock_hold_now: # 代码与标的代码循环对比\n context.order_target_percent(stock, 0) # 全部卖出\n elif timing_signal == 'BUY' or timing_signal == 'KEEP': # 如果信息为买或持有,买入或持有\n context.order_target_percent(check_out_list[0], 1)\n else:\n pass\n # ///////////////////////////////////买卖主函数\n\n\n\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":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","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":"open","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":1000000,"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":"-16"},{"name":"options_data","node_id":"-16"},{"name":"history_ds","node_id":"-16"},{"name":"benchmark_ds","node_id":"-16"},{"name":"trading_calendar","node_id":"-16"}],"output_ports":[{"name":"raw_perf","node_id":"-16"}],"cacheable":false,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"287d2cb0-f53c-4101-bdf8-104b137c8601-62","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2022-01-03","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2022-04-28","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_FUND","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"510050.HOF\n159928.ZOF\n510310.HOF\n510300.HOF\n\n","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":false,"seq_num":7,"comment":"预测数据,用于回测和模拟","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-16' Position='361.6514892578125,364.5211486816406,200,200'/><node_position Node='287d2cb0-f53c-4101-bdf8-104b137c8601-62' Position='79,-74,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
[2022-05-01 19:50:41.706579] INFO: moduleinvoker: instruments.v2 开始运行..
[2022-05-01 19:50:41.775651] INFO: moduleinvoker: instruments.v2 运行完成[0.069072s].
[2022-05-01 19:50:41.825364] INFO: moduleinvoker: backtest.v8 开始运行..
[2022-05-01 19:50:41.835993] INFO: backtest: biglearning backtest:V8.6.2
[2022-05-01 19:50:41.837341] INFO: backtest: product_type:stock by specified
[2022-05-01 19:50:41.906446] INFO: moduleinvoker: cached.v2 开始运行..
[2022-05-01 19:50:42.040401] INFO: backtest: 读取基金行情完成:1273
[2022-05-01 19:50:42.104167] INFO: moduleinvoker: cached.v2 运行完成[0.197722s].
[2022-05-01 19:50:42.140050] INFO: algo: TradingAlgorithm V1.8.7
[2022-05-01 19:50:42.204737] INFO: algo: trading transform...
[2022-05-01 19:50:44.763011] ERROR: moduleinvoker: module name: backtest, module version: v8, trackeback: IndexError: index 4507 is out of bounds for axis 0 with size 4250
[2022-05-01 19:50:44.769162] ERROR: moduleinvoker: module name: trade, module version: v4, trackeback: IndexError: index 4507 is out of bounds for axis 0 with size 4250
2021-12-30 00:00:00+00:00 2.287
2021-12-31 00:00:00+00:00 2.292
2022-01-04 00:00:00+00:00 2.285
Freq: C, Name: close, dtype: float64
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-92-674cafdce305> in <module>
108 )
109
--> 110 m2 = M.trade.v4(
111 instruments=m7.data,
112 start_date='2022-01-03',
<ipython-input-92-674cafdce305> in m2_handle_data_bigquant_run(context, data)
68 # ///////////////////////////////////买卖主函数
69 # 交易主函数,先确定ETF最强的是谁,然后再根据择时信号判断是否需要切换或者清仓
---> 70 timing_signal = get_timing_signal(context, '510300.HOF') # 获取买\卖\持有信号
71 print('今日自选及择时信号:{} {}'.format(check_out_list[0], timing_signal)) # 打印
72
<ipython-input-92-674cafdce305> in get_timing_signal(context, stock)
50 # 只看RSRS因子值作为买入、持有和清仓依据,前版本还加入了移动均线的上行作为条件
51 def get_timing_signal(context, stock):
---> 52 slope_series = initial_slope_series()[:-1]
53 high_low_data = data.history(context.symbol('510300.HOF'), ['high', 'low'], 18, '1d') # 获取基准历史最高价 最低价
54 intercept, slope, r2 = get_ols(high_low_data.low, high_low_data.high)
<ipython-input-92-674cafdce305> in initial_slope_series()
36
37 def initial_slope_series():
---> 38 data_1 = data.history(context.symbol('510300.HOF'), ['high', 'low'], 618, '1d') # 获取基准历史最高价 最低价
39 return [get_ols(data_1.low[i:i + 18], data_1.high[i:i + 18])[1] for i in range(600)]
40
IndexError: index 4507 is out of bounds for axis 0 with size 4250