Py学习  »  Python

用 Python 实现资本资产定价模型

Python中文社区 • 2 年前 • 475 次点击  


在本文中,我们将学习如何计算资本资产定价模型 (CAPM) 并获得贝塔系数。资本资产定价模型(Capital Asset Pricing Model 简称CAPM)是由美国学者于1964年在资产组合理论和资本市场理论的基础上发展起来的,主要研究证券市场中资产的预期收益率与风险资产之间的关系,以及均衡价格是如何形成的,是现代金融市场价格理论的支柱,广泛应用于投资决策和公司理财领域。CAPM 被认为是一个单因子模型,在其之上可以建立更复杂的因子模型。(扫描本文最下方二维码获取全部完整源码和Jupyter Notebook 文件打包下载。)
CAPM 由以下等式表示:

这里,E(ri) 表示资产 i 的预期收益,rf是无风险利率(例如政府债券),E(rm) 是市场的预期收益,β 是贝塔系数。β 可以解释为资产收益的敏感度水平,相对于一般市场水平。β 的一些情况包括:
  • β <= -1:资产向与市场基准相反的方向移动,并且大于基准的负值。
  • -1 < β < 0:资产向与市场基准相反的方向移动
  • β = 0:资产的价格变动与市场基准一致。
  • 0 < β < 1:资产与市场同向运动,但金额较小。一个例子是一家公司的股票价格容易受到日常市场波动的影响。
  • β = 1:资产和市场正朝着同一方向移动相同数量。
  • β > 1:资产与市场同向运动,但金额更大。一个例子是一家公司的股票非常容易受到每日市场新闻的影响。
CAPM 也可以表示为:

这里,等式的左边可以解释为风险溢价,而右侧包含市场溢价。相同的等式可以改写为:

其中:

在这个例子中,我们以亚马逊股票为例并假设标普 500 指数代表市场。我们使用 5 年(2014-2018 年)的月度数据来估计 β。在当前,无风险利率如此之低,为了简单起见,我们假设它等于零。
执行以下步骤以在 Python 中实现 CAPM:
1、导入第三方库:
import pandas as pd
import yfinance as yf
import statsmodels.api as sm
2、指定风险资产和时间范围:
RISKY_ASSET = 'AMZN'
MARKET_BENCHMARK = '^GSPC'
START_DATE = '2014-01-01'
END_DATE = '2018-12-31'
3、从雅虎财经下载必要的数据:



    
df = yf.download([RISKY_ASSET, MARKET_BENCHMARK],
start=START_DATE,
end=END_DATE,
adjusted=True,
progress=False)
4、重新采样到每月数据并计算简单的回报:
X = df['Adj Close'].rename(columns={RISKY_ASSET: 'asset',
MARKET_BENCHMARK: 'market'}) \
.resample('M') \
.last() \
.pct_change() \
.dropna()
5、使用协方差方法计算 β 值:
covariance = X.cov().iloc[0,1]
benchmark_variance = X.market.var()
beta = covariance / benchmark_variance
代码的结果是 β = 1.6709
6、准备输入并将 CAPM 估计为线性回归:
y = X.pop('asset')
X = sm.add_constant(X)

capm_model = sm.OLS(y, X).fit()
print(capm_model.summary())
下图显示了估计 CAPM 模型的结果:

这些结果表明贝塔系数(此处表示为market)等于 1.67,这意味着亚马逊股票的回报比市场波动性高 67%(由标准普尔 500 指数表示市场走势)。截距的值比较小,在 5% 的显著性水平上统计不显著。
首先,我们指定了我们想要使用的资产(亚马逊和标普 500 指数)和时间范围。在第 3 步中,我们从雅虎财经下载了数据。然后,我们只保留了最后一个 每月可用价格并计算每月回报的百分比变化。
在第 5 步中,我们将 β 计算为风险资产与基准方差之间的协方差之比。
在第 6 步中,我们将目标(亚马逊的股票收益)和特征(标准普尔 500 收益)使用 pandas DataFrame 的 pop 方法。之后,我们添加了常量,使用add_constant函数添加到特征(有效地添加一列)。这将截距添加到此回归背后的想法是调查在估计模型——截距(在 CAPM 的情况下,也称为 Jensen's alpha) 是否为零。如果它是积极的和显著的,这意味着——假设 CAPM 模型是真——资产或投资组合会产生异常高的风险调整回报。那么有两个可能的影响——要么市场效率低下,要么还有其他一些未被发现的模型中应包含的风险因素。这个问题被称为联合假设问题。
最后,我们运行 OLS 回归并打印摘要。在这里,我们可以看到market 变量的系数(即 CAPM beta)等于计算步骤 5 中资产与市场之间的协方差。
在主要示例中,我们假设没有无风险利率,这是一个合理的假设。但是,在某些情况下,我们可能希望考虑非零无风险利率。在本节中,我们将介绍三种可能的方法:
  • 使用 Kenneth French 教授网站的数据:市场溢价 (rm-rf) 和 无风险利率(近似于 1 个月的国库券)可以从 Kenneth French 教授的网站下载。该指数不同于标准普尔 500 指数——他的网站上有详细说明。
  • 第二种选择是近似无风险利率,例如,13 周(3个月)国库券(雅虎金融股票代码:^IRX)。
请按照以下步骤了解如何下载数据并将其转换为适当的无风险利率。
1、以天为单位定义期间的长度:
N_DAYS = 90
2、从雅虎财经下载数据:
df_rf = yf.download('^IRX', start=START_DATE, end=END_DATE)
3、将数据重新采样为每月频率(通过为每个月取最后一个值):
rf = df_rf.resample('M').last().Close / 100
4、计算无风险收益(表示为每日值)并将值转换为月收益:
rf = ( 1 / (1 - rf * N_DAYS / 360) )**(1 / N_DAYS)
rf = (rf ** 30) - 1
5、绘制计算出的无风险利率:
rf.plot(title='Risk-free rate (13 Week Treasury Bill)')
下图显示了无风险利率随时间的可视化:

  • 最后一种方法是使用 3 个月期国库券来估算无风险利率,可以从美联储经济数据 (FRED) 数据库下载。请按照以下步骤学习如何下载数据并将其转换为每月无风险利率:
1、导入第三方库:
import pandas_datareader.data as web
2、从 FRED 数据库下载数据:
rf = web.DataReader('TB3MS''fred', start=START_DATE,
end=END_DATE)
3、将获得的无风险利率转换为月值:
rf = (1 + (rf / 100)) ** (1 / 12) - 1
4、绘制计算出的无风险利率:
rf.plot(title='Risk-free rate (3-Month Treasury Bill)')
我们可以通过比较两个方法的图来比较两种方法的无风险利率:

我们可以看出来这些图都非常相似。


E N D


扫描本文最下方二维码获取全部完整源码和Jupyter Notebook 文件打包下载。


长按扫码获取完整源码


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/122228
 
475 次点击