mql5 Indicator with 2 instances of the same indicator

 
In mql5, starting from an indicator, I wanted to make 2 instances of the same indicator, so that the 2 graphs could be presented in the chart.

I started by duplicating the inputs, as well as the arrays, properties and buffers.

After numerous tests, I only managed to present the first instance of the same indicator, but not the second.

Can anyone give me some guidelines so that I can clarify the situation or find a solution?

Thanks in advance, 

#property indicator_chart_window 
#property indicator_buffers 14
#property indicator_plots 2

#property indicator_label1  "ST"
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrGreen, clrRed
#property indicator_width1  2

#property indicator_label2  "ST2"
#property indicator_type2   DRAW_COLOR_LINE
#property indicator_color2  clrLime, clrCrimson
#property indicator_width2  2

input int    atrPeriod=10;  // ATR 1
input double atrFactor=3;   // ATRFactor 1

input int    atrPeriod2=5;  // ATR 2
input double atrFactor2=1;  // ATRFactor 2


double ST[];
double ColorBuffer[];
double Atr[];
double Up[];
double Down[];
double Middle[];
double trend[];

double ST2[];
double ColorBuffer2[];
double Atr2[];
double Up2[];
double Down2[];
double Middle2[];
double trend2[];

int atrHandle, atrHandle2;
int changeOfTrend, changeOfTrend2;
int flag, flag2;
int flagh, flagh2;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {


//--- indicator buffers mapping
   SetIndexBuffer(0,ST,INDICATOR_DATA);
   SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2,Atr,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,Up,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,Down,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,Middle,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,trend,INDICATOR_CALCULATIONS);

