在描述时间序列趋势(如股票价格)时,简单移动平均(SMA)和指数移动平均(EMA)各有特点。以下是详细分析:
指标 | SMA | EMA |
---|---|---|
权重分配 | 等权重 | 指数衰减权重 |
滞后性 | 较高 | 较低 |
噪声敏感性 | 较不敏感 | 更敏感 |
计算复杂度 | 简单 | 需要递归计算 |
参数敏感性 | 对窗口大小敏感 | 对衰减因子敏感 |
公式:
S M A t = 1 n ∑ i = 0 n − 1 P t − i SMA_t = \frac{1}{n}\sum_{i=0}^{n-1} P_{t-i} SMAt=n1i=0∑n−1Pt−i
优势:
劣势:
公式:
E M A t = α ⋅ P t + ( 1 − α ) ⋅ E M A t − 1 EMA_t = \alpha \cdot P_t + (1-\alpha) \cdot EMA_{t-1} EMAt=α⋅Pt+(1−α)⋅EMAt−1
优势:
劣势:
场景 | SMA表现 | EMA表现 |
---|---|---|
趋势反转 | 信号延迟明显 | 能更快捕捉转折点 |
剧烈波动 | 曲线相对平滑 | 可能出现虚假信号 |
长期横盘 | 保持稳定 | 可能产生锯齿状波动 |
缺口跳空 | 缓慢修正趋势线 | 快速调整趋势方向 |
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
# 获取股票数据
data = yf.download('AAPL', start='2023-01-01', end='2023-12-31')
# 计算SMA和EMA
def calculate_metrics(df, window=20, alpha=0.2):
df['SMA'] = df['Close'].rolling(window=window).mean()
df['EMA'] = df['Close'].ewm(alpha=alpha, adjust=False).mean()
return df
data = calculate_metrics(data)
# 可视化对比
plt.figure(figsize=(12,6))
plt.plot(data['Close'], label='Price', color='gray', alpha=0.5)
plt.plot(data['SMA'], label=f'SMA {20}', linestyle='--')
plt.plot(data['EMA'], label=f'EMA (α=0.2)', linestyle='-')
plt.title('SMA vs EMA Comparison')
plt.legend()
plt.show()
# 极端情况模拟分析
def simulate_extreme_cases():
# 生成测试数据
np.random.seed(42)
base = np.sin(np.linspace(0, 6*np.pi, 200))
noise = np.random.normal(0, 0.5, 200)
spike = np.zeros(200)
spike[100] = 5 # 加入异常值
# 构建三种场景
cases = {
'gradual_change': base + 0.1*np.arange(200),
'sudden_spike': base + spike + noise,
'volatile': base*2 + np.random.randn(200)*0.8
}
# 可视化分析
fig, axes = plt.subplots(3, 1, figsize=(12, 12))
for ax, (title, series) in zip(axes, cases.items()):
df = pd.DataFrame({'Value': series})
df['SMA'] = df['Value'].rolling(20).mean()
df['EMA'] = df['Value'].ewm(alpha=0.1).mean()
df.plot(title=title, ax=ax)
ax.legend(['Actual', 'SMA(20)', 'EMA(α=0.1)'])
plt.tight_layout()
plt.show()
simulate_extreme_cases()
趋势跟踪策略:
参数选择技巧:
# 自适应参数调整示例
def dynamic_alpha(volatility):
"""根据波动率动态调整alpha"""
base_alpha = 0.2
return np.clip(base_alpha * (1 + volatility*10), 0.05, 0.5)
组合使用方案:
数学特征 | SMA | EMA |
---|---|---|
频率响应 | 理想低通滤波器 | 一阶低通滤波器 |
相位延迟 | (N-1)/2 周期 | 1/(α) - 1 周期 |
传递函数 | 1 N 1 − z − N 1 − z − 1 \frac{1}{N}\frac{1-z^{-N}}{1-z^{-1}} N11−z−11−z−N | α 1 − ( 1 − α ) z − 1 \frac{\alpha}{1-(1-\alpha)z^{-1}} 1−(1−α)z−1α |
内存需求 | 需要存储N个历史数据 | 仅需存储前一个EMA值 |
# 动态权重混合模型
def hybrid_model(df, short_window=10, long_window=30):
df['SMA_fast'] = df['Close'].rolling(short_window).mean()
df['EMA_slow'] = df['Close'].ewm(span=long_window).mean()
# 计算动态混合权重
volatility = df['Close'].pct_change().rolling(5).std()
weight = 1 / (1 + np.exp(-volatility*100)) # Sigmoid函数归一化
df['Hybrid'] = weight*df['SMA_fast'] + (1-weight)*df['EMA_slow']
return df
data = hybrid_model(data)
data[['Close', 'Hybrid']].plot(figsize=(12,6))
plt.title('Dynamic Hybrid Model')
plt.show()
这个混合模型能够: