﻿//+------------------------------------------------------------------+
//|                                      MACD_ADX_RSI_Confluence.mq5 |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t rates_total,
                const int32_t prev_calculated,
                const int32_t begin,
                const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int32_t id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
//+--//+------------------------------------------------------------------+
//|              MACD_ADX_RSI_Confluence.mq5                         |
//|        Стрелки + алерты: MACD + ADX + RSI confluence             |
//|         ADX > уровень + MACD сигнал + RSI в зоне                 |
//+------------------------------------------------------------------+
#property copyright "Grok / xAI"
#property version   "1.10"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//--- Стили стрелок
#property indicator_type1   DRAW_ARROW
#property indicator_type2   DRAW_ARROW
#property indicator_color1  clrLime
#property indicator_color2  clrRed
#property indicator_width1  4
#property indicator_width2  4

//--- Входные параметры
input int    ADX_Period          = 14;
input double ADX_Level           = 25.0;                  // ADX должен быть выше этого значения

input int    MACD_Fast           = 12;
input int    MACD_Slow           = 26;
input int    MACD_Signal         = 9;

enum MACD_Mode
  {
   Crossover_with_Signal_Line = 0,   // Пересечение MACD и сигнальной линии
   Cross_Zero_Line            = 1    // Пересечение нулевой линии (MACD >< 0)
  };
input MACD_Mode MACD_Signal_Type = Crossover_with_Signal_Line;

input int    RSI_Period          = 14;
input double RSI_Buy_Level       = 55.0;                  // RSI > этого → покупка разрешена
input double RSI_Sell_Level      = 45.0;                  // RSI < этого → продажа разрешена

input bool   UseAlerts           = true;
input bool   UseSound            = true;
input string SoundFile           = "alert2.wav";

//--- Буферы
double BuyArrow[];
double SellArrow[];

//--- Хэндлы
int hADX, hMACD, hRSI;

//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, BuyArrow, INDICATOR_DATA);
   SetIndexBuffer(1, SellArrow, INDICATOR_DATA);
   
   PlotIndexSetInteger(0, PLOT_ARROW, 233);   // стрелка вверх
   PlotIndexSetInteger(1, PLOT_ARROW, 234);   // стрелка вниз
   
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
   
   hADX  = iADX(_Symbol, _Period, ADX_Period);
   hMACD = iMACD(_Symbol, _Period, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE);
   hRSI  = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE);
   
   if(hADX == INVALID_HANDLE || hMACD == INVALID_HANDLE || hRSI == INVALID_HANDLE)
     {
      Print("Ошибка инициализации индикаторов");
      return(INIT_FAILED);
     }
   
   IndicatorSetString(INDICATOR_SHORTNAME, "MACD+ADX+RSI Confluence");
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(hADX);
   IndicatorRelease(hMACD);
   IndicatorRelease(hRSI);
  }

//+------------------------------------------------------------------+
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 start = (prev_calculated <= 0) ? rates_total - 100 : prev_calculated - 1;
   
   for(int i = start; i >= 1; i--)
     {
      BuyArrow[i]  = EMPTY_VALUE;
      SellArrow[i] = EMPTY_VALUE;
      
      // Получаем значения (shift 1 = последняя закрытая свеча)
      double adx       = GetIndValue(hADX,  MODE_MAIN,   i);
      double macd      = GetIndValue(hMACD, MODE_MAIN,   i);
      double signal    = GetIndValue(hMACD, MODE_SIGNAL, i);
      double macd_prev = GetIndValue(hMACD, MODE_MAIN,   i+1);
      double sig_prev  = GetIndValue(hMACD, MODE_SIGNAL, i+1);
      double rsi       = GetIndValue(hRSI,  0,           i);
      
      bool adx_ok      = (adx > ADX_Level);
      bool rsi_buy_ok  = (rsi > RSI_Buy_Level);
      bool rsi_sell_ok = (rsi < RSI_Sell_Level);
      
      bool macd_buy = false;
      bool macd_sell = false;
      
      if(MACD_Signal_Type == Crossover_with_Signal_Line)
        {
         macd_buy  = (macd > signal && macd_prev <= sig_prev);
         macd_sell = (macd < signal && macd_prev >= sig_prev);
        }
      else  // Cross zero
        {
         macd_buy  = (macd > 0 && macd_prev <= 0);
         macd_sell = (macd < 0 && macd_prev >= 0);
        }
      
      // Финальные сигналы confluence
      if(adx_ok && macd_buy && rsi_buy_ok)
        {
         BuyArrow[i] = low[i] - _Point * 15;   // позиция стрелки под минимумом свечи
         
         if(i == 1 && UseAlerts)
            SendAlert("BUY", time[i], rsi, adx);
        }
      
      if(adx_ok && macd_sell && rsi_sell_ok)
        {
         SellArrow[i] = high[i] + _Point * 15;
         
         if(i == 1 && UseAlerts)
            SendAlert("SELL", time[i], rsi, adx);
        }
     }
   
   return(rates_total);
  }

//+------------------------------------------------------------------+
double GetIndValue(int handle, int buffer, int shift)
  {
   double arr[1];
   if(CopyBuffer(handle, buffer, shift, 1, arr) != 1) return 0.0;
   return arr[0];
  }

//+------------------------------------------------------------------+
void SendAlert(string dir, datetime t, double rsi_val, double adx_val)
  {
   static datetime last = 0;
   if(t == last) return;
   
   string msg = StringFormat("%s confluence: %s | RSI=%.1f | ADX=%.1f | %s %s",
                             dir, _Symbol, rsi_val, adx_val,
                             PeriodToString(_Period), TimeToString(t));
   
   Alert(msg);
   if(UseSound) PlaySound(SoundFile);
   
   last = t;
  }

//+------------------------------------------------------------------+
string PeriodToString(ENUM_TIMEFRAMES tf)
  {
   switch(tf)
     {
      case PERIOD_M1:   return "M1";
      case PERIOD_M5:   return "M5";
      case PERIOD_M15:  return "M15";
      case PERIOD_M30:  return "M30";
      case PERIOD_H1:   return "H1";
      case PERIOD_H4:   return "H4";
      case PERIOD_D1:   return "D1";
      default:          return EnumToString(tf);
     }
  }
//+------------------------------------------------------------------+----------------------------------------------------------------+


