4. 计算对数收益率
任务目标
基于股票收盘价序列,计算对数收益率(Log Return),并与简单收益率(Simple Return)进行对比,观察两者在数值上的差异及其随收益率幅度的变化关系。
核心概念
简单收益率:R_simple = (P_t - P_{t-1}) / P_{t-1}
对数收益率:R_log = ln(P_t / P_{t-1})
对数收益率具有时间可加性,且当收益率较小时两者近似相等;收益率越大,差异越明显。本例使用真实股价数据计算并可视化两种收益率的差异。
完整代码
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 1. 获取股票数据(以AAPL为例,近3个月日线)
ticker = "AAPL"
df = yf.download(ticker, period="3mo", interval="1d", progress=False)
close = df["Close"].dropna()
# 2. 计算两种收益率
simple_ret = close.pct_change().dropna() # 简单收益率
log_ret = np.log(close / close.shift(1)).dropna() # 对数收益率
# 3. 合并对比
compare = pd.DataFrame({
"Simple": simple_ret,
"Log": log_ret
})
# 4. 输出统计摘要
print("=== 收益率统计对比 ===")
print(compare.describe())
# 5. 计算两者差异(值)
diff = (simple_ret - log_ret).abs()
print(f"\n最大差异: {diff.max():.6f}")
print(f"平均差异: {diff.mean():.6f}")
# 6. 可视化对比
fig, axes = plt.subplots(2, 1, figsize=(10, 8))
# 上图:两种收益率时间序列
axes[0].plot(compare.index, compare["Simple"], label="Simple Return", alpha=0.7)
axes[0].plot(compare.index, compare["Log"], label="Log Return", alpha=0.7)
axes[0].set_title(f"{ticker} - Simple vs Log Return")
axes[0].legend()
axes[0].grid(True)
# 下图:差异散点(横轴为简单收益率,纵轴为差异)
axes[1].scatter(simple_ret, diff, s=5, alpha=0.6)
axes[1].set_xlabel("Simple Return")
axes[1].set_ylabel("|Simple - Log|")
axes[1].set_title("Difference vs Simple Return Magnitude")
axes[1].grid(True)
plt.tight_layout()
plt.show()
运行方式
- 安装依赖:
pip install yfinance pandas numpy matplotlib - 直接运行脚本,程序会自动下载AAPL最近3个月的日线数据并执行计算。
验证方法
运行后观察以下输出以确认实现正确:
- 统计摘要:两种收益率的均值应非常接近(通常差异在0.001量级以内),标准差也基本一致。
- 最大差异:该值通常出现在股价大幅波动的日期,一般在0.01~0.05之间(取决于期间是否出现单日大幅涨跌)。
- 可视化图形:时间序列图中两条曲线几乎重合;散点图呈现明显的正相关趋势——简单收益率值越大,与对数收益率的差异越大。
若将代码中的ticker更换为其他股票或延长period,上述规律依然成立,且波动剧烈的标的差异更显著。
预期输出(基于代码逻辑)
=== 收益率统计对比 ===
Simple Log
count 62.000000 62.000000
mean 0.001234 0.001156
std 0.018923 0.018877
min -0.049871 -0.051123
25% -0.008234 -0.008319
50% 0.000456 0.000455
75% 0.010234 0.010187
max 0.056789 0.055234
最大差异: 0.001252
平均差异: 0.000187
注:以上数值为基于代码逻辑的示例输出,实际运行结果取决于下载到的真实行情数据。