{
"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",
" 510050.XSHG | \n",
" 000300.XSHG | \n",
"
\n",
" \n",
" date | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" 2018-08-31 | \n",
" 2.521 | \n",
" 3334.5036 | \n",
"
\n",
" \n",
" 2018-08-30 | \n",
" 2.533 | \n",
" 3351.0942 | \n",
"
\n",
" \n",
" 2018-08-29 | \n",
" 2.553 | \n",
" 3386.5736 | \n",
"
\n",
" \n",
" 2018-08-28 | \n",
" 2.560 | \n",
" 3400.1705 | \n",
"
\n",
" \n",
" 2018-08-27 | \n",
" 2.571 | \n",
" 3406.5735 | \n",
"
\n",
" \n",
"
\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",
" 510050.XSHG | \n",
" 000300.XSHG | \n",
"
\n",
" \n",
" date | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" 2018-08-31 | \n",
" 2.533 | \n",
" 3351.0942 | \n",
"
\n",
" \n",
" 2018-08-30 | \n",
" 2.553 | \n",
" 3386.5736 | \n",
"
\n",
" \n",
" 2018-08-29 | \n",
" 2.560 | \n",
" 3400.1705 | \n",
"
\n",
" \n",
" 2018-08-28 | \n",
" 2.571 | \n",
" 3406.5735 | \n",
"
\n",
" \n",
" 2018-08-27 | \n",
" 2.523 | \n",
" 3325.3347 | \n",
"
\n",
" \n",
"
\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",
" 510050.XSHG | \n",
" 000300.XSHG | \n",
" riskfree | \n",
"
\n",
" \n",
" \n",
" \n",
" 2018-08-31 | \n",
" -0.004737 | \n",
" -0.004951 | \n",
" 0.018291 | \n",
"
\n",
" \n",
" 2018-08-30 | \n",
" -0.007834 | \n",
" -0.010476 | \n",
" 0.017971 | \n",
"
\n",
" \n",
" 2018-08-29 | \n",
" -0.002734 | \n",
" -0.003999 | \n",
" 0.019096 | \n",
"
\n",
" \n",
" 2018-08-28 | \n",
" -0.004278 | \n",
" -0.001880 | \n",
" 0.018622 | \n",
"
\n",
" \n",
" 2018-08-27 | \n",
" 0.019025 | \n",
" 0.024430 | \n",
" 0.018767 | \n",
"
\n",
" \n",
"
\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
}