遗传算法在因子投资中的应用

策略分享
标签: #<Tag:0x00007fcbfd438930>

(iQuant) #1

遗传规划(Genetic Programming)由达尔文的进化论演变而来,是一种智能进化
计算 (Evolutionary Computation) 技术,通常用来求解最优化问题。遗传算法在量化投资中的应用主要在于遗传规划(简称GP),是遗传算法的推广和更一般地形式。本文主要介绍在BigQuant平台上如何利用GP算法实现因子寻优,策略完整代码见文末,可直接克隆。

在多因子投资过程中我们面临的问题是选取哪些因子,以及这些因子如何组合在一起才能实现超额收益,使用GP算法可以实现给定目标下的因子最优化组合。

GP算法首先将因子组合表达为树结构,通过设置函数集和因子集,按照一定的适应度函数不断进化,生成表达式,然后基于这些表达式构建交易信号进行回测,输出策略回测指标。

一、因子组合的表示方法

假设我们有基础因子X0和X1(例如市盈率月末值、每股收益月末值),需要预测目标y(例如下月收益率)。一个可能的因子组合方式是:
$$y=X_0^2-3*X_1+0.5$$

image

在这个二叉树里,所有的叶节点都是基础因子变量或者常数,内部的节点则是函数集中的函数。函数集中的可选函数包括:

'add':加法,二元运算
'sub':减法,二元运算
'mul':乘法,二元运算
'div':除法,二元运算
'sqrt':平方根,一元运算
'log':对数,一元运算
'abs':绝对值,一元运算
'neg':相反数,一元运算
'inv':倒数,一元运算
'max':最大值,二元运算
'min':最小值,二元运算
'sin':正弦(弧度),一元运算
'cos':余弦(弧度),一元运算
'tan':正切(弧度),一元运算

二、计算适应度函数

和其他机器学习算法一样,遗传算法的核心在于衡量公式的适应度(fitness function),适应度的地位类似于目标函数、score、loss和error。在GP回归模型(SymbolicRegressor)训练过程中利用遗传算法得到因子组合的公式预测目标变量的值,然后利用label值计算两者之间的error,通过不断寻找因子组合公式来最小化这个error。GP回归模型中的适应度函数有三种,都是机器学习里常见的error function:

  • mae: mean absolute error
  • mse: mean squared error
  • rmse: root mean squared error

当然,用户也可以自定义适应度的标准。

遗传算法内,耗时最大的部分无疑是适应度的计算。所以,gplearn允许用户通过修改n_jobs参数控制并行运算。在数据量和公式数量较大时,并行计算的速度优势最为明显。

三、组合公式的进化

首先定义每代种群的因子组合公式数量(population_size),所有的组合都会以二叉树公式方式随机生成。每棵公式树的深度都会受到init_depth参数的限制。init_depth是一个二元组(min_depth, max_depth),树的初始深度将处在[min_depth, max_depth]的区间内(包含端点)。

通常而言,变量越多,模型越复杂,那么population_size就越大越好。

为了模拟自然选择的过程,大部分「不适应环境」,即适应度不足的因子组合公式会被淘汰。从每一代的所有公式中,tournament_size个公式会被随机选中,其中适应度最高的公式将被认定为生存竞争的胜利者,进入下一代。tournament_size的大小与进化论中的选择压力息息相关:tournament_size越小,选择压力越大,算法收敛的速度可能更快,但也有可能错过一些隐藏的优秀公式。

进入下一代的优胜公式未必原封不动——完全不改变优胜者,直接让它进入下一代的策略被称为繁殖(reproduction)。用户可以采取一系列的变异措施:

交叉(Crossover)
优胜者内随机选择一个子树,替换为另一棵公式树的随机子树。此处的另一棵公式树通常是剩余公式树中适应度最高的。算法模型中,由p_cross_over参数控制子树交叉的发生概率。

image

子树变异(Subtree Mutation)

这是一种更激进的变异策略:优胜者的一棵子树将被另一棵完全随机的全新子树代替。算法模型中,由p_subtree_mutation参数控制子树变异的发生概率。
image

hoist变异(Hoist Mutation)

hoist变异是一种对抗公式树膨胀(bloating,即过于复杂)的方法:从优胜者公式树内随机选择一个子树A,再从A里随机选择一个子树B,然后把B提升到A原来的位置,用B替代A。hoist的含义即「升高、提起」。算法模型中,由p_hoist_mutation参数控制子树变异的发生概率。

image

点变异(Point Mutation)

一个随机的节点将会被改变,比如加法可以被替换成除法,变量X0可以被替换成常数-2.5。点变异可以重新加入一些先前被淘汰的函数和变量,从而促进公式的多样性。算法模型中,由p_point_replace参数控制点变异的发生概率。

