使用 Python 计算资本资产定价模型(CAPM)并获取贝塔系数(β)。
步骤 1:导入必要的库
import pandas as pd
import yfinance as yf
import statsmodels.api as sm
import matplotlib.pyplot as plt
步骤 2:定义参数并下载数据
# 设置参数
RISKY_ASSET = 'AMZN' # 风险资产(亚马逊股票)
MARKET_BENCHMARK = '^GSPC' # 市场基准(标普500指数)
START_DATE = '2014-01-01' # 开始日期
END_DATE = '2018-12-31' # 结束日期
# 从雅虎财经下载数据
df = yf.download([RISKY_ASSET, MARKET_BENCHMARK],
start=START_DATE,
end=END_DATE,
adjusted=True, # 使用调整后的收盘价(包含股息和拆股)
progress=False) # 关闭下载进度条
print("前5行数据:\n", df.head())
步骤 3:处理数据并计算收益率
# 提取调整后的收盘价并重命名列
prices = df['Adj Close'].rename(columns={RISKY_ASSET: 'asset', MARKET_BENCHMARK: 'market'})
# 重采样为月度数据,取每月最后一天的收盘价
monthly_prices = prices.resample('M').last()
# 计算简单收益率(月度)
returns = monthly_prices.pct_change().dropna()
print("月度收益率数据:\n", returns.head())
步骤 4:计算贝塔系数(β)
方法一:协方差与方差之比
# 计算协方差矩阵
covariance_matrix = returns.cov()
covariance = covariance_matrix.iloc[0, 1] # 资产与市场的协方差
# 计算市场方差
market_variance = returns['market'].var()
# 计算贝塔系数
beta = covariance / market_variance
print(f"贝塔系数(协方差法): {beta:.4f}")
方法二:线性回归
# 准备回归数据(市场收益为自变量X,资产收益为因变量y)
X = returns['market'] # 自变量(市场收益)
y = returns['asset'] # 因变量(资产收益)
X = sm.add_constant(X) # 添加截距项
# 拟合线性回归模型
model = sm.OLS(y, X).fit()
# 输出回归结果
print(model.summary())
# 提取贝塔系数
beta_regression = model.params['market']
print(f"贝塔系数(回归法): {beta_regression:.4f}")
步骤 5:处理非零无风险利率(示例)
方法一:从雅虎财经获取 13 周国债利率(^IRX)
# 下载国债利率数据
df_rf = yf.download('^IRX', start=START_DATE, end=END_DATE)
# 转换为月度数据(取每月最后一个值)
rf_monthly = df_rf.resample('M').last()['Close'] / 100 # 转换为小数形式
# 计算月无风险利率(假设90天期限)
n_days = 90 # 13周国债的期限
rf = (1 / (1 - rf_monthly * n_days / 360)) ** (1 / n_days) # 日利率
rf_monthly_rate = (rf ** 30) - 1 # 转换为月利率
# 绘制无风险利率趋势
rf_monthly_rate.plot(title='Risk-Free Rate (13-Week Treasury Bill)')
plt.ylabel('Monthly Rate')
plt.show()
方法二:从 FRED 获取 3 个月国债利率(TB3MS)
import pandas_datareader.data as web
# 下载 FRED 数据
rf = web.DataReader('TB3MS', 'fred', start=START_DATE, end=END_DATE)
# 转换为月利率(年利率转为月复利)
rf_monthly_rate = (1 + rf / 100) ** (1/12) - 1
# 绘制结果
rf_monthly_rate.plot(title='Risk-Free Rate (3-Month Treasury Bill)')
plt.ylabel('Monthly Rate')
plt.show()
步骤 6:使用无风险利率调整的 CAPM
# 假设已获取无风险利率 rf_monthly_rate(与 returns 时间索引对齐)
# 计算超额收益
risk_free_rate = rf_monthly_rate.squeeze() # 确保形状匹配
excess_returns = returns.sub(risk_free_rate, axis=0)
# 准备回归数据(市场超额收益为X,资产超额收益为y)
X_excess = excess_returns['market']
y_excess = excess_returns['asset']
X_excess = sm.add_constant(X_excess) # 添加截距项
# 拟合模型
model_excess = sm.OLS(y_excess, X_excess).fit()
print(model_excess.summary())
QWQ
- 贝塔系数(β):若 β = 1.67,表示亚马逊股票的波动性比市场高 67%。
- 截距项(Alpha):若截距接近零且不显著,说明资产收益完全由市场风险溢价解释。