VWAP (Volume Weighted Average Price) by Naya
689 downloads / 332 views / Created: 31.05.2025 Average Rating: 0
Indicator Description
VWAP (Volume Weighted Average Price) Indicator
The VWAP indicator calculates the average price weighted by trading volume over a specified period. It provides a dynamic reference point that reflects both price and volume activity in the market.
Key Features:
- Calculates price average using (Open+High+Low+Close)/4 formula
- Weights prices by volume to show true average trading price
- Customizable calculation period (2-200 bars)
- Optional bar shifting (0-2 bars)
- Choice to use previous bar's value
Available Signals:
For Entries:
- Enter at VWAP price
- Filter by VWAP direction (rising/falling)
- Filter by price position relative to VWAP
- Filter by price crosses through VWAP
For Exits:
- Exit at VWAP price
- Filter by VWAP direction
- Filter by closing price relative to VWAP
Usage Tips:
- Helps identify fair value prices
- Useful for mean-reversion strategies
- Can act as dynamic support/resistance
- Works well for intraday trading
- Combines price and volume analysis
Technical Details:
- Calculated during each bar (not just at close)
- Blue line visualization
- Compatible with all timeframes
- Works for both long and short positions
Created with the help of DeepSeek AI and Claude AI
The VWAP indicator calculates the average price weighted by trading volume over a specified period. It provides a dynamic reference point that reflects both price and volume activity in the market.
Key Features:
- Calculates price average using (Open+High+Low+Close)/4 formula
- Weights prices by volume to show true average trading price
- Customizable calculation period (2-200 bars)
- Optional bar shifting (0-2 bars)
- Choice to use previous bar's value
Available Signals:
For Entries:
- Enter at VWAP price
- Filter by VWAP direction (rising/falling)
- Filter by price position relative to VWAP
- Filter by price crosses through VWAP
For Exits:
- Exit at VWAP price
- Filter by VWAP direction
- Filter by closing price relative to VWAP
Usage Tips:
- Helps identify fair value prices
- Useful for mean-reversion strategies
- Can act as dynamic support/resistance
- Works well for intraday trading
- Combines price and volume analysis
Technical Details:
- Calculated during each bar (not just at close)
- Blue line visualization
- Compatible with all timeframes
- Works for both long and short positions
Created with the help of DeepSeek AI and Claude AI
Comments
//==============================================================
// THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
//==============================================================
using System;
using System.Drawing;
using ForexStrategyBuilder.Infrastructure.Entities;
using ForexStrategyBuilder.Infrastructure.Enums;
using ForexStrategyBuilder.Infrastructure.Interfaces;
namespace ForexStrategyBuilder.Indicators.Store
{
public class VWAP : Indicator
{
public VWAP()
{
IndicatorName = "VWAP";
PossibleSlots = SlotTypes.Open | SlotTypes.OpenFilter | SlotTypes.Close | SlotTypes.CloseFilter;
IndicatorAuthor = "NAYA +237674724684";
IndicatorVersion = "1.0";
IndicatorDescription = "Volume Weighted Average Price based on OHLC average.";
}
public override void Initialize(SlotTypes slotType)
{
SlotType = slotType;
IndParam.IndicatorType = TypeOfIndicator.Indicator;
IndParam.ExecutionTime = ExecutionTime.DuringTheBar;
// The ComboBox parameters
IndParam.ListParam[0].Caption = "Logic";
switch (slotType)
{
case SlotTypes.Open:
IndParam.ListParam[0].ItemList = new[]
{
"Enter the market at VWAP"
};
break;
case SlotTypes.OpenFilter:
IndParam.ListParam[0].ItemList = new[]
{
"VWAP rises",
"VWAP falls",
"The bar opens above VWAP",
"The bar opens below VWAP",
"The bar opens above VWAP after opening below it",
"The bar opens below VWAP after opening above it",
"The position opens above VWAP",
"The position opens below VWAP"
};
break;
case SlotTypes.Close:
IndParam.ListParam[0].ItemList = new[]
{
"Exit the market at VWAP"
};
break;
case SlotTypes.CloseFilter:
IndParam.ListParam[0].ItemList = new[]
{
"VWAP rises",
"VWAP falls",
"The bar closes below VWAP",
"The bar closes above VWAP"
};
break;
default:
IndParam.ListParam[0].ItemList = new[]
{
"Not Defined"
};
break;
}
IndParam.ListParam[0].Index = 0;
IndParam.ListParam[0].Text = IndParam.ListParam[0].ItemList[IndParam.ListParam[0].Index];
IndParam.ListParam[0].Enabled = true;
IndParam.ListParam[0].ToolTip = "Logic of application of VWAP.";
// The NumericUpDown parameters
IndParam.NumParam[0].Caption = "Period";
IndParam.NumParam[0].Value = 14;
IndParam.NumParam[0].Min = 2;
IndParam.NumParam[0].Max = 200;
IndParam.NumParam[0].Enabled = true;
IndParam.NumParam[0].ToolTip = "VWAP calculation period.";
IndParam.NumParam[1].Caption = "Shift";
IndParam.NumParam[1].Value = 0;
IndParam.NumParam[1].Min = 0;
IndParam.NumParam[1].Max = 2;
IndParam.NumParam[1].Enabled = true;
IndParam.NumParam[1].ToolTip = "How many bars to shift with.";
// The CheckBox parameters
IndParam.CheckParam[0].Caption = "Use previous bar value";
IndParam.CheckParam[0].Enabled = true;
IndParam.CheckParam[0].ToolTip = "Use the indicator value from the previous bar.";
}
public override void Calculate(IDataSet dataSet)
{
DataSet = dataSet;
// Reading the parameters
var period = (int)IndParam.NumParam[0].Value;
var shift = (int)IndParam.NumParam[1].Value;
var previous = IndParam.CheckParam[0].Checked ? 1 : 0;
// TimeExecution
IndParam.ExecutionTime = ExecutionTime.DuringTheBar;
// Calculate average price (OHLC/4)
double[] avgPrice = new double[Bars];
for (int bar = 0; bar < Bars; bar++)
{
avgPrice[bar] = (Open[bar] + High[bar] + Low[bar] + Close[bar]) / 4;
}
// Calculate VWAP
double[] vwap = new double[Bars];
for (int bar = period; bar < Bars; bar++)
{
double sumPV = 0;
double sumV = 0;
for (int i = bar - period + 1; i <= bar; i++)
{
sumPV += avgPrice[i] * Volume[i];
sumV += Volume[i];
}
vwap[bar] = sumV != 0 ? sumPV / sumV : avgPrice[bar];
}
// Apply shift
double[] shiftedVWAP = new double[Bars];
for (int bar = 0; bar < Bars; bar++)
{
if (bar >= shift)
shiftedVWAP[bar] = vwap[bar - shift];
else
shiftedVWAP[bar] = vwap[0];
}
var firstBar = period + shift + previous + 2;
// Saving the components
if (SlotType == SlotTypes.Open || SlotType == SlotTypes.Close)
{
Component = new IndicatorComp[2];
Component[1] = new IndicatorComp { Value = new double[Bars] };
for (var bar = firstBar; bar < Bars; bar++)
{
var value = shiftedVWAP[bar - previous];
var previousValue = shiftedVWAP[bar - previous - 1];
var open = Open[bar];
var tempVal = value;
if (High[bar - 1] < previousValue && open > value ||
Low[bar - 1] > previousValue && open < value ||
Close[bar - 1] < value && open > value ||
Close[bar - 1] > value && open < value)
tempVal = open;
Component[1].Value[bar] = tempVal;
}
}
else
{
Component = new IndicatorComp[3];
Component[1] = new IndicatorComp
{
ChartType = IndChartType.NoChart,
FirstBar = firstBar,
Value = new double[Bars]
};
Component[2] = new IndicatorComp
{
ChartType = IndChartType.NoChart,
FirstBar = firstBar,
Value = new double[Bars]
};
}
Component[0] = new IndicatorComp
{
CompName = "VWAP Value",
DataType = IndComponentType.IndicatorValue,
ChartType = IndChartType.Line,
ChartColor = Color.Blue,
FirstBar = firstBar,
Value = shiftedVWAP
};
switch (SlotType)
{
case SlotTypes.Open:
Component[1].CompName = "Position opening price";
Component[1].DataType = IndComponentType.OpenPrice;
break;
case SlotTypes.OpenFilter:
Component[1].DataType = IndComponentType.AllowOpenLong;
Component[1].CompName = "Is long entry allowed";
Component[2].DataType = IndComponentType.AllowOpenShort;
Component[2].CompName = "Is short entry allowed";
break;
case SlotTypes.Close:
Component[1].CompName = "Position closing price";
Component[1].DataType = IndComponentType.ClosePrice;
break;
case SlotTypes.CloseFilter:
Component[1].DataType = IndComponentType.ForceCloseLong;
Component[1].CompName = "Close out long position";
Component[2].DataType = IndComponentType.ForceCloseShort;
Component[2].CompName = "Close out short position";
break;
}
if (SlotType == SlotTypes.OpenFilter || SlotType == SlotTypes.CloseFilter)
{
switch (IndParam.ListParam[0].Text)
{
case "VWAP rises":
IndicatorRisesLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "VWAP falls":
IndicatorFallsLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The bar opens above VWAP":
BarOpensAboveIndicatorLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The bar opens below VWAP":
BarOpensBelowIndicatorLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The bar opens above VWAP after opening below it":
BarOpensAboveIndicatorAfterOpeningBelowLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The bar opens below VWAP after opening above it":
BarOpensBelowIndicatorAfterOpeningAboveLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The position opens above VWAP":
Component[0].PosPriceDependence = PositionPriceDependence.BuyHigherSellLower;
Component[1].DataType = IndComponentType.Other;
Component[1].ShowInDynInfo = false;
Component[2].DataType = IndComponentType.Other;
Component[2].ShowInDynInfo = false;
break;
case "The position opens below VWAP":
Component[0].PosPriceDependence = PositionPriceDependence.BuyLowerSellHigher;
Component[1].DataType = IndComponentType.Other;
Component[1].ShowInDynInfo = false;
Component[2].DataType = IndComponentType.Other;
Component[2].ShowInDynInfo = false;
break;
case "The bar closes below VWAP":
BarClosesBelowIndicatorLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
case "The bar closes above VWAP":
BarClosesAboveIndicatorLogic(firstBar, previous, shiftedVWAP, ref Component[1], ref Component[2]);
break;
}
}
}
public override void SetDescription()
{
EntryPointLongDescription = "at " + ToString();
EntryPointShortDescription = "at " + ToString();
ExitPointLongDescription = "at " + ToString();
ExitPointShortDescription = "at " + ToString();
switch (IndParam.ListParam[0].Text)
{
case "VWAP rises":
EntryFilterLongDescription = ToString() + " rises";
EntryFilterShortDescription = ToString() + " falls";
ExitFilterLongDescription = ToString() + " rises";
ExitFilterShortDescription = ToString() + " falls";
break;
case "VWAP falls":
EntryFilterLongDescription = ToString() + " falls";
EntryFilterShortDescription = ToString() + " rises";
ExitFilterLongDescription = ToString() + " falls";
ExitFilterShortDescription = ToString() + " rises";
break;
case "The bar opens above VWAP":
EntryFilterLongDescription = "the bar opens above the " + ToString();
EntryFilterShortDescription = "the bar opens below the " + ToString();
break;
case "The bar opens below VWAP":
EntryFilterLongDescription = "the bar opens below the " + ToString();
EntryFilterShortDescription = "the bar opens above the " + ToString();
break;
case "The position opens above VWAP":
EntryFilterLongDescription = "the position opening price is higher than the " + ToString();
EntryFilterShortDescription = "the position opening price is lower than the " + ToString();
break;
case "The position opens below VWAP":
EntryFilterLongDescription = "the position opening price is lower than the " + ToString();
EntryFilterShortDescription = "the position opening price is higher than the " + ToString();
break;
case "The bar opens above VWAP after opening below it":
EntryFilterLongDescription = "the bar opens above the " + ToString() + " after opening below it";
EntryFilterShortDescription = "the bar opens below the " + ToString() + " after opening above it";
break;
case "The bar opens below VWAP after opening above it":
EntryFilterLongDescription = "the bar opens below the " + ToString() + " after opening above it";
EntryFilterShortDescription = "the bar opens above the " + ToString() + " after opening below it";
break;
case "The bar closes above VWAP":
ExitFilterLongDescription = "the bar closes above the " + ToString();
ExitFilterShortDescription = "the bar closes below the " + ToString();
break;
case "The bar closes below VWAP":
ExitFilterLongDescription = "the bar closes below the " + ToString();
ExitFilterShortDescription = "the bar closes above the " + ToString();
break;
}
}
public override string ToString()
{
return string.Format("{0}{1} ({2}, {3})",
IndicatorName,
IndParam.CheckParam[0].Checked ? "*" : "",
IndParam.NumParam[0].ValueToString,
IndParam.NumParam[1].ValueToString);
}
}
}
#property copyright "NAYA 2025." #property link "NAYA +237674724684" #property version "1.0" #property strict #include <Forexsb.com/Indicator.mqh> #include <Forexsb.com/Enumerations.mqh> //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class VWAP : public Indicator { public: VWAP(SlotTypes slotType) { SlotType=slotType; IndicatorName="VWAP"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = false; IsDiscreteValues = false; IsDefaultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void VWAP::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); int period=(int) NumParam[0].Value; int shift =(int) NumParam[1].Value; int previous=CheckParam[0].Checked ? 1 : 0; ExecTime=ExecutionTime_DuringTheBar; // Calculate average price (OHLC/4) double avgPrice[]; ArrayResize(avgPrice, Data.Bars); for(int i = 0; i < Data.Bars; i++) { avgPrice[i] = (Data.Open[i] + Data.High[i] + Data.Low[i] + Data.Close[i]) / 4; } // Calculate VWAP double vwap[]; ArrayResize(vwap, Data.Bars); for(int bar = period; bar < Data.Bars; bar++) { double sumPV = 0; double sumV = 0; for(int i = bar - period + 1; i <= bar; i++) { sumPV += avgPrice[i] * Data.Volume[i]; sumV += Data.Volume[i]; } vwap[bar] = sumV != 0 ? sumPV / sumV : avgPrice[bar]; } // Apply shift double shiftedVWAP[]; ArrayResize(shiftedVWAP, Data.Bars); for(int bar = 0; bar < Data.Bars; bar++) { if(bar >= shift) shiftedVWAP[bar] = vwap[bar - shift]; else shiftedVWAP[bar] = vwap[0]; } int firstBar=period+shift+previous+2; if(SlotType==SlotTypes_Open || SlotType==SlotTypes_Close) { ArrayResize(Component[1].Value,Data.Bars); ArrayInitialize(Component[1].Value,0); for(int bar=firstBar; bar<Data.Bars; bar++) { // Covers the cases when the price can pass through the VWAP without a signal double value = shiftedVWAP[bar-previous]; // Current value double value1 = shiftedVWAP[bar-previous-1]; // Previous value double tempVal = value; if((value1 > Data.High[bar - 1] && value < Data.Open[bar]) || // The Data.Open price jumps above the indicator (value1 < Data.Low[bar - 1] && value > Data.Open[bar]) || // The Data.Open price jumps below the indicator (Data.Close[bar-1]<value && value < Data.Open[bar]) || // The Data.Open price is in a positive gap (Data.Close[bar-1]>value && value>Data.Open[bar])) // The Data.Open price is in a negative gap tempVal=Data.Open[bar]; Component[1].Value[bar]=tempVal; // Entry or exit value } } else { ArrayResize(Component[1].Value, Data.Bars); ArrayResize(Component[2].Value, Data.Bars); } ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "VWAP Value"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = firstBar; ArrayCopy(Component[0].Value,shiftedVWAP); if(SlotType==SlotTypes_Open) { Component[1].CompName = "Position opening price"; Component[1].DataType = IndComponentType_OpenPrice; } if(SlotType==SlotTypes_OpenFilter) { Component[1].DataType = IndComponentType_AllowOpenLong; Component[1].CompName = "Is long entry allowed"; Component[2].DataType = IndComponentType_AllowOpenShort; Component[2].CompName = "Is short entry allowed"; } if(SlotType==SlotTypes_Close) { Component[1].CompName = "Position closing price"; Component[1].DataType = IndComponentType_ClosePrice; } if(SlotType==SlotTypes_CloseFilter) { Component[1].DataType = IndComponentType_ForceCloseLong; Component[1].CompName = "Close out long position"; Component[2].DataType = IndComponentType_ForceCloseShort; Component[2].CompName = "Close out short position"; } if(SlotType==SlotTypes_OpenFilter || SlotType==SlotTypes_CloseFilter) { if(ListParam[0].Text=="VWAP rises") IndicatorRisesLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="VWAP falls") IndicatorFallsLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar opens above VWAP") BarOpensAboveIndicatorLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar opens below VWAP") BarOpensBelowIndicatorLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar opens above VWAP after opening below it") BarOpensAboveIndicatorAfterOpeningBelowLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar opens below VWAP after opening above it") BarOpensBelowIndicatorAfterOpeningAboveLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="VWAP changes its direction upward") IndicatorChangesItsDirectionUpward(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="VWAP changes its direction downward") IndicatorChangesItsDirectionDownward(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The position opens above VWAP") { Component[0].PosPriceDependence=PositionPriceDependence_BuyHigherSellLower; Component[1].DataType=IndComponentType_Other; Component[1].ShowInDynInfo=false; Component[2].DataType=IndComponentType_Other; Component[2].ShowInDynInfo=false; } else if(ListParam[0].Text=="The position opens below VWAP") { Component[0].PosPriceDependence=PositionPriceDependence_BuyLowerSellHigher; Component[1].DataType=IndComponentType_Other; Component[1].ShowInDynInfo=false; Component[2].DataType=IndComponentType_Other; Component[2].ShowInDynInfo=false; } else if(ListParam[0].Text=="The bar closes below VWAP") BarClosesBelowIndicatorLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar closes above VWAP") BarClosesAboveIndicatorLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar closes above VWAP after closing below it") BarClosesAboveIndicatorAfterClosingBelowLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); else if(ListParam[0].Text=="The bar closes below VWAP after closing above it") BarClosesBelowIndicatorAfterClosingAboveLogic(firstBar,previous,shiftedVWAP,Component[1],Component[2]); } } //+------------------------------------------------------------------+
Risk warning: Forex, spread bets and CFD are leveraged products. They may not be suitable for you as they carry a high degree of risk to your capital and you can lose more than your initial investment. You should ensure you understand all of the risks.
Copyright © 2006 - 2025, Forex Software Ltd.;
Copyright © 2006 - 2025, Forex Software Ltd.;