image

通过上述几种方式实现每代种群内个体的表达式进化,就实现了“优胜劣汰,适者生存”的森林法则,最终获取最优的因子组合表达式,同时解决了因子选择和因子间组合方式这两个问题。

四、BigQuant平台上实现GP算法

4.1 构建基础因子库

我们首先构建月频因子数据库,参考华泰金工的相关报告,构建了估值、成长、盈利、财务质量、市值、反转、波动率、换手率、beta和技术等十类基础因子。所有的因子数据按照以下流程进行了清洗处理:

  • 计算基础因子日线数据
  • 计算衍生因子日线数据,例如技术指标日线值计算
  • 对日线因子数据进行月度频率转化
  • 对月度横截面数据逐月进行去极值、行业市值中性化、zscore归一化处理
  • 对zscore后数据中的na值使用0值填充

处理后的结果存放在factor_CN_STOCK_A表中,可以通过DataSource(‘factor_CN_STOCK_A’).read()查看相应数据,表中的各因子如"alpha001"因子公式含义见文末链接。

4.2 构建GP算法流程

如下图所示,分别获取两个历史阶段数据作为GP算法的训练集和预测集数据,在“遗传规划模型训练”模块中使用训练集数据训练GP模型获取因子组合表达式,在“遗传规划模型预测”模块中使用预测集数据和模型进行下月收益率预测。模型训练后会输出最优表达式,例如:

末代最佳表达式: sub(X2, X2) 筛选后最佳表达式: max(min(X1, X0), abs(add(mul(0.781, X1), mul(-0.630, X1))))

获取因子组合表达式后,我们可以通过因子数据计算表达式的下月收益率预测值,并构建月度轮仓策略,每月月初卖出上月持有的股票,并选取下月收益率预测值最高的40只股票买入。
通过m6模块对训练集的数据进行回测,如下图所示;

通过m17模块对预测集的数据进行回测,如下图所示。

4.3 批量测试

为了寻找最优因子组合,采用自定义运行模块,将基础因子进行随机组合,并计算回测结果。
计算流程如下图所示,

image

各种因子组合的最优化结果存储在自定义运行模块m5中,通过m5.result[i]获取各因子组合的计算结果,整理后可以绘制每个因子组合的月度换仓策略下的收益率回测曲线。下面列举几个因子组合的例子:

  • 例1:组合因子表达式
    min(X17, X14) 其中X17和X14 分别为因子库中的alpha014和alpha019

  • 例2:组合因子表达式
    sqrt(mul(max(-0.110, X8), add(X4, X5))) 其中X8,X4和X5分别为 alpha008 alpha026和alpha014

上述例子中是使用2010-01-01~2016-01-01日期范围的历史月度因子数据作为训练集训练GP模型,预测集数据日期范围为2016-01-01~2019-01-01。蓝色曲线为沪深300基准收益,橙色曲线为策略净值曲线,绿色曲线为相对收益率曲线,黑色曲线为日相对收益率的复利净值曲线(假设每日的相对收益可以每日复利投资)。

结语: 本文展示了如何利用平台的月度因子数据和GP遗传规划算法进行因子组合寻优。

参考文献:

2、广发证券—《基于遗传规划的智能交易策略方法—另类交易策略系列之九》
3、申万宏源—《遗传算法和遗传规划—寻找不一样的Alpha》
4遗传算法详解
5BigQuant月度因子库数据

