通达信指标公式(4)MACD指标3个进阶版本与C++源代码(值得收藏)

相信大家都了解MACD这个技术指标,它是基于移动平均线的原理,通过计算短期和长期移动平均线之间的差异和聚合状态,来预测价格的走势,属于趋势型指标。

今天主要分享我在实战中,使用MACD的3个进阶版本(如下图),介绍每个版本的由来,如何一步步优化、调整,从而去除一些干扰的信号(去噪),最终提供相对正确率较高的入场信号。

前情回顾

限时福利

在公众号后台回复关键字,免费获取优质策略资源:

策略大礼包
通达信教程
高盛报告

更多资源尽情期待,文末还有重磅福利!!!

基础知识

MACD指标由三部分组成:快线(DIF)、慢线(DEA)和柱状图(MACD),这三个值的计算方式也比较简单,不过多介绍了,有几个概念需要提前说明下:

  • 金叉:当 DIF 上穿DEA时,通常表示买入信号。
  • 死叉:当 DIF 下穿DEA时,通常表示卖出信号。
  • 顶背离:当价格上涨,但 DIF 和 DEA 下降,表示上涨动能减弱。
  • 底背离:当价格下跌,但 DIF 和 DEA 上升,表示下跌动能减弱。

V2.0 版本

我们希望通过金叉/死叉,提供买入/卖出的信号,但是传统的MACD指标没有这些信号的标记,V2.0版本由此诞生,我们用红色向上的箭头标记买入信号,绿色向下的箭头标记卖出信号。

这个版本的代码比较简单,就是将金叉、死叉的位置标记出来,其他的没有进行任何过滤。

{ 金叉条件 }
GOLD_CROSS := CROSS(DIF,DEA);

{ 死叉条件 }
DEATH_CROSS := CROSS(DEA,DIF);

V3.0版本

V2.0版本相比标准的MACD指标,只是将金叉死叉标记了出来,那这个版本存在哪些问题呢?

问题1-干扰信号过多

当行情k线处于横盘阶段,市场波动不大的时候,会产生很多干扰信号,如上图V2.0版本中,这段时间产生了19次信号,尤其在三个紫色框的部分,我们希望过滤掉这些不太明显的趋势信号。

问题2-零轴分水岭

如果你身边有老股民,他们会经常把一句话挂在嘴巴:“零轴之上不做多、零轴之下不做空”,这个零轴分水岭在很多趋势型技术指标中都适用。

如上图V2.0版本中,在MACD零轴之上有4次做多的信号(买入),在MACD零轴之下有2次做空的信号(卖出),这6个信号也是我们不想要的。

V3.0版本,解决了上面两个问题,代码如下:

{ 定义过滤条件 }
DIF_V := 0.1;        { DIF阈值,可调参数 }
THRESHOLD := 0.1;     { 差值阈值,可调参数 }
ZERO_FILTER := 0;     { 零轴过滤开关:1启用/0禁用 }

{ 金叉条件优化 }
GOLD_CROSS := CROSS(DIF,DEA) 
		   AND ABS(DIF) > DIF_V
           AND DIF < 0
           AND ABS(DIF-DEA) > THRESHOLD 
           AND (ZERO_FILTER = 0 OR (DIF > 0 OR DEA > 0))
           AND MACD > REF(MACD,1);

{ 死叉条件优化 }
DEATH_CROSS := CROSS(DEA,DIF) 
            AND ABS(DIF) > DIF_V
            AND DIF > 0
            AND ABS(DEA-DIF) > THRESHOLD 
            AND (ZERO_FILTER = 0 OR (DIF < 0 OR DEA < 0)) 
            AND MACD < REF(MACD,1);

上面代码,我们在金叉死叉的判断上,增加了更多条件,这个版本优化下来,直接从V2.0版本的19个信号,降低到了10个信号。

当然信号也不是越少越好,而是要相对更高的正确率。

V3.0版本的要点

这个版本优化下来,已经比传统MACD指标强了不少,截至目前也没有将MACD与k线图放到一直进行验证,最开始也说了:优化的目的是为了过滤掉一些干扰信号(去噪),提供相对正确率较高的入场信号。不可能做到百分之百正确率的,主要说下使用该版本的要点:

  • 适用于相对长周期的趋势策略,从我的使用来看,至少在30分钟及以上的k线上
  • 过滤条件定义了2个阈值,需要结合不同市场(股票、期货),不同品种进行调整,这些阈值会相差比较大
  • 我在期货上使用比较多,重点在自己常做的品种上进行阈值调整,找到适合自己的参数

V3.0版本的问题

这个版本的问题,其实也是大多数趋势型技术指标的共性问题,那就是只关注‘价格’这一个维度产生的信号,‘量价量价’,不把‘量’加进来,单单由‘价‘产生的信号,往往会存在欺骗行为。

如上图,MACD金叉产生了买入信号,但是之后行情k线一路下跌,这样的信号就可以称之为虚假信号。那么如何识别并过滤掉这些虚假信号呢?

