Why does my Indicator not plot anything on Strategy Tester Visualization?

 

Hi,


I am trying to replicate a strategy on MQL what I have in Thinkscript. I'm starting with one indicator, an anchored intraday VWAP line. I have read forums and watched videos on youtube on how to build an indicator and I do not understand what I am doing incorrectly. Can anybody please point me in the direction of getting this working?


Thanks in advance.

My code:

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

//|                                                Anchored_VWAP.mq5 |
//|                                                             Aabh |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Aabh"
#property link      ""
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_plots 1

#property indicator_type1 DRAW_LINE
#property indicator_label1 "Anchored_VWAP"
#property indicator_color1 clrGhostWhite
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4



//--- input parameters

input int Interval = 1;

bool time;
int startTime = 0;
int endTime = 24;

double BufferVWP[];
double BufferVS[];
double BufferVWAP[];
double BufferVWAPSD[];
double BufferVWAPSQR[];

int VWPHandle;
int VSHandle;
int VWAPHandle;
int VWAPSDHandle;
int VWAPSQRHandle;

   datetime tm = TimeCurrent(); //gets current time in datetime data type
   string str = TimeToString(tm,TIME_MINUTES); //changing the data type to a string
   string current = StringSubstr(str, 0, 2); //selecting the first two characters of the datetime e.g. if it's 5:00:00 then it'll save it as 5, if it's 18 it will save 18.
   int currentTimeInt = StringToInteger(current); //changes the string to an integer

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

    MqlRates rates[];
   ArraySetAsSeries(rates,true);
   
   
int copied=CopyRates(
                        Symbol(),             // symbol name
                        PERIOD_CURRENT,       // Don't hard code constants PERIOD_CURRENT
                        startTime,                   // Start Time:  
                        endTime,                   // End Time:    
                        rates                 // array
                     );


ArraySetAsSeries(BufferVWP,true);
ArraySetAsSeries(BufferVS,true);
ArraySetAsSeries(BufferVWAP,true);
ArraySetAsSeries(BufferVWAPSD,true);
ArraySetAsSeries(BufferVWAPSQR,true);




   SetIndexBuffer(0,BufferVWAP, INDICATOR_DATA);
     {





   if(currentTimeInt>startTime && endTime>currentTimeInt) {time = true;
   }

   else {time = false;
   }

   if(time == true) {

   //do calculations here
   if(currentTimeInt == startTime) {VWPHandle = rates[0].close * rates[0].real_volume;
   }
   else {VWPHandle = BufferVWP[1]+ (rates[0].close * rates[0].real_volume);
   }

   CopyBuffer(VWPHandle,0,0,0,BufferVWP);              
               
   if(currentTimeInt == startTime) {VSHandle = rates[0].real_volume;
   }
   else {VSHandle = BufferVS[1]+ (rates[0].real_volume);
   }

   CopyBuffer(VSHandle,0,0,0,BufferVS);
   
   VWAPHandle = VWPHandle / VSHandle;
   
   CopyBuffer(VWAPHandle,0,0,0,BufferVWAP);
   
   if(currentTimeInt == startTime) {VWAPSQRHandle = MathPow((rates[0].close - BufferVWAP[0]),2);
   }
   else {VWAPSQRHandle = BufferVWAPSQR[1]+ MathPow((rates[0].close - BufferVWAP[0]),2);
   }
   
   CopyBuffer(VWAPSQRHandle,0,0,0,BufferVWAPSQR);
               
   VWAPSDHandle = MathSqrt(VWAPSQRHandle/VSHandle);
   CopyBuffer(VWAPSDHandle,0,0,0,BufferVWAPSD);
   }
   
//PLOT_DRAW_BEGIN
//PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,0);



}
   return(INIT_SUCCEEDED);
  }
  
void OnDeinit(const int reason) {

IndicatorRelease(VWPHandle);
IndicatorRelease(VSHandle);
IndicatorRelease(VWAPHandle);
IndicatorRelease(VWAPSDHandle);
IndicatorRelease(VWAPSQRHandle);


}

