Commit 69b2d0d7 authored by Dr.李's avatar Dr.李

added machine learning example

parent b8bd868e
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> 本例展示如何在alpha-mind中使用机器学习模型"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import datetime as dt\n",
"import numpy as np\n",
"import pandas as pd\n",
"from alphamind.api import *\n",
"from PyFin.api import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 数据配置\n",
"------------"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"freq = '60b'\n",
"universe = Universe('custom', ['zz800'])\n",
"batch = 1\n",
"neutralized_risk = industry_styles\n",
"risk_model = 'short'\n",
"pre_process = [winsorize_normal, standardize]\n",
"post_process = [standardize]\n",
"warm_start = 3\n",
"data_source = None\n",
"horizon = map_freq(freq)\n",
"\n",
"engine = SqlEngine(data_source)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们使用当期的`roe_q`因子,来尝试预测未来大概一个月以后的`roe_q`因子。\n",
"\n",
"* 训练的股票池为`zz800`;;\n",
"* 因子都经过中性化以及标准化等预处理;\n",
"* 对于线性模型,我们以20个工作日为一个时间间隔,用过去4期的数据作为训练用特征。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"fit_intercept = True\n",
"kernal_feature = 'roe_q'\n",
"regress_features = {kernal_feature: LAST(kernal_feature),\n",
" kernal_feature + '_l1': SHIFT(kernal_feature, 1),\n",
" kernal_feature + '_l2': SHIFT(kernal_feature, 2),\n",
" kernal_feature + '_l3': SHIFT(kernal_feature, 3)\n",
" }\n",
"const_features = {kernal_feature: LAST(kernal_feature)}\n",
"fit_target = [kernal_feature]\n",
"\n",
"data_meta = DataMeta(freq=freq,\n",
" universe=universe,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" risk_model=risk_model,\n",
" pre_process=pre_process,\n",
" post_process=post_process,\n",
" warm_start=warm_start,\n",
" data_source=data_source)\n",
"\n",
"alpha_model = LinearRegression(features=regress_features, fit_intercept=True, fit_target=fit_target)\n",
"composer = Composer(alpha_model=alpha_model, data_meta=data_meta)\n",
"\n",
"start_date = '2011-01-01'\n",
"end_date = '2018-01-01'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 指标与时间序列相关性分析\n",
"--------------\n",
"\n",
"在本段中,我们要尝试回答如下的问题:**对于考察的指标,是当期指标与下期指标哪个对于下期收益的预测性更好?**\n",
"\n",
"这里,假设下期日期为`T`,考察周期为`M`,则:\n",
"\n",
"* 当期指标为,`T - M`时的指标值;\n",
"* 下期指标为,`T`时的指标值;\n",
"* 下期收益为,`T - M`至`T`时的区间收益;\n",
"* 我们同时检验了下期数据与当期数据差值与下期收益的相关性。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-04-16 19:44:49,889 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
"2018-04-16 19:44:50,436 - ALPHA_MIND - INFO - factor data loading finished\n",
"2018-04-16 19:44:51,753 - ALPHA_MIND - INFO - fit target data loading finished\n",
"2018-04-16 19:44:51,921 - ALPHA_MIND - INFO - industry data loading finished\n",
"2018-04-16 19:44:52,029 - ALPHA_MIND - INFO - benchmark data loading finished\n",
"2018-04-16 19:44:53,205 - ALPHA_MIND - INFO - data merging finished\n",
"2018-04-16 19:44:53,403 - ALPHA_MIND - INFO - Loading data is finished\n",
"2018-04-16 19:44:53,523 - ALPHA_MIND - INFO - Data processing is finished\n"
]
}
],
"source": [
"data_package1 = fetch_data_package(engine,\n",
" alpha_factors=[kernal_feature],\n",
" start_date=start_date,\n",
" end_date=end_date,\n",
" frequency=freq,\n",
" universe=universe,\n",
" benchmark=906,\n",
" warm_start=warm_start,\n",
" batch=batch,\n",
" neutralized_risk=neutralized_risk,\n",
" pre_process=pre_process,\n",
" post_process=post_process,\n",
" fit_target=fit_target)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"t_m_factor = data_package1['predict']['x']\n",
"t_factor = data_package1['predict']['y']\n",
"codes_list1 = data_package1['predict']['code']"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-04-16 19:44:53,628 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
"2018-04-16 19:44:54,124 - ALPHA_MIND - INFO - factor data loading finished\n",
"2018-04-16 19:46:01,930 - ALPHA_MIND - INFO - fit target data loading finished\n",
"2018-04-16 19:46:02,091 - ALPHA_MIND - INFO - industry data loading finished\n",
"2018-04-16 19:46:02,197 - ALPHA_MIND - INFO - benchmark data loading finished\n",
"2018-04-16 19:46:03,408 - ALPHA_MIND - INFO - data merging finished\n",
"2018-04-16 19:46:03,614 - ALPHA_MIND - INFO - Loading data is finished\n",
"2018-04-16 19:46:03,656 - ALPHA_MIND - INFO - Data processing is finished\n"
]
}
],
"source": [
"data_package2 = fetch_data_package(engine,\n",
" alpha_factors=[kernal_feature],\n",
" start_date=start_date,\n",
" end_date=end_date,\n",
" frequency=freq,\n",
" universe=universe,\n",
" benchmark=906,\n",
" warm_start=warm_start,\n",
" batch=1,\n",
" neutralized_risk=neutralized_risk,\n",
" pre_process=pre_process,\n",
" post_process=post_process)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"t_return = data_package2['predict']['y']\n",
"codes_list2 = data_package2['predict']['code']"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"total_data = pd.DataFrame(columns=['dx', 'T-M', 'T', 'Δ'])\n",
"\n",
"for key in t_m_factor.keys():\n",
" t_m = t_m_factor[key].values.flatten()\n",
" t = t_factor[key].flatten()\n",
" ret = t_return[key].flatten()\n",
" \n",
" df1 = pd.DataFrame({'T-M': t_m, 'T': t}, index=codes_list1[key])\n",
" df2 = pd.DataFrame({'dx': ret}, index=codes_list2[key])\n",
" \n",
" df = pd.merge(df1, df2, left_index=True, right_index=True)\n",
" df['Δ'] = df['T'] - df['T-M']\n",
" total_data.loc[key, ['dx', 'T-M', 'T', 'Δ']] = df.corr().loc['dx'][['dx', 'T-M', 'T', 'Δ']]"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dx 1.000000\n",
"T-M 0.053046\n",
"T 0.124049\n",
"Δ 0.076091\n",
"dtype: float64"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"total_data.mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 模型预测\n",
"-----------"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"ref_date = '2017-01-31'\n",
"ref_date = adjustDateByCalendar('china.sse', ref_date).strftime('%Y-%m-%d')\n",
"composer.train(ref_date)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Testing IC: 0.5464\n"
]
}
],
"source": [
"print(\"Testing IC: {0:.4f}\".format(composer.ic(ref_date=ref_date)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 模型对比 (线性回归模型 v.s. Naive - 常数线性模型)\n",
"------------------"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"const_model = ConstLinearModel(features=const_features, weights={kernal_feature: 1.}, fit_target=fit_target)\n",
"regression_model = LinearRegression(features=regress_features, fit_intercept=fit_intercept, fit_target=fit_target)\n",
"\n",
"const_composer = Composer(alpha_model=const_model, data_meta=data_meta)\n",
"regression_composer = Composer(alpha_model=regression_model, data_meta=data_meta)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"const_composer.train(ref_date)\n",
"regression_composer.train(ref_date)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Const. Testing IC: 0.5529\n",
"Regression Testing IC: 0.5464\n"
]
}
],
"source": [
"print(\"\\nConst. Testing IC: {0:.4f}\".format(const_composer.ic(ref_date=ref_date)))\n",
"print(\"Regression Testing IC: {0:.4f}\".format(regression_composer.ic(ref_date=ref_date)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 模型时间序列\n",
"-------------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"通过比较在测试集的结果,我们观察如下两个模型的表现:\n",
"\n",
"* Naive Model:简单的使用因子上期值作为当期值的预测;\n",
"* 线性回归模型:利用过去四期的因子值回归后得到模型,然后用这个模型预测当期值;"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"2010-07-07 Const. Testing IC: 0.5775\n",
"2010-07-07 Regression Testing IC: 0.5750\n",
"\n",
"2010-10-11 Const. Testing IC: 0.6586\n",
"2010-10-11 Regression Testing IC: 0.6907\n",
"\n",
"2011-01-04 Const. Testing IC: 0.5799\n",
"2011-01-04 Regression Testing IC: 0.5460\n",
"\n",
"2011-04-07 Const. Testing IC: 0.4843\n",
"2011-04-07 Regression Testing IC: 0.6691\n",
"\n",
"2011-07-04 Const. Testing IC: 0.5862\n",
"2011-07-04 Regression Testing IC: 0.6395\n",
"\n",
"2011-09-27 Const. Testing IC: 0.6134\n",
"2011-09-27 Regression Testing IC: 0.6809\n",
"\n",
"2011-12-27 Const. Testing IC: 0.6155\n",
"2011-12-27 Regression Testing IC: 0.5721\n",
"\n",
"2012-03-29 Const. Testing IC: 0.3999\n",
"2012-03-29 Regression Testing IC: 0.5205\n",
"\n",
"2012-06-29 Const. Testing IC: 0.0054\n",
"2012-06-29 Regression Testing IC: 0.0579\n",
"\n",
"2012-09-21 Const. Testing IC: 0.6827\n",
"2012-09-21 Regression Testing IC: 0.6291\n",
"\n",
"2012-12-21 Const. Testing IC: 0.7544\n",
"2012-12-21 Regression Testing IC: 0.2699\n",
"\n",
"2013-03-27 Const. Testing IC: 0.4713\n",
"2013-03-27 Regression Testing IC: 0.6270\n",
"\n",
"2013-07-01 Const. Testing IC: 0.6004\n",
"2013-07-01 Regression Testing IC: 0.6572\n",
"\n",
"2013-09-25 Const. Testing IC: 0.6586\n",
"2013-09-25 Regression Testing IC: 0.6992\n",
"\n",
"2013-12-25 Const. Testing IC: 0.2487\n",
"2013-12-25 Regression Testing IC: 0.2631\n",
"\n",
"2014-03-27 Const. Testing IC: 0.3904\n",
"2014-03-27 Regression Testing IC: 0.6418\n",
"\n",
"2014-06-25 Const. Testing IC: 0.5018\n",
"2014-06-25 Regression Testing IC: 0.6655\n",
"\n",
"2014-09-18 Const. Testing IC: 0.6088\n",
"2014-09-18 Regression Testing IC: 0.7215\n",
"\n",
"2014-12-18 Const. Testing IC: 0.7788\n",
"2014-12-18 Regression Testing IC: 0.6722\n",
"\n",
"2015-03-23 Const. Testing IC: 0.4714\n",
"2015-03-23 Regression Testing IC: 0.7190\n",
"\n",
"2015-06-17 Const. Testing IC: 0.6239\n",
"2015-06-17 Regression Testing IC: 0.6565\n",
"\n",
"2015-09-14 Const. Testing IC: 0.5984\n",
"2015-09-14 Regression Testing IC: 0.6728\n",
"\n",
"2015-12-14 Const. Testing IC: 0.9509\n",
"2015-12-14 Regression Testing IC: 0.8566\n",
"\n",
"2016-03-15 Const. Testing IC: 0.4935\n",
"2016-03-15 Regression Testing IC: 0.6239\n",
"\n",
"2016-06-13 Const. Testing IC: 0.5908\n",
"2016-06-13 Regression Testing IC: 0.5992\n",
"\n",
"2016-09-05 Const. Testing IC: 0.6832\n",
"2016-09-05 Regression Testing IC: 0.6782\n",
"\n",
"2016-12-07 Const. Testing IC: 0.9502\n",
"2016-12-07 Regression Testing IC: 0.9013\n",
"\n",
"2017-03-09 Const. Testing IC: 0.5316\n",
"2017-03-09 Regression Testing IC: 0.5288\n",
"\n",
"2017-06-08 Const. Testing IC: 0.5680\n",
"2017-06-08 Regression Testing IC: 0.5823\n",
"\n",
"2017-08-31 Const. Testing IC: 0.6802\n",
"2017-08-31 Regression Testing IC: 0.6701\n",
"\n",
"2017-11-30 Const. Testing IC: 0.9940\n",
"2017-11-30 Regression Testing IC: 0.8682\n"
]
}
],
"source": [
"model_dates = [d.strftime('%Y-%m-%d') for d in list(data_package2['predict']['x'].keys())]\n",
"\n",
"model_df = pd.DataFrame(columns=['naive', 'regress', 'naive ic.', 'regress ic.'])\n",
"\n",
"for ref_date in model_dates:\n",
" const_composer.train(ref_date)\n",
" regression_composer.train(ref_date)\n",
" \n",
" model_df.loc[ref_date, 'naive'] = const_composer[ref_date]\n",
" model_df.loc[ref_date, 'regress'] = regression_composer[ref_date]\n",
" model_df.loc[ref_date, 'naive ic.'] = const_composer.ic(ref_date=ref_date)\n",
" model_df.loc[ref_date, 'regress ic.'] = regression_composer.ic(ref_date=ref_date)\n",
" print(\"\\n{1} Const. Testing IC: {0:.4f}\".format(model_df.loc[ref_date, 'naive ic.'], ref_date))\n",
" print(\"{1} Regression Testing IC: {0:.4f}\".format( model_df.loc[ref_date, 'regress ic.'], ref_date))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>naive ic.</th>\n",
" <th>regress ic.</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>0.592022</td>\n",
" <td>0.617903</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>0.193060</td>\n",
" <td>0.168037</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" naive ic. regress ic.\n",
"mean 0.592022 0.617903\n",
"std 0.193060 0.168037"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_df[['naive ic.', 'regress ic.']].agg(['mean', 'std'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在这个例子中,线性回归模型的IC值略微高于Naive模型。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 回测( simple long short strategy)\n",
"--------------------------"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"industry_name = 'sw_adj'\n",
"industry_level = 1\n",
"\n",
"industry_names = industry_list(industry_name, industry_level)\n",
"industry_total = engine.fetch_industry_matrix_range(universe, dates=model_dates, category=industry_name, level=industry_level)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2018-04-16 19:48:10,968 - ALPHA_MIND - INFO - 2010-07-07 full re-balance: 799\n",
"2018-04-16 19:48:12,597 - ALPHA_MIND - INFO - 2010-07-07 is finished\n",
"2018-04-16 19:48:12,606 - ALPHA_MIND - INFO - 2010-10-11 full re-balance: 798\n",
"2018-04-16 19:48:14,369 - ALPHA_MIND - INFO - 2010-10-11 is finished\n",
"2018-04-16 19:48:14,379 - ALPHA_MIND - INFO - 2011-01-04 full re-balance: 799\n",
"2018-04-16 19:48:16,279 - ALPHA_MIND - INFO - 2011-01-04 is finished\n",
"2018-04-16 19:48:16,287 - ALPHA_MIND - INFO - 2011-04-07 full re-balance: 798\n",
"2018-04-16 19:48:18,041 - ALPHA_MIND - INFO - 2011-04-07 is finished\n",
"2018-04-16 19:48:18,050 - ALPHA_MIND - INFO - 2011-07-04 full re-balance: 798\n",
"2018-04-16 19:48:19,781 - ALPHA_MIND - INFO - 2011-07-04 is finished\n",
"2018-04-16 19:48:19,790 - ALPHA_MIND - INFO - 2011-09-27 full re-balance: 797\n",
"2018-04-16 19:48:21,799 - ALPHA_MIND - INFO - 2011-09-27 is finished\n",
"2018-04-16 19:48:21,807 - ALPHA_MIND - INFO - 2011-12-27 full re-balance: 798\n",
"2018-04-16 19:48:23,524 - ALPHA_MIND - INFO - 2011-12-27 is finished\n",
"2018-04-16 19:48:23,532 - ALPHA_MIND - INFO - 2012-03-29 full re-balance: 796\n",
"2018-04-16 19:48:25,323 - ALPHA_MIND - INFO - 2012-03-29 is finished\n",
"2018-04-16 19:48:25,331 - ALPHA_MIND - INFO - 2012-06-29 full re-balance: 798\n",
"2018-04-16 19:48:27,215 - ALPHA_MIND - INFO - 2012-06-29 is finished\n",
"2018-04-16 19:48:27,225 - ALPHA_MIND - INFO - 2012-09-21 full re-balance: 799\n",
"2018-04-16 19:48:28,993 - ALPHA_MIND - INFO - 2012-09-21 is finished\n",
"2018-04-16 19:48:29,001 - ALPHA_MIND - INFO - 2012-12-21 full re-balance: 799\n",
"2018-04-16 19:48:30,722 - ALPHA_MIND - INFO - 2012-12-21 is finished\n",
"2018-04-16 19:48:30,730 - ALPHA_MIND - INFO - 2013-03-27 full re-balance: 800\n",
"2018-04-16 19:48:32,704 - ALPHA_MIND - INFO - 2013-03-27 is finished\n",
"2018-04-16 19:48:32,712 - ALPHA_MIND - INFO - 2013-07-01 full re-balance: 800\n",
"2018-04-16 19:48:34,441 - ALPHA_MIND - INFO - 2013-07-01 is finished\n",
"2018-04-16 19:48:34,450 - ALPHA_MIND - INFO - 2013-09-25 full re-balance: 799\n",
"2018-04-16 19:48:36,183 - ALPHA_MIND - INFO - 2013-09-25 is finished\n",
"2018-04-16 19:48:36,191 - ALPHA_MIND - INFO - 2013-12-25 full re-balance: 800\n",
"2018-04-16 19:48:38,121 - ALPHA_MIND - INFO - 2013-12-25 is finished\n",
"2018-04-16 19:48:38,130 - ALPHA_MIND - INFO - 2014-03-27 full re-balance: 800\n",
"2018-04-16 19:48:39,910 - ALPHA_MIND - INFO - 2014-03-27 is finished\n",
"2018-04-16 19:48:39,920 - ALPHA_MIND - INFO - 2014-06-25 full re-balance: 800\n",
"2018-04-16 19:48:41,848 - ALPHA_MIND - INFO - 2014-06-25 is finished\n",
"2018-04-16 19:48:41,856 - ALPHA_MIND - INFO - 2014-09-18 full re-balance: 800\n",
"2018-04-16 19:48:43,598 - ALPHA_MIND - INFO - 2014-09-18 is finished\n",
"2018-04-16 19:48:43,606 - ALPHA_MIND - INFO - 2014-12-18 full re-balance: 800\n",
"2018-04-16 19:48:45,300 - ALPHA_MIND - INFO - 2014-12-18 is finished\n",
"2018-04-16 19:48:45,309 - ALPHA_MIND - INFO - 2015-03-23 full re-balance: 799\n",
"2018-04-16 19:48:47,258 - ALPHA_MIND - INFO - 2015-03-23 is finished\n",
"2018-04-16 19:48:47,267 - ALPHA_MIND - INFO - 2015-06-17 full re-balance: 800\n",
"2018-04-16 19:48:48,995 - ALPHA_MIND - INFO - 2015-06-17 is finished\n",
"2018-04-16 19:48:49,004 - ALPHA_MIND - INFO - 2015-09-14 full re-balance: 800\n",
"2018-04-16 19:48:50,814 - ALPHA_MIND - INFO - 2015-09-14 is finished\n",
"2018-04-16 19:48:50,822 - ALPHA_MIND - INFO - 2015-12-14 full re-balance: 800\n",
"2018-04-16 19:48:52,784 - ALPHA_MIND - INFO - 2015-12-14 is finished\n",
"2018-04-16 19:48:52,792 - ALPHA_MIND - INFO - 2016-03-15 full re-balance: 799\n",
"2018-04-16 19:48:54,587 - ALPHA_MIND - INFO - 2016-03-15 is finished\n",
"2018-04-16 19:48:54,597 - ALPHA_MIND - INFO - 2016-06-13 full re-balance: 800\n",
"2018-04-16 19:48:56,296 - ALPHA_MIND - INFO - 2016-06-13 is finished\n",
"2018-04-16 19:48:56,307 - ALPHA_MIND - INFO - 2016-09-05 full re-balance: 800\n",
"2018-04-16 19:48:58,297 - ALPHA_MIND - INFO - 2016-09-05 is finished\n",
"2018-04-16 19:48:58,306 - ALPHA_MIND - INFO - 2016-12-07 full re-balance: 800\n",
"2018-04-16 19:49:00,028 - ALPHA_MIND - INFO - 2016-12-07 is finished\n",
"2018-04-16 19:49:00,036 - ALPHA_MIND - INFO - 2017-03-09 full re-balance: 800\n",
"2018-04-16 19:49:01,747 - ALPHA_MIND - INFO - 2017-03-09 is finished\n",
"2018-04-16 19:49:01,754 - ALPHA_MIND - INFO - 2017-06-08 full re-balance: 800\n",
"2018-04-16 19:49:03,679 - ALPHA_MIND - INFO - 2017-06-08 is finished\n",
"2018-04-16 19:49:03,688 - ALPHA_MIND - INFO - 2017-08-31 full re-balance: 800\n",
"2018-04-16 19:49:05,486 - ALPHA_MIND - INFO - 2017-08-31 is finished\n",
"2018-04-16 19:49:05,494 - ALPHA_MIND - INFO - 2017-11-30 full re-balance: 800\n",
"2018-04-16 19:49:07,468 - ALPHA_MIND - INFO - 2017-11-30 is finished\n"
]
}
],
"source": [
"rets1 = []\n",
"rets2 = []\n",
"\n",
"for i, ref_date in enumerate(model_dates):\n",
" py_ref_date = dt.datetime.strptime(ref_date, '%Y-%m-%d')\n",
" industry_matrix = industry_total[industry_total.trade_date == ref_date]\n",
" dx_returns = pd.DataFrame({'dx': data_package2['predict']['y'][py_ref_date].flatten(),\n",
" 'code': data_package2['predict']['code'][py_ref_date].flatten()})\n",
" \n",
" res = pd.merge(dx_returns, industry_matrix, on=['code']).dropna()\n",
" codes = res.code.values.tolist()\n",
" \n",
" alpha_logger.info('{0} full re-balance: {1}'.format(ref_date, len(codes)))\n",
" \n",
" ## naive model\n",
" \n",
" raw_predict1 = const_composer.predict(ref_date).loc[codes]\n",
" er1 = raw_predict1.fillna(raw_predict1.median()).values\n",
" \n",
" target_pos1, _ = er_portfolio_analysis(er1,\n",
" res.industry_name.values,\n",
" None,\n",
" None,\n",
" False,\n",
" None,\n",
" method='ls')\n",
" \n",
" target_pos1['code'] = codes\n",
" result1 = pd.merge(target_pos1, dx_returns, on=['code'])\n",
" ret1 = result1.weight.values @ (np.exp(result1.dx.values) - 1.)\n",
" rets1.append(np.log(1. + ret1))\n",
"\n",
" ## regression model\n",
" \n",
" raw_predict2 = regression_composer.predict(ref_date).loc[codes]\n",
" er2 = raw_predict2.fillna(raw_predict2.median()).values\n",
" \n",
" target_pos2, _ = er_portfolio_analysis(er2,\n",
" res.industry_name.values,\n",
" None,\n",
" None,\n",
" False,\n",
" None,\n",
" method='ls')\n",
" \n",
" target_pos2['code'] = codes\n",
" result2 = pd.merge(target_pos2, dx_returns, on=['code'])\n",
" ret2 = result2.weight.values @ (np.exp(result2.dx.values) - 1.)\n",
" rets2.append(np.log(1. + ret2))\n",
" ## perfect forcast\n",
" \n",
" alpha_logger.info('{0} is finished'.format(ref_date))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x1b6adc713c8>"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ret_df = pd.DataFrame({'naive': rets1, 'regress': rets2}, index=model_dates)\n",
"ret_df.loc[advanceDateByCalendar('china.sse', model_dates[-1], freq).strftime('%Y-%m-%d')] = 0.\n",
"ret_df = ret_df.shift(1)\n",
"ret_df.iloc[0] = 0.\n",
"\n",
"ret_df[['naive', 'regress']].cumsum().plot(figsize=(12, 6),\n",
" title='Fixed freq rebalanced: {0}'.format(freq))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment