Author: 2015, neskk.com
macd-neskk

Overview

This technical tool is designed to help traders analyze market trends by combining two primary analytical methods: Moving Average Convergence Divergence (MACD) and Momentum Analysis. Rather than just looking at the price of an asset, this script calculates the relationship between different moving averages to identify shifts in trend strength and speed.

Core Components

The script generates five distinct visual elements on your chart to provide a comprehensive view of market dynamics:

  1. MACD Line: This represents the difference between two different moving averages (a fast one and a slow one). It helps identify the current direction of the trend.
  2. Signal Line: This is a moving average of the MACD line itself. It acts as a smoothing filter to help identify potential turning points.
  3. MACD Histogram: A visual representation of the distance between the MACD Line and the Signal Line. It highlights the expansion or contraction of market momentum.
  4. Momentum: This measures the change in the MACD value over a specific number of bars, showing how quickly the trend is accelerating or decelerating.
  5. Smooth Momentum: A refined, smoothed version of the raw momentum, designed to filter out "noise" and make it easier to spot significant shifts in market behavior.

How the Logic Works

The script operates by processing historical price data to calculate these five metrics simultaneously. It looks for specific mathematical interactions to provide actionable information:

  • Trend Detection: By comparing the MACD Line against the Signal Line, the script identifies when a trend is gaining strength or beginning to weaken.
  • Momentum Shifts: By calculating the rate of change in the MACD, the script can detect "acceleration." For example, it tracks how much the MACD value has moved over a set period to see if the market is pushing harder in one direction.

Automated Alerts and Notifications

The logic includes a built-in notification system designed to alert the trader to specific market conditions without requiring constant manual observation. The script monitors for two main types of events:

  • Zero Crossovers: The script identifies moments when the MACD line crosses above or below the Signal line (or the zero level), which are often interpreted as potential entry or exit points.
  • Momentum Reversals: The tool watches the "Smooth Momentum" values. If it detects a specific sequence where the momentum begins to pivot—indicating that the speed of a move is starting to turn back on itself—it triggers a notification.

These alerts are programmed to be "smart," meaning they track the direction of the last alert to ensure you aren't bombarded with repetitive signals, focusing instead on significant shifts in market sentiment.

Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
16 Views
0 Downloads
0 Favorites
macd-neskk
//+------------------------------------------------------------------+
//|                                                   MACD-neskk.mq4 |
//|                                          neskk.com 2015 Portugal |
//+------------------------------------------------------------------+
#property copyright   "2015, neskk.com"
#property link        "http://www.neskk.com"
#property version     "1.200"
#property description "Moving Averages Convergence/Divergence with a momentum indicator"
//#property strict // compiler directive for strict compilation mode 

//--- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 5
// MACD line
#property indicator_color1 DodgerBlue
#property indicator_width1 1
#property indicator_style1 STYLE_SOLID
// Signal line
#property indicator_color2 FireBrick
#property indicator_width2 1
#property indicator_style2 STYLE_SOLID
// MACD histogram
#property indicator_color3 Silver
#property indicator_width3 2
#property indicator_style1 STYLE_SOLID
// Momentum
#property indicator_color4 LightYellow
#property indicator_width4 1
#property indicator_style4 STYLE_DOT
// Smooth Momentum
#property indicator_color5 Gold
#property indicator_width5 1 
#property indicator_style5 STYLE_DASH

//--- indicator parameters
input int BarsToProcess=1000;
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE;
input int PeriodFastEMA=12;
input int PeriodSlowEMA=26;
input int PeriodSignal=9;
input ENUM_MA_METHOD SignalMA=MODE_EMA;
input int DeltaMomentum=10;
input int PeriodMomentum=3;
input ENUM_MA_METHOD MomentumMA=MODE_SMA;
input bool AlarmZeroCrossover=true;
input bool AlarmMomentumReverse=true;

#property indicator_level1 0.0
#property indicator_levelcolor Silver
#property indicator_levelwidth 1
#property indicator_levelstyle STYLE_DOT

//--- indicator buffers
double _bufferMACD[];
double _bufferSignal[];
double _bufferHistogram[];
double _bufferMomentum[];
double _bufferSmoothMomentum[];
//--- right input parameters flag
bool _flagParameters=false;
//---- store last bar time and the last alert direction
static int _prevSignal=0,_prevTime=0;
//---- bar number the alert to be searched by
#define SIGNAL_BAR 1
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- set the precision
   IndicatorDigits(Digits+1);
//--- drawing settings
   SetIndexStyle(0,DRAW_LINE);               // MACD
   SetIndexStyle(1,DRAW_LINE);               // Signal
   SetIndexStyle(2,DRAW_HISTOGRAM);          // MACD Histogram
   SetIndexStyle(3,DRAW_LINE,STYLE_DOT);     // Momentum        
   SetIndexStyle(4,DRAW_LINE,STYLE_SOLID);   // SmoothMomentum
//--- drawing offset
   SetIndexDrawBegin(0,PeriodFastEMA+PeriodSlowEMA);
   SetIndexDrawBegin(1,PeriodFastEMA+PeriodSlowEMA);
   SetIndexDrawBegin(3,PeriodMomentum);
   SetIndexDrawBegin(4,PeriodMomentum);
