MT5 indicator Arrows not showing on chart, Kindly help

 

Dear Coders and Friends, i made a mt5 indicator ,its not showing buy sell arrows on the chart. Whereas with similar configuration it shows arrows on mt4 chart. i have been using this mt4 indicator since the last 4 years on mt4. What am i doing wrong. Kindly help and rectify.

Thanks in advance

//--- indicator settings

#property indicator_chart_window

#property indicator_buffers 4

#property indicator_plots 4



#property indicator_type1 DRAW_ARROW

#property indicator_width1 5

#property indicator_color1 0xFCFCFA

#property indicator_label1 "Buy"



#property indicator_type2 DRAW_ARROW

#property indicator_width2 5

#property indicator_color2 0xFCFCFA

#property indicator_label2 "Buy"



#property indicator_type3 DRAW_ARROW

#property indicator_width3 5

#property indicator_color3 0xF40AFC

#property indicator_label3 "Sell"



#property indicator_type4 DRAW_ARROW

#property indicator_width4 5

#property indicator_color4 0xF40AFC

#property indicator_label4 "Sell"



#define PLOT_MAXIMUM_BARS_BACK 50000

#define OMIT_OLDEST_BARS 50



//--- indicator buffers

double Buffer1[];

double Buffer2[];

double Buffer3[];

double Buffer4[];



input int Period1 = 144;

input int MA_Shift = 0;

input int Shift1 = 0;

input int Tenken = 27;

input int Kijun_sen = 78;

input int Senkou_Span_B = 156;

input int Candle_Index = 5;

input int Shift2 = 1;

datetime time_alert; //used when sending alert

input bool Send_Email = true;

input bool Audible_Alerts = true;

input bool Push_Notifications = true;

double myPoint; //initialized in OnInit

int MA_handle;

double MA[];

int Ichimoku_handle;

double Ichimoku_SenkouspanA[];

double Ichimoku_SenkouspanB[];

double Low[];

int ATR_handle;

double ATR[];

int MA_handle2;

double MA2[];

double High[];



void myAlert(string type, string message)

  {

   int handle;

   if(type == "print")

      Print(message);

   else if(type == "error")

     {

      Print(type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

     }

   else if(type == "order")

     {

     }

   else if(type == "modify")

     {

     }

   else if(type == "indicator")

     {

      Print(type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

      if(Audible_Alerts) Alert(type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

      if(Send_Email) SendMail("JS Channel new", type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

      handle = FileOpen("JS Channel new.txt", FILE_TXT|FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE, ';');

      if(handle != INVALID_HANDLE)

        {

         FileSeek(handle, 0, SEEK_END);

         FileWrite(handle, type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

         FileClose(handle);

        }

      if(Push_Notifications) SendNotification(type+" | JS Channel new @ "+Symbol()+","+IntegerToString(Period())+" | "+message);

     }

  }



//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int OnInit()

  {   

   SetIndexBuffer(0, Buffer1);

   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));

   PlotIndexSetInteger(0, PLOT_ARROW, 241);

   SetIndexBuffer(1, Buffer2);

   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));

   PlotIndexSetInteger(1, PLOT_ARROW, 241);

   SetIndexBuffer(2, Buffer3);

   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));

   PlotIndexSetInteger(2, PLOT_ARROW, 242);

   SetIndexBuffer(3, Buffer4);

   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));

   PlotIndexSetInteger(3, PLOT_ARROW, 242);

   //initialize myPoint

   myPoint = Point();

   if(Digits() == 5 || Digits() == 3)

     {

      myPoint *= 10;

     }

   MA_handle = iMA(NULL, PERIOD_CURRENT, Period1, MA_Shift, MODE_EMA, PRICE_LOW);

   if(MA_handle < 0)

     {

      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);

      Print("Runtime error = ", GetLastError());

      return(INIT_FAILED);

     }

   

   Ichimoku_handle = iIchimoku(NULL, PERIOD_CURRENT, Tenken, Kijun_sen, Senkou_Span_B);

   if(Ichimoku_handle < 0)

     {

      Print("The creation of iIchimoku has failed: Ichimoku_handle=", INVALID_HANDLE);

      Print("Runtime error = ", GetLastError());

      return(INIT_FAILED);

     }

   

   ATR_handle = iATR(NULL, PERIOD_CURRENT, 14);

   if(ATR_handle < 0)

     {

      Print("The creation of iATR has failed: ATR_handle=", INVALID_HANDLE);

      Print("Runtime error = ", GetLastError());

      return(INIT_FAILED);

     }

   

   MA_handle2 = iMA(NULL, PERIOD_CURRENT, Period1, MA_Shift, MODE_EMA, PRICE_HIGH);

   if(MA_handle2 < 0)

     {

      Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);

      Print("Runtime error = ", GetLastError());

      return(INIT_FAILED);

     }

   

   return(INIT_SUCCEEDED);

  }