加入成交量指标进行过滤,上面的截图已经非常明了了,虽然MACD金叉产生了买入信号,但是这根k线的成交量非常低,甚至还不到前一根k线成交量的一半。

V4.0版本

V4.0版本不仅仅是增加了成交量Volume的指标,我还增加了一些更复杂的计算逻辑:MACD值的线性回归斜率等,最终V4.0版本从V3.0版本的10个信号,降到了6个。

1、增加成交量指标

下面的代码相比V3.0版本,只增加了2行,这两是一样的,当前K线的成交量要大于前一根K线的成交量:AND VOL > REF(VOL, 1)。

{ 金叉条件优化 }
GOLD_CROSS := CROSS(DIF,DEA) 
		   AND ABS(DIF) > DIF_V
           AND DIF < 0
           AND ABS(DIF-DEA) > THRESHOLD 
           AND (ZERO_FILTER = 0 OR (DIF > 0 OR DEA > 0))
		   AND VOL > REF(VOL, 1)
           AND MACD > REF(MACD,1);

{ 死叉条件优化 }
DEATH_CROSS := CROSS(DEA,DIF) 
            AND ABS(DIF) > DIF_V
            AND DIF > 0
            AND ABS(DEA-DIF) > THRESHOLD 
            AND (ZERO_FILTER = 0 OR (DIF < 0 OR DEA < 0)) 
		    AND VOL > REF(VOL, 1)
            AND MACD < REF(MACD,1);

同样,这个条件针对不同品种还需进一步调整,比如成交量要大于前一根k线成交量的1.5倍、2倍、3倍等等。

看到这里,相信我,目前的MACD指标进阶版本,已经可以战胜市场上绝大多数使用传统MACD指标的投资者了。

2、增加线性回归斜率

以下仅展示斜率的计算代码,至于斜率如何加入使用,暂且留个悬念,后面找机会分享。

{ 参数设置,默认与前5个周期计算斜率 }
N:=5; 

{ 线性回归斜率计算 }
MACD_SLOPE:=SLOPE(MACD, N);
DIF_SLOPE:=SLOPE(DIF, N);
DEA_SLOPE:=SLOPE(DEA, N);

比如我常做的期货日内趋势型策略,需要关注短周期的变化,尤其是反转行情,斜率就可以用上了。

其他优化方案

  • 可调整MACD参数,比如将快慢EMA调整为14和28,信号线调整为10,或者其他组合。
  • 采用自定义K线周期进行观察,比如31分钟、37分钟等
  • 调整更合适的成交量阈值
  • 如果是股票,可以加入成交额参数进行过滤
  • 如果是期货,可以加入持仓量参数进行过滤

C++代码(主要函数源码)

	// 判断金叉或死叉
	inline BoolArray CROSS(const DoubleArray& S1, const DoubleArray& S2) {
		BoolArray result = xt::empty<bool>(S1.shape());
		for (size_t i = 1; i < S1.size(); ++i) {
			result(i) = (S1(i - 1) <= S2(i - 1)) && (S1(i) > S2(i));
		}
		result(0) = false; // 第一个值无效
		return result;
	}
	
	// 线性回归斜率
	inline DoubleArray SLOPE(const DoubleArray& S, int N) {
		DoubleArray result = xt::empty_like(S);
		DoubleArray X = xt::arange(0, N);

		for (size_t i = 0; i < S.size(); ++i) {
			if (i >= N - 1) {
				auto sub_array = xt::view(S, xt::range(i - N + 1, i + 1));
				double numerator = xt::sum((X - xt::mean(X)) * (sub_array - xt::mean(sub_array)))();
				double denominator = xt::sum(xt::square(X - xt::mean(X)))();
				double slope = numerator / denominator;
				result(i) = slope;
			}
			else {
				result(i) = get_nan();
			}
		}
		return result;
	}
	
    // EMA 指标
    inline DoubleArray EMA(const DoubleArray& close, std::size_t period) {
        double alpha = 2.0 / (period + 1);
        DoubleArray ema = xt::empty<double>({ close.size() });

        ema(0) = close(0);

        for (std::size_t i = 1; i < close.size(); ++i) {
            ema(i) = (close(i) - ema(i - 1)) * alpha + ema(i - 1);
        }

        return ema;
    }
    
    // MACD 指标
    inline std::tuple<DoubleArray, DoubleArray, DoubleArray> MACD(const DoubleArray& close, std::size_t short_period, std::size_t long_period, std::size_t mid_period) {
        auto dif = EMA(close, short_period) - EMA(close, long_period);
        auto dea = EMA(dif, mid_period);
        auto macd = (dif - dea) * 2;

        return std::make_tuple(dif, dea, macd);
   }

MACD指标最终版本获取方式

创作不易,如果想要最终版本的MACD指标源码,打赏50及以上,在后台留下你的邮箱,发给你,或者加我微信进行交流沟通。

原文跳转链接

社群介绍:码上君量化互助社群介绍

📌 声明:交易有风险,入市需谨慎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值