{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前 SDK 版本号是: 1.2.6 已是最新版\n"
     ]
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "from matplotlib import pyplot as plt\n",
    "import uqer\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from uqer import DataAPI as api\n",
    "import alphamind.data.store as store\n",
    "from alphamind.data.store import append_industry_info\n",
    "from alphamind.data.neutralize import neutralize\n",
    "\n",
    "plt.style.use('ggplot')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "使用token: f1b9bea1d0b4e489c5ab9b69c3e2326a1bee6057af858067dbd1546453f428b2 验证成功\n"
     ]
    }
   ],
   "source": [
    "_ = uqer.Client(token='f1b9bea1d0b4e489c5ab9b69c3e2326a1bee6057af858067dbd1546453f428b2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "ref_date = '20170623'\n",
    "factor = 'FY12P'\n",
    "weight_factor = 'LFLO'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Algorithm Description\n",
    "--------------------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "猜测的 ``neutralize`` 残差$\\bar Res$计算公式：\n",
    "\n",
    "$$\\bar Res_{i,k} = \\bar f_{i,k} - \\sum_j \\beta_{j,k} \\times \\bar Ex_{i, j, k}$$\n",
    "\n",
    "其中：$k$为行业分类，$i$为该行业中第$i$只股票，$j$为第$j$个风险因子。$\\bar f$为因子序列，$\\bar Ex$为风险暴露矩阵。系数$\\beta_{j,k}$由OLS确定。\n",
    "\n",
    "下面的章节，我们分别比较三种``neutralize``的方法差别：\n",
    "\n",
    "* **UQER Neutralize**\n",
    "\n",
    "    使用优矿的SDK计算因子残差。\n",
    "\n",
    "\n",
    "* **Alpha-Mind Neutralize**\n",
    "\n",
    "    使用alpha-mind计算因子残差，alpha-mind可以由以下地址安装：\n",
    "    \n",
    "    ```\n",
    "    https://github.com/wegamekinglc/alpha-mind\n",
    "    ```\n",
    "\n",
    "* **Direct Weighted Least Square Fit Implementation**\n",
    "\n",
    "    直接使用scikit-learn的线性回归功能来计算因子残差。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Raw Data\n",
    "---------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "risk_factors = pd.read_pickle('20170623.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "risk_styles = risk_factors.columns[1:].tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "factor_data = api.MktStockFactorsOneDayGet(tradeDate=ref_date, field='ticker,' + factor + ',' + weight_factor)\n",
    "total_data = pd.merge(factor_data, risk_factors, on=['ticker'])\n",
    "total_data.set_index('ticker', inplace=True)\n",
    "total_data.dropna(inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>FY12P</th>\n",
       "      <th>LFLO</th>\n",
       "      <th>BETA</th>\n",
       "      <th>MOMENTUM</th>\n",
       "      <th>SIZE</th>\n",
       "      <th>EARNYILD</th>\n",
       "      <th>RESVOL</th>\n",
       "      <th>GROWTH</th>\n",
       "      <th>BTOP</th>\n",
       "      <th>LEVERAGE</th>\n",
       "      <th>...</th>\n",
       "      <th>BEV</th>\n",
       "      <th>FOODPROD</th>\n",
       "      <th>HEALTH</th>\n",
       "      <th>BANKS</th>\n",
       "      <th>DVFININS</th>\n",
       "      <th>REALEST</th>\n",
       "      <th>SOFTWARE</th>\n",
       "      <th>HDWRSEMI</th>\n",
       "      <th>UTILITIE</th>\n",
       "      <th>COUNTRY</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ticker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>600778</th>\n",
       "      <td>-0.0916</td>\n",
       "      <td>21.6110</td>\n",
       "      <td>1.678</td>\n",
       "      <td>-1.031</td>\n",
       "      <td>-2.916</td>\n",
       "      <td>-3.419</td>\n",
       "      <td>-0.922</td>\n",
       "      <td>-1.468</td>\n",
       "      <td>0.224</td>\n",
       "      <td>1.801</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000962</th>\n",
       "      <td>-0.0819</td>\n",
       "      <td>22.0732</td>\n",
       "      <td>0.616</td>\n",
       "      <td>-1.163</td>\n",
       "      <td>-2.363</td>\n",
       "      <td>-2.523</td>\n",
       "      <td>0.616</td>\n",
       "      <td>-2.122</td>\n",
       "      <td>-0.255</td>\n",
       "      <td>-0.426</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>601608</th>\n",
       "      <td>-0.0345</td>\n",
       "      <td>23.8892</td>\n",
       "      <td>0.265</td>\n",
       "      <td>-0.277</td>\n",
       "      <td>-0.170</td>\n",
       "      <td>-2.712</td>\n",
       "      <td>-1.117</td>\n",
       "      <td>-1.617</td>\n",
       "      <td>-0.764</td>\n",
       "      <td>0.310</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>600096</th>\n",
       "      <td>-0.0059</td>\n",
       "      <td>22.8140</td>\n",
       "      <td>1.105</td>\n",
       "      <td>-1.336</td>\n",
       "      <td>-1.280</td>\n",
       "      <td>-2.718</td>\n",
       "      <td>-1.250</td>\n",
       "      <td>-0.935</td>\n",
       "      <td>-0.186</td>\n",
       "      <td>2.400</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>002154</th>\n",
       "      <td>-0.0046</td>\n",
       "      <td>22.1009</td>\n",
       "      <td>1.179</td>\n",
       "      <td>-2.021</td>\n",
       "      <td>-2.144</td>\n",
       "      <td>-2.722</td>\n",
       "      <td>-1.028</td>\n",
       "      <td>-0.841</td>\n",
       "      <td>0.588</td>\n",
       "      <td>-0.419</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 45 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         FY12P     LFLO   BETA  MOMENTUM   SIZE  EARNYILD  RESVOL  GROWTH  \\\n",
       "ticker                                                                      \n",
       "600778 -0.0916  21.6110  1.678    -1.031 -2.916    -3.419  -0.922  -1.468   \n",
       "000962 -0.0819  22.0732  0.616    -1.163 -2.363    -2.523   0.616  -2.122   \n",
       "601608 -0.0345  23.8892  0.265    -0.277 -0.170    -2.712  -1.117  -1.617   \n",
       "600096 -0.0059  22.8140  1.105    -1.336 -1.280    -2.718  -1.250  -0.935   \n",
       "002154 -0.0046  22.1009  1.179    -2.021 -2.144    -2.722  -1.028  -0.841   \n",
       "\n",
       "         BTOP  LEVERAGE   ...     BEV  FOODPROD  HEALTH  BANKS  DVFININS  \\\n",
       "ticker                    ...                                              \n",
       "600778  0.224     1.801   ...       0         0       0      0         0   \n",
       "000962 -0.255    -0.426   ...       0         0       0      0         0   \n",
       "601608 -0.764     0.310   ...       0         0       0      0         0   \n",
       "600096 -0.186     2.400   ...       0         0       0      0         0   \n",
       "002154  0.588    -0.419   ...       0         0       0      0         0   \n",
       "\n",
       "        REALEST  SOFTWARE  HDWRSEMI  UTILITIE  COUNTRY  \n",
       "ticker                                                  \n",
       "600778        0         0         0         0        1  \n",
       "000962        0         0         0         0        1  \n",
       "601608        0         0         0         0        1  \n",
       "600096        0         0         0         0        1  \n",
       "002154        0         0         0         0        1  \n",
       "\n",
       "[5 rows x 45 columns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "total_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2406"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(total_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "total_data['FLO'] = np.exp(total_data['LFLO'])\n",
    "total_data['wls'] = (total_data['FLO'] / total_data['FLO'].sum()) ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# UQER Neutralize\n",
    "-----------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 169 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "neutralized_factor_uqer = uqer.neutralize(total_data[factor],\n",
    "                                          target_date=ref_date,\n",
    "                                          risk_module='short',\n",
    "                                          industry_type='short')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>uqer</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>000001</th>\n",
       "      <td>0.015150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000002</th>\n",
       "      <td>-0.003985</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000006</th>\n",
       "      <td>-0.008520</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000008</th>\n",
       "      <td>0.003012</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000010</th>\n",
       "      <td>0.020408</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            uqer\n",
       "000001  0.015150\n",
       "000002 -0.003985\n",
       "000006 -0.008520\n",
       "000008  0.003012\n",
       "000010  0.020408"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame(neutralized_factor_uqer, columns=['uqer'])\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2406"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(neutralized_factor_uqer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Alpha-Mind Neutralize\n",
    "--------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = total_data[risk_styles].values\n",
    "y = total_data[factor].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 1 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "neutralized_factor_alphamind = neutralize(x, y, weights=np.ones(len(y)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "alphamind_series = pd.Series(neutralized_factor_alphamind.flatten(), index=total_data.index)\n",
    "df['alpha-mind'] = alphamind_series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2406"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(alphamind_series)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Ticker Missing in UQER but Still in Alpha-Mind\n",
    "-----------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "missed_codes = [c for c in alphamind_series.index if c not in neutralized_factor_uqer.index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>FY12P</th>\n",
       "      <th>LFLO</th>\n",
       "      <th>BETA</th>\n",
       "      <th>MOMENTUM</th>\n",
       "      <th>SIZE</th>\n",
       "      <th>EARNYILD</th>\n",
       "      <th>RESVOL</th>\n",
       "      <th>GROWTH</th>\n",
       "      <th>BTOP</th>\n",
       "      <th>LEVERAGE</th>\n",
       "      <th>...</th>\n",
       "      <th>HEALTH</th>\n",
       "      <th>BANKS</th>\n",
       "      <th>DVFININS</th>\n",
       "      <th>REALEST</th>\n",
       "      <th>SOFTWARE</th>\n",
       "      <th>HDWRSEMI</th>\n",
       "      <th>UTILITIE</th>\n",
       "      <th>COUNTRY</th>\n",
       "      <th>FLO</th>\n",
       "      <th>wls</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ticker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>0 rows × 47 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [FY12P, LFLO, BETA, MOMENTUM, SIZE, EARNYILD, RESVOL, GROWTH, BTOP, LEVERAGE, LIQUIDTY, SIZENL, ENERGY, CHEM, CONMAT, MTLMIN, MATERIAL, AERODEF, BLDPROD, CNSTENG, ELECEQP, INDCONG, MACH, TRDDIST, COMSERV, AIRLINE, MARINE, RDRLTRAN, AUTO, HOUSEDUR, LEISLUX, CONSSERV, MEDIA, RETAIL, PERSPRD, BEV, FOODPROD, HEALTH, BANKS, DVFININS, REALEST, SOFTWARE, HDWRSEMI, UTILITIE, COUNTRY, FLO, wls]\n",
       "Index: []\n",
       "\n",
       "[0 rows x 47 columns]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "total_data.ix[missed_codes]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Direct Weighted Least Square Fit Implementation\n",
    "------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import statsmodels.api as sm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "mod = sm.WLS(y, x, weights=np.ones(len(y))).fit()\n",
    "lg_series = pd.Series(mod.resid, index=total_data.index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.07230463, -0.0828871 , -0.03309311, ...,  0.04199391,\n",
       "        0.09846184,  0.47469864])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mod.resid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "df['ols'] = lg_series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Comparison\n",
    "------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "df['uqer - ols'] = df['uqer'] - df['ols']\n",
    "df['alphamind - ols'] = df['alpha-mind'] - df['ols']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x14ea6f708d0>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n7XbrP//zP2UYhj7zmc/on/7pnyRJ+/bt065duyRJBQUFmjt37pXdPMaW+QnT399vfve73zVPnDhh\n9vb2mt///vfN48ePmzt37jQrKipM0zTNiooKc+fOnaZpmubx48fN73//+2ZPT4/5wQcfmN/97nfN\n/v5+0zRN8+GHHzYPHz5s+v1+8/HHHzcPHDhgmqZp/u53vzO3bdtmmqZp/v73vzeLi4sD87/55pum\nx+Mxn3jiiSu5bYSYy+3DxsZGs7293TRN0/zTn/5k3nfffaZpmubZs2fNt956yzRN0+zt7TUfffTR\nQB+apml2d3ebP/zhD81Vq1aZDQ0NgdcXLlx4RfaJ0Of3+80zZ86YpvlRD61cudI8fPjwqP5MPH36\ndGA+j8djPvbYY4FjfibiY5s2bTKrqqpM0/yoF7u6uka1D9966y3z7Nmzpmma5iuvvDLg381r1qwx\nDx06ZJqmaZ45cyYwDp9Oo9GLp06dMr/97W+bHR0dgXO++eabpmmaZnNzs/mDH/zA7OzsNE3TND/8\n8EPTNE2zs7PT/M53vmN2dnYO+Ht8enzibjVsaGhQUlKSEhMTZbfblZ2dLY/HI4/Ho5ycHElSTk6O\nPB6PJMnj8Sg7O1vh4eFKSEhQUlKSGhoa5PP5dObMGaWmpsowDM2ZMydQU1dXF/g/FFlZWXr77bdl\n/v8zStLS0hQZGXnlN46Qcrl9eM011wR+V92UKVPU09Oj3t5ejRs3TjNnzpQk2e12XXPNNQN+x93P\nf/5z3XnnnQoPD7/CO8TfCsMwNH78eElSf3+/+vv7ZRjGqP5MnDBhQmC+s2fPyjCMwDE/EyFJ3d3d\nevfdd3XLLbdI+ujn2VVXXTWqfThz5kyNGzdOkjRjxgx5vV5JUlNTk/r7+zVr1ixJ0vjx4wPj8Onz\nf+3dXUiT/RvA8a+bEOnMuYHzpSA2hcgSqyVFRxKkJRSInSSGSNGLUB3pSVkRvZmQUYoWEQ6CTkwJ\ngjrI0gPJIPGlCJM5X8jpsIk6Jdx27zkQ73976v/wxLOVuutz5vbb78cPrl3zuu/rvu9QxeLExATJ\nycnqM2gzMzPp7OwE4NWrV+Tm5qpnzOLj44HFTpjMzEx0Oh06nY7MzEy6u7t/6/7Fn7XqWg3dbjdG\no1H922g0MjAwwPT0NAkJCQDo9Xqmp6fV8enp6ep4g8GA2+1Gq9X+MM9SEv9+Da1WS0xMDLOzsz99\ngLSITL8ah9/r7OzEbDb/UEzNzc3x/v17Dhw4ACy220xOTrJ9+3aePXsWNNbr9VJRUUF0dDSHDh0i\nOzs71FsUK4iiKFRUVDA+Pk5ubi7p6ekhzYkAL1684Pnz5/h8PiorK3/TzsRK4XK5WLduHXV1dQwP\nD2M2mykpKQl5HC5pbW1V28HGxsaIjY2luroal8vF1q1bKSoqQqNZdceexb8QqljcsmULY2NjuFwu\njEYj7969w+fzAYsxB3DhwgUUReHw4cNkZWX98L/B0lwickRk1omKigo6IivEn/CzOBwdHeXx48cc\nP3486HW/38+dO3fYv38/JpMJRVGw2WwcPXr0p3PX1dVx8+ZNzpw5Q2NjI+Pj42Hbh1j+NBoNt27d\nor6+HrvdzsjISND7ociJeXl53L17l6KiIpqamv7TXGL18fv9OBwO9u3bR1VVFWvWrKGlpSVoTKh+\nm9vb2xkcHOTgwYPA4oGHT58+UVxczPXr15mYmODNmzf/eR2xMoUqFnU6HceOHaOmpobKykoSExPV\nYl5RFJxOJxcvXuTs2bM0NDQwNzcXtj2JlWPVFV4GgyGoFevr168YDAbi4+OZmpoCYGpqSj079ffx\nbrcbg8Hwf+f5+2f8fj/z8/PExcWFfW9i5fjVOFwaU11dTVlZGUlJSUHzNTQ0kJSURH5+PrDYzjU6\nOsrly5cpKytjYGCAqqoq7Ha7uj6AyWRi8+bNDA0NhXO7YoWIjY0lIyOD7u7ukObE7y211QrxPaPR\niNFoVM8c7Nq1C4fDEfI47O3tpbm5mfLycrVrwGAwsHHjRkwmE1qtluzsbAYHB8O+Z7E8hSoWAaxW\nK9euXePq1aukpKSQkpKifsZqtRIdHU1iYiLJyck4nc5/nEtEhlVXeFksFpxOJy6XC5/PR0dHB1ar\nFavVSltbGwBtbW3s3LkTWPzSdHR04PV6cblcOJ1O0tLSSEhIYO3atXz+/JlAIEB7eztWqxWAHTt2\nqEfL3r59S0ZGhpxBE0F+NQ7n5ua4ceMGR44cYdOmTUFzPXnyhPn5eUpKStTXYmJiePjwIbW1tdTW\n1pKenk55eTkWiwWPx4PX6wVgZmaG/v5+9Q5zIvLMzMyoR1oXFhbo7e0lNTU1pDnR6XSq63V1dZGc\nnPybdymWO71ej9FoVFuw+vr6WL9+fUjj0OFw8ODBA8rLy9VragDS0tKYn59nZmYGgA8fPkhOjGCh\nikVAbUf0eDy8fPlSvW4sOzubjx8/Aos52Ol0YjKZyMrKoqenB4/Hg8fjoaenR22JFZEhKrB0V4hV\npKuri8bGRhRFIScnh4KCAmZnZ7l9+zaTk5M/3Cb06dOnvH79Go1GQ0lJCdu2bQPAbrdTV1fHwsIC\nWVlZlJaWEhUVxcLCAvfu3cPhcKDT6Th37hwmkwmAyspKvnz5wrdv34iLi+PkyZPypYpQvxKHTU1N\ntLS0BJ3pOn/+PD6fj1OnTpGamkp09OIlmXl5eezduzdorUuXLlFcXIzFYqG/v5/79++j0WhQFIX8\n/Hz1x0BEnuHhYWpra1EUhUAgwO7duyksLAxpTnz06BF9fX1otVp0Oh2lpaVs2LABkJwo/mdoaIj6\n+np8Ph+JiYmcPn2aQCAQsji8cuUKIyMj6PV6IPhRGr29vdhsNgKBAGazmRMnTqg5VUSeUMViTU0N\nw8PDABQWFrJnzx4AAoEANpuN7u5uNBoNBQUF6nutra00NzcDi7eTz8nJ+d3bF3/Qqiy8hBBCCCGE\nEGI5WXWthkIIIYQQQgix3EjhJYQQQgghhBBhJoWXEEIIIYQQQoSZFF5CCCGEEEIIEWZSeAkhhBBC\nCCFEmEnhJYQQQgghhBBhJoWXEEIIIYQQQoTZX144IUukMrsAAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x14ea6f73f98>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df[['uqer - ols', 'alphamind - ols']].plot(figsize=(14, 7), ylim=(-1e-4, 1e-4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>uqer</th>\n",
       "      <th>alpha-mind</th>\n",
       "      <th>ols</th>\n",
       "      <th>uqer - ols</th>\n",
       "      <th>alphamind - ols</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>000001</th>\n",
       "      <td>0.015150</td>\n",
       "      <td>0.015150</td>\n",
       "      <td>0.015150</td>\n",
       "      <td>2.775558e-17</td>\n",
       "      <td>3.053113e-16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000002</th>\n",
       "      <td>-0.003985</td>\n",
       "      <td>-0.003985</td>\n",
       "      <td>-0.003985</td>\n",
       "      <td>1.942890e-16</td>\n",
       "      <td>1.110223e-16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000006</th>\n",
       "      <td>-0.008520</td>\n",
       "      <td>-0.008520</td>\n",
       "      <td>-0.008520</td>\n",
       "      <td>-2.636780e-16</td>\n",
       "      <td>-4.163336e-17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000008</th>\n",
       "      <td>0.003012</td>\n",
       "      <td>0.003012</td>\n",
       "      <td>0.003012</td>\n",
       "      <td>-1.595946e-16</td>\n",
       "      <td>-1.700029e-16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>000010</th>\n",
       "      <td>0.020408</td>\n",
       "      <td>0.020408</td>\n",
       "      <td>0.020408</td>\n",
       "      <td>-6.383782e-16</td>\n",
       "      <td>-2.914335e-16</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            uqer  alpha-mind       ols    uqer - ols  alphamind - ols\n",
       "000001  0.015150    0.015150  0.015150  2.775558e-17     3.053113e-16\n",
       "000002 -0.003985   -0.003985 -0.003985  1.942890e-16     1.110223e-16\n",
       "000006 -0.008520   -0.008520 -0.008520 -2.636780e-16    -4.163336e-17\n",
       "000008  0.003012    0.003012  0.003012 -1.595946e-16    -1.700029e-16\n",
       "000010  0.020408    0.020408  0.020408 -6.383782e-16    -2.914335e-16"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Missing Codes for UQER neutralize in 2017\n",
    "--------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from PyFin.api import bizDatesList"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "biz_dates = bizDatesList('china.sse', '2017-01-05', '2017-07-03')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "missed_codes_dict = {}\n",
    "\n",
    "for date in biz_dates:\n",
    "    ref_date = date.strftime('%Y%m%d')\n",
    "    factor_data = api.MktStockFactorsOneDayGet(tradeDate=ref_date, field='ticker,' + factor)\n",
    "    risk_factors = api.RMExposureDayGet(tradeDate=ref_date)\n",
    "    append_industry_info(risk_factors)\n",
    "\n",
    "    total_data = pd.merge(factor_data, risk_factors, on=['ticker'])\n",
    "    total_data.set_index('ticker', inplace=True)\n",
    "    total_data.dropna(inplace=True)\n",
    "    \n",
    "    neutralized_factor_uqer = uqer.neutralize(total_data[factor],\n",
    "                                              target_date=ref_date,\n",
    "                                              risk_module='day',\n",
    "                                              industry_type='day')\n",
    "    \n",
    "    missed_codes = [c for c in total_data.index if c not in neutralized_factor_uqer.index]\n",
    "    missed_codes_dict[date] = missed_codes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2017-01-05    [002821]\n",
       "2017-01-06    [002821]\n",
       "2017-01-09    [002821]\n",
       "2017-01-10    [002821]\n",
       "2017-01-11    [002821]\n",
       "dtype: object"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "missing_codes = pd.Series(missed_codes_dict)\n",
    "missing_codes.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
