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.
Backtest Performance
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
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Bar-based, backtesting only | Tick-based, live trading |
| Deployment | TradingView alerts | Runs 24/5 on VPS/MT5 |
| Broker access | Via TradingView broker integration | Direct broker connectivity |
| Backtesting | Built-in, no data download needed | Strategy Tester, tick data required |
| Code complexity | Simpler, functional syntax | C++-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.