News:

Exness ลงทะเบียนระบบใหม่ ใส่รหัสพาร์ทเนอร์ 73208
https://www.exness.com/boarding/sign-up/a/73208?lng=th
1. เลือกประเทศ ไทย
2. อีเมล์จริงของคุณ
3. รหัสผ่าน
* รหัสผ่านต้องมีความยาว 8-15 ตัว
* ใช้ทั้งอักษรตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
* ใช้ทั้งตัวเลขและตัวอักษรภาษาอังกฤษ
* ห้ามใช้อักขระพิเศษ (!@#$%^&*., และอื่นๆ)
4. ใส่รหัสพาร์ทเนอร์ 73208
---------------------------------------------------------

Main Menu

แจกโค๊ดฟรี MACD Divergence Indicator (MQL5)

Started by junjao, April 24, 2026, 05:16:41 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

junjao

แจกฟรี MACD Divergence Indicator (MQL5)

เปิดบัญชีมืออาชีพได้ที่ https://www.exness.com/a/73208

ไว้ดูกราฟ MT5 หาประกอบกับ EA ที่ได้เขียนมาใช้งานเทรด

//+------------------------------------------------------------------+
//| MACD Divergence Indicator (MQL5)                                |
//| Converted from MQL4 original                                    |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2026, junjao.com"
#property link      "http://www.exness.com/a/73208"

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots  5
#property indicator_level1  0.0

//---- ไม่ใช้ #property indicator_label/type/color ที่นี่
//---- เพราะ MQL5 จะ warning "property already exists" เมื่อ type หรือ color ซ้ำกัน
//---- ตั้งค่าทั้งหมดใน OnInit() ด้วย PlotIndexSet แทน

#define arrowsDisplacement 0.0001

//---- Input parameters
input string separator1              = "*** MACD Settings ***";
input int    FastMAPeriod            = 12;
input int    SlowMAPeriod            = 26;
input int    SignalMAPeriod          = 9;
input string separator2              = "*** Indicator Settings ***";
input bool  drawIndicatorTrendLines = true;
input bool  drawPriceTrendLines    = true;
input bool  displayAlert            = true;

//---- Buffers
double MACDLineBuffer[];
double SignalLineBuffer[];
double HistogramBuffer[];
double bullishDivergence[];
double bearishDivergence[];

//---- Variables
double alpha  = 0;
double alpha_1 = 0;

static datetime lastAlertTime;
static string  indicatorName;

//---- Handles for iMA
int hFastMA;
int hSlowMA;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                        |
//+------------------------------------------------------------------+
int OnInit()
  {
  IndicatorSetInteger(INDICATOR_DIGITS, _Digits + 1);

  //---- Bind buffers
  SetIndexBuffer(0, MACDLineBuffer,    INDICATOR_DATA);
  SetIndexBuffer(1, SignalLineBuffer,  INDICATOR_DATA);
  SetIndexBuffer(2, HistogramBuffer,  INDICATOR_DATA);
  SetIndexBuffer(3, bullishDivergence, INDICATOR_DATA);
  SetIndexBuffer(4, bearishDivergence, INDICATOR_DATA);

  //---- Plot 0: MACD Line (DodgerBlue)
  PlotIndexSetInteger(0, PLOT_DRAW_TYPE,  DRAW_LINE);
  PlotIndexSetInteger(0, PLOT_LINE_COLOR,  clrDodgerBlue);
  PlotIndexSetInteger(0, PLOT_LINE_WIDTH,  1);
  PlotIndexSetString (0, PLOT_LABEL,      "MACD Line");
  PlotIndexSetInteger(0, PLOT_DRAW_BEGIN,  SlowMAPeriod);

  //---- Plot 1: Signal Line (Red)
  PlotIndexSetInteger(1, PLOT_DRAW_TYPE,  DRAW_LINE);
  PlotIndexSetInteger(1, PLOT_LINE_COLOR,  clrRed);
  PlotIndexSetInteger(1, PLOT_LINE_WIDTH,  1);
  PlotIndexSetString (1, PLOT_LABEL,      "Signal Line");
  PlotIndexSetInteger(1, PLOT_DRAW_BEGIN,  SlowMAPeriod + SignalMAPeriod);

  //---- Plot 2: Histogram (Silver)
  PlotIndexSetInteger(2, PLOT_DRAW_TYPE,  DRAW_HISTOGRAM);
  PlotIndexSetInteger(2, PLOT_LINE_COLOR,  clrSilver);
  PlotIndexSetInteger(2, PLOT_LINE_WIDTH,  2);
  PlotIndexSetString (2, PLOT_LABEL,      "Histogram");
  PlotIndexSetInteger(2, PLOT_DRAW_BEGIN,  SlowMAPeriod + SignalMAPeriod);

  //---- Plot 3: Bullish Divergence arrow (Lime, arrow 233 = up)
  PlotIndexSetInteger(3, PLOT_DRAW_TYPE,  DRAW_ARROW);
  PlotIndexSetInteger(3, PLOT_ARROW,      233);
  PlotIndexSetInteger(3, PLOT_LINE_COLOR,  clrLime);
  PlotIndexSetString (3, PLOT_LABEL,      "Bullish Divergence");
  PlotIndexSetDouble (3, PLOT_EMPTY_VALUE, EMPTY_VALUE);

  //---- Plot 4: Bearish Divergence arrow (Red, arrow 234 = down)
  PlotIndexSetInteger(4, PLOT_DRAW_TYPE,  DRAW_ARROW);
  PlotIndexSetInteger(4, PLOT_ARROW,      234);
  PlotIndexSetInteger(4, PLOT_LINE_COLOR,  clrRed);
  PlotIndexSetString (4, PLOT_LABEL,      "Bearish Divergence");
  PlotIndexSetDouble (4, PLOT_EMPTY_VALUE, EMPTY_VALUE);

  //---- Indicator short name
  indicatorName = "MACD(" + IntegerToString(FastMAPeriod) + "," +
                  IntegerToString(SlowMAPeriod) + "," +
                  IntegerToString(SignalMAPeriod) + ")";
  IndicatorSetString(INDICATOR_SHORTNAME, indicatorName);

  //---- EMA smoothing factor
  alpha  = 2.0 / (SignalMAPeriod + 1.0);
  alpha_1 = 1.0 - alpha;

  //---- Create MA handles
  hFastMA = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
  hSlowMA = iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);

  if(hFastMA == INVALID_HANDLE || hSlowMA == INVALID_HANDLE)
    {
      Print("Failed to create MA handles");
      return(INIT_FAILED);
    }

  return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  for(int i = ObjectsTotal(0, 0, -1) - 1; i >= 0; i--)
    {
      string label = ObjectName(0, i, 0, -1);
      if(StringSubstr(label, 0, 19) != "MACD_DivergenceLine")
        continue;
      ObjectDelete(0, label);
    }
  IndicatorRelease(hFastMA);
  IndicatorRelease(hSlowMA);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
  if(rates_total < SlowMAPeriod + SignalMAPeriod + 5)
      return(0);

  //---- Copy MA buffers
  double fastMA[], slowMA[];
  if(CopyBuffer(hFastMA, 0, 0, rates_total, fastMA) <= 0) return(prev_calculated);
  if(CopyBuffer(hSlowMA, 0, 0, rates_total, slowMA) <= 0) return(prev_calculated);

  //---- Use chronological order: index 0 = oldest bar
  ArraySetAsSeries(fastMA, false);
  ArraySetAsSeries(slowMA, false);
  ArraySetAsSeries(time,  false);
  ArraySetAsSeries(high,  false);
  ArraySetAsSeries(low,    false);

  int limit = (prev_calculated == 0) ? SlowMAPeriod : prev_calculated - 1;

  //---- Calculate MACD, Signal, Histogram
  for(int i = limit; i < rates_total; i++)
    {
      MACDLineBuffer = fastMA - slowMA;
      if(i == 0)
        SignalLineBuffer = MACDLineBuffer;
      else
        SignalLineBuffer = alpha * MACDLineBuffer + alpha_1 * SignalLineBuffer[i - 1];
      HistogramBuffer  = MACDLineBuffer - SignalLineBuffer;
      bullishDivergence = EMPTY_VALUE;
      bearishDivergence = EMPTY_VALUE;
    }

  //---- Detect divergences (skip last 2 unconfirmed bars)
  for(int i = limit; i < rates_total - 2; i++)
    {
      CatchBullishDivergence(i, time, low,  rates_total);
      CatchBearishDivergence(i, time, high, rates_total);
    }

  return(rates_total);
  }

