{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Alpha的后验分解\n", "\n", "最近在学习量化分析, 其中有一个作业是这样:\n", "\n", "> Alpha的后验分解:给定一个组合P,估算该组合相对于业绩基准组合B的各参数:$β_p$ 、$α_p$、 以及组合风险 $σ_p$ 和残差风险 $ω_p$\n", "\n", "总觉得自己哪里算错了, 比如[华夏上证50ETF(代码: 510050)](http://cn.morningstar.com/quicktake/F0000003X3)的alpha算出来总是-0.00091, \n", "\n", "一时检查不出来, 暂时先摆出来供讨论\n", "" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import tushare as ts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 设定目标" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "target=\"510050.XSHG\" # 华夏上证50\n", "benchmark=\"000300.XSHG\" # 沪深300指数\n", "start=\"2015-1-1\"\n", "end=\"2018-9-1\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 获得历史价格" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# 如果有基金净值数据, 不能使用get_price取得, 因此分别提取数据\n", "p_target =get_price(target , start_date=start, end_date=end, fields=\"close\")\n", "p_benchmark=get_price(benchmark, start_date=start, end_date=end, fields=\"close\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
510050.XSHG000300.XSHG
date
2018-08-312.5213334.5036
2018-08-302.5333351.0942
2018-08-292.5533386.5736
2018-08-282.5603400.1705
2018-08-272.5713406.5735
\n", "
" ], "text/plain": [ " 510050.XSHG 000300.XSHG\n", "date \n", "2018-08-31 2.521 3334.5036\n", "2018-08-30 2.533 3351.0942\n", "2018-08-29 2.553 3386.5736\n", "2018-08-28 2.560 3400.1705\n", "2018-08-27 2.571 3406.5735" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 为避免投资组合的净值(价格)采样时间与基准的采样时间不同, 取两者的交集\n", "price= pd.concat([p_target, p_benchmark], axis=1, join='inner') \n", "price.columns=[target,benchmark]\n", "# 通过ts获取基金净值的时间顺序, 与通过ts获取股票价格的时间顺序, 这两者可能不同, 因此统一到时间降序上\n", "price.sort_index(ascending=False, inplace=True)\n", "price.head()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
510050.XSHG000300.XSHG
date
2018-08-312.5333351.0942
2018-08-302.5533386.5736
2018-08-292.5603400.1705
2018-08-282.5713406.5735
2018-08-272.5233325.3347
\n", "
" ], "text/plain": [ " 510050.XSHG 000300.XSHG\n", "date \n", "2018-08-31 2.533 3351.0942\n", "2018-08-30 2.553 3386.5736\n", "2018-08-29 2.560 3400.1705\n", "2018-08-28 2.571 3406.5735\n", "2018-08-27 2.523 3325.3347" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 前一个交易日价格\n", "price.shift(-1).head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 计算收益率\n", "\n", "每日收益率: 通过投资组合权益计算出的日收益率。\n", "\n", "$$\n", "每日收益率=\\frac{当前交易日总权益-前一交易日总权益}{前一交易日总权益}\n", "$$" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
510050.XSHG000300.XSHGriskfree
2018-08-31-0.004737-0.0049510.018291
2018-08-30-0.007834-0.0104760.017971
2018-08-29-0.002734-0.0039990.019096
2018-08-28-0.004278-0.0018800.018622
2018-08-270.0190250.0244300.018767
\n", "
" ], "text/plain": [ " 510050.XSHG 000300.XSHG riskfree\n", "2018-08-31 -0.004737 -0.004951 0.018291\n", "2018-08-30 -0.007834 -0.010476 0.017971\n", "2018-08-29 -0.002734 -0.003999 0.019096\n", "2018-08-28 -0.004278 -0.001880 0.018622\n", "2018-08-27 0.019025 0.024430 0.018767" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r= (price-price.shift(-1))/price.shift(-1)\n", "r.drop(r.index[-1], inplace=True) # last row is NaN, I think it should be droped\n", "# 取得中债国债收益率曲线作为无风险收益率\n", "r_riskfree=get_yield_curve(start_date=start, end_date=end, tenor='0S')\n", "r = pd.merge(r, r_riskfree, left_index=True, right_index=True,how=\"inner\")\n", "r.columns=[target, benchmark, \"riskfree\"]\n", "r.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 计算$\\beta$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "计算方法参考[RiceQuant API文档](https://www.ricequant.com/api/python/chn#backtest-results-factors)\n", "\n", "> 贝塔(beta, $\\beta$ ): [CAPM](https://en.wikipedia.org/wiki/Capital_asset_pricing_model)模型中市场基准组合项的系数,表示资产收益对市场整体收益波动的敏感程度。\n", " $$\n", " \\beta=\\frac{Cov(r_{p,e}, r_{b,e})}{Var(r_{b,e})}\n", " $$\n", "\n", "> 其中$r_{p,e}$为策略超额收益率(策略收益率 - 无风险组合收益率);$r_{b,e}$为市场基准组合超额收益率(市场基准组合收益率 - 无风险组合收益率);Cov 表示协方差;Var 表示方差\n", "\n", "\n", "\n", "\n", "注意: numpy中, np.cov(a,b)的计算结果是$2\\times2$矩阵\n", "$$\n", "np.cov(a,b)=\\left[ \\begin{array}{cc} cov\\left( a,\\; a \\right) & cov\\left( a,\\; b \\right) \\\\ cov\\left( a,\\; b \\right) & cov\\left( b,\\; b \\right) \\end{array} \\right]\n", "$$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9511718021320907" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r_pe=r[target]-r[\"riskfree\"]\n", "r_be=r[benchmark]-r[\"riskfree\"]\n", "beta=np.cov(r_pe, r_be)[0,1]/np.var(r_be)\n", "beta" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 求解$\\alpha$\n", "\n", "## 方法1\n", "计算方法参考[RiceQuant API文档](https://www.ricequant.com/api/python/chn#backtest-results-factors)\n", "\n", "> 阿尔法(alpha, $\\alpha$): [CAPM](https://en.wikipedia.org/wiki/Capital_asset_pricing_model)模型表达式中的残余项。表示策略所持有投资组合的收益中和市场整体收益无关的部分,是策略选股能力的度量。当策略所选股票的总体表现优于市场基准组合成分股时,阿尔法取正值;反之取负值。\n", "$$\n", "\\alpha=E[r_p-[r_f+\\beta \\times (r_b-r_f)]]\n", "$$\n", "\n", "> 其中$r_p$为策略所持有投资组合收益;$r_f$为无风险组合收益;$\\beta$为CAPM模型中的贝塔系数;E表示随机变量的期望。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-0.00091193563738157" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alpha=(r[target]-(r[\"riskfree\"]+beta*(r[benchmark]-r[\"riskfree\"]))).mean()\n", "alpha" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 方法2\n", "\n", "$$\n", "\\theta_p(t)= \\alpha_p+ \\epsilon(t)\n", "\\\\\n", "E[r_p(t)] = \\beta_p E[r_B(t)] + E[\\theta_p(t)]\n", "\\\\\n", "\\alpha_p=E[\\theta_p(t)]\n", "\\\\\n", "\\alpha_p=E[r_p(t)]-\\beta_p E[r_B(t)]\n", "$$\n", "\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-0.0009119356373815703" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(r_pe.mean()-beta*r_be.mean())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 求解投资组合风险 $\\sigma_p$\n", "\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.01640696817905404" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sigma_p=r[target].std()\n", "sigma_p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 求解残差风险 $\\omega_p$\n", "\n", "$$\n", "\\omega _{p}=\\; \\sqrt{\\sigma _{p}^{2}-\\beta _{p}^{2}\\cdot \\sigma _{B}^{2}\\; }\n", "$$\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.005885928156058898" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "omega_p=np.sqrt(sigma_p**2-beta**2*(r[benchmark].std()**2))\n", "omega_p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 年化\n", "这里假设一年有244个交易日。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0.008566663958171634, 0.005885928156058898)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "day_count=len(get_trading_dates(start_date=start,end_date=end))\n", "annual_correct=np.sqrt(244/(day_count-1))\n", "annual_sigma_p=annual_correct*sigma_p\n", "annual_omega_p=annual_correct*omega_p\n", "annual_sigma_p, omega_p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# RiceQuant上其他一些指标" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 年化波动率(volatility, $\\sigma_t$): \n", ">策略收益率的标准差,最常用的风险度量。波动率越大,策略承担的风险越高。这里假设一年有244个交易日。\n", "\n", "$$\n", "\\sigma =\\sqrt{\\frac{244}{n-1}\\sum_{i=1}^{n}{\\left[ r_{p}\\left( i \\right)\\; -\\; \\bar{r_{p}} \\right]^{2}}}\n", "$$\n", "\n", ">其中,n为回测期内交易日数目;$r_p(i)$ 表示第 i 个交易日策略所持有投资组合的日收益率;$ \\bar{r_p} $ 为回测期内策略日收益率的均值。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.008566663958171633" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "volatility=np.sqrt(244/(day_count-1)*(r[target].std()**2)) # 定义与年化投资组合风险sigma_p一致\n", "volatility" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 年化跟踪误差(tracking error,$\\sigma_t$ ): \n", "\n", ">纯多头主动交易策略(阿尔法策略和基准择时策略)收益和市场基准组合收益之间差异的度量。跟踪误差越大,意味着策略所持有投资组合偏离基准组合的程度越大。需要注意,跟踪误差不适用于多-空结合的对冲策略的风险评估\n", "\n", "\n", "$$\n", "\\sigma =\\sqrt{\\frac{244}{n-1}\\sum_{i=1}^{n}{\\left[ r_{pa}\\left( i \\right)\\; -\\; \\bar{r_{pa}} \\right]^{2}}}\n", "\\\\\n", "r_{pa}(i)=r_p(i)-r_b(i)\n", "$$\n", "其中,n为回测期内交易日数量;$r_{pa}(i), r_p(i), r_b(i)$分别表示第i个交易日策略所持有投资组合的日主动收益、日收益率和基准组合的日收益率。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.5218443423891064" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tracking_error=np.sqrt(244/(day_count-1 * (r_pe.std()**2)))\n", "tracking_error" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 年化下行波动率(downside risk, $\\sigma_d$):\n", "\n", "> 相比波动率,下行波动率对收益向下波动和向上波动两种情况做出了区分,并认为只有收益向下波动才意味着风险。在实际计算中,我们统一使用基准组合收益为目标收益,作为向上波动和向下波动的判断标准。\n", "\n", "$$\n", "\\sigma =\\sqrt{\\frac{244}{n-1}\\sum_{i=1}^{n}{\\left[ r_{p}\\left( i \\right)\\; -\\; r_{b}(i) \\right]^{2} I(i)}}\n", "$$\n", "$$\n", "I(i)=\\begin{cases}1 & r_p(i)其中,n为回测期内交易日数量;$r_p,r_b$ 分别表示第i个交易日策略所持有投资组合的日收益率、基准组合的日收益率;I(i)为指示函数(indicator function),如果第i个交易日策略所持有投资组合收益低于基准组合收益,则标记为1(向下波动),否则标记为0(向上波动)。" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.06079720493473829" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "downside_r=r.where(r[target] 在回测期内,在任一交易日往后推,策略总权益走到最低点时收益率回撤幅度的最大值。最大回撤是评估策略极端风险管理能力的重要指标。其计算方式如下:\n", "$$\n", "Drawdown_t=\\begin{cases}0 & NET_t = min_{j \\geq t} NET_j\\\\\\frac{NET_t-min_{j \\geq t}NET_j}{NET_t} & ELSE\\end{cases}\n", "\\\\\n", "NET=某期净值\n", "\\\\\n", "MaxDrawdown=Max(Drawdown_t)\n", "$$\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Timestamp('2015-06-08 00:00:00'), 0.44965219768536796)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "NET=p_target\n", "NET.sort_index(ascending=False, inplace=True)\n", "NET_min=NET.copy()\n", "for date in NET.index:\n", " NET_min.loc[date]=(NET.loc[:date].min())\n", "Drawdown_t=(NET-NET_min)/NET\n", "max_Drawdown=Drawdown_t.max()\n", "max_Drawdown_date=Drawdown_t.idxmax()\n", "(max_Drawdown_date, max_Drawdown)" ] }, { "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.5.5" }, "nikola": { "category": "", "date": "2018-9-23 1:00 UTC+08:00", "description": "", "link": "", "slug": "Alpha_tear", "tags": "python", "title": "Alpha的后验分解", "type": "text" } }, "nbformat": 4, "nbformat_minor": 2 }