{"description":"实验创建于2021/10/29","graph":{"edges":[{"to_node_id":"-41:input_1","from_node_id":"-558:raw_perf"},{"to_node_id":"-558:instruments","from_node_id":"-589:data_1"},{"to_node_id":"-558:options_data","from_node_id":"-589:data_2"}],"nodes":[{"node_id":"-558","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.stock_pools = context.options['data'].read()\n context.show_debug_info = False\n # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数\n context.set_commission(PerOrder(buy_cost=0.0001, sell_cost=0.0001, min_cost=5))\n context.options['hold_days'] = 22\n context.stock_count = 200\n context.trade_index = 0\n context.opt = T.PORTFOLIO_OPTIMIZERS(context.stock_pools, context.start_date, context.end_date, model_type='daily', benchmark='000905.HIX')\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n context.trade_index += 1 # 交易日历递增1\n today = data.current_dt.strftime(\"%Y-%m-%d\")\n print('current_date is:', today)\n context.stock_pool = context.stock_pools[context.stock_pools.date == today]\n\n if context.trade_index == 1: # 第一天建仓\n try:\n context.opt.get_today_factor_data(context.stock_pool, today) ##当日数据初始化\n tf = context.opt.MinStyleDeviation({\"growth\":1}, if_pred=False, relative=True)\n objective = tf[0]\n cons = tf[1:]\n constraints = [context.opt.TotalWeightsConstraint(upper_limit=1), context.opt.Bounds(lower_limit=0, upper_limit=0.05, relative=True), context.opt.ExcludeStyleConstraint(\"growth\",lower_limit=-0.01,upper_limit=0.01,relative=True)]\n constraints.append(cons)\n weights_data = context.opt.optimize(objective, today, constraints, stock_count=context.stock_count, verbose=False, response=True, hard=False)\n\n def buy_1(df):\n target = df[\"instrument\"]\n weight = df[\"weight\"]\n sid = context.symbol(target)\n if data.can_trade(sid):\n context.order_target_percent(sid, weight)\n else:\n print(f\"{today} {target} 无法交易\")\n weights_data.apply(buy_1, axis=1)\n \n except Exception as e:\n print(today, \"当前日期建仓失败! except:\", e)\n context.trade_index -= 1 # 交易日历索引保持不变,以便当日优化失败后次日接着优化\n\n if context.trade_index % context.options[\"hold_days\"] == 0 and context.trade_index != 1: # 每隔调仓日进行调仓\n positions_weight = {e.symbol: p.amount * p.last_sale_price / context.portfolio.portfolio_value for e, p in context.portfolio.positions.items()} # 持仓权重\n equities = [e.symbol for e, p in context.portfolio.positions.items()] # 持仓股票列表\n w0 = pd.Series(positions_weight, index=equities)\n w0 = pd.DataFrame({'pre_weight': w0.values, 'instrument': w0.index})\n context.stock_pool = pd.merge(context.stock_pool, w0, on=['instrument'], how='left').fillna(0)\n context.opt.get_today_factor_data(context.stock_pool, today)\n\n try:\n tf = context.opt.MinStyleDeviation({\"growth\":1}, if_pred=False, relative=True)\n objective = tf[0]\n cons = tf[1:]\n constraints = [context.opt.TotalWeightsConstraint(upper_limit=1), context.opt.Bounds(lower_limit=0, upper_limit=0.05, relative=True),\n context.opt.ExcludeStyleConstraint(\"growth\",lower_limit=-0.01,upper_limit=0.01,relative=True, priority=1), context.opt.TurnoverConstraint(turnrate=0.5, priority=0)]\n constraints.append(cons)\n weights_data = context.opt.optimize(objective, today, constraints, stock_count=context.stock_count, verbose=False, response=True, hard=False)\n\n # 卖出逻辑\n need_hold_stocks = set(weights_data.instrument)\n for sx in equities:\n if sx not in need_hold_stocks: # 无法交易的持仓、优化股票之外的持仓 直接卖出\n order_target_percent(context.symbol(sx), 0)\n equities.remove(sx)\n positions_weight = {e:p for e, p in positions_weight.items() if e != sx}\n\n # 买入逻辑\n def buy_2(df):\n target = df[\"instrument\"]\n weight = df[\"weight\"]\n sid = context.symbol(target)\n if data.can_trade(sid):\n context.order_target_percent(sid, weight)\n else:\n print(f\"{today} {target} 无法交易\")\n weights_data.apply(buy_2, axis=1)\n \n except Exception as e:\n print(today, \"当前日期调仓失败! except:\", e)\n \n print('----------------------------------------------------------------------------------------date {} over----------------------------------------------------------------------------------------'.format(today))","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.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":"open","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":"000905.HIX","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-558"},{"name":"options_data","node_id":"-558"},{"name":"history_ds","node_id":"-558"},{"name":"benchmark_ds","node_id":"-558"},{"name":"trading_calendar","node_id":"-558"}],"output_ports":[{"name":"raw_perf","node_id":"-558"}],"cacheable":false,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-589","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 start_date = '2018-01-01'\n end_date = '2021-10-18'\n index_cons = DataSource('index_element_weight').read(start_date=start_date, end_date=end_date)\n pred_data = index_cons[index_cons.instrument_index=='000905.HIX'][['instrument','weight','date']].reset_index(drop=True)\n pred_df = DataSource.write_df(pred_data)\n ## instruments\n ins = {}\n stock_list = pred_data.instrument.unique().tolist()\n ins['instruments'] = [x for x in stock_list if str(x) != 'nan']\n ins['start_date'] = start_date\n ins['end_date'] = end_date\n ins = DataSource.write_pickle(ins)\n return Outputs(data_1=ins, data_2=pred_df, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-589"},{"name":"input_2","node_id":"-589"},{"name":"input_3","node_id":"-589"}],"output_ports":[{"name":"data_1","node_id":"-589"},{"name":"data_2","node_id":"-589"},{"name":"data_3","node_id":"-589"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-41","module_id":"BigQuantSpace.barra_risk_factor_analysis1.barra_risk_factor_analysis1-v8","parameters":[{"name":"analysis_flag","value":"relative","type":"Literal","bound_global_parameter":null},{"name":"benchmark_index","value":"000905.HIX","type":"Literal","bound_global_parameter":null},{"name":"terms","value":"daily","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-41"}],"output_ports":[{"name":"data_1","node_id":"-41"},{"name":"data_2","node_id":"-41"}],"cacheable":true,"seq_num":3,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-558' Position='64,560,200,200'/><node_position Node='-589' Position='63,413,200,200'/><node_position Node='-41' Position='141.30999755859375,661.8947143554688,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
[2021-10-29 13:40:11.210062] INFO: moduleinvoker: cached.v3 开始运行..
[2021-10-29 13:40:11.237603] INFO: moduleinvoker: 命中缓存
[2021-10-29 13:40:11.239396] INFO: moduleinvoker: cached.v3 运行完成[0.029382s].
[2021-10-29 13:40:13.804809] INFO: moduleinvoker: backtest.v8 开始运行..
[2021-10-29 13:40:13.823950] INFO: moduleinvoker: 命中缓存
[2021-10-29 13:40:16.655694] INFO: moduleinvoker: backtest.v8 运行完成[2.850905s].
[2021-10-29 13:40:16.658384] INFO: moduleinvoker: trade.v4 运行完成[5.405463s].
[2021-10-29 13:40:16.740439] INFO: moduleinvoker: barra_risk_factor_analysis1.v8 开始运行..
[2021-10-29 13:47:21.814502] INFO: moduleinvoker: barra_risk_factor_analysis1.v8 运行完成[425.074076s].
- 收益率47.81%
- 年化收益率11.31%
- 基准收益率13.07%
- 阿尔法0.08
- 贝塔0.84
- 夏普比率0.48
- 胜率0.45
- 盈亏比1.42
- 收益波动率20.54%
- 信息比率0.05
- 最大回撤27.14%
bigcharts-data-start/{"__type":"tabs","__id":"bigchart-b144927050384489ba4f1dc033e10359"}/bigcharts-data-end