//+------------------------------------------------------------------+

//| 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[])

  {

   int limit = rates_total - prev_calculated;

   //--- counting from 0 to rates_total

   ArraySetAsSeries(Buffer1, true);

   ArraySetAsSeries(Buffer2, true);

   ArraySetAsSeries(Buffer3, true);

   ArraySetAsSeries(Buffer4, true);

   //--- initial zero

   if(prev_calculated < 1)

     {

      ArrayInitialize(Buffer1, EMPTY_VALUE);

      ArrayInitialize(Buffer2, EMPTY_VALUE);

      ArrayInitialize(Buffer3, EMPTY_VALUE);

      ArrayInitialize(Buffer4, EMPTY_VALUE);

     }

   else

      limit++;

   datetime Time[];

   

   if(BarsCalculated(MA_handle) <= 0) 

      return(0);

   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);

   ArraySetAsSeries(MA, true);

   if(BarsCalculated(Ichimoku_handle) <= 0) 

      return(0);

   if(CopyBuffer(Ichimoku_handle, SENKOUSPANA_LINE, 0, rates_total, Ichimoku_SenkouspanA) <= 0) return(rates_total);

   ArraySetAsSeries(Ichimoku_SenkouspanA, true);

   if(BarsCalculated(Ichimoku_handle) <= 0) 

      return(0);

   if(CopyBuffer(Ichimoku_handle, SENKOUSPANB_LINE, 0, rates_total, Ichimoku_SenkouspanB) <= 0) return(rates_total);

   ArraySetAsSeries(Ichimoku_SenkouspanB, true);

   if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);

   ArraySetAsSeries(Low, true);

   if(BarsCalculated(ATR_handle) <= 0) 

      return(0);

   if(CopyBuffer(ATR_handle, 0, 0, rates_total, ATR) <= 0) return(rates_total);

   ArraySetAsSeries(ATR, true);

   if(BarsCalculated(MA_handle2) <= 0) 

      return(0);

   if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);

   ArraySetAsSeries(MA2, true);

   if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);

   ArraySetAsSeries(High, true);

   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);

   ArraySetAsSeries(Time, true);

   //--- main loop

   for(int i = limit-1; i >= 0; i--)

     {

      if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   

      

      //Indicator Buffer 1

      if(MA[Shift1+i] > Ichimoku_SenkouspanA[Shift1+i]

      && MA[Shift1+i+1] < Ichimoku_SenkouspanA[Shift1+i+1] //Moving Average crosses above Ichimoku Kinko Hyo

      && MA[Shift1+i] > Ichimoku_SenkouspanB[Shift1+i] //Moving Average > Ichimoku Kinko Hyo

      )

        {

         Buffer1[i] = Low[1+i] + ATR[i]; //Set indicator value at Candlestick Low + Average True Range

         if(i == 0 && Time[0] != time_alert) { myAlert("indicator", "Buy"); time_alert = Time[0]; } //Instant alert, only once per bar

        }

      else

        {

         Buffer1[i] = EMPTY_VALUE;

        }

      //Indicator Buffer 2

      if(MA[Shift2+i] > Ichimoku_SenkouspanB[Shift1+i]

      && MA[Shift2+i+1] < Ichimoku_SenkouspanB[Shift1+i+1] //Moving Average crosses above Ichimoku Kinko Hyo

      && MA[Shift2+i] > Ichimoku_SenkouspanA[Shift1+i] //Moving Average > Ichimoku Kinko Hyo

      )

        {

         Buffer2[i] = Low[1+i] + ATR[i]; //Set indicator value at Candlestick Low + Average True Range

         if(i == 0 && Time[0] != time_alert) { myAlert("indicator", "Buy"); time_alert = Time[0]; } //Instant alert, only once per bar

        }

      else

        {

         Buffer2[i] = EMPTY_VALUE;

        }

      //Indicator Buffer 3

      if(MA2[i] < Ichimoku_SenkouspanB[i]

      && MA2[i+1] > Ichimoku_SenkouspanB[i+1] //Moving Average crosses below Ichimoku Kinko Hyo

      && MA2[Shift1+i] < Ichimoku_SenkouspanA[Shift1+i] //Moving Average < Ichimoku Kinko Hyo

      )

        {

         Buffer3[i] = High[1+i] - ATR[i]; //Set indicator value at Candlestick High - Average True Range

         if(i == 0 && Time[0] != time_alert) { myAlert("indicator", "Sell"); time_alert = Time[0]; } //Instant alert, only once per bar

        }

      else

        {

         Buffer3[i] = EMPTY_VALUE;

        }

      //Indicator Buffer 4

      if(MA2[Shift2+i] < Ichimoku_SenkouspanA[Shift1+i]

      && MA2[Shift2+i+1] > Ichimoku_SenkouspanA[Shift1+i+1] //Moving Average crosses below Ichimoku Kinko Hyo

      && MA2[Shift2+i] < Ichimoku_SenkouspanB[Shift1+i] //Moving Average < Ichimoku Kinko Hyo

      )

        {

         Buffer4[i] = High[1+i] - ATR[i]; //Set indicator value at Candlestick High - Average True Range

         if(i == 0 && Time[0] != time_alert) { myAlert("indicator", "Sell"); time_alert = Time[0]; } //Instant alert, only once per bar

        }

      else

        {

         Buffer4[i] = EMPTY_VALUE;

        }

     }

   return(rates_total);

  }

