跳到主内容
研究主线统计估计与回归基础 · 第6–13讲5/8模块导览 →
讲义

第10讲:估计的不稳定性 (Instability of Estimates)

用重复抽样和滚动窗口展示均值、方差与夏普比率的不稳定性,并讨论样本长度和结构变化的影响。

完成状态保存在当前浏览器,可随时取消。

一、参数估计基础概念#

1.1 什么是参数?#

参数是描述数据集或概率分布的统计量。例如:

  • 正态分布由均值μ和标准差σ参数化

  • 时间序列中常用的参数包括移动平均、相关系数、夏普比率等

关键公式——正态分布概率密度函数:

f(x)=1σ2πe(xμ)22σ2f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}

这个函数各部分的含义是:

  1. μ\mu:均值参数,决定了分布的中心位置

  2. σ\sigma:标准差参数,控制分布的宽度或分散程度

  3. 1σ2π\frac{1}{\sigma\sqrt{2\pi}}:归一化系数,确保概率密度函数的总积分为1

  4. e(xμ)22σ2e^{-\frac{(x-\mu)^2}{2\sigma^2}}:指数部分,决定了钟形曲线的形状

xx接近μ\mu时,指数部分接近1,密度达到最大值;随着xx远离μ\mu,概率密度迅速下降。较大的σ\sigma值会使曲线更平坦宽广,较小的σ\sigma值则使曲线更高且集中。

正态分布有"68-95-99.7"规则:约68%的数据在μ±σ\mu±\sigma范围内,约95%在μ±2σ\mu±2\sigma范围内,约99.7%在μ±3σ\mu±3\sigma范围内。

1.2 估计的本质#

所有参数估计都存在不确定性:

  • 样本均值是真实均值μ的估计
μ^=1nxi\hat{\mu} = \frac{1}{n}\sum x_i
  • 估计值会随样本变化而波动

  • 需通过标准误差/置信区间评估估计质量

二、参数稳定性分析#

2.1 正态分布案例#

code
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
normal_data = np.random.randn(500)

# 不同样本量的均值估计
print(f"10样本均值: {np.mean(normal_data[:10]):.2f}")
print(f"250样本均值: {np.mean(normal_data[:250]):.2f}")

# 绘制累积分布直方图
plt.hist([normal_data[:10], normal_data[:100], normal_data],
         bins=30, stacked=True, density=True)
plt.xlabel('Value')
plt.ylabel('Frequency Density')

2.2 非正态分布挑战#

双峰分布示例:

code
def generate_bimodal(n):
    choice = np.random.binomial(1, 0.5, n)
    return np.where(choice, np.random.normal(5,1,n),
                    np.random.normal(-5,1,n))

bimodal_data = generate_bimodal(1000)

# Jarque-Bera正态性检验
from statsmodels.stats.stattools import jarque_bera
jb_value, pvalue = jarque_bera(bimodal_data)[:2]
print(f"P值: {pvalue:.4f}")  # 通常<0.05拒绝正态假设
特征正态分布双峰分布
均值意义明确中心误导性中心
标准差解释描述离散度混合分布的距离
适用统计量均值、标准差分位数、众数

三、金融时间序列案例#

3.1 数据获取 (yfinance)#

code
import yfinance as yf

# 获取标的价格数据
start = '2018-01-01'
end = '2023-01-01'
price_data = yf.download('AMZN', start, end)['Close']
returns = price_data.pct_change().dropna()

3.2 滚动夏普比率#

计算90天窗口的滚动夏普比率,该指标衡量了投资回报相对于风险的表现。这里简化处理,假设无风险利率为0:

code
# 假设无风险利率为0(简化处理)
def rolling_sharpe(returns, window=90):
    mean = returns.rolling(window).mean()
    std = returns.rolling(window).std()
    return (mean / std).dropna()

plt.plot(rolling_sharpe(returns))
plt.ylabel('90-Day Sharpe Ratio')
plt.xlabel('Date')

3.3 移动平均与布林带#

这段代码实现了移动平均线和布林带的绘制:

  1. 首先计算了90天的移动平均线(ma_90)

  2. 然后计算了90天的标准差(std_90)

  3. 绘制了原始价格数据和90天移动平均线

  4. 使用fill_between函数绘制了布林带(移动平均线±标准差的区域)

  5. 最后添加图例

布林带是一种常用的技术分析工具,由移动平均线和上下两条波动带组成,能帮助判断价格的波动性和可能的支撑/阻力位。当价格接近上轨时可能被视为超买,接近下轨时可能被视为超卖。

code
ma_90 = price_data.rolling(90).mean()
std_90 = price_data.rolling(90).std()

plt.plot(price_data, label='Price')
plt.plot(ma_90, label='90D MA')
plt.fill_between(ma_90.index,
                 ma_90 - std_90,
                 ma_90 + std_90,
                 alpha=0.2)
plt.legend()

需要注意的是,代码中使用的是单一标准差,而传统布林带通常使用两倍标准差。

四、实践练习#

习题1:滚动波动率分析#

请完成以下代码,计算并绘制标普500指数的180日滚动年化波动率:

code
import yfinance as yf

# 获取SPY数据
spy = yf.download('SPY', '2020-01-01', '2023-01-01')['Adj Close']
returns = _____.pct_change().dropna()

# 计算滚动年化波动率(假设252个交易日)
window = 180
volatility = _____.rolling(window).std() * np.sqrt(252)

# 绘制结果
plt.figure(figsize=(10,4))
_____.plot()
plt.title('SPY 180-Day Rolling Volatility')
plt.ylabel('Annualized Volatility')

习题2:分布形态分析#

给定一个包含收益率数据的数组returns,请:

  1. 计算其偏度和峰度

  2. 执行Jarque-Bera检验

  3. 判断是否符合正态分布

code
from scipy.stats import skew, kurtosis

skewness = ...
excess_kurtosis = ...

jb_test = jarque_bera(returns)
print(f"偏度: {skewness:.2f}, 超额峰度: {excess_kurtosis:.2f}")
print(f"JB检验p值: {jb_test[1]:.4f}")

# 判断标准(α=0.05)
if jb_test[1] < 0.05:
    print("拒绝正态性假设")
else:
    print("无法拒绝正态性假设")

五、关键要点总结#

  • 参数估计本质上具有不确定性,需评估稳定性

  • 滚动窗口法是分析参数时变特征的有效工具

  • 数据分布形态显著影响参数解释力

  • 夏普比率等复合参数需双重稳定性分析

  • 正态性检验是参数方法应用的前提

注意事项:

  1. 滚动窗口长度影响平滑度与敏感性

  2. 非平稳时序需先进行平稳化处理

  3. 多参数组合需考虑协方差结构

  4. 市场机制变化会导致参数突变