VWAP Crossover by Naya
673 downloads / 301 views / Created: 31.05.2025 Average Rating: 0
Indicator Description
VWAP Crossover Indicator
This technical indicator tracks the relationship between two Volume Weighted Average Price (VWAP) lines - a Fast VWAP and a Slow VWAP - to generate trading signals based on their crossovers and relative positions.
Key Features:
- Uses two VWAP calculations with different periods (Fast and Slow)
- Four signal generation methods:
* Fast VWAP crossing above Slow VWAP
* Fast VWAP crossing below Slow VWAP
* Fast VWAP above Slow VWAP (without crossing)
* Fast VWAP below Slow VWAP (without crossing)
- Customizable periods for both VWAP lines (2-200 bars)
- Adjustable shift parameters (0-2 bars) for each VWAP
- Option to use previous bar's values
Technical Details:
- Calculates VWAP using (Open+High+Low+Close)/4 price average
- Weights prices by volume for accurate average calculation
- Visualized with two colored lines (goldenrod for Fast, red for Slow)
- Works as both entry and exit filter
- Suitable for all timeframes
Usage Scenarios:
- Identifying trend direction changes
- Confirming momentum shifts
- Filtering trade entries/exits
- Combining with other indicators for strategy development
Parameters:
- Fast VWAP period (default: 13)
- Slow VWAP period (default: 21)
- Fast VWAP shift (default: 0)
- Slow VWAP shift (default: 0)
- Previous bar option (default: off)
**Visualization:**
- Fast VWAP appears as goldenrod line
- Slow VWAP appears as red line
- Signals generated at crossovers or when lines diverge
Created witht 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 VWAPCrossover : Indicator
{
public VWAPCrossover()
{
IndicatorName = "VWAP Crossover";
PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter;
IndicatorAuthor = "NAYA +237674724684";
IndicatorVersion = "1.0";
IndicatorDescription = "Volume Weighted Average Price Crossover based on OHLC average.";
}
public override void Initialize(SlotTypes slotType)
{
SlotType = slotType;
// The ComboBox parameters
IndParam.ListParam[0].Caption = "Logic";
IndParam.ListParam[0].ItemList = new[]
{
"Fast VWAP crosses Slow VWAP upward",
"Fast VWAP crosses Slow VWAP downward",
"Fast VWAP is higher than Slow VWAP",
"Fast VWAP is lower than Slow VWAP"
};
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 the indicator.";
// The NumericUpDown parameters
IndParam.NumParam[0].Caption = "Fast VWAP period";
IndParam.NumParam[0].Value = 13;
IndParam.NumParam[0].Min = 2;
IndParam.NumParam[0].Max = 200;
IndParam.NumParam[0].Enabled = true;
IndParam.NumParam[0].ToolTip = "The period of Fast VWAP.";
IndParam.NumParam[1].Caption = "Slow VWAP period";
IndParam.NumParam[1].Value = 21;
IndParam.NumParam[1].Min = 2;
IndParam.NumParam[1].Max = 200;
IndParam.NumParam[1].Enabled = true;
IndParam.NumParam[1].ToolTip = "The period of Slow VWAP.";
IndParam.NumParam[2].Caption = "Fast VWAP shift";
IndParam.NumParam[2].Value = 0;
IndParam.NumParam[2].Min = 0;
IndParam.NumParam[2].Max = 2;
IndParam.NumParam[2].Point = 0;
IndParam.NumParam[2].Enabled = true;
IndParam.NumParam[2].ToolTip = "The shifting value of Fast VWAP.";
IndParam.NumParam[3].Caption = "Slow VWAP shift";
IndParam.NumParam[3].Value = 0;
IndParam.NumParam[3].Min = 0;
IndParam.NumParam[3].Max = 2;
IndParam.NumParam[3].Point = 0;
IndParam.NumParam[3].Enabled = true;
IndParam.NumParam[3].ToolTip = "The shifting value of Slow VWAP.";
// 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.";
}
private double[] CalculateVWAP(int period, int shift)
{
// Calculate average price (OHLC/4)
double[] avgPrice = new double[Bars];
for (int i = 0; i < Bars; i++)
{
avgPrice[i] = (Open[i] + High[i] + Low[i] + Close[i]) / 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];
}
return shiftedVWAP;
}
public override void Calculate(IDataSet dataSet)
{
DataSet = dataSet;
// Reading the parameters
var periodFast = (int)IndParam.NumParam[0].Value;
var periodSlow = (int)IndParam.NumParam[1].Value;
var shiftFast = (int)IndParam.NumParam[2].Value;
var shiftSlow = (int)IndParam.NumParam[3].Value;
int previous = IndParam.CheckParam[0].Checked ? 1 : 0;
int firstBar = Math.Max(periodFast + shiftFast, periodSlow + shiftSlow) + previous + 2;
double[] vwapFast = CalculateVWAP(periodFast, shiftFast);
double[] vwapSlow = CalculateVWAP(periodSlow, shiftSlow);
var vwapOscillator = new double[Bars];
for (int bar = firstBar; bar < Bars; bar++)
{
vwapOscillator[bar] = vwapFast[bar] - vwapSlow[bar];
}
// Saving the components
Component = new IndicatorComp[4];
Component[0] = new IndicatorComp
{
CompName = "Fast VWAP",
ChartColor = Color.Goldenrod,
DataType = IndComponentType.IndicatorValue,
ChartType = IndChartType.Line,
FirstBar = firstBar,
Value = vwapFast
};
Component[1] = new IndicatorComp
{
CompName = "Slow VWAP",
ChartColor = Color.IndianRed,
DataType = IndComponentType.IndicatorValue,
ChartType = IndChartType.Line,
FirstBar = firstBar,
Value = vwapSlow
};
Component[2] = new IndicatorComp
{
ChartType = IndChartType.NoChart,
FirstBar = firstBar,
Value = new double[Bars]
};
Component[3] = new IndicatorComp
{
ChartType = IndChartType.NoChart,
FirstBar = firstBar,
Value = new double[Bars]
};
// Sets the Component's type
if (SlotType == SlotTypes.OpenFilter)
{
Component[2].DataType = IndComponentType.AllowOpenLong;
Component[2].CompName = "Is long entry allowed";
Component[3].DataType = IndComponentType.AllowOpenShort;
Component[3].CompName = "Is short entry allowed";
}
else if (SlotType == SlotTypes.CloseFilter)
{
Component[2].DataType = IndComponentType.ForceCloseLong;
Component[2].CompName = "Close out long position";
Component[3].DataType = IndComponentType.ForceCloseShort;
Component[3].CompName = "Close out short position";
}
// Calculation of the logic
var logicRule = IndicatorLogic.It_does_not_act_as_a_filter;
switch (IndParam.ListParam[0].Text)
{
case "Fast VWAP crosses Slow VWAP upward":
logicRule = IndicatorLogic.The_indicator_crosses_the_level_line_upward;
break;
case "Fast VWAP crosses Slow VWAP downward":
logicRule = IndicatorLogic.The_indicator_crosses_the_level_line_downward;
break;
case "Fast VWAP is higher than Slow VWAP":
logicRule = IndicatorLogic.The_indicator_is_higher_than_the_level_line;
break;
case "Fast VWAP is lower than Slow VWAP":
logicRule = IndicatorLogic.The_indicator_is_lower_than_the_level_line;
break;
}
OscillatorLogic(firstBar, previous, vwapOscillator, 0, 0, ref Component[2], ref Component[3], logicRule);
}
public override void SetDescription()
{
EntryFilterLongDescription = ToString() + "; Fast VWAP ";
EntryFilterShortDescription = ToString() + "; Fast VWAP ";
ExitFilterLongDescription = ToString() + "; Fast VWAP ";
ExitFilterShortDescription = ToString() + "; Fast VWAP ";
switch (IndParam.ListParam[0].Text)
{
case "Fast VWAP crosses Slow VWAP upward":
EntryFilterLongDescription += "crosses Slow VWAP upward";
EntryFilterShortDescription += "crosses Slow VWAP downward";
ExitFilterLongDescription += "crosses Slow VWAP upward";
ExitFilterShortDescription += "crosses Slow VWAP downward";
break;
case "Fast VWAP crosses Slow VWAP downward":
EntryFilterLongDescription += "crosses Slow VWAP downward";
EntryFilterShortDescription += "crosses Slow VWAP upward";
ExitFilterLongDescription += "crosses Slow VWAP downward";
ExitFilterShortDescription += "crosses Slow VWAP upward";
break;
case "Fast VWAP is higher than Slow VWAP":
EntryFilterLongDescription += "is higher than Slow VWAP";
EntryFilterShortDescription += "is lower than Slow VWAP";
ExitFilterLongDescription += "is higher than Slow VWAP";
ExitFilterShortDescription += "is lower than Slow VWAP";
break;
case "Fast VWAP is lower than Slow VWAP":
EntryFilterLongDescription += "is lower than Slow VWAP";
EntryFilterShortDescription += "is higher than Slow VWAP";
ExitFilterLongDescription += "is lower than Slow VWAP";
ExitFilterShortDescription += "is higher than Slow VWAP";
break;
}
}
public override string ToString()
{
return IndicatorName +
(IndParam.CheckParam[0].Checked ? "* (" : " (") +
IndParam.NumParam[0].ValueToString + ", " + // Fast VWAP period
IndParam.NumParam[1].ValueToString + ", " + // Slow VWAP period
IndParam.NumParam[2].ValueToString + ", " + // Fast VWAP shift
IndParam.NumParam[3].ValueToString + ")"; // Slow VWAP shift
}
}
}
#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 VWAPCrossover : public Indicator { public: VWAPCrossover(SlotTypes slotType) { SlotType=slotType; IndicatorName="VWAP Crossover"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = false; IsDiscreteValues = false; IsDefaultGroupAll = false; } virtual void Calculate(DataSet &dataSet); private: void CalculateVWAP(int period, int shift, double &vwap[]); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void VWAPCrossover::CalculateVWAP(int period, int shift, double &vwap[]) { ArrayResize(vwap, Data.Bars); ArrayInitialize(vwap, 0); // 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 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 tempVWAP[]; ArrayResize(tempVWAP, Data.Bars); ArrayCopy(tempVWAP, vwap); for(int bar = 0; bar < Data.Bars; bar++) { if(bar >= shift) vwap[bar] = tempVWAP[bar - shift]; else vwap[bar] = tempVWAP[0]; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void VWAPCrossover::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); int iNFastVWAP = (int) NumParam[0].Value; int iNSlowVWAP = (int) NumParam[1].Value; int iSFastVWAP = (int) NumParam[2].Value; int iSSlowVWAP = (int) NumParam[3].Value; int previous=CheckParam[0].Checked ? 1 : 0; int firstBar=MathMax(iNFastVWAP+iSFastVWAP,iNSlowVWAP+iSSlowVWAP)+previous+2; double vwapFast[]; CalculateVWAP(iNFastVWAP, iSFastVWAP, vwapFast); double vwapSlow[]; CalculateVWAP(iNSlowVWAP, iSSlowVWAP, vwapSlow); double oscillator[]; ArrayResize(oscillator,Data.Bars); ArrayInitialize(oscillator,0); for(int bar=firstBar; bar<Data.Bars; bar++) { oscillator[bar]=vwapFast[bar]-vwapSlow[bar]; } ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "Fast VWAP"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = firstBar; ArrayCopy(Component[0].Value,vwapFast); ArrayResize(Component[1].Value,Data.Bars); Component[1].CompName = "Slow VWAP"; Component[1].DataType = IndComponentType_IndicatorValue; Component[1].FirstBar = firstBar; ArrayCopy(Component[1].Value,vwapSlow); ArrayResize(Component[2].Value,Data.Bars); Component[2].FirstBar=firstBar; ArrayResize(Component[3].Value,Data.Bars); Component[3].FirstBar=firstBar; if(SlotType==SlotTypes_OpenFilter) { Component[2].DataType = IndComponentType_AllowOpenLong; Component[2].CompName = "Is long entry allowed"; Component[3].DataType = IndComponentType_AllowOpenShort; Component[3].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[2].DataType = IndComponentType_ForceCloseLong; Component[2].CompName = "Close out long position"; Component[3].DataType = IndComponentType_ForceCloseShort; Component[3].CompName = "Close out short position"; } IndicatorLogic indLogic=IndicatorLogic_It_does_not_act_as_a_filter; if(ListParam[0].Text=="Fast VWAP crosses Slow VWAP upward") indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_upward; else if(ListParam[0].Text=="Fast VWAP crosses Slow VWAP downward") indLogic=IndicatorLogic_The_indicator_crosses_the_level_line_downward; else if(ListParam[0].Text=="Fast VWAP is higher than Slow VWAP") indLogic=IndicatorLogic_The_indicator_is_higher_than_the_level_line; else if(ListParam[0].Text=="Fast VWAP is lower than Slow VWAP") indLogic=IndicatorLogic_The_indicator_is_lower_than_the_level_line; OscillatorLogic(firstBar,previous,oscillator,0,0,Component[2],Component[3],indLogic); } //+------------------------------------------------------------------+
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.;