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.
Historical test results
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.
How the Supertrend signal works
Bullish flip
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.
Bearish flip
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 Custom Indicator 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, save it in the MQL5/Indicators folder, and compile with F7.
Change the settings or add your own signal filter
Describe the ATR inputs, alert rules, visual style, or confirmation filter you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.
Pine Script vs MQL5: Same Strategy, Different Platforms
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Series evaluated on chart updates | Event handlers with explicit buffers |
| Deployment | Runs in TradingView with alerts | Runs in the MT5 terminal or on a VPS |
| Broker access | Via TradingView broker integration | Direct broker connectivity |
| Backtesting | Strategy Tester for strategy scripts | Strategy Tester for Expert Advisors |
| Code complexity | Simpler, functional syntax | C++-like, more powerful |
The calculation can be implemented on either platform, but the runtime model and buffer APIs differ. Read the Pine Script Supertrend reference before porting logic between them.
Frequently Asked Questions
Related MQL5 pages
Risk and testing note
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.