//+------------------------------------------------------------------+
//| Returns true if bar[shift] is a MACD trough                      |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift, int total)
  {
  if(shift < 2 || shift >= total - 1) return(false);
  return(MACDLineBuffer[shift] <= MACDLineBuffer[shift - 1] &&
          MACDLineBuffer[shift] <  MACDLineBuffer[shift - 2] &&
          MACDLineBuffer[shift] <  MACDLineBuffer[shift + 1]);
  }

//+------------------------------------------------------------------+
//| Returns true if bar[shift] is a MACD peak                        |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift, int total)
  {
  if(shift < 2 || shift >= total - 1) return(false);
  return(MACDLineBuffer[shift] >= MACDLineBuffer[shift - 1] &&
          MACDLineBuffer[shift] >  MACDLineBuffer[shift - 2] &&
          MACDLineBuffer[shift] >  MACDLineBuffer[shift + 1]);
  }

//+------------------------------------------------------------------+
//| Find the previous MACD trough before shift                      |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift, int total)
  {
  for(int i = shift - 5; i >= 2; i--)
    {
      if(SignalLineBuffer <= SignalLineBuffer[i - 1] &&
        SignalLineBuffer <= SignalLineBuffer[i - 2] &&
        SignalLineBuffer <= SignalLineBuffer[i + 1] &&
        SignalLineBuffer <= SignalLineBuffer[i + 2])
        {
        for(int j = i; j >= 2; j--)
          {
            if(MACDLineBuffer[j] <= MACDLineBuffer[j - 1] &&
              MACDLineBuffer[j] <  MACDLineBuffer[j - 2] &&
              MACDLineBuffer[j] <= MACDLineBuffer[j + 1] &&
              MACDLineBuffer[j] <  MACDLineBuffer[j + 2])
              return(j);
          }
        }
    }
  return(-1);
  }

