如何用 Python 计算 DMA 平行线差指标?

一句话回答: 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 取回前复权日线,从单股信号到全市场金叉筛选都能几行搞定。

参考

相关推荐
奈葵1 小时前
Python
开发语言·python
happylifetree1 小时前
Python54-55:核心语法-数据容器-字典dict-案例
python
小小张说故事1 小时前
Python 迭代器和生成器到底啥区别?3 个例子讲透,别再背概念了
python
外收内放2 小时前
Python基础语法练习题(56优化版补充)
开发语言·python
专注API从业者2 小时前
告别复杂页面解析,OpenClaw 快速搭建电商商品监控与数据分析脚本
大数据·数据库·python·数据挖掘·数据分析
王立志_LEO3 小时前
HTTPX 完整用法总结
python
ggb喔3 小时前
52pojie 的图片工具:为什么无损转换后体积涨了 6 倍、照片方向还是歪的
图像处理·python·算法·计算机视觉·图形渲染·媒体
hnxaoli3 小时前
win10小程序(二十三)新建带时间文件夹
python
企业数字化笔记3 小时前
AI工具参数很多怎么办?预设、表单校验、危险参数与配置审计
java·spring boot·python·音视频