/ / /
第10讲:估计的不稳定性 (Instability of Estimates)
🔴
入学要求
💯
能力测试
🛣️
课程安排
🕹️
研究资源

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

💡

查看全集:💎Quantopia量化分析56讲

一、参数估计基础概念

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:均值参数,决定了分布的中心位置
  1. σ\sigma:标准差参数,控制分布的宽度或分散程度
  1. 1σ2π\frac{1}{\sigma\sqrt{2\pi}}:归一化系数,确保概率密度函数的总积分为1
  1. 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 估计的本质

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

二、参数稳定性分析

2.1 正态分布案例

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 非正态分布挑战

双峰分布示例:

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)

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:

# 假设无风险利率为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)
  1. 然后计算了90天的标准差(std_90)
  1. 绘制了原始价格数据和90天移动平均线
  1. 使用fill_between函数绘制了布林带(移动平均线±标准差的区域)
  1. 最后添加图例
布林带是一种常用的技术分析工具,由移动平均线和上下两条波动带组成,能帮助判断价格的波动性和可能的支撑/阻力位。当价格接近上轨时可能被视为超买,接近下轨时可能被视为超卖。
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日滚动年化波动率:

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. 计算其偏度和峰度
  1. 执行Jarque-Bera检验
  1. 判断是否符合正态分布
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. 滚动窗口长度影响平滑度与敏感性
  1. 非平稳时序需先进行平稳化处理
  1. 多参数组合需考虑协方差结构
  1. 市场机制变化会导致参数突变

附:练习合集