//+------------------------------------------------------------------+
//| Find the previous MACD peak before shift                        |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift, int total)
  {
  for(int i = shift - 5; i >= 2; i--)
    {
      if(SignalLineBuffer >= SignalLineBuffer[i - 1] &&
        SignalLineBuffer >= SignalLineBuffer[i - 2] &&
        SignalLineBuffer >= SignalLineBuffer[i + 1] &&
        SignalLineBuffer >= SignalLineBuffer[i + 2])
        {
        for(int j = i; j >= 2; j--)
          {
            if(MACDLineBuffer[j] >= MACDLineBuffer[j - 1] &&
              MACDLineBuffer[j] >  MACDLineBuffer[j - 2] &&
              MACDLineBuffer[j] >= MACDLineBuffer[j + 1] &&
              MACDLineBuffer[j] >  MACDLineBuffer[j + 2])
              return(j);
          }
        }
    }
  return(-1);
  }

//+------------------------------------------------------------------+
//| Detect and mark bullish divergence at bar[shift]                |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift,
                            const datetime &time[],
                            const double  &low[],
                            int            total)
  {
  if(!IsIndicatorTrough(shift, total)) return;

  int currentTrough = shift;
  int lastTrough    = GetIndicatorLastTrough(shift, total);
  if(lastTrough == -1) return;

  //---- Classical: MACD higher low + price lower low
  if(MACDLineBuffer[currentTrough] > MACDLineBuffer[lastTrough] &&
      low[currentTrough] < low[lastTrough])
    {
      bullishDivergence[currentTrough] = MACDLineBuffer[currentTrough] - arrowsDisplacement;
      if(drawPriceTrendLines)
        DrawPriceTrendLine(time[currentTrough], time[lastTrough],
                            low[currentTrough],  low[lastTrough], clrLime, STYLE_SOLID);
      if(drawIndicatorTrendLines)
        DrawIndicatorTrendLine(time[currentTrough], time[lastTrough],
                                MACDLineBuffer[currentTrough], MACDLineBuffer[lastTrough],
                                clrLime, STYLE_SOLID);
      if(displayAlert)
        DisplayAlert("Classical bullish divergence on: ", shift, time);
    }

  //---- Reverse: MACD lower low + price higher low
  if(MACDLineBuffer[currentTrough] < MACDLineBuffer[lastTrough] &&
      low[currentTrough] > low[lastTrough])
    {
      bullishDivergence[currentTrough] = MACDLineBuffer[currentTrough] - arrowsDisplacement;
      if(drawPriceTrendLines)
        DrawPriceTrendLine(time[currentTrough], time[lastTrough],
                            low[currentTrough],  low[lastTrough], clrLime, STYLE_DOT);
      if(drawIndicatorTrendLines)
        DrawIndicatorTrendLine(time[currentTrough], time[lastTrough],
                                MACDLineBuffer[currentTrough], MACDLineBuffer[lastTrough],
                                clrLime, STYLE_DOT);
      if(displayAlert)
        DisplayAlert("Reverse bullish divergence on: ", shift, time);
    }
  }

