{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 本例展示如何在alpha-mind中使用机器学习模型\n",
    "\n",
    "* 请在环境变量中设置`DB_URI`指向数据库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import os\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 = os.environ['DB_URI']\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-05-05 14:00:27,215 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
      "2018-05-05 14:00:29,623 - ALPHA_MIND - INFO - factor data loading finished\n",
      "2018-05-05 14:00:32,271 - ALPHA_MIND - INFO - fit target data loading finished\n",
      "2018-05-05 14:00:36,819 - ALPHA_MIND - INFO - industry data loading finished\n",
      "2018-05-05 14:00:38,193 - ALPHA_MIND - INFO - benchmark data loading finished\n",
      "2018-05-05 14:00:44,173 - ALPHA_MIND - INFO - data merging finished\n",
      "2018-05-05 14:00:44,449 - ALPHA_MIND - INFO - Loading data is finished\n",
      "2018-05-05 14:00:44,624 - 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-05-05 14:00:49,320 - ALPHA_MIND - INFO - Starting data package fetching ...\n",
      "2018-05-05 14:00:50,281 - ALPHA_MIND - INFO - factor data loading finished\n",
      "2018-05-05 14:02:09,314 - ALPHA_MIND - INFO - fit target data loading finished\n",
      "2018-05-05 14:02:09,570 - ALPHA_MIND - INFO - industry data loading finished\n",
      "2018-05-05 14:02:09,700 - ALPHA_MIND - INFO - benchmark data loading finished\n",
      "2018-05-05 14:02:11,229 - ALPHA_MIND - INFO - data merging finished\n",
      "2018-05-05 14:02:11,486 - ALPHA_MIND - INFO - Loading data is finished\n",
      "2018-05-05 14:02:11,553 - 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.051985\n",
       "T      0.122122\n",
       "Δ      0.076031\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",
      "2011-01-04 Const. Testing IC: 0.5800\n",
      "2011-01-04 Regression Testing IC: 0.5802\n",
      "\n",
      "2011-04-07 Const. Testing IC: 0.4844\n",
      "2011-04-07 Regression Testing IC: 0.6694\n",
      "\n",
      "2011-07-04 Const. Testing IC: 0.5862\n",
      "2011-07-04 Regression Testing IC: 0.6396\n",
      "\n",
      "2011-09-27 Const. Testing IC: 0.6321\n",
      "2011-09-27 Regression Testing IC: 0.6784\n",
      "\n",
      "2011-12-27 Const. Testing IC: 0.6823\n",
      "2011-12-27 Regression Testing IC: 0.6613\n",
      "\n",
      "2012-03-29 Const. Testing IC: 0.3676\n",
      "2012-03-29 Regression Testing IC: 0.4809\n",
      "\n",
      "2012-06-29 Const. Testing IC: 0.8619\n",
      "2012-06-29 Regression Testing IC: 0.8502\n",
      "\n",
      "2012-09-21 Const. Testing IC: 0.6434\n",
      "2012-09-21 Regression Testing IC: 0.5957\n",
      "\n",
      "2012-12-21 Const. Testing IC: 0.7544\n",
      "2012-12-21 Regression Testing IC: 0.7612\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.2465\n",
      "2013-12-25 Regression Testing IC: 0.2582\n",
      "\n",
      "2014-03-27 Const. Testing IC: 0.3836\n",
      "2014-03-27 Regression Testing IC: 0.6062\n",
      "\n",
      "2014-06-25 Const. Testing IC: 0.5018\n",
      "2014-06-25 Regression Testing IC: 0.6660\n",
      "\n",
      "2014-09-18 Const. Testing IC: 0.6088\n",
      "2014-09-18 Regression Testing IC: 0.7217\n",
      "\n",
      "2014-12-18 Const. Testing IC: 0.7788\n",
      "2014-12-18 Regression Testing IC: 0.6732\n",
      "\n",
      "2015-03-23 Const. Testing IC: 0.4714\n",
      "2015-03-23 Regression Testing IC: 0.7187\n",
      "\n",
      "2015-06-17 Const. Testing IC: 0.6239\n",
      "2015-06-17 Regression Testing IC: 0.6569\n",
      "\n",
      "2015-09-14 Const. Testing IC: 0.5672\n",
      "2015-09-14 Regression Testing IC: 0.6353\n",
      "\n",
      "2015-12-14 Const. Testing IC: 0.9450\n",
      "2015-12-14 Regression Testing IC: 0.8404\n",
      "\n",
      "2016-03-15 Const. Testing IC: 0.4935\n",
      "2016-03-15 Regression Testing IC: 0.6238\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.6523\n",
      "2016-09-05 Regression Testing IC: 0.6519\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.6659\n",
      "2017-08-31 Regression Testing IC: 0.6648\n",
      "\n",
      "2017-11-30 Const. Testing IC: 0.9940\n",
      "2017-11-30 Regression Testing IC: 0.8681\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.617097</td>\n",
       "      <td>0.658524</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.172611</td>\n",
       "      <td>0.123526</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      naive ic.  regress ic.\n",
       "mean   0.617097     0.658524\n",
       "std    0.172611     0.123526"
      ]
     },
     "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-05-05 14:05:43,938 - ALPHA_MIND - INFO - 2011-01-04 full re-balance: 799\n",
      "2018-05-05 14:05:46,929 - ALPHA_MIND - INFO - 2011-01-04 is finished\n",
      "2018-05-05 14:05:46,941 - ALPHA_MIND - INFO - 2011-04-07 full re-balance: 798\n",
      "2018-05-05 14:05:49,923 - ALPHA_MIND - INFO - 2011-04-07 is finished\n",
      "2018-05-05 14:05:49,935 - ALPHA_MIND - INFO - 2011-07-04 full re-balance: 798\n",
      "2018-05-05 14:05:53,094 - ALPHA_MIND - INFO - 2011-07-04 is finished\n",
      "2018-05-05 14:05:53,106 - ALPHA_MIND - INFO - 2011-09-27 full re-balance: 797\n",
      "2018-05-05 14:05:56,334 - ALPHA_MIND - INFO - 2011-09-27 is finished\n",
      "2018-05-05 14:05:56,345 - ALPHA_MIND - INFO - 2011-12-27 full re-balance: 798\n",
      "2018-05-05 14:05:59,460 - ALPHA_MIND - INFO - 2011-12-27 is finished\n",
      "2018-05-05 14:05:59,469 - ALPHA_MIND - INFO - 2012-03-29 full re-balance: 796\n",
      "2018-05-05 14:06:02,529 - ALPHA_MIND - INFO - 2012-03-29 is finished\n",
      "2018-05-05 14:06:02,538 - ALPHA_MIND - INFO - 2012-06-29 full re-balance: 798\n",
      "2018-05-05 14:06:05,431 - ALPHA_MIND - INFO - 2012-06-29 is finished\n",
      "2018-05-05 14:06:05,441 - ALPHA_MIND - INFO - 2012-09-21 full re-balance: 799\n",
      "2018-05-05 14:06:08,657 - ALPHA_MIND - INFO - 2012-09-21 is finished\n",
      "2018-05-05 14:06:08,668 - ALPHA_MIND - INFO - 2012-12-21 full re-balance: 799\n",
      "2018-05-05 14:06:11,593 - ALPHA_MIND - INFO - 2012-12-21 is finished\n",
      "2018-05-05 14:06:11,602 - ALPHA_MIND - INFO - 2013-03-27 full re-balance: 800\n",
      "2018-05-05 14:06:14,838 - ALPHA_MIND - INFO - 2013-03-27 is finished\n",
      "2018-05-05 14:06:14,849 - ALPHA_MIND - INFO - 2013-07-01 full re-balance: 800\n",
      "2018-05-05 14:06:17,748 - ALPHA_MIND - INFO - 2013-07-01 is finished\n",
      "2018-05-05 14:06:17,759 - ALPHA_MIND - INFO - 2013-09-25 full re-balance: 799\n",
      "2018-05-05 14:06:20,887 - ALPHA_MIND - INFO - 2013-09-25 is finished\n",
      "2018-05-05 14:06:20,897 - ALPHA_MIND - INFO - 2013-12-25 full re-balance: 800\n",
      "2018-05-05 14:06:24,106 - ALPHA_MIND - INFO - 2013-12-25 is finished\n",
      "2018-05-05 14:06:24,117 - ALPHA_MIND - INFO - 2014-03-27 full re-balance: 800\n",
      "2018-05-05 14:06:27,141 - ALPHA_MIND - INFO - 2014-03-27 is finished\n",
      "2018-05-05 14:06:27,151 - ALPHA_MIND - INFO - 2014-06-25 full re-balance: 800\n",
      "2018-05-05 14:06:30,239 - ALPHA_MIND - INFO - 2014-06-25 is finished\n",
      "2018-05-05 14:06:30,249 - ALPHA_MIND - INFO - 2014-09-18 full re-balance: 800\n",
      "2018-05-05 14:06:33,049 - ALPHA_MIND - INFO - 2014-09-18 is finished\n",
      "2018-05-05 14:06:33,058 - ALPHA_MIND - INFO - 2014-12-18 full re-balance: 800\n",
      "2018-05-05 14:06:35,926 - ALPHA_MIND - INFO - 2014-12-18 is finished\n",
      "2018-05-05 14:06:35,936 - ALPHA_MIND - INFO - 2015-03-23 full re-balance: 799\n",
      "2018-05-05 14:06:39,030 - ALPHA_MIND - INFO - 2015-03-23 is finished\n",
      "2018-05-05 14:06:39,040 - ALPHA_MIND - INFO - 2015-06-17 full re-balance: 800\n",
      "2018-05-05 14:06:41,833 - ALPHA_MIND - INFO - 2015-06-17 is finished\n",
      "2018-05-05 14:06:41,844 - ALPHA_MIND - INFO - 2015-09-14 full re-balance: 800\n",
      "2018-05-05 14:06:44,789 - ALPHA_MIND - INFO - 2015-09-14 is finished\n",
      "2018-05-05 14:06:44,800 - ALPHA_MIND - INFO - 2015-12-14 full re-balance: 800\n",
      "2018-05-05 14:06:48,028 - ALPHA_MIND - INFO - 2015-12-14 is finished\n",
      "2018-05-05 14:06:48,039 - ALPHA_MIND - INFO - 2016-03-15 full re-balance: 799\n",
      "2018-05-05 14:06:51,033 - ALPHA_MIND - INFO - 2016-03-15 is finished\n",
      "2018-05-05 14:06:51,044 - ALPHA_MIND - INFO - 2016-06-13 full re-balance: 800\n",
      "2018-05-05 14:06:54,095 - ALPHA_MIND - INFO - 2016-06-13 is finished\n",
      "2018-05-05 14:06:54,107 - ALPHA_MIND - INFO - 2016-09-05 full re-balance: 800\n",
      "2018-05-05 14:06:57,177 - ALPHA_MIND - INFO - 2016-09-05 is finished\n",
      "2018-05-05 14:06:57,188 - ALPHA_MIND - INFO - 2016-12-07 full re-balance: 800\n",
      "2018-05-05 14:07:00,012 - ALPHA_MIND - INFO - 2016-12-07 is finished\n",
      "2018-05-05 14:07:00,023 - ALPHA_MIND - INFO - 2017-03-09 full re-balance: 800\n",
      "2018-05-05 14:07:03,315 - ALPHA_MIND - INFO - 2017-03-09 is finished\n",
      "2018-05-05 14:07:03,328 - ALPHA_MIND - INFO - 2017-06-08 full re-balance: 800\n",
      "2018-05-05 14:07:06,336 - ALPHA_MIND - INFO - 2017-06-08 is finished\n",
      "2018-05-05 14:07:06,348 - ALPHA_MIND - INFO - 2017-08-31 full re-balance: 800\n",
      "2018-05-05 14:07:09,893 - ALPHA_MIND - INFO - 2017-08-31 is finished\n",
      "2018-05-05 14:07:09,904 - ALPHA_MIND - INFO - 2017-11-30 full re-balance: 800\n",
      "2018-05-05 14:07:13,134 - 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 0x1fbc693ee48>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nREREJOD9P7YiQOMpZl+hAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1fbc693e438>"
      ]
     },
     "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.3"
  },
  "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
}