//--- indicator buffers mapping
   SetIndexBuffer(0,_bufferMACD);
   SetIndexBuffer(1,_bufferSignal);
   SetIndexBuffer(2,_bufferHistogram);
   SetIndexBuffer(3,_bufferMomentum);
   SetIndexBuffer(4,_bufferSmoothMomentum);
//--- name for DataWindow and indicator subwindow label
   IndicatorShortName("MACD("+IntegerToString(PeriodFastEMA)+","+IntegerToString(PeriodSlowEMA)+","+IntegerToString(PeriodSignal)+")");

   SetIndexLabel(0,"MACD");
   SetIndexLabel(1,"Signal");
   SetIndexLabel(2,"MACD histogram");
   SetIndexLabel(3,"Momentum");
   SetIndexLabel(4,"Smooth Momentum");
//--- check input parameters
   if(PeriodFastEMA<=1 || PeriodSlowEMA<=1 || PeriodSignal<=1 || PeriodFastEMA>=PeriodSlowEMA || PeriodMomentum<=0)
     {
      Print("Wrong input parameters");
      _flagParameters=false;
      return(INIT_PARAMETERS_INCORRECT);
     }
   else
     {
      _flagParameters=true;
     }
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int i,limit;
//---
   if(rates_total<=PeriodSignal || !_flagParameters) return(0);
//--- last counted bar will be recounted
   limit=rates_total-prev_calculated;

   if(prev_calculated==0)
      limit=rates_total-BarsToProcess;
   if(prev_calculated>0)
      limit--;
//--- MACD
   for(i=limit; i>=0; i--)
      _bufferMACD[i]=iMA(NULL,0,PeriodFastEMA,0,MODE_EMA,AppliedPrice,i)-iMA(NULL,0,PeriodSlowEMA,0,MODE_EMA,AppliedPrice,i);
//--- Signal
   for(i=limit; i>=0; i--)
     {
      _bufferSignal[i]=iMAOnArray(_bufferMACD,0,PeriodSignal,0,SignalMA,i);
      _bufferHistogram[i]=_bufferMACD[i]-_bufferSignal[i];
     }
//--- Momentum
   for(i=limit; i>=0; i--)
     {
      _bufferMomentum[i]=_bufferMACD[i]-_bufferMACD[i+DeltaMomentum];
     }
   for(i=limit; i>=0; i--)
      _bufferSmoothMomentum[i]=iMAOnArray(_bufferMomentum,0,PeriodMomentum,0,MomentumMA,i);

//---- Alarms
//---- avoid analyze the same bar multiple times
   if(SIGNAL_BAR>0 && Time[0]<=_prevTime)
      return(rates_total);
//---- mark that this bar was checked
   _prevTime=Time[0];

   double currentPrice=NormalizeDouble((open[SIGNAL_BAR]+close[SIGNAL_BAR])/2,Digits);
//---- preceding alert was SELL or this is the first launch (PrevSignal=0)
   if(_prevSignal<=0)
     {
      if(AlarmZeroCrossover && 
         _bufferMACD[SIGNAL_BAR]-_bufferSignal[SIGNAL_BAR]>0 && 
         _bufferSignal[SIGNAL_BAR+1]-_bufferMACD[SIGNAL_BAR+1]>=0)
        {
         _prevSignal=1;
         //Alert("[BUY] MACD (", Symbol(), ", ", Period(), ", ", currentPrice, ")");
         Print("[BUY] MACD (",Symbol(),", ",Period(),", ",currentPrice,")");
         //Comment("[BUY] MACD (", Symbol(), ", ", Period(), ", ", currentPrice, ")");
         //PlaySound("Alert2.wav");
        }
      if(AlarmMomentumReverse && 
         _bufferSmoothMomentum[SIGNAL_BAR]-_bufferSmoothMomentum[SIGNAL_BAR+1]>0 && 
         _bufferSmoothMomentum[SIGNAL_BAR+2]-_bufferSmoothMomentum[SIGNAL_BAR+1]>0)
        {
         _prevSignal=1;
         Print("[BUY] MACD Momentum (",Symbol(),", ",Period(),", ",currentPrice,")");
        }
     }
//---- preceding alert was BUY or this is the first launch (PrevSignal=0)
   if(_prevSignal>=0)
     {
      if(AlarmZeroCrossover && 
         _bufferSignal[SIGNAL_BAR]-_bufferMACD[SIGNAL_BAR]>0 && 
         _bufferMACD[SIGNAL_BAR+1]-_bufferSignal[SIGNAL_BAR+1]>=0)
        {
         _prevSignal=-1;
         //Alert("[SELL] MACD (", Symbol(), ", ", Period(), ", ", currentPrice, ")");
         Print("[SELL] MACD (",Symbol(),", ",Period(),", ",currentPrice,")");
         //Comment("[SELL] MACD (", Symbol(), ", ", Period(), ", ", currentPrice, ")");
         //PlaySound("Alert.wav");
        }
      if(AlarmMomentumReverse && 
         _bufferSmoothMomentum[SIGNAL_BAR+1]-_bufferSmoothMomentum[SIGNAL_BAR]>0 && 
         _bufferSmoothMomentum[SIGNAL_BAR+1]-_bufferSmoothMomentum[SIGNAL_BAR+2]>0)
        {
         _prevSignal=-1;
         Print("[SELL] MACD Momentum (",Symbol(),", ",Period(),", ",currentPrice,")");
        }
     }
//--- done
   return(rates_total);
  }
//+------------------------------------------------------------------+

Comments