//--- indicator buffers mapping
   SetIndexBuffer(7,ST2,INDICATOR_DATA);
   SetIndexBuffer(8,ColorBuffer2,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(9,Atr2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(10,Up2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(11,Down2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(12,Middle2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(13,trend2,INDICATOR_CALCULATIONS);

   atrHandle=iATR(_Symbol,0,atrPeriod);
   atrHandle2=iATR(_Symbol,0,atrPeriod2);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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 to_copy;
   if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
   else{
         to_copy=rates_total-prev_calculated;
         if(prev_calculated>0) to_copy++;
       }
   int first; // checking for the first start of calculation of an indicator
   if(prev_calculated>rates_total || prev_calculated<=0){ first=atrPeriod; } // starting index for calculation of all bars
   else{ first=prev_calculated-1; } // starting number for calculation of new bars

   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyBuffer(atrHandle,0,0,to_copy,Atr)<=0)  { Print("ST Fallo en la obtención de Atr! Error ",GetLastError()); return(0); }
   if(CopyBuffer(atrHandle2,0,0,to_copy,Atr2)<=0){ Print("ST 2 Fallo en la obtención de Atr! Error",GetLastError()); return(0); }

   for(int i=first; i<rates_total && !IsStopped(); i++){

//----------------------    ST
      Middle[i]=(high[i]+low[i])/2;
      Up[i]  = Middle[i]+(atrFactor*Atr[i]);
      Down[i]= Middle[i]-(atrFactor*Atr[i]);

      if(close[i]>Up[i-1]) {
         trend[i]=1;
         if(trend[i-1]==-1) changeOfTrend=1;
      }
      else if(close[i]<Down[i-1]){
               trend[i]=-1;
               if(trend[i-1]==1) changeOfTrend=1;
           }else if(trend[i-1]==1) {
                     trend[i]=1;
                     changeOfTrend=0;
                 }else if(trend[i-1]==-1){
                        trend[i]=-1;
                        changeOfTrend=0;
                       }

      if(trend[i]<0 && trend[i-1]>0){ flag=1; }
      else { flag=0; }

      if(trend[i]>0 && trend[i-1]<0){ flagh=1; }
      else { flagh=0; }

      if(trend[i]>0 && Down[i]<Down[i-1]) Down[i]=Down[i-1];

      if(trend[i]<0 && Up[i]>Up[i-1])  Up[i]=Up[i-1];

      if(flag==1) Up[i]=Middle[i]+(atrFactor*Atr[i]);

      if(flagh==1) Down[i]=Middle[i]-(atrFactor*Atr[i]);

      //-- Draw the indicator
      if(trend[i]==1){
         ST[i]=Down[i];
         if(changeOfTrend==1){
            ST[i-1]=ST[i-2];
            changeOfTrend=0;
         }
         ColorBuffer[i]=0.0;
      }else if(trend[i]==-1){
               ST[i]=Up[i];
               if(changeOfTrend==1){
                  ST[i-1]= ST[i-2];
                  changeOfTrend = 0;
               }
               ColorBuffer[i]=1.0;
            }
     //Print(ST[1]);
     //}
     
//----------------------    ST2
   
   //for(int i=first; i<rates_total && !IsStopped(); i++){
      Middle2[i]=(high[i]+low[i])/2;
      Up2[i]  = Middle2[i]+(atrFactor2*Atr2[i]);
      Down2[i]= Middle2[i]-(atrFactor2*Atr2[i]);

      if(close[i]>Up2[i-1]) {
         trend2[i]=1;
         if(trend2[i-1]==-1) changeOfTrend2=1;
      }
      else if(close[i]<Down2[i-1]){
               trend2[i]=-1;
               if(trend2[i-1]==1) changeOfTrend2=1;
           }else if(trend2[i-1]==1) {
                     trend2[i]=1;
                     changeOfTrend2=0;
                 }else if(trend2[i-1]==-1){
                        trend2[i]=-1;
                        changeOfTrend2=0;
                       }

      if(trend2[i]<0 && trend2[i-1]>0){ flag2=1; }
      else { flag2=0; }

      if(trend2[i]>0 && trend2[i-1]<0){ flagh2=1; }
      else { flagh2=0; }

      if(trend2[i]>0 && Down2[i]<Down2[i-1]) Down2[i]=Down2[i-1];

      if(trend2[i]<0 && Up2[i]>Up2[i-1])  Up2[i]=Up2[i-1];

      if(flag2==1) Up2[i]=Middle2[i]+(atrFactor2*Atr2[i]);

      if(flagh2==1) Down2[i]=Middle2[i]-(atrFactor2*Atr2[i]);

      //-- Draw the indicator
      if(trend2[i]==1){
         ST2[i]=Down2[i];
         if(changeOfTrend2==1){
            ST2[i-1]=ST2[i-2];
            changeOfTrend2=0;
         }
         ColorBuffer2[i]=0.0;
      }else if(trend2[i]==-1){
               ST2[i]=Up2[i];
               if(changeOfTrend2==1){
                  ST2[i-1]= ST2[i-2];
                  changeOfTrend2 = 0;
               }
               ColorBuffer2[i]=1.0;
            }
     
     }  
     
   return(rates_total);
}


 
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window 
#property indicator_buffers 14
#property indicator_plots 2

#property indicator_label1  "ST"
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrGreen, clrRed
#property indicator_width1  2

#property indicator_label2  "ST2"
#property indicator_type2   DRAW_COLOR_LINE
#property indicator_color2  clrLime, clrCrimson
#property indicator_width2  2

input int    atrPeriod=10;  // ATR 1
input double atrFactor=3;   // ATRFactor 1

input int    atrPeriod2=5;  // ATR 2
input double atrFactor2=1;  // ATRFactor 2


double ST[];
double ColorBuffer[];
double Atr[];
double Up[];
double Down[];
double Middle[];
double trend[];

double ST2[];
double ColorBuffer2[];
double Atr2[];
double Up2[];
double Down2[];
double Middle2[];
double trend2[];

int atrHandle, atrHandle2;
int changeOfTrend, changeOfTrend2;
int flag, flag2;
int flagh, flagh2;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {


//--- indicator buffers mapping
   SetIndexBuffer(0,ST,INDICATOR_DATA);
   SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2,ST2,INDICATOR_DATA);
   SetIndexBuffer(3,ColorBuffer2,INDICATOR_COLOR_INDEX);

   SetIndexBuffer(4,Atr,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,Up,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,Down,INDICATOR_CALCULATIONS);
   SetIndexBuffer(7,Middle,INDICATOR_CALCULATIONS);
   SetIndexBuffer(8,trend,INDICATOR_CALCULATIONS);

//--- indicator buffers mapping
   SetIndexBuffer(9,Atr2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(10,Up2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(11,Down2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(12,Middle2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(13,trend2,INDICATOR_CALCULATIONS);

   atrHandle=iATR(_Symbol,0,atrPeriod);
   atrHandle2=iATR(_Symbol,0,atrPeriod2);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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 to_copy;
   if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
   else{
         to_copy=rates_total-prev_calculated;
         if(prev_calculated>0) to_copy++;
       }
   int first; // checking for the first start of calculation of an indicator
   if(prev_calculated>rates_total || prev_calculated<=0){ first=atrPeriod; } // starting index for calculation of all bars
   else{ first=prev_calculated-1; } // starting number for calculation of new bars

   if(IsStopped()) return(0); //Checking for stop flag
   if(CopyBuffer(atrHandle,0,0,to_copy,Atr)<=0)  { Print("ST Fallo en la obtención de Atr! Error ",GetLastError()); return(0); }
   if(CopyBuffer(atrHandle2,0,0,to_copy,Atr2)<=0){ Print("ST 2 Fallo en la obtención de Atr! Error",GetLastError()); return(0); }

   for(int i=first; i<rates_total && !IsStopped(); i++){

//----------------------    ST
      Middle[i]=(high[i]+low[i])/2;
      Up[i]  = Middle[i]+(atrFactor*Atr[i]);
      Down[i]= Middle[i]-(atrFactor*Atr[i]);

      if(close[i]>Up[i-1]) {
         trend[i]=1;
         if(trend[i-1]==-1) changeOfTrend=1;
      }
      else if(close[i]<Down[i-1]){
               trend[i]=-1;
               if(trend[i-1]==1) changeOfTrend=1;
           }else if(trend[i-1]==1) {
                     trend[i]=1;
                     changeOfTrend=0;
                 }else if(trend[i-1]==-1){
                        trend[i]=-1;
                        changeOfTrend=0;
                       }

      if(trend[i]<0 && trend[i-1]>0){ flag=1; }
      else { flag=0; }

      if(trend[i]>0 && trend[i-1]<0){ flagh=1; }
      else { flagh=0; }

      if(trend[i]>0 && Down[i]<Down[i-1]) Down[i]=Down[i-1];

      if(trend[i]<0 && Up[i]>Up[i-1])  Up[i]=Up[i-1];

      if(flag==1) Up[i]=Middle[i]+(atrFactor*Atr[i]);

      if(flagh==1) Down[i]=Middle[i]-(atrFactor*Atr[i]);

      //-- Draw the indicator
      if(trend[i]==1){
         ST[i]=Down[i];
         if(changeOfTrend==1){
            ST[i-1]=ST[i-2];
            changeOfTrend=0;
         }
         ColorBuffer[i]=0.0;
      }else if(trend[i]==-1){
               ST[i]=Up[i];
               if(changeOfTrend==1){
                  ST[i-1]= ST[i-2];
                  changeOfTrend = 0;
               }
               ColorBuffer[i]=1.0;
            }
     //Print(ST[1]);
     //}
     
//----------------------    ST2
   
   //for(int i=first; i<rates_total && !IsStopped(); i++){
      Middle2[i]=(high[i]+low[i])/2;
      Up2[i]  = Middle2[i]+(atrFactor2*Atr2[i]);
      Down2[i]= Middle2[i]-(atrFactor2*Atr2[i]);

      if(close[i]>Up2[i-1]) {
         trend2[i]=1;
         if(trend2[i-1]==-1) changeOfTrend2=1;
      }
      else if(close[i]<Down2[i-1]){
               trend2[i]=-1;
               if(trend2[i-1]==1) changeOfTrend2=1;
           }else if(trend2[i-1]==1) {
                     trend2[i]=1;
                     changeOfTrend2=0;
                 }else if(trend2[i-1]==-1){
                        trend2[i]=-1;
                        changeOfTrend2=0;
                       }

      if(trend2[i]<0 && trend2[i-1]>0){ flag2=1; }
      else { flag2=0; }

      if(trend2[i]>0 && trend2[i-1]<0){ flagh2=1; }
      else { flagh2=0; }

      if(trend2[i]>0 && Down2[i]<Down2[i-1]) Down2[i]=Down2[i-1];

      if(trend2[i]<0 && Up2[i]>Up2[i-1])  Up2[i]=Up2[i-1];

      if(flag2==1) Up2[i]=Middle2[i]+(atrFactor2*Atr2[i]);

      if(flagh2==1) Down2[i]=Middle2[i]-(atrFactor2*Atr2[i]);

      //-- Draw the indicator
      if(trend2[i]==1){
         ST2[i]=Down2[i];
         if(changeOfTrend2==1){
            ST2[i-1]=ST2[i-2];
            changeOfTrend2=0;
         }
         ColorBuffer2[i]=0.0;
      }else if(trend2[i]==-1){
               ST2[i]=Up2[i];
               if(changeOfTrend2==1){
                  ST2[i-1]= ST2[i-2];
                  changeOfTrend2 = 0;
               }
               ColorBuffer2[i]=1.0;
            }
     
     }  
     
   return(rates_total);
}
You have to bring the two plots to the top...
 
Yashar Seyyedin #:
You have to bring the two plots to the top...
I can't believe it! It was just that, and I didn't even know it.
Thank you so much, Yashar.
Yashar Seyyedin
Yashar Seyyedin
  • 2025.04.25
  • www.mql5.com
Trader's profile