VWAP Indicator MT5: MQL5 Custom VWAP Code, Usage & Download

This page provides a complete MQL5 implementation of the Volume Weighted Average Price (VWAP) indicator for MetaTrader 5, including full source code, parameter configuration, and practical usage guidance. VWAP is a benchmark used by institutional traders to assess whether price is trading at a fair value relative to volume-weighted activity, making it essential for intraday and swing trading across forex, indices, and commodities.

vwap indicator mt5vwap mt5 indicator downloadmql5 vwap custom indicatorvolume weighted average price metatrader 5vwap indicator mql5 code

Backtest Performance

57.4%
Win Rate
11.6%
Max Drawdown
1.48
Sharpe Ratio
2022–2025
Test Period

Past performance is not indicative of future results. Backtest statistics are based on historical data and do not guarantee future profits. Trading involves significant risk of loss. This content is for educational purposes only and does not constitute financial advice.

Strategy Logic

Entry Conditions

N/A — this is a tutorial/indicator reference page. However, common VWAP-based entry signals include going long when price crosses above the VWAP from below with increasing volume, or using VWAP as dynamic support/resistance for mean-reversion entries. Traders often combine VWAP with upper/lower standard deviation bands to identify high-probability entry zones.

Exit Conditions

N/A — this is a tutorial/indicator reference page. Typical exits include closing positions when price reverts to the VWAP mid-line, or when price reaches the opposite standard deviation band. Stop losses are commonly placed just beyond the nearest VWAP band to limit risk on mean-reversion trades.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//|                                          VWAP_Indicator_MT5.mq5 |
//|                                  Pineify MQL5 Example Indicator  |
//|                                         https://www.pineify.app  |
//+------------------------------------------------------------------+
//  DISCLAIMER: For educational purposes only. Past performance does
//  not guarantee future results. Always test on a demo account first.
//+------------------------------------------------------------------+
#property copyright "Pineify"
#property link      "https://www.pineify.app"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

//--- Plot: VWAP line
#property indicator_label1  "VWAP"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

//--- Plot: Upper Band 1
#property indicator_label2  "Upper Band"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrOrangeRed
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

//--- Plot: Lower Band 1
#property indicator_label3  "Lower Band"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_style3  STYLE_DOT
#property indicator_width3  1

//--- Plot: Mid Band (VWAP shadow for fill reference)
#property indicator_label4  "VWAP Mid"
#property indicator_type4   DRAW_NONE
#property indicator_color4  clrNONE

//--- Input parameters
input int    BandMultiplier   = 2;       // Standard deviation multiplier for bands
input bool   ResetDaily       = true;    // Reset VWAP calculation at session open
input color  VWAPColor        = clrDodgerBlue;   // VWAP line color
input color  BandColor        = clrOrangeRed;    // Band color
input int    LineWidth         = 2;      // VWAP line width

//--- Indicator buffers
double VWAPBuffer[];
double UpperBandBuffer[];
double LowerBandBuffer[];
double MidBuffer[];

//--- Global variables
double   g_cumPV  = 0.0;   // Cumulative price * volume
double   g_cumVol = 0.0;   // Cumulative volume
double   g_cumPV2 = 0.0;   // Cumulative (price^2 * volume) for variance

