【学习笔记】get_EMA优化:
```
def get_EMA(security_code, days, data):
if days == 1:
t = attribute_history(security_code, 2, "1d", "close")
return t["close"][-2], t["close"][-1]
#全局缓存
if not hasattr(g, "EMAs"):
g.EMAs = {}
key = (security_code, days) # 用元祖作键,更安全
if key in g.EMAs:
# 标准EMA:EMA_now = EMA_pre * alpha + Price * (1 - alpha)
# 其中 (1 - alpha) = 2 / (days + 1),=> alpha = (days - 1) / (days + 1)
alpha = (days - 1.0) / (days + 1.0)
EMA_pre = g.EMAs[key]
price_now = data[security_code].close
EMA_now = EMA_pre * alpha + price_now * (1.0 - alpha)
g.EMAs[key] = EMA_now
return EMA_pre, EMA_now
else:
ma = get_MA(security_code, days)
if not isnan(ma):
g.EMAs[key] = ma
return float("nan"), ma
else:
return float("nan"), float("nan")
code
```
MA(或者SMA,简单移动平均)对比 EMA(指数移动平均),为什么很多场景用EMA来追踪趋势:
1. SMA计算最近N天等权平均,EMA对越新的价格权重越大、切权重按指数衰减,没有生硬的窗口阶段,所以EMA对新价赋更大权重、对趋势拐点更敏感;
2. EMA比直接价格更平滑(去噪),又比同周期的SMA滞后少,常用于均线、MACD等动量/趋势指标;
3. EMA在线迭代、计算/存储友好。只需要保存上一次EMA和当前价即可更新,复杂度O(1),比每次重算的SMA的窗口合计更省;
4. SMA在“加一天/减一天”时会突然替换最旧的一天,边界会造成突变;EMA权重指数衰减,变化更连续;
5. 用同一个N,EMA更贴近“当下”,SMA更钝更稳。追踪“指数/趋势”(如指数基金、股指或任意标的的价格趋势),EMA更实用。
2025-10-28