期货异同移动平均线(MACD):零轴和两线交叉有什么区别?

看期货异同移动平均线(MACD)时,你可能遇到这样的画面:DIFF还在零轴下方,柱子却已经转正,两条线也由下向上交叉了。这并不矛盾,因为零轴和两线交叉比较的不是同一件事。

零轴给出的是数值基准,两线关系给出的是DIFF相对其平滑线的位置。弄清这两种比较,再看前后变化,就能准确描述"零下上穿",而不必把几个不同条件都叫作同一个信号。TqSdk的ta.MACD返回三列数据,可以把图上的关系逐项对应出来。

DIFF低于零,与DIFF低于DEA不是一回事

TqSdk的ta.MACD(df, short, long, m)接收K线DataFrame和三个周期参数,返回diff、dea、bar三列。按TqSdk 3.10.4的实现,它们的关系是:

text 复制代码
DIFF = 收盘价的短周期EMA - 收盘价的长周期EMA
DEA  = DIFF的m周期EMA
柱值bar = 2 × (DIFF - DEA)

EMA是指数加权移动平均。这里不必把三条计算链记成术语,抓住它们各自在比较什么即可:

  • diff > 0:短周期收盘价EMA高于长周期EMA。
  • diff > dea:DIFF高于自身的平滑线,此时该实现的柱值为正。
  • diff < 0且diff > dea:DIFF仍在零下,但已经高于DEA,完全可能同时成立。

因此,"柱值转正"对应的是DIFF与DEA之间的差转正,不是DIFF已经越过零轴。两条线都在零下时,也可以出现正柱;两条线都在零上时,也可以出现负柱。

这些值处在价格差的尺度上,不是涨跌百分比,也不是成交金额。short、long和m以所选K线的根数计:在一分钟线上,12是12根一分钟K线,不会因为参数写了12就自动变成12天。

一组零轴下方上穿的例子

假设相邻两根已结束K线对应的指标值如下,只用来说明位置关系,不对应某个实际合约行情:

时点 DIFF DEA bar=2×(DIFF-DEA)
前一根 -3 -2 -2
当前根 -1 -1.8 1.6

前一根中,-3低于-2,DIFF在DEA下方。当前根中,-1高于-1.8,DIFF转到DEA上方,柱值由-2变成1.6。

但DIFF从-3变为-1,两个值都小于0。因此,按这两个结束时点可以描述为"两线关系由下转上,DIFF仍在零轴下方",不能描述成"DIFF已经上穿零轴"。

这一区分对期货复盘很实用。同样是正柱,一种情况可能是DIFF已经在零上,另一种却是DIFF仍在零下、只是相对DEA的位置改变。把这两种状态混在一起,就会丢掉原本可以从三列数据中读出的差别。

交叉是前后关系,不是一张截图

看到当前diff > dea,只能确定DIFF现在位于DEA上方。它可能刚转上来,也可能已经连续多根保持在上方。要描述一次新的上穿,必须比较前一根与当前根。

本文把"上穿"明确定义为:前一根diff <= dea,当前根diff > dea。这把前一根刚好相等也纳入起点;如果采用其他相等处理方式,应保持自己的定义一致,不能在不同观察中临时切换。

DIFF上穿零轴则是另一组条件:前一根diff <= 0,当前根diff > 0。这两组条件可能同时成立,也可能只成立一组。上面的假设恰好就是"两线上穿成立,DIFF上穿零轴不成立"。

在TqSdk中把两种判断并排看

以下是已有TqSdk程序中的局部用法。api为已有连接,symbol是程序已经确认的期货合约代码。先请求一分钟K线,200表示请求根数:

python 复制代码
klines = api.get_kline_serial(
    symbol, duration_seconds=60, data_length=200
)

序列会随数据更新,订阅返回并不能代替收线确认。下段应接在已有数据更新流程之后:由该流程确认合约和周期、输入范围有效且按时间排列、历史长度符合所用计算口径,并确认范围末尾两根是相邻且已结束的K线,相关指标值可用。window_start、window_stop是调用方提供的当前行位置,选取范围左端包含、右端不包含;不是SDK自带的自动收线或历史充分性判定。

python 复制代码
from tqsdk import ta

# 保留已确认输入的副本;12、26、9用于说明参数,不代表最优组合
bars = klines.iloc[window_start:window_stop].copy()
macd = ta.MACD(bars, 12, 26, 9)

# diff必须按列名取值,避免与DataFrame的diff()方法混淆
previous_diff = macd["diff"].iloc[-2]
previous_dea = macd["dea"].iloc[-2]
current_diff = macd["diff"].iloc[-1]
current_dea = macd["dea"].iloc[-1]

# 前后点均来自这次计算的同一输入范围,分别判断两种上穿
crossed_dea_up = previous_diff <= previous_dea and current_diff > current_dea
crossed_zero_up = previous_diff <= 0 and current_diff > 0

print("对应K线:", bars[["id", "datetime"]].tail(2))
print("DIFF、DEA、柱值:", current_diff, current_dea, macd["bar"].iloc[-1])
print("两线上穿、DIFF上穿零轴:", crossed_dea_up, crossed_zero_up)

macd["diff"]才是取DIFF这一列,不能写成macd.diff来代替。代码中的两个布尔结果分别对应前文两组条件,不是两次重复确认同一种变化。

计算还应保留同一输入范围和参数。不要把上次用一段历史计算的前值,与这次换了起点重算的当前值随意拼接。输入长度不足、数据缺失或指标值不可用时,应暂缓判断,不能把空值补0,因为0正是本文要判断的真实边界。

对于未结束K线,收盘字段仍可能变化,相应的MACD关系也可能改变。本文比较的是相邻结束时点的关系,不声称两点之间只交叉过一次,更不还原盘中的每次穿越。图表柱色还受显示设置影响,用正负数值说明关系比只说"红柱""绿柱"明确。

为什么推荐用TqSdk核对这类指标含义

对想把期货MACD读明白的读者,我推荐用TqSdk将同一输入范围的DIFF、DEA和柱值并排观察。它在本题的价值不是替你把交叉翻译成买入指令,而是让图形描述有明确对应:究竟是DIFF过零、两线相对位置变化,还是当前只是保持在某一侧。

三列来自同一次官方函数计算,再与原K线身份相连,能够减少"看见正柱就以为DIFF为正"的误读。把指标所表达的事实说准,才有基础讨论它在自己的期货观察方法中承担什么作用;交叉本身并没有提供盈利保证。

相关推荐
开源量化GO1 小时前
期货成交额变大,为什么成交手数反而少了?
期货·tqsdk
CTA终结者4 小时前
期货当日成交量超过持仓量,是统计错了吗?
期货·tqsdk
量化吞吐机13 小时前
期货波动怎么看?平均真实波幅(ATR)和历史波动率怎么选?
期货·tqsdk
nanawinona2 天前
期货保证金相同,控制的合约规模就一样吗?
期货·tqsdk
量化吞吐机2 天前
期货复盘选了一个月,究竟覆盖多少个交易日?
期货·tqsdk
量化吞吐机6 天前
期货主连换月,涨跌和合约价差怎么分清?
期货·tqsdk
CTA量化套保6 天前
研究期货价差,最新报价和同周期K线该怎么选?
期货·tqsdk
nanawinona7 天前
期货持仓没变,挂单为什么变了?用TqSdk分清仓位和委托
期货·tqsdk
开源量化GO13 天前
期货研究反复取数,什么时候值得用下载程序?
tqsdk