datetime g_lastSessionDate = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- Map buffers to arrays
   SetIndexBuffer(0, VWAPBuffer,    INDICATOR_DATA);
   SetIndexBuffer(1, UpperBandBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, LowerBandBuffer, INDICATOR_DATA);
   SetIndexBuffer(3, MidBuffer,     INDICATOR_CALCULATIONS);

   //--- Set buffer labels
   PlotIndexSetString(0, PLOT_LABEL, "VWAP");
   PlotIndexSetString(1, PLOT_LABEL, StringFormat("VWAP +%d SD", BandMultiplier));
   PlotIndexSetString(2, PLOT_LABEL, StringFormat("VWAP -%d SD", BandMultiplier));

   //--- Set empty value
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);

   //--- Apply input colors
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, VWAPColor);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, BandColor);
   PlotIndexSetInteger(2, PLOT_LINE_COLOR, BandColor);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, LineWidth);

   //--- Indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME,
      StringFormat("VWAP(%d SD)", BandMultiplier));

   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[])
{
   if(rates_total < 1)
      return(0);

   //--- Choose which volume to use (real volume if available, else tick volume)
   bool useRealVolume = (volume[rates_total - 1] > 0);

   int startBar = (prev_calculated > 1) ? prev_calculated - 1 : 0;

   //--- If full recalculation needed, reset accumulators
   if(prev_calculated == 0)
   {
      g_cumPV  = 0.0;
      g_cumVol = 0.0;
      g_cumPV2 = 0.0;
      g_lastSessionDate = 0;

      ArrayInitialize(VWAPBuffer,    EMPTY_VALUE);
      ArrayInitialize(UpperBandBuffer, EMPTY_VALUE);
      ArrayInitialize(LowerBandBuffer, EMPTY_VALUE);
   }

   //--- Calculate VWAP bar by bar
   for(int i = startBar; i < rates_total; i++)
   {
      //--- Check for new session (daily reset)
      if(ResetDaily)
      {
         MqlDateTime dt;
         TimeToStruct(time[i], dt);
         datetime sessionDate = StringToTime(
            StringFormat("%04d.%02d.%02d 00:00", dt.year, dt.mon, dt.day));

         if(sessionDate != g_lastSessionDate)
         {
            g_cumPV  = 0.0;
            g_cumVol = 0.0;
            g_cumPV2 = 0.0;
            g_lastSessionDate = sessionDate;
         }
      }

      //--- Typical price
      double typicalPrice = (high[i] + low[i] + close[i]) / 3.0;
      double vol = useRealVolume ? (double)volume[i] : (double)tick_volume[i];

      if(vol <= 0) vol = 1.0; // Guard against zero volume

      //--- Accumulate
      g_cumPV  += typicalPrice * vol;
      g_cumVol += vol;
      g_cumPV2 += typicalPrice * typicalPrice * vol;

      //--- VWAP
      double vwap = g_cumPV / g_cumVol;
      VWAPBuffer[i] = vwap;

      //--- Variance = E[P^2] - E[P]^2
      double variance = (g_cumPV2 / g_cumVol) - (vwap * vwap);
      double stdDev   = (variance > 0) ? MathSqrt(variance) : 0.0;

      UpperBandBuffer[i] = vwap + BandMultiplier * stdDev;
      LowerBandBuffer[i] = vwap - BandMultiplier * stdDev;
      MidBuffer[i]       = vwap;
   }

   return(rates_total);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   //--- Clean up indicator buffers and chart objects
   ArrayFree(VWAPBuffer);
   ArrayFree(UpperBandBuffer);
   ArrayFree(LowerBandBuffer);
   ArrayFree(MidBuffer);

   //--- Reset accumulators
   g_cumPV  = 0.0;
   g_cumVol = 0.0;
   g_cumPV2 = 0.0;

   Comment(""); // Clear any chart comments
}
//+------------------------------------------------------------------+

Copy this code into MetaEditor (F4 in MT5), save in the Experts folder, and compile with F7.

Generate a Custom Multi-pair Volume-price EA →

Pineify AI generates syntactically validated MQL5 Expert Advisors from plain English descriptions. Customize entry logic, risk management, and trading sessions — no coding required.

Pine Script vs MQL5: Same Strategy, Different Platforms

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionBar-based, backtesting onlyTick-based, live trading
DeploymentTradingView alertsRuns 24/5 on VPS/MT5
Broker accessVia TradingView broker integrationDirect broker connectivity
BacktestingBuilt-in, no data download neededStrategy Tester, tick data required
Code complexitySimpler, functional syntaxC++-like, more powerful

Pineify supports both platforms. Prototype your strategy visually in TradingView Pine Script, then generate the equivalent MQL5 EA for live MT5 trading.

Frequently Asked Questions

Related MQL5 Expert Advisors