void OnTick() {

//--- indicator buffers mapping
 

//PLOT_DRAW_BEGIN
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,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[])
  {
//---
   if (IsStopped()) return(0);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+



Documentation on MQL5: Constants, Enumerations and Structures / Indicator Constants / Indicators Lines
Documentation on MQL5: Constants, Enumerations and Structures / Indicator Constants / Indicators Lines
  • www.mql5.com
Indicators Lines - Indicator Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
Files:
Capture.JPG  378 kb
 

Forum on trading, automated trading systems and testing trading strategies

When you post code please use the CODE button (Alt-S)!

Use the CODE button



 
Aabh Shah:

Why does my EA not plot anything on Strategy Tester Visualization?

Your posted code is not an EA — it is an indicator.

 
My apologies I have now updated the question.
 
  1. int OnCalculate(…){
       return(rates_total);
    }

    You do not populate your buffer, so nothing is shown.

  2. VWPHandle = rates[0].close * rates[0].real_volume;
    A handle is an int not a double. Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. 2004
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
              How to call indicators in MQL5 - MQL5 Articles 12 March 2010

  3. double BufferVWP[];
    double BufferVS[];
    double BufferVWAP[];
    double BufferVWAPSD[];
    double BufferVWAPSQR[];

    None of these (except BufferVWAP) are buffers. They are arrays with zero size.

  4. int OnInit(){
    ⋮
    int copied=CopyRates(…

    Don't try to use any price or server related functions in OnInit (or on load), as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

 
//+------------------------------------------------------------------+
//|                                                Anchored_VWAP.mq5 |
//|                                                             Aabh |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Aabh"
#property link      ""
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_plots 1

#property indicator_type1 DRAW_LINE
#property indicator_label1 "VWAP_Daily"
#property indicator_color1 clrGhostWhite
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4



//--- input parameters

input int Interval = 1;

//bool time;
//int startTime = T'0:00:00';
//int endTime = T'23:58:00';

//int startTime = 0;
//int endTime = 23;


MqlRates rates[];
double volumesum, volume_times_close, vwap_now, vwap_square, vwap_sd, u, x, y, z;
double vtc[], v[], vwap[], vwap_sqr[], vwap_SD[];
int arraylimit = 24, i = 0;


   datetime tm = TimeCurrent(); //gets current time in datetime data type
   string str = TimeToString(tm,TIME_MINUTES); //changing the data type to a string
   string current = StringSubstr(str, 0, 2); //selecting the first two characters of the datetime e.g. if it's 5:00:00 then it'll save it as 5, if it's 18 it will save 18.
   int currentTimeInt = StringToInteger(current); //changes the string to an integer

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


   ArraySetAsSeries(rates,true);
//   ArraySetAsSeries(vwap,true);
//   ArraySetAsSeries(vwap_SD,true);
   
      

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

   SetIndexBuffer(0,vwap,INDICATOR_DATA);


   ObjectCreate(0,"VWAP_Daily",OBJ_LABEL,0,0,0);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_CORNER,3);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_XDISTANCE,180);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_YDISTANCE,40);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_COLOR,indicator_color1);
   ObjectSetInteger(0,"VWAP_Daily",OBJPROP_FONTSIZE,7);
   ObjectSetString(0,"VWAP_Daily",OBJPROP_FONT,"Verdana");
   ObjectSetString(0,"VWAP_Daily",OBJPROP_TEXT," ");

   

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int pReason)
  {
   ObjectDelete(0,"VWAP_Daily");

  }      
      
   
 void OnTick()

 {  
 int copied=CopyRates(
                        Symbol(),             // symbol name
                        PERIOD_CURRENT,       // Don't hard code constants PERIOD_CURRENT
                        0,                   // Shift 
                        100,                   // how many bars back    
                        rates                 // array
                     );
 
   static int   LastBarCount = 0;

ArrayResize(vtc,arraylimit);
ArrayResize(v,arraylimit);
ArrayResize(vwap,arraylimit);
ArrayResize(vwap_sqr,arraylimit);
ArrayResize(vwap_SD,arraylimit);

for(i;i<arraylimit;i++)
   {
    if (Bars(_Symbol, _Period) > LastBarCount)
      {LastBarCount = Bars(_Symbol, _Period);
      Print(LastBarCount);
      Print(i);
      Print("bar real volume " + (string) rates[1].tick_volume);
      Print("bar close " + (string) rates[1].close);
      volume_times_close = rates[1].tick_volume * rates[1].close;
      volumesum = rates[1].tick_volume;

      Print("vtc " + (string) volume_times_close);


      
      //volume times close
      Print("vtc " + (string) volume_times_close);
      if (i == 0)
         ArrayFill(vtc,i,1,volume_times_close);
      else
         ArrayFill(vtc,i,1,vtc[i-1]+volume_times_close);
      Print("vtc array " + (string) i + " " + (string) vtc[i]);
      
      //volume
      Print("v " + (string) volumesum);
      if (i == 0)
         ArrayFill(v,i,1,volumesum);
      else
         ArrayFill(v,i,1,v[i-1]+volumesum);
      Print("v array " + (string) i + " " + (string) v[i]);
      
      //vwap
      ArrayFill(vwap,i,1,vtc[i]/v[i]);
      Print("vwap array " + (string) i + " " + (string) vwap[i]);
      
      //vwap squared      
//      Print("vwap_sqr " + (string) vwap_square);
      u = rates[1].close-vwap[i];
      Print("u " + u);
      x = pow(u,2);
      Print("x " + x);
      Print("x*volume " + x*volumesum);
//      y = v[i];
//      z = x*v;
      if (i == 0)
         ArrayFill(vwap_sqr,i,1,pow((rates[1].close-vwap[i]),2)*volumesum);
      else
         ArrayFill(vwap_sqr,i,1,vwap_sqr[i-1]+pow((rates[1].close-vwap[i]),2)*volumesum);
      Print("vwap_sqr array " + (string) i + " " + (string) vwap_sqr[i]);
      
      //vwap standard deviaton
      ArrayFill(vwap_SD,i,1,MathSqrt(vwap_sqr[i]/v[i]));
      Print("vwap_SD array " + (string) i + " " + (string) vwap_SD[i]);      
      

      }
    else
    return; 

   
   
   
   }

}


/*
 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[])
{
   return (rates_total);
}
  */
 

Hi,

I spent the last few weeks reading documentation and posts on this forum and I have posted in the comment as source code the new code for a vwap and I have tested the output of the data, i.e. arrays and all the data looks good but could someone please help me with what commands I need to add (and under which section) in order that I can plot the vwap[] and vwap_SD[] array data onto the chart?

Eventually my plan is to actually use the vwap and vwap_SD array data as part of my strategy but I would also like to visualize it.

Many thanks in advance.

Aabh