对数收益率
直觉
我们关心的不是价格本身,而是价格的变化。两种常见的度量方式:
- 简单收益率:
- 对数收益率:
对数收益率在量化里用得更多,因为它可加:多期收益直接相加即可。
数学原理
设连续 期的对数收益率为 ,则总对数收益率为
而简单收益率只能用连乘:。
「人话」解释:为什么可加这么重要?
求和比连乘好处理得多 —— 求均值、求方差、做正态性假设、做回归,都建立在「可加」之上。 当单期收益较小时,(因为 ),两者数值很接近; 但跨多期累计时,对数收益率的可加性让统计分析干净利落。
年化换算(假设一年 252 个交易日,收益独立同分布):
可运行代码案例
下面这段代码会模拟一段几何布朗运动价格,计算简单收益率与对数收益率,对比两者,并画出价格与收益率分布。
点「运行」即可执行;你也可以直接改 mu、sigma、n_days 再跑一遍。
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(42)
# —— 参数(可自行修改)——
n_days = 252 # 交易日数
mu = 0.08 # 年化漂移
sigma = 0.20 # 年化波动率
P0 = 100.0 # 初始价格
dt = 1 / 252
# 几何布朗运动:对数收益率 ~ 正态
log_rets = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * rng.standard_normal(n_days)
prices = P0 * np.exp(np.cumsum(log_rets))
prices = np.insert(prices, 0, P0)
# 两种收益率
simple_ret = prices[1:] / prices[:-1] - 1
log_ret = np.log(prices[1:] / prices[:-1])
print(f"日均对数收益率 : {log_ret.mean():.5f}")
print(f"日波动率 : {log_ret.std():.5f}")
print(f"年化收益(对数) : {log_ret.mean()*252:.4f}")
print(f"年化波动率 : {log_ret.std()*np.sqrt(252):.4f}")
print(f"简单 vs 对数 最大差异: {np.abs(simple_ret - log_ret).max():.6f}")
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].plot(prices, color="#2563eb")
axes[0].set_title("Simulated Price Path")
axes[0].set_xlabel("day"); axes[0].set_ylabel("price")
axes[1].hist(log_ret, bins=30, color="#10b981", alpha=0.8)
axes[1].set_title("Log Return Distribution")
axes[1].set_xlabel("log return"); axes[1].set_ylabel("count")
plt.tight_layout()
plt.show()
动手改一改
试着把 sigma 从 0.20 调到 0.40,再运行 —— 观察价格路径变得多么剧烈,以及收益率分布如何变宽。
这就是「波动率」的直观含义。
小结
- 对数收益率 可加,是量化分析的默认选择;
- 小收益时 ;
- 年化:均值 、波动率 。
下一节我们会用真实的价格数据,研究收益率分布的「肥尾」现象。
小测验
1. 对数收益率相比简单收益的核心优点是?
2. 当单期收益很小时,对数收益 r 与简单收益 R 的关系?
3. 把日波动率年化,标准差应乘以?