收益分布与正态性(肥尾)
直觉
经典金融理论常假设收益「服从正态分布」。但真实收益有一个重要特征:肥尾(fat tails)——极端事件(暴涨暴跌)出现的频率,远高于正态分布的预测。低估肥尾,就是低估风险。
数学原理
衡量分布形状的两个关键量:
「人话」解释:偏度与峰度在说什么?
- 偏度:分布是否对称。 对称; 左偏(长尾在亏损侧,常见于股市); 右偏。
- 峰度:尾部有多「厚」。正态分布的超额峰度 ;金融收益往往超额峰度显著为正(如 3~10),意味着极端值的概率远高于正态。
峰度大 = 「黑天鹅」比想象中更常见。这就是肥尾。
可运行案例:检验合成 SPY 收益的肥尾
下面读取 spy_daily.csv,计算对数收益,画出直方图 + 正态分布叠加,并报告偏度、峰度——你会看到峰度明显大于 0(肥尾)。
:::caution 合成数据
spy_daily.csv 是合成数据(学生 t 分布 + GARCH 波动聚集),刻意带有肥尾,非真实行情。
:::
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from scipy import stats
df = pd.read_csv('/data/spy_daily.csv', parse_dates=['date']).set_index('date')
r = np.log(df['close'] / df['close'].shift(1)).dropna()
mu, sigma = r.mean(), r.std(ddof=0)
skew = stats.skew(r)
kurt = stats.kurtosis(r) # 超额峰度(正态=0)
print(f"样本数 : {len(r)}")
print(f"日均收益 : {mu:.5f}")
print(f"日波动率 : {sigma:.5f}")
print(f"偏度 : {skew:.3f} (正态=0)")
print(f"超额峰度 : {kurt:.3f} (正态=0, 越大越肥尾)")
# 正态性检验(Jarque-Bera)
jb_stat, jb_p = stats.jarque_bera(r)
print(f"Jarque-Bera : stat={jb_stat:.1f}, p={jb_p:.3g} (p≈0 → 拒绝正态)")
# 直方图 + 正态叠加
plt.figure(figsize=(9, 3.8))
plt.hist(r, bins=60, density=True, color="#2563eb", alpha=0.5, label="收益直方图")
xs = np.linspace(r.min(), r.max(), 200)
plt.plot(xs, stats.norm.pdf(xs, mu, sigma), color="crimson", lw=2, label="正态拟合")
plt.yscale("log")
plt.gca().yaxis.set_major_formatter(mticker.FuncFormatter(lambda y, _: f"{y:g}"))
plt.gca().yaxis.set_minor_formatter(mticker.NullFormatter())
plt.title("对数收益分布(对数纵轴,看尾部)"); plt.xlabel("对数收益"); plt.ylabel("密度(对数)")
plt.legend(); plt.tight_layout(); plt.show()
注意对数纵轴下,真实的尾部柱子明显高于红色正态曲线——这就是肥尾的直观证据。
动手改一改
把正态拟合换成「学生 t 分布」拟合(stats.t.fit(r)),你会发现 t 分布的尾部贴合得好得多。这也是为什么风险建模常用 t 分布而非正态。
小结
- 金融收益往往偏度≠0、峰度>0(肥尾);
- 正态分布低估极端事件的概率,直接用会低估风险;
- 肥尾提醒我们:风险管理要用「尾部敏感」的指标(见模块 10 的 VaR/CVaR)。