克隆策略

    {"Description":"实验创建于2018/6/4","Summary":"","Graph":{"EdgesInternal":[{"DestinationInputPortId":"-304:instruments","SourceOutputPortId":"-1023:data"},{"DestinationInputPortId":"-104:instruments","SourceOutputPortId":"-1023:data"},{"DestinationInputPortId":"-276:instruments","SourceOutputPortId":"-1031:data"},{"DestinationInputPortId":"-112:instruments","SourceOutputPortId":"-1031:data"},{"DestinationInputPortId":"-276:options_data","SourceOutputPortId":"-113:data_1"},{"DestinationInputPortId":"-113:input_1","SourceOutputPortId":"-196:data_1"},{"DestinationInputPortId":"-304:options_data","SourceOutputPortId":"-196:data_2"},{"DestinationInputPortId":"-196:input_1","SourceOutputPortId":"-104:data"},{"DestinationInputPortId":"-196:input_2","SourceOutputPortId":"-103:data"},{"DestinationInputPortId":"-113:input_2","SourceOutputPortId":"-103:data"},{"DestinationInputPortId":"-107:features_ds","SourceOutputPortId":"-103:data"},{"DestinationInputPortId":"-104:features","SourceOutputPortId":"-107:data"},{"DestinationInputPortId":"-112:features","SourceOutputPortId":"-107:data"},{"DestinationInputPortId":"-113:input_3","SourceOutputPortId":"-112:data"}],"ModuleNodes":[{"Id":"-276","ModuleId":"BigQuantSpace.trade.trade-v4","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n # 按日期过滤得到今日的预测数据\n today=data.current_dt.strftime('%Y%m%d')\n year_month = today[:6]\n if context.is_new == year_month:\n return \n \n context.is_new = year_month \n \n try:\n stock_to_buy = context.daily_buy_stock.ix[year_month]\n except:\n stock_to_buy = []\n \n \n \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions]\n stock_to_sell = [i for i in stock_hold_now if i not in stock_to_buy]\n\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 \n # 如果当天没有买入的股票,就返回\n if len(stock_to_buy) == 0:\n return\n \n # 等权重买入 \n weight = 1 / len(stock_to_buy)\n # 换仓买入\n for stock in stock_to_buy:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), weight)","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"prepare","Value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n \n # 加载预测数据,获取每日股票的预测指标值\n prediction = context.options['data'].read_pickle()['prediction'] \n gp_model = context.options['data'].read_pickle()['gp_model']\n \n def tmp(df): \n if df['month'] == '01':\n return str(df['y'] + 1)\n else:\n return str(df['y'])\n \n prediction['month'] = prediction.date.apply(lambda x:x.month+1 if x.month<12 else 1)\n prediction['y'] = prediction.date.apply(lambda x:x.year)\n prediction['month'] = prediction['month'].apply(lambda x:'0'+str(x) if x <10 else str(x))\n prediction['year'] = prediction.apply(tmp, axis=1)\n prediction['month'] = prediction['year']+prediction['month']\n \n context.daily_buy_stock = prediction.groupby('month').\\\n apply(lambda x:list(x.sort_values('prediction_value',\n ascending=False)['instrument'][:40]))\n import re\n totalCount = re.findall(r'X(\\d+)', str(gp_model))\n f = m8.data.read_pickle()\n \n print(context.daily_buy_stock.head(),'\\n','###'*15,'表达式: ',gp_model, [f[int(i)] for i in totalCount])","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n context.is_new = ''\n print('预测集回测结果:')","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"before_trading_start","Value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"volume_limit","Value":0.025,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_buy","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_sell","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":"1000000","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"auto_cancel_non_tradable_orders","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"data_frequency","Value":"daily","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"price_type","Value":"后复权","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"product_type","Value":"股票","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"plot_charts","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"backtest_only","Value":"False","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"000300.HIX","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-276"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-276"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"history_ds","NodeId":"-276"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"benchmark_ds","NodeId":"-276"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"trading_calendar","NodeId":"-276"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-276","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":17,"Comment":"测试集回测","CommentCollapsed":false},{"Id":"-1023","ModuleId":"BigQuantSpace.instruments.instruments-v2","ModuleParameters":[{"Name":"start_date","Value":"2016-01-31","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2017-01-31","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"market","Value":"CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_list","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_count","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"rolling_conf","NodeId":"-1023"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-1023","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":2,"Comment":"","CommentCollapsed":true},{"Id":"-1031","ModuleId":"BigQuantSpace.instruments.instruments-v2","ModuleParameters":[{"Name":"start_date","Value":"2017-01-31","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2018-11-30","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"market","Value":"CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_list","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_count","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"rolling_conf","NodeId":"-1031"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-1031","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":3,"Comment":"","CommentCollapsed":true},{"Id":"-304","ModuleId":"BigQuantSpace.trade.trade-v4","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n # 按日期过滤得到今日的预测数据\n today=data.current_dt.strftime('%Y%m%d')\n year_month = today[:6]\n if context.is_new == year_month:\n return \n \n context.is_new = year_month \n \n try:\n stock_to_buy = context.daily_buy_stock.ix[year_month]\n except:\n stock_to_buy = []\n \n \n \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions]\n stock_to_sell = [i for i in stock_hold_now if i not in stock_to_buy]\n\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 \n # 如果当天没有买入的股票,就返回\n if len(stock_to_buy) == 0:\n return\n \n # 等权重买入 \n weight = 1 / len(stock_to_buy)\n # 换仓买入\n for stock in stock_to_buy:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), weight)","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"prepare","Value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n \n # 加载预测数据,获取每日股票的预测指标值\n prediction = context.options['data'].read_pickle()['prediction'] \n gp_model = context.options['data'].read_pickle()['gp_model']\n \n def tmp(df): \n if df['month'] == '01':\n return str(df['y'] + 1)\n else:\n return str(df['y'])\n \n prediction['month'] = prediction.date.apply(lambda x:x.month+1 if x.month<12 else 1)\n prediction['y'] = prediction.date.apply(lambda x:x.year)\n prediction['month'] = prediction['month'].apply(lambda x:'0'+str(x) if x <10 else str(x))\n prediction['year'] = prediction.apply(tmp, axis=1)\n prediction['month'] = prediction['year']+prediction['month']\n\n context.daily_buy_stock = prediction.groupby('month').\\\n apply(lambda x:list(x.sort_values('prediction_value',\n ascending=False)['instrument'][:40]))\n import re\n totalCount = re.findall(r'X(\\d+)', str(gp_model))\n f = m8.data.read_pickle()\n \n print(context.daily_buy_stock.head(),'\\n','###'*15,'表达式: ', gp_model, [f[int(i)] for i in totalCount])","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n context.is_new = ''\n print('训练集回测结果:')","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"before_trading_start","Value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"volume_limit","Value":0.025,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_buy","Value":"close","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_sell","Value":"close","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":"1000000","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"auto_cancel_non_tradable_orders","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"data_frequency","Value":"daily","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"price_type","Value":"后复权","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"product_type","Value":"股票","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"plot_charts","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"backtest_only","Value":"False","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"000300.HIX","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-304"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-304"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"history_ds","NodeId":"-304"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"benchmark_ds","NodeId":"-304"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"trading_calendar","NodeId":"-304"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-304","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":6,"Comment":"训练集回测","CommentCollapsed":false},{"Id":"-113","ModuleId":"BigQuantSpace.GP_predict.GP_predict-v1","ModuleParameters":[],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-113"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-113"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_3","NodeId":"-113"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-113","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":1,"Comment":"","CommentCollapsed":true},{"Id":"-196","ModuleId":"BigQuantSpace.gplearn_train.gplearn_train-v1","ModuleParameters":[{"Name":"IS_USE_BEST_GP","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"gnrtn","Value":"3","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"ppltn","Value":"80","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_samples","Value":"0.9","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"metric","Value":"rmse","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"stopping_criteria","Value":"0.01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"init_depth_min","Value":"2","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"init_depth_max","Value":"6","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"p_crossover","Value":"0.9","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"p_hoist_mutation","Value":"0.01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"p_point_mutation","Value":"0.05","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"p_point_replace","Value":"0.01","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"p_subtree_mutation","Value":"0.01","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_1","NodeId":"-196"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"input_2","NodeId":"-196"}],"OutputPortsInternal":[{"Name":"data_1","NodeId":"-196","OutputType":null},{"Name":"data_2","NodeId":"-196","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":4,"Comment":"","CommentCollapsed":true},{"Id":"-104","ModuleId":"BigQuantSpace.use_datasource.use_datasource-v1","ModuleParameters":[{"Name":"datasource_id","Value":"factor_CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-104"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-104"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-104","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":9,"Comment":"","CommentCollapsed":true},{"Id":"-103","ModuleId":"BigQuantSpace.factor_select.factor_select-v16","ModuleParameters":[{"Name":"feature","Value":"%7B%22enumItems%22%3A%5B%7B%22value%22%3A%22alpha001%22%2C%22displayValue%22%3A%22alpha001%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22alpha002%22%2C%22displayValue%22%3A%22alpha002%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22alpha003%22%2C%22displayValue%22%3A%22alpha003%22%2C%22selected%22%3Atrue%7D%2C%7B%22value%22%3A%22alpha004%22%2C%22displayValue%22%3A%22alpha004%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha005%22%2C%22displayValue%22%3A%22alpha005%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha006%22%2C%22displayValue%22%3A%22alpha006%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha007%22%2C%22displayValue%22%3A%22alpha007%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha008%22%2C%22displayValue%22%3A%22alpha008%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha009%22%2C%22displayValue%22%3A%22alpha009%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha010%22%2C%22displayValue%22%3A%22alpha010%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha011%22%2C%22displayValue%22%3A%22alpha011%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha012%22%2C%22displayValue%22%3A%22alpha012%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha013%22%2C%22displayValue%22%3A%22alpha013%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha014%22%2C%22displayValue%22%3A%22alpha014%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha015%22%2C%22displayValue%22%3A%22alpha015%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha016%22%2C%22displayValue%22%3A%22alpha016%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha017%22%2C%22displayValue%22%3A%22alpha017%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha018%22%2C%22displayValue%22%3A%22alpha018%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha019%22%2C%22displayValue%22%3A%22alpha019%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha020%22%2C%22displayValue%22%3A%22alpha020%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha021%22%2C%22displayValue%22%3A%22alpha021%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha022%22%2C%22displayValue%22%3A%22alpha022%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha023%22%2C%22displayValue%22%3A%22alpha023%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha024%22%2C%22displayValue%22%3A%22alpha024%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha025%22%2C%22displayValue%22%3A%22alpha025%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha026%22%2C%22displayValue%22%3A%22alpha026%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha027%22%2C%22displayValue%22%3A%22alpha027%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha028%22%2C%22displayValue%22%3A%22alpha028%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha029%22%2C%22displayValue%22%3A%22alpha029%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha030%22%2C%22displayValue%22%3A%22alpha030%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha031%22%2C%22displayValue%22%3A%22alpha031%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha032%22%2C%22displayValue%22%3A%22alpha032%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha033%22%2C%22displayValue%22%3A%22alpha033%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha034%22%2C%22displayValue%22%3A%22alpha034%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha035%22%2C%22displayValue%22%3A%22alpha035%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha036%22%2C%22displayValue%22%3A%22alpha036%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha037%22%2C%22displayValue%22%3A%22alpha037%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha038%22%2C%22displayValue%22%3A%22alpha038%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha039%22%2C%22displayValue%22%3A%22alpha039%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha040%22%2C%22displayValue%22%3A%22alpha040%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha041%22%2C%22displayValue%22%3A%22alpha041%22%2C%22selected%22%3Afalse%7D%2C%7B%22value%22%3A%22alpha042%22%2C%22displayValue%22%3A%22alpha042%22%2C%22selected%22%3Afalse%7D%5D%7D","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[],"OutputPortsInternal":[{"Name":"data","NodeId":"-103","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":8,"Comment":"","CommentCollapsed":true},{"Id":"-107","ModuleId":"BigQuantSpace.input_features.input_features-v1","ModuleParameters":[{"Name":"features","Value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nprice\n","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features_ds","NodeId":"-107"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-107","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":10,"Comment":"","CommentCollapsed":true},{"Id":"-112","ModuleId":"BigQuantSpace.use_datasource.use_datasource-v1","ModuleParameters":[{"Name":"datasource_id","Value":"factor_CN_STOCK_A","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-112"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"features","NodeId":"-112"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-112","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":7,"Comment":"","CommentCollapsed":true}],"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions><NodePosition Node='-276' Position='-43,350,200,200'/><NodePosition Node='-1023' Position='-560,-169,200,200'/><NodePosition Node='-1031' Position='193,-145,200,200'/><NodePosition Node='-304' Position='-520.5108032226562,311,200,200'/><NodePosition Node='-113' Position='-200,214,200,200'/><NodePosition Node='-196' Position='-457,134,200,200'/><NodePosition Node='-104' Position='-414,-1,200,200'/><NodePosition Node='-103' Position='-99,-226,200,200'/><NodePosition Node='-107' Position='-261,-115,200,200'/><NodePosition Node='-112' Position='117,20,200,200'/></NodePositions><NodeGroups /></DataV1>"},"IsDraft":true,"ParentExperimentId":null,"WebService":{"IsWebServiceExperiment":false,"Inputs":[],"Outputs":[],"Parameters":[{"Name":"交易日期","Value":"","ParameterDefinition":{"Name":"交易日期","FriendlyName":"交易日期","DefaultValue":"","ParameterType":"String","HasDefaultValue":true,"IsOptional":true,"ParameterRules":[],"HasRules":false,"MarkupType":0,"CredentialDescriptor":null}}],"WebServiceGroupId":null,"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions></NodePositions><NodeGroups /></DataV1>"},"DisableNodesUpdate":false,"Category":"user","Tags":[],"IsPartialRun":true}
    In [7]:
    # 本代码由可视化策略环境自动生成 2019年1月14日 14:57
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m6_handle_data_bigquant_run(context, data):
        
        # 按日期过滤得到今日的预测数据
        today=data.current_dt.strftime('%Y%m%d')
        year_month = today[:6]
        if context.is_new == year_month:
            return 
                                       
        context.is_new = year_month                            
        
        try:
            stock_to_buy = context.daily_buy_stock.ix[year_month]
        except:
            stock_to_buy = []
        
        
        
        stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
        stock_to_sell = [i for i in stock_hold_now if i not in stock_to_buy]
    
        # 换仓卖出
        for stock in stock_to_sell:
            if data.can_trade(context.symbol(stock)):
                context.order_target_percent(context.symbol(stock), 0)
        
        # 如果当天没有买入的股票,就返回
        if len(stock_to_buy) == 0:
            return
        
        # 等权重买入 
        weight =  1 / len(stock_to_buy)
        # 换仓买入
        for stock in stock_to_buy:
            if data.can_trade(context.symbol(stock)):
                context.order_target_percent(context.symbol(stock), weight)
    # 回测引擎:准备数据,只执行一次
    def m6_prepare_bigquant_run(context):
       
        # 加载预测数据,获取每日股票的预测指标值
        prediction = context.options['data'].read_pickle()['prediction']    
        gp_model = context.options['data'].read_pickle()['gp_model']
        
        def tmp(df): 
            if df['month'] == '01':
                return str(df['y'] + 1)
            else:
                return str(df['y'])
            
        prediction['month'] = prediction.date.apply(lambda x:x.month+1 if x.month<12 else 1)
        prediction['y'] = prediction.date.apply(lambda x:x.year)
        prediction['month'] = prediction['month'].apply(lambda x:'0'+str(x) if x <10 else str(x))
        prediction['year'] = prediction.apply(tmp, axis=1)
        prediction['month'] = prediction['year']+prediction['month']
    
        context.daily_buy_stock = prediction.groupby('month').\
            apply(lambda x:list(x.sort_values('prediction_value',
                                              ascending=False)['instrument'][:40]))
        import re
        totalCount = re.findall(r'X(\d+)', str(gp_model))
        f = m8.data.read_pickle()
            
        print(context.daily_buy_stock.head(),'\n','###'*15,'表达式: ', gp_model, [f[int(i)] for i in totalCount])
    # 回测引擎:初始化函数,只执行一次
    def m6_initialize_bigquant_run(context):
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        context.is_new = ''
        print('训练集回测结果:')
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m6_before_trading_start_bigquant_run(context, data):
        pass
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m17_handle_data_bigquant_run(context, data):
        
        # 按日期过滤得到今日的预测数据
        today=data.current_dt.strftime('%Y%m%d')
        year_month = today[:6]
        if context.is_new == year_month:
            return 
                                       
        context.is_new = year_month                            
        
        try:
            stock_to_buy = context.daily_buy_stock.ix[year_month]
        except:
            stock_to_buy = []
        
        
        
        stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
        stock_to_sell = [i for i in stock_hold_now if i not in stock_to_buy]
    
        # 换仓卖出
        for stock in stock_to_sell:
            if data.can_trade(context.symbol(stock)):
                context.order_target_percent(context.symbol(stock), 0)
        
        # 如果当天没有买入的股票,就返回
        if len(stock_to_buy) == 0:
            return
        
        # 等权重买入 
        weight =  1 / len(stock_to_buy)
        # 换仓买入
        for stock in stock_to_buy:
            if data.can_trade(context.symbol(stock)):
                context.order_target_percent(context.symbol(stock), weight)
    # 回测引擎:准备数据,只执行一次
    def m17_prepare_bigquant_run(context):
       
        # 加载预测数据,获取每日股票的预测指标值
        prediction = context.options['data'].read_pickle()['prediction']    
        gp_model = context.options['data'].read_pickle()['gp_model']
        
        def tmp(df): 
            if df['month'] == '01':
                return str(df['y'] + 1)
            else:
                return str(df['y'])
            
        prediction['month'] = prediction.date.apply(lambda x:x.month+1 if x.month<12 else 1)
        prediction['y'] = prediction.date.apply(lambda x:x.year)
        prediction['month'] = prediction['month'].apply(lambda x:'0'+str(x) if x <10 else str(x))
        prediction['year'] = prediction.apply(tmp, axis=1)
        prediction['month'] = prediction['year']+prediction['month']
        
        context.daily_buy_stock = prediction.groupby('month').\
            apply(lambda x:list(x.sort_values('prediction_value',
                                              ascending=False)['instrument'][:40]))
        import re
        totalCount = re.findall(r'X(\d+)', str(gp_model))
        f = m8.data.read_pickle()
        
        print(context.daily_buy_stock.head(),'\n','###'*15,'表达式: ',gp_model, [f[int(i)] for i in totalCount])
    # 回测引擎:初始化函数,只执行一次
    def m17_initialize_bigquant_run(context):
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        context.is_new = ''
        print('预测集回测结果:')
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m17_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m2 = M.instruments.v2(
        start_date='2016-01-31',
        end_date='2017-01-31',
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    m3 = M.instruments.v2(
        start_date='2017-01-31',
        end_date='2018-11-30',
        market='CN_STOCK_A',
        instrument_list='',
        max_count=0
    )
    
    m8 = M.factor_select.v16(
        feature=['alpha001', 'alpha002', 'alpha003']
    )
    
    m10 = M.input_features.v1(
        features_ds=m8.data,
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    price
    """
    )
    
    m9 = M.use_datasource.v1(
        instruments=m2.data,
        features=m10.data,
        datasource_id='factor_CN_STOCK_A',
        start_date='',
        end_date='',
        m_cached=False
    )
    
    m4 = M.gplearn_train.v1(
        input_1=m9.data,
        input_2=m8.data,
        IS_USE_BEST_GP=True,
        gnrtn=3,
        ppltn=80,
        max_samples=0.9,
        metric='rmse',
        stopping_criteria=0.01,
        init_depth_min=2,
        init_depth_max=6,
        p_crossover=0.9,
        p_hoist_mutation=0.01,
        p_point_mutation=0.05,
        p_point_replace=0.01,
        p_subtree_mutation=0.01
    )
    
    m6 = M.trade.v4(
        instruments=m2.data,
        options_data=m4.data_2,
        start_date='',
        end_date='',
        handle_data=m6_handle_data_bigquant_run,
        prepare=m6_prepare_bigquant_run,
        initialize=m6_initialize_bigquant_run,
        before_trading_start=m6_before_trading_start_bigquant_run,
        volume_limit=0.025,
        order_price_field_buy='close',
        order_price_field_sell='close',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='后复权',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark='000300.HIX'
    )
    
    m7 = M.use_datasource.v1(
        instruments=m3.data,
        features=m10.data,
        datasource_id='factor_CN_STOCK_A',
        start_date='',
        end_date=''
    )
    
    m1 = M.GP_predict.v1(
        input_1=m4.data_1,
        input_2=m8.data,
        input_3=m7.data
    )
    
    m17 = M.trade.v4(
        instruments=m3.data,
        options_data=m1.data_1,
        start_date='',
        end_date='',
        handle_data=m17_handle_data_bigquant_run,
        prepare=m17_prepare_bigquant_run,
        initialize=m17_initialize_bigquant_run,
        before_trading_start=m17_before_trading_start_bigquant_run,
        volume_limit=0.025,
        order_price_field_buy='open',
        order_price_field_sell='open',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='后复权',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark='000300.HIX'
    )
    
    [2019-01-14 14:55:18.288011] INFO: bigquant: instruments.v2 开始运行..
    [2019-01-14 14:55:18.293212] INFO: bigquant: 命中缓存
    [2019-01-14 14:55:18.294084] INFO: bigquant: instruments.v2 运行完成[0.006091s].
    [2019-01-14 14:55:18.296407] INFO: bigquant: instruments.v2 开始运行..
    [2019-01-14 14:55:18.301385] INFO: bigquant: 命中缓存
    [2019-01-14 14:55:18.302470] INFO: bigquant: instruments.v2 运行完成[0.006053s].
    [2019-01-14 14:55:18.305753] INFO: bigquant: factor_select.v16 开始运行..
    [2019-01-14 14:55:18.310317] INFO: bigquant: 命中缓存
    [2019-01-14 14:55:18.311280] INFO: bigquant: factor_select.v16 运行完成[0.005528s].
    [2019-01-14 14:55:18.313708] INFO: bigquant: input_features.v1 开始运行..
    [2019-01-14 14:55:18.317749] INFO: bigquant: 命中缓存
    [2019-01-14 14:55:18.318685] INFO: bigquant: input_features.v1 运行完成[0.00497s].
    [2019-01-14 14:55:18.320740] INFO: bigquant: use_datasource.v1 开始运行..
    [2019-01-14 14:55:21.888356] INFO: bigquant: use_datasource.v1 运行完成[3.567574s].
    [2019-01-14 14:55:21.892713] INFO: bigquant: gplearn_train.v1 开始运行..
    参与训练模型的因子有:  ['alpha001', 'alpha002', 'alpha003']
        |    Population Average   |             Best Individual              |
    ---- ------------------------- ------------------------------------------ ----------
     Gen   Length          Fitness   Length          Fitness      OOB Fitness  Time Left
       0     16.8 110.33691733488766       12 0.15053385057077157 0.16956418914954743      1.03s
       1     5.01 8.680501429719829        3 0.14970258869213351 0.1760622784425075      0.54s
       2     2.42 0.977946912370028        3 0.14907948323079948 0.18075752651707433      0.00s
    ############################################# 末代最佳表达式:  sub(X2, X2) 筛选后最佳表达式: max(min(X1, X0), abs(add(mul(0.781, X1), mul(-0.630, X1))))
    ############################################# 因子有效性: True
    ############################################# 使用全局最优表达式 True
    [2019-01-14 14:55:31.175290] INFO: bigquant: gplearn_train.v1 运行完成[9.282556s].
    [2019-01-14 14:55:31.190401] INFO: bigquant: backtest.v8 开始运行..
    [2019-01-14 14:55:31.192447] INFO: bigquant: biglearning backtest:V8.1.6
    month
    201602    [601668.SHA, 601390.SHA, 600606.SHA, 601186.SH...
    201603    [601668.SHA, 601390.SHA, 600606.SHA, 601186.SH...
    201604    [601668.SHA, 601186.SHA, 600606.SHA, 601390.SH...
    201605    [601668.SHA, 600606.SHA, 601186.SHA, 601390.SH...
    201606    [601668.SHA, 600606.SHA, 601186.SHA, 601390.SH...
    dtype: object 
     ############################################# 表达式:  max(min(X1, X0), abs(add(mul(0.781, X1), mul(-0.630, X1)))) ['alpha002', 'alpha001', 'alpha002', 'alpha002']
    [2019-01-14 14:55:34.990538] INFO: bigquant: product_type:stock by specified
    [2019-01-14 14:55:44.132361] INFO: bigquant: 读取股票行情完成:1371857
    [2019-01-14 14:55:57.406676] INFO: algo: TradingAlgorithm V1.4.2
    训练集回测结果:
    [2019-01-14 14:56:07.351097] INFO: algo: trading transform...
    [2019-01-14 14:56:09.712668] INFO: Performance: Simulated 242 trading days out of 242.
    [2019-01-14 14:56:09.713959] INFO: Performance: first open: 2016-02-01 09:30:00+00:00
    [2019-01-14 14:56:09.714944] INFO: Performance: last close: 2017-01-26 15:00:00+00:00
    
    • 收益率23.5%
    • 年化收益率24.58%
    • 基准收益率15.0%
    • 阿尔法0.05
    • 贝塔1.32
    • 夏普比率0.87
    • 胜率0.84
    • 盈亏比1.95
    • 收益波动率25.52%
    • 信息比率0.04
    • 最大回撤18.81%
    [2019-01-14 14:56:11.602993] INFO: bigquant: backtest.v8 运行完成[40.412566s].
    [2019-01-14 14:56:11.609718] INFO: bigquant: use_datasource.v1 开始运行..
    [2019-01-14 14:56:11.615113] INFO: bigquant: 命中缓存
    [2019-01-14 14:56:11.616074] INFO: bigquant: use_datasource.v1 运行完成[0.00636s].
    [2019-01-14 14:56:11.623019] INFO: bigquant: GP_predict.v1 开始运行..
    [2019-01-14 14:56:11.759952] INFO: bigquant: GP_predict.v1 运行完成[0.136922s].
    [2019-01-14 14:56:11.781148] INFO: bigquant: backtest.v8 开始运行..
    [2019-01-14 14:56:11.783480] INFO: bigquant: biglearning backtest:V8.1.6
    month
    201702    [601668.SHA, 000002.SZA, 600606.SHA, 601186.SH...
    201703    [601668.SHA, 000002.SZA, 600606.SHA, 601186.SH...
    201704    [601668.SHA, 000002.SZA, 600606.SHA, 601186.SH...
    201705    [601668.SHA, 000002.SZA, 600606.SHA, 601186.SH...
    201706    [601668.SHA, 000002.SZA, 600606.SHA, 601186.SH...
    dtype: object 
     ############################################# 表达式:  max(min(X1, X0), abs(add(mul(0.781, X1), mul(-0.630, X1)))) ['alpha002', 'alpha001', 'alpha002', 'alpha002']
    [2019-01-14 14:56:19.594249] INFO: bigquant: product_type:stock by specified
    [2019-01-14 14:56:35.299891] INFO: bigquant: 读取股票行情完成:2229404
    [2019-01-14 14:56:57.484401] INFO: algo: TradingAlgorithm V1.4.2
    预测集回测结果:
    [2019-01-14 14:57:08.605246] INFO: algo: trading transform...
    [2019-01-14 14:57:13.134043] INFO: Performance: Simulated 449 trading days out of 449.
    [2019-01-14 14:57:13.135052] INFO: Performance: first open: 2017-02-03 09:30:00+00:00
    [2019-01-14 14:57:13.135801] INFO: Performance: last close: 2018-11-30 15:00:00+00:00
    
    • 收益率-21.02%
    • 年化收益率-12.4%
    • 基准收益率-6.35%
    • 阿尔法-0.08
    • 贝塔1.02
    • 夏普比率-0.59
    • 胜率0.51
    • 盈亏比0.72
    • 收益波动率23.07%
    • 信息比率-0.03
    • 最大回撤34.39%
    [2019-01-14 14:57:15.836299] INFO: bigquant: backtest.v8 运行完成[64.055128s].
    

    (iQuant) #2

    (user341) #3

    学习学习 为你们点赞