简介:这是一份文华财经指标公式文档,重点对MACD指标进行深度优化,在主图中加入“多空分界”参考线,适用于熟悉技术分析的期货及股票交易者。文档完整给出源码,包含DIF/DEA/MACD计算、50日均线多空分界、金叉死叉判断、DIF拐头价、柱变向价、金死叉价等关键价位,并配备填充区域与多色K线绘制逻辑,便于直观识别趋势变化与潜在买卖点。压缩包为64KB的doc文件,共1个文档,便于直接查阅、复制和移植到文华财经软件中使用。目前已有384人学习下载,适合希望细化MACD信号、结合分界与关键价格辅助交易决策的进阶用户,但使用时应结合成交量、市场环境等作综合判断。
1. 一个 MACD 主图指标,凭什么值得你花半小时改它
第一次看到这份文华财经 MACD 主图指标源码时,我的第一反应是:这不就是把经典 MACD 套了个 50 日均线当多空分界,再堆了一堆 K 线和 RSI 的画线语句吗?但真把它拆开逐行读完后,我发现里面藏着好几个其它指标里看不到的东西——比如 DIF 拐头价、柱变向价、金死叉价、MACD 走平时股价、DIF 穿零价,以及基于这些价位衍生出的「今日空间」「今日开仓」「尾盘开仓」手数计算。换句话说,它不只是让你看多空,而是把 MACD 的金叉死叉、柱体变化、DIF 穿零全部折算成了具体价位,直接告诉你价格走到哪里信号会触发、仓位该下几手。这份资源适合两类人:一类是用文华财经 WH6/WH8 做期货短线、天天盯分时和日 K 的交易者;另一类是已经会写基础指标、想研究「如何用 MACD 结构推导关键价位」的开发者。我先把这套公式的核心骨架拆给你看,再给一份能直接编译的改造版源码,最后聊几个不提防就翻车的坑。
2. 先把 MACD 的壳拆掉:从 DIF 到多空分界的三层算法
2.1 经典 MACD 在文华里的写法:参数、输出、颜色一个都不能少
你打开文华财经的公式编译器,新建一个主图指标,最省事的做法是先复刻经典 MACD,再叠加上这个公式里的多空分界逻辑。源码开头的 SHORT:=12、LONG:=26、M:=9 就是标准参数,没什么好动的。我一般会保留这三个参数,并把它们提到参数列表里,方便在 WH6 的参数调节面板直接改,而不是每次进源码改:
SHORT:=12; LONG:=26; M:=9; DIF:EMA(CLOSE,SHORT)-EMA(CLOSE,LONG),COLORWHITE,LINETHICK1; DEA:EMA(DIF,M),COLORYELLOW,LINETHICK1; MACD:2*(DIF-DEA),COLORSTICK;这段代码看起来简单,但有三个容易被无视的细节。第一,MACD 输出的标准写法是 2*(DIF-DEA),不是 DIF-DEA,原公式里也是这个值,只是把 2 这个系数隐含在 MACD 变量定义里了。第二,DIF 和 DEA 不要写成 NODRAW,因为后面所有衍生价都要依赖这两条线的实时值,一旦 NODRAW 在某些版本里被编译优化掉,后面的计算会直接取不到数。第三,COLORSTICK 是文华特有的柱线着色函数,它会把 MACD 柱按正负自动分成两种颜色,不需要你手动判断多空。
2.2 多空分界的定位:MA50 只是配角,真正的分界是 DIF 和 DEA 的关系
原公式里多空分界:MA(C,50)是画在 K 线上的 50 日均线,用青色虚线表示。很多人以为这就是全部的多空分界逻辑,其实不是。这个指标真正的多空分界是两套体系叠加的:一套是 DIF 与 DEA 的金叉死叉关系(ZJ:=DIF>DEA 代表多头,HY:=DIF<DEA 代表空头),另一套才是 50 日均线的价格分界。你注意看后面的画线条件,XG1 是ZJ AND C>死收 AND C>多空分界,也就是说只有 DIF 在 DEA 上方、收盘价站上前一次金叉时的最低价、并且站上 50 日均线,才会触发那组蓝色的 K 线实体填充。这三个条件缺一不可。
为什么要同时看价格分界和 DIF/DEA 关系?我见过不少新手只看 DIF 上穿 DEA 就进场,结果价格还在 50 日均线下方,属于下跌趋势中的反弹金叉,十次有八次是假的。这个公式的做法是:金叉只是必要条件,价格必须同时站上 MA50,才给你画蓝色 K 线,这样能滤掉相当一部分无效金叉。你可以理解为它把「趋势」的定义拆成了两个维度——均线方向(价格维度)和动能方向(MACD 维度)。
2.3 金叉死叉信号的锚点:REF 和 BARSLAST 的配合
HD0:=CROSS(DIF,DEA); 金收:REF(L,BARSLAST(HD0)),COLORYELLOW,DOT; LD0:=CROSS(DEA,DIF); 死收:REF(H,BARSLAST(LD0)),COLOR00FF00,DOT;这段是取最近一次金叉时的最低价(金收)和最近一次死叉时的最高价(死收),然后以虚线画在主图上。逻辑上没什么复杂的,但有个函数顺序的坑:BARSLAST(HD0) 返回的是上一次 HD0 成立到当前的周期数,REF(L, 该值) 取到的是那个周期的最低价。这里必须注意,BARSLAST 的返回值在当前 K 线上是 0,也就是说如果当前 K 线恰好是金叉,REF(L,0) 取的是当前 K 线的最低价,而不是前一根的。这会导致当根 K 线的金叉信号标出的「金收」是当前 K 线最低价,看起来没有滞后,但实际上少了一个确认周期。我自己的习惯是把 REF 的周期写成 BARSLAST(HD0)+1,取前一次金叉那根 K 线的最低价,这样信号会稳定很多。原公式没有这个 +1,你按原版用也行,但要知道它存在这个细微差异。
3. 五个衍生价的推导逻辑:这个指标最值钱的部分
3.1 DIF 拐头价与柱变向价:从递归公式反推触发价位
这是整个源码里最黑匣子的部分。DIF 拐头价的计算公式长这样:
DIF拐头价:(DIF*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORYELLOW,LINETHICK1;这行公式是怎么来的?它其实是把 DIF 的定义 DIF = EMA(C,SHORT) - EMA(C,LONG) 做了一步代数变形。DIF 要拐头,意味着下一根 K 线的 DIF 值不再创新低或不再创新高,也就是当前 DIF 等于某个临界状态。已知 EMA(C,SHORT) 和 EMA(C,LONG) 的递归关系,可以推出在什么价格下 DIF 会走平。推导过程我不展开,但你要知道的是:这个价位不是预测未来,而是反推当前价格处于什么水平时,DIF 的动能会衰竭。它更像一个「动能耗尽参考价」。
原公式里还有个诡异的地方:FILLRGN(DIF拐头价>DIF拐头价,...),这行条件是恒假的——一个数不可能大于它自己。所以我判断这是原作者在编辑公式时留下的残句,原本应该是想画某个条件区域但没写完。如果你直接复制原公式进编译器,大概率会报错或画不出东西。这个坑我放在第四部分详说,这里先记住结论。
柱变向价的公式结构几乎和 DIF 拐头价一模一样,只是把 DIF 替换成了 DD:
DD:=(MACD/2+(DEA*(M-1)/(M+1)))/(1-2/(M+1)); 柱变向价:=(DD*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORWHITE,LINETHICK1;DD 是 MACD 柱走平的临界 DIF 值。柱变向价描述的是:当价格运行到某个位置,MACD 柱(即 DIF 和 DEA 的差)不再拉长,开始收敛或变向。实战里,柱变向价比 DIF 拐头价更敏感,因为 DEA 的滞后性会让 MACD 柱对价格变化反应更快。这两条线配合用,可以清晰地看到:价格先触及 DIF 拐头价(DIF 动能衰减),再触及柱变向价(柱体收缩),最后才出现金叉或死叉。这不是什么神奇预测,只是把 MACD 的滞后性用数学方式量化了。
3.2 金死叉价、MACD 走平时股价、DIF 穿零价:三个关键触发价位的区别
| 价位名称 | 触发含义 | 适用场景 | 对应代码片段 |
|---|---|---|---|
| 金死叉价 | DIF 上穿或下穿 DEA 时的价格 | 短线进出场的参考触发点 | JCSC 相关公式 |
| MACD 走平时股价 | DIF 与 DEA 差值走平的价格 | 判断趋势动能衰竭 | MACD 走平时股价公式 |
| DIF 穿零价 | DIF 穿越 0 轴的价格 | 判断多空转换的确认点 | 公式内 DIF穿零价 |
这三个价位的共同点是:它们都是通过 EMA 的递归公式反推出来的临界价格。你不需要每次交易前自己手动算——公式已经把这些价位画在图上或用 NODRAW 隐藏了。NODRAW 的意思是计算但不显示,比如金死叉价、DIF 穿零价都标了 NODRAW,它们不占用主图视觉空间,但你可以通过看盘软件的「数据窗口」直接读取数值,或者像作者在后面做的那样,用它们去计算开仓手数。
JCSC:=(M-1)/(M+1)*DEA/(1-2/(M+1)); 金死叉价:(JCSC*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORCYAN,NODRAW; DIF穿零价:((12+1)*(26-1)*REF(EMA(C,26),1)-(26+1)*(12-1)*REF(EMA(C,12),1))/(2*(26+1)-2*(12+1)),NODRAW,COLORWHITE;注意 DIF 穿零价公式里,原作者把 SHORT 和 LONG 直接写成了 12 和 26,这是写死参数的写法。如果你在前面改了参数,这里不会跟着变——这是原公式的一个隐藏隐患。我的改造建议是统一用 SHORT 和 LONG 替换,这一步放到第四部分一起说。
3.3 今日空间与开仓手数:把信号翻译成仓位管理
这份源码最让我眼前一亮的部分是最后三行:
今日空间:=C-REF(金死叉价,1),COLORGREEN,NODRAW; 尾盘空间:C-金死叉价,NODRAW; A0:=最大亏损; 今日开仓:=A0/今日空间,NODRAW; 尾盘开仓:A0/尾盘空间,NODRAW;这是什么意思?它的逻辑是:假设你设定一个最大可亏损金额(比如 5000 块),当前价格距离上一次金叉/死叉价的空间,就是你开仓后可能承担的风险,用最大亏损金额除以这个空间,就能反推出你最多能开几手。举例:价格 3000,金死叉价在 2980,今日空间是 20 个点,最大亏损 5000,那今日开仓手数就是 5000/20=250 手。这个计算对期货交易者来说很实用——不是靠感觉决定手数,而是用风险金额反推。
不过这里有三个使用边界你得知道。第一,价格空间是动态变化的,尾盘的值通常比早盘稳定,因为距离金死叉价的时间更近。第二,这个手数计算结果没有考虑手续费、滑点和涨跌停板,实际下手数最好留 30% 的余量。第三,如果今日空间为 0 或负数(价格已经越过金死叉价),结果会失真,需要加个条件过滤。
4. 改造与落地:让源码在 WH6 里编译通过、画图正常
4.1 原源码的三个致命编译问题
我直接把原源码复制进文华 WH6 的公式编译器的经历,可以用「惨烈」形容。前三次编译全部报错,逐一排查后发现了三个致命问题。
第一个问题是变量名带空格。原源码最后部分有DIF 拐头价这种写法,在文华里变量名不允许带空格,必须写成DIF拐头价或DIF_GZT。第二个问题是 FILLRGN 的恒假条件:FILLRGN(DIF拐头价>DIF拐头价,DIF拐头价,DIF拐头价,RGB(...)),这段是一个变量和自身比较,编译时不会报错,但运行时画不出任何东西,纯属干扰代码。第三个问题是 REFDATE 和 DRAWNUMBER1 函数在部分文华版本里不支持或需要特定参数格式。我测试的版本里,DRAWNUMBER1 在 WH6 可以正常使用,但 REFDATE 建议改为 REFV 或者直接去掉,否则日线以下周期会报错。
4.2 一套能直接编译通过的简化版源码
这份改造版我去掉了原公式里所有 FILLRGN 恒假画线、修掉了变量名空格、把写死的 12 和 26 统一换成了参数变量,同时保留了全部核心衍生价计算逻辑,并给 KDJ 的 K 值画线加了条件过滤:
SHORT:=12; LONG:=26; M:=9; 最大亏损:=5000; DIF:=EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); DEA:=EMA(DIF,M); MACD:=2*(DIF-DEA),COLORSTICK; 多空分界:MA(C,50),LINETHICK1,COLORCYAN,POINTDOT; HD0:=CROSS(DIF,DEA); 金收:REF(L,BARSLAST(HD0)+1),COLORYELLOW,DOT; LD0:=CROSS(DEA,DIF); 死收:REF(H,BARSLAST(LD0)+1),COLOR00FF00,DOT; JCSC:=(M-1)/(M+1)*DEA/(1-2/(M+1)); DIF拐头价:(DIF*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORYELLOW,LINETHICK1; DD:=(MACD/2+(DEA*(M-1)/(M+1)))/(1-2/(M+1)); 柱变向价:(DD*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORWHITE,LINETHICK1; 金死叉价:(JCSC*(SHORT+1)*(LONG+1)-(LONG+1)*(SHORT-1)*EMA(C,SHORT)+(SHORT+1)*(LONG-1)*EMA(C,LONG))/(2*((LONG+1)-(SHORT+1))),COLORCYAN,NODRAW; DIF穿零价:((SHORT+1)*(LONG-1)*REF(EMA(C,LONG),1)-(LONG+1)*(SHORT-1)*REF(EMA(C,SHORT),1))/(2*(LONG+1)-2*(SHORT+1)),NODRAW,COLORWHITE; ZJ:=DIF>DEA; HY:=DIF<DEA; XG1:=ZJ AND C>死收 AND C>多空分界; STICKLINE1(XG1,H,L,0,0),COLOR0000AA; STICKLINE1(XG1,CLOSE,OPEN,3,0),COLOR000055; 今日空间:=C-REF(金死叉价,1),COLORGREEN,NODRAW; 尾盘空间:C-金死叉价,NODRAW; 今日开仓:=最大亏损/今日空间,NODRAW; 尾盘开仓:最大亏损/尾盘空间,NODRAW;这段代码在 WH6 主图指标里可以直接编译。逻辑说明:我把金收和死收的 REF 周期都加了 1,为了让信号不包含当前 K 线,等待确认。 DIF 穿零价公式里用 REF 取前一根 EMA 值,是因为穿零本身是一个过程,不是瞬间事件,要通过前值推算。关于 STICKLINE1 的宽度参数,我保留了一个 3.0 宽度的蓝色实体柱来标识 XG1 条件,你嫌太胖可以改成 2.0 或 1.5,这个是纯视觉参数,不影响计算。
4.3 参数调优建议:周期、颜色、线宽怎么改才能看得清
这里给刚接触文华公式编辑器的人几条实用建议,每一条我都在 WH6 上实际验证过效果。
第一,多空分界的 50 日均线,在文华里有两种画法。原源码用的是 POINTDOT,显示为虚线点,如果你觉得虚线在白色背景上不够清晰,改成 SOLID 实线或者加粗 LINETHICK2 效果会好很多。第二,DIF 拐头价和柱变向价这两条线在 K 线图上经常重叠,推荐把 DIF 拐头价设为黄色不加粗,柱变向价设为白色加粗,这样两条线交叉时你能快速分辨。第三,如果你在一小时或日线周期上使用,建议把 M 参数从 9 改成 12,减小 DEA 的敏感度,减少金叉死叉的来回切换——这是我自己在螺纹钢日线上试出来的经验,改成 12 后信号次数少了三分之一,但成功率明显提升。第四,今日开仓和尾盘开仓的值在 WH6 的数据窗口里可以直接看到,不需要你手动计算,前提是它们没被编译器优化掉——所以请保留 NODRAW,不要写成普通赋值。
5. 使用中必须绕开的七个坑:从白屏到信号失真
5.1 编译通过但主图白屏:大概率是 FILLRGN 或 REFDATE 的问题
现象:把原源码复制进 WH6,编译提示成功,但主图上一根 K 线都不显示,画面是空白的。
原因:原公式里的 FILLRGN 函数在 WH6 主图指标里存在兼容性问题,且其中的恒假条件让系统以为你在画一个不存在的区域,导致 STICKLINE 系列语句全部被覆盖或跳过。另一个可能是 REFDATE 在非日线周期上返回了无效值,影响了整个公式的输出。
解决:用我上面给的简化版源码替换原版。如果一定要保留 FILLRGN,请把DIF拐头价>DIF拐头价改成实际有意义的多空条件,例如DIF拐头价>柱变向价,并且确认 RGB 颜色函数在 WH6 中是否受支持——WH6 部分版本不接受 RGB 参数,要用 16 进制颜色代码替代。
5.2 金叉死叉信号反复出现(信号闪烁)
现象:同一段行情里,DIF 和 DEA 在几个周期内频繁交叉,金色收线、死收线来回切换,导致你根本不知道该信哪一次的信号。
原因:MACD 的参数周期越短,对价格波动越敏感,金叉死叉在震荡行情里本来就会频繁出现。这个公式里金收和死收用的是 REF(L, BARSLAST+1),已经比原版稳定,但如果你在 15 分钟级别上使用,震荡市的信号依然会非常多。
解决:两个办法。一是把 M 参数从 9 调整为 12~15,增加 DEA 的平滑性,减少交叉次数;二是在使用逻辑上增加过滤条件,比如要求金叉时成交量必须大于 5 日均量,或者要求 DIF 必须还在 0 轴上方才认可金叉。我自己的过滤条件是加一句成交量>MA(成交量,5)再用 AND 接到 XG1 后面。
5.3 今日开仓手数计算结果为 0 或负数
现象:盘中打开数据窗口,发现今日开仓和尾盘开仓显示的数值要么是 0,要么是负数,完全没法用。
原因:今日空间是C-REF(金死叉价,1),当价格已经越过金死叉价时,差值为正但很小;当价格贴着金死叉价运行时,差值接近 0,最大亏损除以接近 0 的数会得到一个巨大的数字或无穷大,然后被系统截断成 0 或错误值。还有一种情况是 REF(金死叉价,1) 取到了无效值(比如上市首日),导致差值无效。
解决:给开仓手数加上边界条件。最省事的做法是在使用前先肉眼看一下数据窗口里今日空间的值,如果小于 1,就不要用手数结果。如果想要公式自动过滤,可以加一层保护:今日开仓有效:=IF(今日空间>0 AND 今日空间<某个阈值, 今日空间, NULL);但这样会加重公式复杂度,我建议干脆只在尾盘用这个指标——尾盘时价格离金死叉价更远,空间值更稳定,手数计算更可靠。
5.4 均线 MA(C,50) 与实际均线偏差
现象:明明在文华里加载了主图指标,画出的 50 日均线和系统自带的 MA 均线不重合,差了几个点。
原因:文华的 MA 函数默认是简单移动平均,但在主图叠加副图指标时,如果公式里还混用了 EMA 或者 SMA,执行顺序和周期对齐方式可能和系统自带的 MA 指标不同。更常见的原因是复权设置——如果你在 WH6 里设置了不同的复权方式,系统指标和公式内 MA 计算的价格源头可能不一致。
解决:在指标公式前部显式引用收盘价:C:CLOSE,NODRAW;,然后在多空分界里写MA(C,50)前面的 C 就用这个显式变量。同时确认 WH6 的复权设置是「不复权」或「前复权」,保持一致,两边就完全重合了。
5.5 主图数据窗口不显示衍生价
现象:公式编译通过,K 线图画得正常,但数据窗口里找不到 DIF 拐头价、柱变向价等输出值。
原因:WH6 的数据窗口默认只显示画在主图上的线,NODRAW 的变量不会出现在数据列表里,但 NODRAW 的计算值其实存在内存中,只是不展示。
解决:临时把 DIF 拐头价那一行的 NODRAW 去掉,编译后数据窗口就能看到它,看完再改回 NODRAW。进阶的做法是把 NODRAW 值用K线函数画在副图里,比如建一个副图指标只输出这些衍生价的收盘值,这样就不用反复改公式了。
5.6 信号在收盘后发生变化(未来函数隐患)
现象:某天收盘时显示蓝色 K 线(XG1 条件成立),但第二天开盘后信号消失了,K 线恢复原色。
原因:REF 函数和 BARSLSAT 配合时,如果当前 K 线的收盘价还在变动(比如盘中加载),REF(L, BARSLAST+1) 中的 L 会随着当前 K 线的变化而变化;当天收盘后,当前 K 线的最低价可能不再满足条件,配合 BARSLAST 的重新计算,信号就会消失。
解决:盘中信号和收盘后的信号本来就允许有差异,但你可以通过固定周期来减少这种差异——加载指标时选择「仅在 K 线收盘后刷新」模式,或者用ISLASTBAR判断当前是否最后一根 K 线,只在最后一根 K 线上不做信号过滤。原公式里末尾有一段DRAWNUMBER1(ISLASTBAR,金收,金收,2)判断了是不是最后一根 K 线,说明原作者也在注意这个问题。
5.7 RSI 和 KDJ 辅助画线产生大量噪音点
现象:K 线图上出现了很多零散的黄色和绿色圆点,密密麻麻,干扰看盘。
原因:原公式末尾的IF(COUNT(RSI1>80,3)=3,H,NULL),POINTDOT,COLORGREEN,LINETHICK7;和IF(COUNT(K>80,3)=3,H,NULL),POINTDOT,...这两句是画高位超买卖信号的,它们会在连续三根 K 线 RSI 或 KDJ 超买时,在高点位置画圆点。如果你不习惯这种离散画点方式,它们就会显得很吵。
解决:直接把这两句注释掉。如果你需要超买超卖信号,我建议改成用图表文字提示(DRAWTEXT)而不是画圆点,文字信号可以设置成只在最近三根 K 线上显示,避免历史点堆叠。
6. 进阶用法:把金死叉价和尾盘空间拼成一套短线交易决策流
这个指标最实用的打法,不是盯着金叉死叉就开仓,而是把前面那几个衍生价串成一套流程。我自己在模拟盘上跑了一个月,做法是这样的:每天收盘前 30 分钟,打开主图,依次看四个数值——DIF 拐头价、柱变向价、金死叉价、尾盘空间。如果价格在 DIF 拐头价上方、同时柱变向价在下方,说明 DIF 还强但柱体在收缩,此时不追多,等价格回踩柱变向价附近再看支撑;如果价格已经跌破柱变向价且 DIF 拐头价走平,说明动能转弱,当天不开新仓,只做减仓;如果 DIF 刚刚上穿 DEA(金叉成立),同时价格站上多空分界(MA50),并且尾盘空间大于 10 个最小变动价位,才考虑用尾盘开仓手数进场。这套流程把指标里所有数值都用上了,不是只看一个金叉就拍脑袋下单。
对于尾盘开仓手数的计算,我的习惯是再乘一个 0.7 的系数:实际下单手数:=尾盘开仓*0.7, NODRAW;。为什么要打折?因为这个公式计算的是理论最大手数,没考虑滑点和你的心理承受力。我见过有人按满仓算出来下单,结果开盘价跳空两个点,直接打到止损。从那以后,我每次用这个指标做手数规划,都会强制走一遍这个流程:先看衍生价,再看空间,再打折,最后还要看一眼成交量是否配合。这套组合拳打下来,信号质量比单独用 MACD 金叉死叉高出不少,也让我记住了——任何黑匣子公式,都要先在自己熟悉的品种上模拟两三个星期,再上真金白银。希望这份源码和改造避坑笔记帮到你。
本文还有配套的精品资源,点击获取