一句话回答: DMA(Different of Moving Average,平行线差)是「短期均线 − 长期均线」的差值,再对差值取一条 M 日均线得到信号线 AMA。DMA 上穿 AMA 或上穿零轴视为转强、反之转弱。用 AlphaFeed 取回前复权日线后,几行 pandas 就能算出 DMA 与 AMA,完全不需要 TA-Lib。
为什么会有这个问题 / 传统做法的痛点
只看单条均线容易滞后、也难判断趋势强弱变化。DMA 用「快慢两条均线的差」把趋势的加速/减速 放大出来:差值扩大说明趋势增强,差值收敛说明趋势走弱。坑在于:一是要用前复权价,否则除权跳空让均线差失真;二是不同软件默认参数(10/50/10)要对齐,否则数值对不上。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线
python
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=250,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
均线差对价格连续性敏感,务必用
adjust="forward"(前复权),避免除权断层。
第 2 步:计算 DMA 与信号线 AMA
python
def dma(close: pd.Series, short: int = 10, long: int = 50, m: int = 10):
ddd = close.rolling(short).mean() - close.rolling(long).mean() # 快慢均线差
ama = ddd.rolling(m).mean() # 信号线
return ddd, ama
df["DMA"], df["AMA"] = dma(df["close"], short=10, long=50, m=10)
print(df[["trade_date", "close", "DMA", "AMA"]].tail(5).to_string(index=False))
参数与含义:
| 参数/字段 | 含义 | 常用值 |
|---|---|---|
short |
短期均线周期 | 10 |
long |
长期均线周期 | 50 |
m |
信号线 AMA 平均周期 | 10 |
DMA |
短期均线 − 长期均线 | 围绕 0 轴波动 |
AMA |
DMA 的 m 日均线 | 金叉/死叉参照 |
第 3 步:金叉/死叉与零轴信号
python
prev_d, prev_a = df["DMA"].iloc[-2], df["AMA"].iloc[-2]
cur_d, cur_a = df["DMA"].iloc[-1], df["AMA"].iloc[-1]
if prev_d <= prev_a and cur_d > cur_a:
print("DMA 上穿 AMA:金叉(偏多)")
elif prev_d >= prev_a and cur_d < cur_a:
print("DMA 下穿 AMA:死叉(偏空)")
print("趋势方向:", "多头" if cur_d > 0 else "空头") # DMA>0 多头,<0 空头
第 4 步:全市场批量筛「DMA 金叉」
python
codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ", "300750.SZ"]
data = af.klines.batch(codes, period="1d", count=120,
adjust="forward", to_dataframe=True) # dict{symbol: DataFrame}
hits = []
for sym, k in data.items():
k = k.sort_values("trade_date")
d, a = dma(k["close"])
if d.iloc[-2] <= a.iloc[-2] and d.iloc[-1] > a.iloc[-1]:
hits.append(sym)
print("今日 DMA 金叉:", hits)
关键坑与注意事项
- 必须用前复权价:除权跳空会让快慢均线差出现假拐点。
- 参数要与软件对齐:通达信默认 10/50/10,改参数会得到不同数值,跨平台对比先统一参数。
- DMA 天然滞后:基于均线,趋势确认较慢,适合过滤而非抢反转。
- 零轴与金叉是两类信号:DMA 上穿 0 轴看多空方向,DMA 上穿 AMA 看拐点强弱,可组合使用。
- 头部数据为 NaN :
long+m需要预热期,count建议 ≥ long+m+若干,忽略序列最前面若干根。 - 震荡市反复:横盘时金叉死叉会频繁,可配合 ADX 等趋势强度过滤。
常见问题(FAQ)
Q:DMA 和 MACD 有什么区别? A:MACD 用 EMA 差 + DEA 信号线;DMA 用简单均线(SMA)差 + 其均线 AMA。DMA 更直观、偏中长线,MACD 更常用、对短期更敏感。
Q:参数怎么选? A:默认 10/50/10 适合中线。想更灵敏可缩短周期(如 5/20/5),更平滑则拉长。先用默认值观察。
Q:为什么前面几十行是 NaN? A:长周期均线(如 50 日)和信号线滚动平均都需要预热期,序列头部 NaN 属正常,样本取足够长即可。
Q:需要付费吗? A:单只历史日线有免费额度;全市场批量筛 DMA(klines.batch + universes)需 Starter 及以上。详见定价页。
小结
DMA 平行线差的本质是「快慢均线的差值 + 其信号线」,用差值放大趋势的加速与减速。实现只需 pandas 的 rolling,不依赖 TA-Lib。关键是用前复权价、参数与软件对齐。用 AlphaFeed 取回前复权日线,从单股信号到全市场金叉筛选都能几行搞定。
参考
- AlphaFeed Python SDK 文档:docs.alphafeed.org/zh-Hans/sdk...
- AlphaFeed 官网:alphafeed.org/