Category Trend  Published on 19/02/2021

VWAP

Description

VWAP with anchored option for daily weekly and monthly.

CREDIT to SOL Digital Consultoria LTDA   MQL5.

UPATE 11/02/2021 VERSION 1.2 (Bug fix)

UPATE 19/02/2021 VERSION 1.3 (Bug fix)

 

 


using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using System.Linq;
using System.Collections.Generic;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class VWAPAnchor : Indicator
    {

        [Parameter(DefaultValue = PRICE_TYPE.CLOSE_HIGH_LOW)]
        public PRICE_TYPE Price_Type { get; set; }

        [Parameter("Enable_Daily", DefaultValue = true)]
        public bool Enable_Daily { get; set; }

        [Parameter("Enable_Weekly", DefaultValue = false)]
        public bool Enable_Weekly { get; set; }

        [Parameter("Enable_Monthly", DefaultValue = false)]
        public bool Enable_Monthly { get; set; }

        [Parameter("Enable_Level_01", DefaultValue = false)]
        public bool Enable_Level_01 { get; set; }

        [Parameter("VWAP_Level_01_Period", DefaultValue = 5)]
        public int VWAP_Level_01_Period { get; set; }

        [Parameter("Enable_Level_02", DefaultValue = false)]
        public bool Enable_Level_02 { get; set; }

        [Parameter("VWAP_Level_02_Period", DefaultValue = 13)]
        public int VWAP_Level_02_Period { get; set; }

        [Parameter("Enable_Level_03", DefaultValue = false)]
        public bool Enable_Level_03 { get; set; }

        [Parameter("VWAP_Level_03_Period", DefaultValue = 20)]
        public int VWAP_Level_03_Period { get; set; }

        [Parameter("Enable_Level_04", DefaultValue = false)]
        public bool Enable_Level_04 { get; set; }

        [Parameter("VWAP_Level_04_Period", DefaultValue = 30)]
        public int VWAP_Level_04_Period { get; set; }

        [Parameter("Enable_Level_05", DefaultValue = false)]
        public bool Enable_Level_05 { get; set; }

        [Parameter("VWAP_Level_05_Period", DefaultValue = 40)]
        public int VWAP_Level_05_Period { get; set; }

        [Output("VWAP_Buffer_Daily", LineColor = "Blue")]
        public IndicatorDataSeries VWAP_Buffer_Daily { get; set; }

        [Output("VWAP_Buffer_Weekly", LineColor = "Red")]
        public IndicatorDataSeries VWAP_Buffer_Weekly { get; set; }

        [Output("VWAP_Buffer_Monthly", LineColor = "Yellow")]
        public IndicatorDataSeries VWAP_Buffer_Monthly { get; set; }

        //[Output("Under", LineColor = "Red")]
        //public IndicatorDataSeries Under { get; set; }

        //[Output("Over", LineColor = "LimeGreen")]
        //public IndicatorDataSeries Over { get; set; }

        [Output("VWAP_Buffer_01")]
        public IndicatorDataSeries VWAP_Buffer_01 { get; set; }

        [Output("VWAP_Buffer_02")]
        public IndicatorDataSeries VWAP_Buffer_02 { get; set; }

        [Output("VWAP_Buffer_03")]
        public IndicatorDataSeries VWAP_Buffer_03 { get; set; }

        [Output("VWAP_Buffer_04")]
        public IndicatorDataSeries VWAP_Buffer_04 { get; set; }

        [Output("VWAP_Buffer_05")]
        public IndicatorDataSeries VWAP_Buffer_05 { get; set; }


        public double[] nPriceArr { get; set; }

        public double[] nTotalTPV { get; set; }

        public double[] nTotalVol { get; set; }

        private DateTime lastTime;

        double nSumDailyTPV = 0, nSumWeeklyTPV = 0, nSumMonthlyTPV = 0;
        double nSumDailyVol = 0, nSumWeeklyVol = 0, nSumMonthlyVol = 0;



        int nIdxDaily = 0, nIdxWeekly = 0, nIdxMonthly = 0, nIdx = 0;
        DateTime dtLastDay = CreateDateTime(DATE_TYPE.DAILY), dtLastWeek = CreateDateTime(DATE_TYPE.WEEKLY), dtLastMonth = CreateDateTime(DATE_TYPE.MONTHLY);


        protected override void Initialize()
        {
            if (Enable_Daily)
            {
                nIdx = nIdxDaily;
                nSumDailyTPV = 0;
                nSumDailyVol = 0;
            }
            if (Enable_Weekly)
            {
                nIdx = nIdxWeekly;
                nSumWeeklyTPV = 0;
                nSumWeeklyVol = 0;
            }
            if (Enable_Monthly)
            {
                nIdx = nIdxMonthly;
                nSumMonthlyTPV = 0;
                nSumMonthlyVol = 0;
            }

            nPriceArr = new double[Int16.MaxValue];
            nTotalTPV = new double[Int16.MaxValue];
            nTotalVol = new double[Int16.MaxValue];

        }

        private bool NewBar(int index)
        {
            if (lastTime != Bars.OpenTimes[index])
            {
                lastTime = Bars.OpenTimes[index];
                return true;
            }

            return false;
        }
        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = ...
            // if (IsLastBar) return;

            if (!NewBar(index))
                return;

            index = index - 1;

            if (CreateDateTime(DATE_TYPE.DAILY, Bars.OpenTimes[index]) != dtLastDay)
            {
                nIdxDaily = index;
                nSumDailyTPV = 0;
                nSumDailyVol = 0;
            }
            if (CreateDateTime(DATE_TYPE.WEEKLY, Bars.OpenTimes[index]) != dtLastWeek)
            {
                nIdxWeekly = index;
                nSumWeeklyTPV = 0;
                nSumWeeklyVol = 0;
            }
            if (CreateDateTime(DATE_TYPE.MONTHLY, Bars.OpenTimes[index]) != dtLastMonth)
            {
                nIdxMonthly = index;
                nSumMonthlyTPV = 0;
                nSumMonthlyVol = 0;
            }

            switch (Price_Type)
            {
                case PRICE_TYPE.OPEN:
                    nPriceArr[index] = Bars.OpenPrices[index];
                    break;
                case PRICE_TYPE.CLOSE:
                    nPriceArr[index] = Bars.ClosePrices[index];
                    break;
                case PRICE_TYPE.HIGH:
                    nPriceArr[index] = Bars.HighPrices[index];
                    break;
                case PRICE_TYPE.LOW:
                    nPriceArr[index] = Bars.LowPrices[index];
                    break;
                case PRICE_TYPE.HIGH_LOW:
                    nPriceArr[index] = (Bars.HighPrices[index] + Bars.LowPrices[index]) / 2;
                    break;
                case PRICE_TYPE.OPEN_CLOSE:
                    nPriceArr[index] = (Bars.OpenPrices[index] + Bars.ClosePrices[index]) / 2;
                    break;
                case PRICE_TYPE.CLOSE_HIGH_LOW:
                    nPriceArr[index] = (Bars.ClosePrices[index] + Bars.HighPrices[index] + Bars.LowPrices[index]) / 3;
                    break;
                case PRICE_TYPE.OPEN_CLOSE_HIGH_LOW:
                    nPriceArr[index] = (Bars.OpenPrices[index] + Bars.ClosePrices[index] + Bars.HighPrices[index] + Bars.LowPrices[index]) / 4;
                    break;
                default:
                    nPriceArr[index] = (Bars.ClosePrices[index] + Bars.HighPrices[index] + Bars.LowPrices[index]) / 3;
                    break;
            }


            if (Bars.TickVolumes[index] > 0.0)
            {
                nTotalTPV[index] = (nPriceArr[index] * Bars.TickVolumes[index]);
                nTotalVol[index] = (double)Bars.TickVolumes[index];
            }
            if (Enable_Daily && (index >= nIdxDaily))
            {
                try
                {
                    nSumDailyTPV += nTotalTPV[index];
                    nSumDailyVol += nTotalVol[index];

                    if (nSumDailyVol > 0)
                        VWAP_Buffer_Daily[index] = (nSumDailyTPV / nSumDailyVol);

                    Print(string.Format("{0} Sum vol {1} Vwap {2} Index {3}", nSumDailyTPV, nSumDailyVol, nSumDailyTPV / nSumDailyVol, index));
                } catch (Exception e)
                {
                    Print(string.Format("{0}", e.Message));
                }
            }
            if (Enable_Weekly && (index >= nIdxWeekly))
            {
                nSumWeeklyTPV += nTotalTPV[index];
                nSumWeeklyVol += nTotalVol[index];

                if (nSumWeeklyVol > 0)
                    VWAP_Buffer_Weekly[index] = (nSumWeeklyTPV / nSumWeeklyVol);
            }
            if (Enable_Monthly && (index >= nIdxMonthly))
            {
                nSumMonthlyTPV += nTotalTPV[index];
                nSumMonthlyVol += nTotalVol[index];

                if (nSumMonthlyVol > 0)
                    VWAP_Buffer_Monthly[index] = (nSumMonthlyTPV / nSumMonthlyVol);

                //if (VWAP_Buffer_Monthly[index] < VWAP_Buffer_Monthly[index - 1])
                //{
                //    Under[index] = VWAP_Buffer_Monthly[index];
                //    Under[index - 1] = VWAP_Buffer_Monthly[index - 1];


                //}
                //if (VWAP_Buffer_Monthly[index] > VWAP_Buffer_Monthly[index - 1])
                //{
                //    Over[index] = VWAP_Buffer_Monthly[index];
                //    Over[index - 1] = VWAP_Buffer_Monthly[index - 1];

                //}
            }
            dtLastDay = CreateDateTime(DATE_TYPE.DAILY, Bars.OpenTimes[index]);
            dtLastWeek = CreateDateTime(DATE_TYPE.WEEKLY, Bars.OpenTimes[index]);
            dtLastMonth = CreateDateTime(DATE_TYPE.MONTHLY, Bars.OpenTimes[index]);


            if (Enable_Level_01)
            {
                int nStartPos = (index > VWAP_Level_01_Period) ? (index) : VWAP_Level_01_Period;
                for (nIdx = nStartPos; nIdx < Bars.Count; nIdx++)
                {
                    double nSumTotalTPV = 0;
                    double nSumTotalVol = 0;
                    VWAP_Buffer_01[nIdx] = 0;

                    for (int nSubIdx = 1; nSubIdx < VWAP_Level_01_Period; nSubIdx++)
                    {
                        nSumTotalTPV += nTotalTPV[nIdx - nSubIdx];
                        nSumTotalVol += nTotalVol[nIdx - nSubIdx];
                    }
                    if (nSumTotalVol > 0)
                        VWAP_Buffer_01[nIdx] = (nSumTotalTPV / nSumTotalVol);
                    else
                        VWAP_Buffer_01[nIdx] = 0;

                }
            }
            if (Enable_Level_02)
            {
                int nStartPos = (index > VWAP_Level_02_Period) ? (index) : VWAP_Level_02_Period;
                for (nIdx = nStartPos; nIdx < Bars.Count; nIdx++)
                {
                    double nSumTotalTPV = 0;
                    double nSumTotalVol = 0;
                    VWAP_Buffer_02[nIdx] = 0;

                    for (int nSubIdx = 1; nSubIdx < VWAP_Level_02_Period; nSubIdx++)
                    {
                        nSumTotalTPV += nTotalTPV[nIdx - nSubIdx];
                        nSumTotalVol += nTotalVol[nIdx - nSubIdx];
                    }
                    if (nSumTotalVol > 0)
                        VWAP_Buffer_02[nIdx] = (nSumTotalTPV / nSumTotalVol);
                    else
                        VWAP_Buffer_02[nIdx] = 0;

                }
            }
            if (Enable_Level_03)
            {
                int nStartPos = (index > VWAP_Level_03_Period) ? (index) : VWAP_Level_03_Period;
                for (nIdx = nStartPos; nIdx < Bars.Count; nIdx++)
                {
                    double nSumTotalTPV = 0;
                    double nSumTotalVol = 0;
                    VWAP_Buffer_03[nIdx] = 0;

                    for (int nSubIdx = 1; nSubIdx < VWAP_Level_03_Period; nSubIdx++)
                    {
                        nSumTotalTPV += nTotalTPV[nIdx - nSubIdx];
                        nSumTotalVol += nTotalVol[nIdx - nSubIdx];
                    }
                    if (nSumTotalVol > 0)
                        VWAP_Buffer_03[nIdx] = (nSumTotalTPV / nSumTotalVol);
                    else
                        VWAP_Buffer_03[nIdx] = 0;

                }
            }
            if (Enable_Level_04)
            {
                int nStartPos = (index > VWAP_Level_04_Period) ? (index) : VWAP_Level_04_Period;
                for (nIdx = nStartPos; nIdx < Bars.Count; nIdx++)
                {
                    double nSumTotalTPV = 0;
                    double nSumTotalVol = 0;
                    VWAP_Buffer_04[nIdx] = 0;

                    for (int nSubIdx = 1; nSubIdx < VWAP_Level_04_Period; nSubIdx++)
                    {
                        nSumTotalTPV += nTotalTPV[nIdx - nSubIdx];
                        nSumTotalVol += nTotalVol[nIdx - nSubIdx];
                    }
                    if (nSumTotalVol > 0)
                        VWAP_Buffer_04[nIdx] = (nSumTotalTPV / nSumTotalVol);
                    else
                        VWAP_Buffer_04[nIdx] = 0;

                }
                if (Enable_Level_05)
                {
                    nStartPos = (index > VWAP_Level_05_Period) ? (index) : VWAP_Level_05_Period;
                    for (nIdx = nStartPos; nIdx < Bars.Count; nIdx++)
                    {
                        double nSumTotalTPV = 0;
                        double nSumTotalVol = 0;
                        VWAP_Buffer_05[nIdx] = 0;

                        for (int nSubIdx = 1; nSubIdx < VWAP_Level_05_Period; nSubIdx++)
                        {
                            nSumTotalTPV += nTotalTPV[nIdx - nSubIdx];
                            nSumTotalVol += nTotalVol[nIdx - nSubIdx];
                        }
                        if (nSumTotalVol > 0)
                            VWAP_Buffer_05[nIdx] = (nSumTotalTPV / nSumTotalVol);
                        else
                            VWAP_Buffer_05[nIdx] = 0;

                    }
                }

            }
        }
        public static DateTime CreateDateTime(DATE_TYPE nReturnType = DATE_TYPE.DAILY, DateTime? dtDay = null, int pHour = 0, int pMinute = 0, int pSecond = 0)
        {
            DateTime dtReturnDate;

            if (!dtDay.HasValue)
                return DateTime.MinValue;

            dtReturnDate = new DateTime(dtDay.Value.Year, dtDay.Value.Month, dtDay.Value.Day, pHour, pMinute, pSecond);

            if (nReturnType == DATE_TYPE.WEEKLY)
            {
                if (dtReturnDate.DayOfWeek != 0)
                {
                    dtReturnDate = dtReturnDate.StartOfWeek(DayOfWeek.Monday);

                }
            }

            if (nReturnType == DATE_TYPE.MONTHLY)
            {

                dtReturnDate = new DateTime(dtDay.Value.Year, dtDay.Value.Month, 1);
            }

            return dtReturnDate;
        }

    }
    public static class DateTimeExtensions
    {
        public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
        {
            int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
            return dt.AddDays(-1 * diff).Date;
        }
    }

    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    public enum DATE_TYPE
    {
        DAILY,
        WEEKLY,
        MONTHLY
    }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    public enum PRICE_TYPE
    {
        OPEN,
        CLOSE,
        HIGH,
        LOW,
        OPEN_CLOSE,
        HIGH_LOW,
        CLOSE_HIGH_LOW,
        OPEN_CLOSE_HIGH_LOW
    }



}


CT
ctid1744086

Joined on 10.02.2021

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: VWAP-Anchored.algo
  • Rating: 5
  • Installs: 2773
  • Modified: 13/10/2021 09:54
Comments
Log in to add a comment.
CT
ctid7880129 · 3 months ago

Works as expected, Thanks.

One improvement idea; A timezone support would be nice to have as the daily switches at UTC+0 and not at e.g. London UTC+1 or Berlin UTC+1/+2 (Summer/Winter).

 

ST
stdujer · 10 months ago

Excellent! Thank you