查看全集:💎Quantopia量化分析56讲
参数是描述数据集或概率分布的统计量。例如:
关键公式——正态分布概率密度函数:
这个函数各部分的含义是:
当接近时,指数部分接近1,密度达到最大值;随着远离,概率密度迅速下降。较大的值会使曲线更平坦宽广,较小的值则使曲线更高且集中。
正态分布有"68-95-99.7"规则:约68%的数据在范围内,约95%在范围内,约99.7%在范围内。
所有参数估计都存在不确定性:
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')
双峰分布示例:
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拒绝正态假设
特征 | 正态分布 | 双峰分布 |
均值意义 | 明确中心 | 误导性中心 |
标准差解释 | 描述离散度 | 混合分布的距离 |
适用统计量 | 均值、标准差 | 分位数、众数 |
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()
计算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')
这段代码实现了移动平均线和布林带的绘制:
ma_90
)std_90
)fill_between
函数绘制了布林带(移动平均线±标准差的区域)布林带是一种常用的技术分析工具,由移动平均线和上下两条波动带组成,能帮助判断价格的波动性和可能的支撑/阻力位。当价格接近上轨时可能被视为超买,接近下轨时可能被视为超卖。
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()
需要注意的是,代码中使用的是单一标准差,而传统布林带通常使用两倍标准差。
请完成以下代码,计算并绘制标普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')
给定一个包含收益率数据的数组returns,请:
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("无法拒绝正态性假设")
注意事项:
- 滚动窗口长度影响平滑度与敏感性
- 非平稳时序需先进行平稳化处理
- 多参数组合需考虑协方差结构
- 市场机制变化会导致参数突变