//+------------------------------------------------------------------+
Files:
 
Sonu Jolly:

Dear Coders and Friends, i made a mt5 indicator ,its not showing buy sell arrows on the chart. Whereas with similar configuration it shows arrows on mt4 chart. i have been using this mt4 indicator since the last 4 years on mt4. What am i doing wrong. Kindly help and rectify.

Thanks in advance

Traders and coders are working for free:

  • if it is interesting for them personally, or
  • if it is interesting for many members on this forum.

Freelance section of the forum should be used in most of the cases.

NOTE: some details in your code are common for AI-generated, so it can be hardly helped (would need considerable human review/corrections before being usable in a live trading environment).

Trading applications for MetaTrader 5 to order
Trading applications for MetaTrader 5 to order
  • 2025.12.18
  • www.mql5.com
The largest freelance service with MQL5 application developers
 
Oleksandr Medviediev #:

Traders and coders are working for free:

  • if it is interesting for them personally, or
  • if it is interesting for many members on this forum.

Freelance section of the forum should be used in most of the cases.

NOTE: some details in your code are common for AI-generated, so it can be hardly helped (would need considerable human review/corrections before being usable in a live trading environment).

…and they’re quite uninformed, because EABuilder is not artificial intelligence.

//+------------------------------------------------------------------+
//|                                               JS_Channel_Pro.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

//--- Plot settings
#property indicator_type1   DRAW_ARROW
#property indicator_width1  3
#property indicator_color1  clrWhite
#property indicator_label1  "Buy Signal 1"

#property indicator_type2   DRAW_ARROW
#property indicator_width2  3
#property indicator_color2  clrWhite
#property indicator_label2  "Buy Signal 2"

#property indicator_type3   DRAW_ARROW
#property indicator_width3  3
#property indicator_color3  clrMagenta
#property indicator_label3  "Sell Signal 1"

#property indicator_type4   DRAW_ARROW
#property indicator_width4  3
#property indicator_color4  clrMagenta
#property indicator_label4  "Sell Signal 2"