//+------------------------------------------------------------------+
//| Detect and mark bearish divergence at bar[shift]                |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift,
                            const datetime &time[],
                            const double  &high[],
                            int            total)
  {
  if(!IsIndicatorPeak(shift, total)) return;

  int currentPeak = shift;
  int lastPeak    = GetIndicatorLastPeak(shift, total);
  if(lastPeak == -1) return;

  //---- Classical: MACD lower high + price higher high
  if(MACDLineBuffer[currentPeak] < MACDLineBuffer[lastPeak] &&
      high[currentPeak] > high[lastPeak])
    {
      bearishDivergence[currentPeak] = MACDLineBuffer[currentPeak] + arrowsDisplacement;
      if(drawPriceTrendLines)
        DrawPriceTrendLine(time[currentPeak], time[lastPeak],
                            high[currentPeak], high[lastPeak], clrRed, STYLE_SOLID);
      if(drawIndicatorTrendLines)
        DrawIndicatorTrendLine(time[currentPeak], time[lastPeak],
                                MACDLineBuffer[currentPeak], MACDLineBuffer[lastPeak],
                                clrRed, STYLE_SOLID);
      if(displayAlert)
        DisplayAlert("Classical bearish divergence on: ", shift, time);
    }

  //---- Reverse: MACD higher high + price lower high
  if(MACDLineBuffer[currentPeak] > MACDLineBuffer[lastPeak] &&
      high[currentPeak] < high[lastPeak])
    {
      bearishDivergence[currentPeak] = MACDLineBuffer[currentPeak] + arrowsDisplacement;
      if(drawPriceTrendLines)
        DrawPriceTrendLine(time[currentPeak], time[lastPeak],
                            high[currentPeak], high[lastPeak], clrRed, STYLE_DOT);
      if(drawIndicatorTrendLines)
        DrawIndicatorTrendLine(time[currentPeak], time[lastPeak],
                                MACDLineBuffer[currentPeak], MACDLineBuffer[lastPeak],
                                clrRed, STYLE_DOT);
      if(displayAlert)
        DisplayAlert("Reverse bearish divergence on: ", shift, time);
    }
  }

//+------------------------------------------------------------------+
//| Alert only on the 2 most recent bars                            |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift, const datetime &time[])
  {
  int fromEnd = ArraySize(time) - 1 - shift;
  if(fromEnd <= 2 && time[shift] != lastAlertTime)
    {
      lastAlertTime = time[shift];
      Alert(message, _Symbol, " , ", _Period, " minutes chart");
    }
  }

//+------------------------------------------------------------------+
//| Draw trend line on price chart (main window)                    |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2,
                        double y1,  double y2,
                        color lineColor, ENUM_LINE_STYLE style)
  {
  string label = "MACD_DivergenceLine.0# " + IntegerToString((long)x1);
  ObjectDelete(0, label);
  ObjectCreate(0, label, OBJ_TREND, 0, x1, y1, x2, y2);
  ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, false);
  ObjectSetInteger(0, label, OBJPROP_COLOR,    lineColor);
  ObjectSetInteger(0, label, OBJPROP_STYLE,    style);
  }

//+------------------------------------------------------------------+
//| Draw trend line on indicator sub-window                          |
//+------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1, datetime x2,
                            double y1,  double y2,
                            color lineColor, ENUM_LINE_STYLE style)
  {
  int indicatorWindow = ChartWindowFind(0, indicatorName);
  if(indicatorWindow < 0) return;

  string label = "MACD_DivergenceLine.0$# " + IntegerToString((long)x1);
  ObjectDelete(0, label);
  ObjectCreate(0, label, OBJ_TREND, indicatorWindow, x1, y1, x2, y2);
  ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, false);
  ObjectSetInteger(0, label, OBJPROP_COLOR,    lineColor);
  ObjectSetInteger(0, label, OBJPROP_STYLE,    style);
  }
//+------------------------------------------------------------------+

MT4 MT5 EA Indicator EURUSD USDJPY XAUUSD Gold Bitcoin Oil
สอบถาม 081-446-5311 , line : junjaocom , Email : jun_jao2000@hotmail.com
สมัคร Exness ได้ที่ https://www.exness.com/a/73208
หน้าลงทะเบียน Exness ได้ที่ https://www.exness.com/boarding/sign-up/a/73208?lng=th
ขั้นตอนสมัคร exness https://www.junjao.com/board/index.php?topic=279

junjao

MT4 MT5 EA Indicator EURUSD USDJPY XAUUSD Gold Bitcoin Oil
สอบถาม 081-446-5311 , line : junjaocom , Email : jun_jao2000@hotmail.com
สมัคร Exness ได้ที่ https://www.exness.com/a/73208
หน้าลงทะเบียน Exness ได้ที่ https://www.exness.com/boarding/sign-up/a/73208?lng=th
ขั้นตอนสมัคร exness https://www.junjao.com/board/index.php?topic=279