How do I use a custom indicator (VWAP Lite) from an expert advisor?

 
I downloaded the free indicator VWAP Lite ('VWAP Lite - Volume Weighted Average Price'). It works fine as an indicator but how do I make it a part of my expert advisor? I understand I need a handle in OnInit() and some kind of call in OnTick(). But how should it look like? Any help is appreciated.

This is the indicator VWAP Lite:


//+------------------------------------------------------------------+
//|                                                    VWAP_Lite.mq5 |
//|                     Copyright 2016, SOL Digital Consultoria LTDA |
//|                          http://www.soldigitalconsultoria.com.br |
//              Fil kopierad från https://www.mql5.com/en/code/14557

/* VWAP is an intra-day calculation used primarily by algorithms and institutional traders to assess 
   where a stock is trading relative to its volume weighted average for the day. Day traders also 
   use VWAP for assessing market direction and filtering trade signals. Before using VWAP, understand 
   how it is calculated, how to interpret it and use it, as well the drawbacks of the indicator 
   (http://traderhq.com/trading-strategies/understanding-volume-weight-average-price/).

   This is a VWAP indicator based on the Investopedia description 
   (http://www.investopedia.com/articles/trading/11/trading-with-vwap-mvwap.asp).

   I've added three lines to this indicator. The principal is the VWAP Daily which is the calculation 
   based on the intra-day values, there's the Weekly and the Monthly that is calculated based in the 
   week and month starts respectively. All three lines are independent. As default only the intra-day 
   comes enabled, but you can enable the others in the properties panel.
*/

//+------------------------------------------------------------------+
#property copyright         "Copyright 2016, SOL Digital Consultoria LTDA"
#property link              "http://www.soldigitalconsultoria.com.br"
#property version           "1.49"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

#property indicator_label1  "VWAP Daily"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_DASH
#property indicator_width1  2

#property indicator_label2  "VWAP Weekly"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_DASH
#property indicator_width2  2