//--- Inputs
input group "Moving Average Settings"
input int      InpMAPeriod    = 144;      // MA Period
input int      InpMAShift     = 0;        // MA Shift
input ENUM_MA_METHOD InpMAMethod = MODE_EMA; // MA Method

input group "Ichimoku Settings"
input int      InpTenkan      = 27;       // Tenkan-sen
input int      InpKijun       = 78;       // Kijun-sen
input int      InpSenkouB     = 156;      // Senkou Span B

input group "Logic Settings"
input int      InpShift1      = 0;        // Logic Shift 1
input int      InpShift2      = 1;        // Logic Shift 2
input int      InpATRPeriod   = 14;       // ATR Period for Arrows

input group "Alerts"
input bool     InpUseAlerts   = true;     // Enable Alerts
input bool     InpUsePush     = true;     // Enable Push Notifications

//--- Indicator Buffers
double BufferBuy1[];
double BufferBuy2[];
double BufferSell1[];
double BufferSell2[];

//--- Handles
int    h_ma_low;
int    h_ma_high;
int    h_ichimoku;
int    h_atr;

//--- Calculation Arrays (Dynamic)
double ma_low[];
double ma_high[];
double span_a[];
double span_b[];
double atr[];

//--- Alert State
datetime last_alert_time = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Indicator Buffers Mapping
   SetIndexBuffer(0, BufferBuy1, INDICATOR_DATA);
   SetIndexBuffer(1, BufferBuy2, INDICATOR_DATA);
   SetIndexBuffer(2, BufferSell1, INDICATOR_DATA);
   SetIndexBuffer(3, BufferSell2, INDICATOR_DATA);

//--- Plot settings
   PlotIndexSetInteger(0, PLOT_ARROW, 233); // Up Arrow
   PlotIndexSetInteger(1, PLOT_ARROW, 233); // Up Arrow
   PlotIndexSetInteger(2, PLOT_ARROW, 234); // Down Arrow
   PlotIndexSetInteger(3, PLOT_ARROW, 234); // Down Arrow

//--- Set Empty Values
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);

//--- Create Handles
// 1. MA on Low Price
   h_ma_low = iMA(_Symbol, _Period, InpMAPeriod, InpMAShift, InpMAMethod, PRICE_LOW);
   if(h_ma_low == INVALID_HANDLE)
     {
      Print("Failed to create MA Low handle");
      return(INIT_FAILED);
     }

// 2. MA on High Price
   h_ma_high = iMA(_Symbol, _Period, InpMAPeriod, InpMAShift, InpMAMethod, PRICE_HIGH);
   if(h_ma_high == INVALID_HANDLE)
     {
      Print("Failed to create MA High handle");
      return(INIT_FAILED);
     }

// 3. Ichimoku
   h_ichimoku = iIchimoku(_Symbol, _Period, InpTenkan, InpKijun, InpSenkouB);
   if(h_ichimoku == INVALID_HANDLE)
     {
      Print("Failed to create Ichimoku handle");
      return(INIT_FAILED);
     }

// 4. ATR
   h_atr = iATR(_Symbol, _Period, InpATRPeriod);
   if(h_atr == INVALID_HANDLE)
     {
      Print("Failed to create ATR handle");
      return(INIT_FAILED);
     }

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| 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[])
  {
//--- Check for minimum bars
   if(rates_total < InpMAPeriod + InpSenkouB)
      return(0);

//--- 1. Determine Calculation Range (O(1) Optimization)
   int limit;
   if(prev_calculated == 0)
     {
      limit = rates_total - InpSenkouB - 1; // Start from beginning (safe margin)
     }
   else
     {
      limit = rates_total - prev_calculated + 1; // Only new bars + 1 for crossover
     }

//--- 2. Set Arrays as Series (Index 0 is newest)
// This aligns with the logic: i is current, i+1 is previous
   ArraySetAsSeries(BufferBuy1, true);
   ArraySetAsSeries(BufferBuy2, true);
   ArraySetAsSeries(BufferSell1, true);
   ArraySetAsSeries(BufferSell2, true);

   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(time, true);

//--- 3. Copy Data from Handles
// We copy slightly more than 'limit' to handle the lookback (i+1) safely
   int copy_count = limit + 5;
   if(copy_count > rates_total)
      copy_count = rates_total;

// Copy MA Low
   if(CopyBuffer(h_ma_low, 0, 0, copy_count, ma_low) < copy_count)
      return(0);
   ArraySetAsSeries(ma_low, true);

// Copy MA High
   if(CopyBuffer(h_ma_high, 0, 0, copy_count, ma_high) < copy_count)
      return(0);
   ArraySetAsSeries(ma_high, true);

// Copy Ichimoku (Span A is buffer 2, Span B is buffer 3)
   if(CopyBuffer(h_ichimoku, 2, 0, copy_count, span_a) < copy_count)
      return(0);
   ArraySetAsSeries(span_a, true);

   if(CopyBuffer(h_ichimoku, 3, 0, copy_count, span_b) < copy_count)
      return(0);
   ArraySetAsSeries(span_b, true);

// Copy ATR
   if(CopyBuffer(h_atr, 0, 0, copy_count, atr) < copy_count)
      return(0);
   ArraySetAsSeries(atr, true);

//--- 4. Main Calculation Loop
   for(int i = limit - 1; i >= 0; i--)
     {
      // Safety check for array bounds
      if(i + InpShift1 + 1 >= copy_count || i + InpShift2 + 1 >= copy_count)
         continue;

      // Reset buffers
      BufferBuy1[i] = EMPTY_VALUE;
      BufferBuy2[i] = EMPTY_VALUE;
      BufferSell1[i] = EMPTY_VALUE;
      BufferSell2[i] = EMPTY_VALUE;

      //--- Logic 1: Buy (MA Low crosses above Span A, and is above Span B)
      // Uses InpShift1
      int idx1 = i + InpShift1;
      if(ma_low[idx1] > span_a[idx1] && ma_low[idx1+1] <= span_a[idx1+1] && ma_low[idx1] > span_b[idx1])
        {
         BufferBuy1[i] = low[i] - atr[i]; // Place arrow below low
         if(i == 0)
            TriggerAlert("Buy Signal 1", time[i]);
        }

      //--- Logic 2: Buy (MA Low crosses above Span B, and is above Span A)
      // Uses InpShift2 for MA check (Based on original code logic structure)
      // Original: MA[Shift2+i] > SpanB[Shift1+i] ...
      int idx2 = i + InpShift2;
      if(ma_low[idx2] > span_b[idx1] && ma_low[idx2+1] <= span_b[idx1+1] && ma_low[idx2] > span_a[idx1])
        {
         BufferBuy2[i] = low[i] - atr[i];
         if(i == 0)
            TriggerAlert("Buy Signal 2", time[i]);
        }

      //--- Logic 3: Sell (MA High crosses below Span B, and is below Span A)
      // Uses InpShift1
      if(ma_high[idx1] < span_b[idx1] && ma_high[idx1+1] >= span_b[idx1+1] && ma_high[idx1] < span_a[idx1])
        {
         BufferSell1[i] = high[i] + atr[i]; // Place arrow above high
         if(i == 0)
            TriggerAlert("Sell Signal 1", time[i]);
        }

      //--- Logic 4: Sell (MA High crosses below Span A, and is below Span B)
      // Uses InpShift2
      if(ma_high[idx2] < span_a[idx1] && ma_high[idx2+1] >= span_a[idx1+1] && ma_high[idx2] < span_b[idx1])
        {
         BufferSell2[i] = high[i] + atr[i];
         if(i == 0)
            TriggerAlert("Sell Signal 2", time[i]);
        }
     }

   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Helper: Trigger Alert                                            |
//+------------------------------------------------------------------+
void TriggerAlert(string message, datetime time)
  {
   if(!InpUseAlerts && !InpUsePush)
      return;
   if(time == last_alert_time)
      return; // Prevent duplicate alerts for same bar

   last_alert_time = time;

   string text = "JS Channel: " + message + " on " + _Symbol;

   if(InpUseAlerts)
      Alert(text);
   if(InpUsePush)
      SendNotification(text);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+