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.;