#property indicator_label3  "VWAP Monthly"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGreen
#property indicator_style3  STYLE_DASH
#property indicator_width3  2
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum DATE_TYPE
  {
   DAILY,
   WEEKLY,
   MONTHLY
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum PRICE_TYPE
  {
   OPEN,
   CLOSE,
   HIGH,
   LOW,
   OPEN_CLOSE,
   HIGH_LOW,
   CLOSE_HIGH_LOW,
   OPEN_CLOSE_HIGH_LOW
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime CreateDateTime(DATE_TYPE nReturnType=DAILY,datetime dtDay=D'2000.01.01 00:00:00',int pHour=0,int pMinute=0,int pSecond=0)
  {
   datetime    dtReturnDate;
   MqlDateTime timeStruct;

   TimeToStruct(dtDay,timeStruct);
   timeStruct.hour = pHour;
   timeStruct.min  = pMinute;
   timeStruct.sec  = pSecond;
   dtReturnDate=(StructToTime(timeStruct));

   if(nReturnType==WEEKLY)
     {
      while(timeStruct.day_of_week!=0)
        {
         dtReturnDate=(dtReturnDate-86400);
         TimeToStruct(dtReturnDate,timeStruct);
        }
     }

   if(nReturnType==MONTHLY)
     {
      timeStruct.day=1;
      dtReturnDate=(StructToTime(timeStruct));
     }

   return dtReturnDate;
  }

sinput  string      Indicator_Name      = "Volume Weighted Average Price (VWAP)";
input   PRICE_TYPE  Price_Type          = CLOSE_HIGH_LOW;
input   bool        Calc_Every_Tick     = false;
input   bool        Enable_Daily        = true;
input   bool        Show_Daily_Value    = true;
input   bool        Enable_Weekly       = false;
input   bool        Show_Weekly_Value   = false;
input   bool        Enable_Monthly      = false;
input   bool        Show_Monthly_Value  = false;

double          VWAP_Buffer_Daily[],VWAP_Buffer_Weekly[],VWAP_Buffer_Monthly[];
double          nPriceArr[],nTotalTPV[],nTotalVol[];
double          nSumDailyTPV = 0, nSumWeeklyTPV = 0, nSumMonthlyTPV = 0;
double          nSumDailyVol = 0, nSumWeeklyVol = 0, nSumMonthlyVol = 0;
int             nIdxDaily=0,nIdxWeekly=0,nIdxMonthly=0,nIdx=0;
bool            bIsFirstRun=true;
string          sDailyStr = "", sWeeklyStr  = "", sMonthlyStr = "";
datetime        dtLastDay = CreateDateTime(DAILY), dtLastWeek = CreateDateTime(WEEKLY), dtLastMonth = CreateDateTime(MONTHLY);
ENUM_TIMEFRAMES LastTimePeriod=PERIOD_MN1;
int             nStringYDistance=40;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit(){
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

   SetIndexBuffer(0,VWAP_Buffer_Daily,INDICATOR_DATA);
   SetIndexBuffer(1,VWAP_Buffer_Weekly,INDICATOR_DATA);
   SetIndexBuffer(2,VWAP_Buffer_Monthly,INDICATOR_DATA);

   if(Show_Daily_Value){
      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,nStringYDistance);
      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," ");
      nStringYDistance=nStringYDistance+20;
   }

   if(Show_Weekly_Value){
      ObjectCreate(0,"VWAP_Weekly",OBJ_LABEL,0,0,0);
      ObjectSetInteger(0,"VWAP_Weekly",OBJPROP_CORNER,3);
      ObjectSetInteger(0,"VWAP_Weekly",OBJPROP_XDISTANCE,180);
      ObjectSetInteger(0,"VWAP_Weekly",OBJPROP_YDISTANCE,nStringYDistance);
      ObjectSetInteger(0,"VWAP_Weekly",OBJPROP_COLOR,indicator_color2);
      ObjectSetInteger(0,"VWAP_Weekly",OBJPROP_FONTSIZE,7);
      ObjectSetString(0,"VWAP_Weekly",OBJPROP_FONT,"Verdana");
      ObjectSetString(0,"VWAP_Weekly",OBJPROP_TEXT," ");
      nStringYDistance=nStringYDistance+20;
   }

   if(Show_Monthly_Value){
      ObjectCreate(0,"VWAP_Monthly",OBJ_LABEL,0,0,0);
      ObjectSetInteger(0,"VWAP_Monthly",OBJPROP_CORNER,3);
      ObjectSetInteger(0,"VWAP_Monthly",OBJPROP_XDISTANCE,180);
      ObjectSetInteger(0,"VWAP_Monthly",OBJPROP_YDISTANCE,nStringYDistance);
      ObjectSetInteger(0,"VWAP_Monthly",OBJPROP_COLOR,indicator_color3);
      ObjectSetInteger(0,"VWAP_Monthly",OBJPROP_FONTSIZE,7);
      ObjectSetString(0,"VWAP_Monthly",OBJPROP_FONT,"Verdana");
      ObjectSetString(0,"VWAP_Monthly",OBJPROP_TEXT," ");
   }

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int pReason){
   if(Show_Daily_Value) ObjectDelete(0,"VWAP_Daily");
   if(Show_Weekly_Value) ObjectDelete(0,"VWAP_Weekly");
   if(Show_Monthly_Value) ObjectDelete(0,"VWAP_Monthly");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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(PERIOD_CURRENT!=LastTimePeriod){
      bIsFirstRun=true;
      LastTimePeriod=PERIOD_CURRENT;
   }

   if(rates_total>prev_calculated || bIsFirstRun || Calc_Every_Tick){
      ArrayResize(nPriceArr,rates_total);
      ArrayResize(nTotalTPV,rates_total);
      ArrayResize(nTotalVol,rates_total);

      if(Enable_Daily)   {nIdx = nIdxDaily;   nSumDailyTPV = 0;   nSumDailyVol = 0;}
      if(Enable_Weekly)  {nIdx = nIdxWeekly;  nSumWeeklyTPV = 0;  nSumWeeklyVol = 0;}
      if(Enable_Monthly) {nIdx = nIdxMonthly; nSumMonthlyTPV = 0; nSumMonthlyVol = 0;}

      for(; nIdx<rates_total; nIdx++){
         VWAP_Buffer_Daily[nIdx]=EMPTY_VALUE;
         VWAP_Buffer_Weekly[nIdx]=EMPTY_VALUE;
         VWAP_Buffer_Monthly[nIdx]=EMPTY_VALUE;

         if(CreateDateTime(DAILY,time[nIdx])!=dtLastDay)
           {
            nIdxDaily=nIdx;
            nSumDailyTPV = 0;
            nSumDailyVol = 0;
           }
         if(CreateDateTime(WEEKLY,time[nIdx])!=dtLastWeek)
           {
            nIdxWeekly=nIdx;
            nSumWeeklyTPV = 0;
            nSumWeeklyVol = 0;
           }
         if(CreateDateTime(MONTHLY,time[nIdx])!=dtLastMonth)
           {
            nIdxMonthly=nIdx;
            nSumMonthlyTPV = 0;
            nSumMonthlyVol = 0;
           }

         nPriceArr[nIdx] = 0;
         nTotalTPV[nIdx] = 0;
         nTotalVol[nIdx] = 0;

         switch(Price_Type)
           {
            case OPEN:
               nPriceArr[nIdx]=open[nIdx];
               break;
            case CLOSE:
               nPriceArr[nIdx]=close[nIdx];
               break;
            case HIGH:
               nPriceArr[nIdx]=high[nIdx];
               break;
            case LOW:
               nPriceArr[nIdx]=low[nIdx];
               break;
            case HIGH_LOW:
               nPriceArr[nIdx]=(high[nIdx]+low[nIdx])/2;
               break;
            case OPEN_CLOSE:
               nPriceArr[nIdx]=(open[nIdx]+close[nIdx])/2;
               break;
            case CLOSE_HIGH_LOW:
               nPriceArr[nIdx]=(close[nIdx]+high[nIdx]+low[nIdx])/3;
               break;
            case OPEN_CLOSE_HIGH_LOW:
               nPriceArr[nIdx]=(open[nIdx]+close[nIdx]+high[nIdx]+low[nIdx])/4;
               break;
            default:
               nPriceArr[nIdx]=(close[nIdx]+high[nIdx]+low[nIdx])/3;
               break;
           }

         if(tick_volume[nIdx])
           {
            nTotalTPV[nIdx] = (nPriceArr[nIdx] * tick_volume[nIdx]);
            nTotalVol[nIdx] = (double)tick_volume[nIdx];
              } else if(volume[nIdx]) {
            nTotalTPV[nIdx] = (nPriceArr[nIdx] * volume[nIdx]);
            nTotalVol[nIdx] = (double)volume[nIdx];
           }

         if(Enable_Daily && (nIdx>=nIdxDaily))
           {
            nSumDailyTPV += nTotalTPV[nIdx];
            nSumDailyVol += nTotalVol[nIdx];

            if(nSumDailyVol)
               VWAP_Buffer_Daily[nIdx]=(nSumDailyTPV/nSumDailyVol);

            if((sDailyStr!="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits)) && Show_Daily_Value)
              {
               sDailyStr="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits);
               ObjectSetString(0,"VWAP_Daily",OBJPROP_TEXT,sDailyStr);
              }
           }

         if(Enable_Weekly && (nIdx>=nIdxWeekly))
           {
            nSumWeeklyTPV += nTotalTPV[nIdx];
            nSumWeeklyVol += nTotalVol[nIdx];

            if(nSumWeeklyVol)
               VWAP_Buffer_Weekly[nIdx]=(nSumWeeklyTPV/nSumWeeklyVol);

            if((sWeeklyStr!="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits)) && Show_Weekly_Value)
              {
               sWeeklyStr="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits);
               ObjectSetString(0,"VWAP_Weekly",OBJPROP_TEXT,sWeeklyStr);
              }
           }

         if(Enable_Monthly && (nIdx>=nIdxMonthly))
           {
            nSumMonthlyTPV += nTotalTPV[nIdx];
            nSumMonthlyVol += nTotalVol[nIdx];

            if(nSumMonthlyVol)
               VWAP_Buffer_Monthly[nIdx]=(nSumMonthlyTPV/nSumMonthlyVol);

            if((sMonthlyStr!="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits)) && Show_Monthly_Value)
              {
               sMonthlyStr="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits);
               ObjectSetString(0,"VWAP_Monthly",OBJPROP_TEXT,sMonthlyStr);
              }
           }

         dtLastDay=CreateDateTime(DAILY,time[nIdx]);
         dtLastWeek=CreateDateTime(WEEKLY,time[nIdx]);
         dtLastMonth=CreateDateTime(MONTHLY,time[nIdx]);
        }

      bIsFirstRun=false;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+


This is how far I got with my expert advisor:

#resource "\\Indicators\\vwap_lite.ex5"

int IndicatorHandle;
enum PRICE_TYPE{
   OPEN,
   CLOSE,
   HIGH,
   LOW,
   OPEN_CLOSE,
   HIGH_LOW,
   CLOSE_HIGH_LOW,
   OPEN_CLOSE_HIGH_LOW
};

sinput  string      Indicator_Name      = "Volume Weighted Average Price (VWAP)";
input   PRICE_TYPE  Price_Type          = CLOSE_HIGH_LOW;
input   bool        Calc_Every_Tick     = false;
input   bool        Enable_Daily        = true;
input   bool        Show_Daily_Value    = true;
input   bool        Enable_Weekly       = false;
input   bool        Show_Weekly_Value   = false;
input   bool        Enable_Monthly      = false;
input   bool        Show_Monthly_Value  = false;

int OnInit(){
   IndicatorHandle=iCustom(NULL,PERIOD_CURRENT,"::Indicators\\vwap_lite.ex5", Indicator_Name, Price_Type, Calc_Every_Tick, Enable_Daily, Show_Daily_Value, Enable_Weekly, Show_Weekly_Value, Enable_Monthly, Show_Monthly_Value);
   if(IndicatorHandle==INVALID_HANDLE){
      Print("Expert: iCustom call: Error code=",GetLastError());
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

void OnTick(){
        // What do I need here?
}
VWAP Lite - Volume Weighted Average Price
VWAP Lite - Volume Weighted Average Price
  • www.mql5.com
VWAP is an intra-day calculation used primarily by algorithms and institutional traders to assess where a stock is trading relative to its volume weighted average for the day.
 
Does anyone know what code I should write in OnTick() to be able to use the Indicator as a trade signal? Or at least how I should start?
 

Have you tried with iCustom? 


You don't have to write the indicator to you EA.

You only need to call it. 

https://docs.mql4.com/indicators/icustom

iCustom - Technical Indicators - MQL4 Reference
iCustom - Technical Indicators - MQL4 Reference
  • docs.mql4.com
iCustom - Technical Indicators - MQL4 Reference
 

But what did you find so special with this indicator? Is like MA...if you plot SMA with a period of 1, you will have your daily vwap daily line.

Similar you can find the settings for other lines also in this indicator.

 
Daniel Cioca #:

Have you tried with iCustom? 


You don't have to write the indicator to you EA.

You only need to call it. 

https://docs.mql4.com/indicators/icustom

Thanks for your input. I use iCustom to get a handle to the indicator in OnInit(). The main question is how I call the indicator after that, in OnTick(). And I use mql5, not mql4.
 
Daniel Cioca #:

But what did you find so special with this indicator? Is like MA...if you plot SMA with a period of 1, you will have your daily vwap daily line.

Similar you can find the settings for other lines also in this indicator.

VWAP takes consideration to both the price and the volume, SMA only the price.

Simple Moving Average (SMA) Definition (investopedia.com)
"A simple moving average (SMA) calculates the average of a selected range of prices, usually closing prices, by the number of periods in that range."

Volume-Weighted Average Price (VWAP) Definition (investopedia.com)

"The volume-weighted average price (VWAP) is a trading benchmark used by traders that gives the average price a security has traded at throughout the day, based on both volume and price. VWAP is important because it provides traders with insight into both the trend and value of a security."

 

This is how far I got with the OnTick() function in my expert advisor:

void OnTick(){     
      double VWAP_Buffer_Daily[];
      int start_pos=0,count=3;
      ArraySetAsSeries(VWAP_Buffer_Daily,true);
      CopyBuffer(IndicatorHandle,0,start_pos,count,VWAP_Buffer_Daily);
      //Print("OnTick, VWAP_Buffer_Daily[0] ", VWAP_Buffer_Daily[0]);   // Test print
}

It seems to return the right numbers. But it does not draw a chart. Does anyone know what code I need to add in order to do that?

 
Herbader #:   

gives the average price a security has traded at throughout the day, based on both volume and price.

be careful: this volume should be distinguished by buy- or sell- volume -- in order you could trust this info... but in MT you do not have such volume division

Herbader # : Does anyone know what code I need to add in order to do that?
Daniel Cioca # : Have you tried with iCustom?  
How do I use a custom indicator (VWAP Lite) from an expert advisor?
How do I use a custom indicator (VWAP Lite) from an expert advisor?
  • 2021.09.15
  • www.mql5.com
I downloaded the free indicator VWAP Lite ( 'VWAP Lite - Volume Weighted Average Price'...
 
Herbader #:
I use iCustom to get a handle to the indicator in OnInit(). . And I use mql5, not mql4.

What is that "handle"? You want to use this indicator in your EA correct?


You need to call indicator buffers in your EA. You do that using iCustom, NOT the way you did it.


#property indicator_buffers 3

you have 3 buffers, you have to call them individually.


   SetIndexBuffer(0,VWAP_Buffer_Daily,INDICATOR_DATA);
   SetIndexBuffer(1,VWAP_Buffer_Weekly,INDICATOR_DATA);
   SetIndexBuffer(2,VWAP_Buffer_Monthly,INDICATOR_DATA);

These are the buffers.


I am not sure, but I believe that iCustom works the same way in mql5 also. MQL5 is like a customized mql4, and both of them the have the core in C++... 

 
Herbader #:

VWAP takes consideration to both the price and the volume, SMA only the price.

Simple Moving Average (SMA) Definition (investopedia.com)
"A simple moving average (SMA) calculates the average of a selected range of prices, usually closing prices, by the number of periods in that range."

Volume-Weighted Average Price (VWAP) Definition (investopedia.com)

"The volume-weighted average price (VWAP) is a trading benchmark used by traders that gives the average price a security has traded at throughout the day, based on both volume and price. VWAP is important because it provides traders with insight into both the trend and value of a security."

Ok I understand. Just for your own experience, put this indicator on the chart with daily range, and put also EMA with period of one. Both of them on a daily timeframe


Yellow line is 1 period SMA on median price, blue line is you indicator daily. 

As JeeyCi said. MT cannot separate sell/buy volume and NOT to be confused with volatility. 


As a suggestion : don't look for indictors like swiss army knifes.. which they do a lot of things , but every thing is doing is very poor quality.. :) 

Files:
WTIDaily.png  50 kb
Reason: