Category Trend  Published on 27/10/2023

Anchored VWAP

Description

VWAP and 2 Bands, anchored by: h1, h4, h8, h12, D1, W1, Month1.

Designed for Performance.

 

Settings:

Anchor: choose from h1, h4, h8, h12, D1, W1, Month1. E.g, if you choose h4, the VWAP and Bands are reset and calculated every 4 hours. Default is D1 (every day).

Factor1, Factor2: the multiplier factor when calculate the bands.

The source code is fully published.


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

namespace cAlgo
{
    [Indicator(IsOverlay = true, AutoRescale = true, AccessRights = AccessRights.None)]
    public class LT_Ind_VWAP : Indicator
    {
        [Parameter(DefaultValue = Anchors.D1)]
        public Anchors Anchor { get; set; }
        [Parameter(DefaultValue = 1.0)]
        public double Factor1 { get; set; }
        [Parameter(DefaultValue = 2.0)]
        public double Factor2 { get; set; }


        [Output("UpBand2", LineColor = "Red", LineStyle = LineStyle.Dots)]
        public IndicatorDataSeries UpBand2 { get; set; }
        [Output("UpBand1", LineColor = "Red")]
        public IndicatorDataSeries UpBand1 { get; set; }
        [Output("Vwap", LineColor = "Orange")]
        public IndicatorDataSeries Vwap { get; set; }
        [Output("DnBand1", LineColor = "Blue")]
        public IndicatorDataSeries DnBand1 { get; set; }
        [Output("DnBand2", LineColor = "Blue", LineStyle = LineStyle.Dots)]
        public IndicatorDataSeries DnBand2 { get; set; }

        Bars _hiBars;
        protected override void Initialize()
        {
            _hiBars = MarketData.GetBars(TimeFrame.Parse(Anchor.ToString()));
            _vwap.Reset();
        }

        Vwap _vwap = new Vwap();
        int _lastIndex = -1;
        int _lastIndexHigher = -1;
        public override void Calculate(int index)
        {
            var indexHigher = _hiBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            if (_lastIndexHigher != indexHigher)
            {
                _vwap.Reset();
                _lastIndexHigher = indexHigher;
            }

            if (_lastIndex != index && index > 0)
            {
                // Cal up to last bar and update permanent
                Cal(index - 1, true);

                _lastIndex = index;
            }

            // Temporary cal at cur index
            Cal(index, false);

        }

        void Cal(int index, bool updateCum)
        {
            (double vwap, double std) cal = _vwap.Cal(Bars.TickVolumes[index], Bars.TypicalPrices[index], updateCum);
            Vwap[index] = cal.vwap;
            UpBand1[index] = cal.vwap + Factor1 * cal.std;
            DnBand1[index] = cal.vwap - Factor1 * cal.std;
            UpBand2[index] = cal.vwap + Factor2 * cal.std;
            DnBand2[index] = cal.vwap - Factor2 * cal.std;

        }

    }

    public class Vwap
    {
        /// <summary>
        /// Cummulation volume
        /// </summary>
        public double CumVol { get; set; }

        /// <summary>
        /// Cumulation price * volume
        /// </summary>
        public double CumPriceVol { get; set; }

        /// <summary>
        /// Cumulation Square of Diff (xi - xbar)2
        /// </summary>
        public double CumSqrDiff { get; set; }

        /// <summary>
        /// Cumulation Population Size
        /// </summary>
        public int CumPSize { get; set; }

        public void Reset()
        {
            CumVol = 0; CumPriceVol = 0; CumSqrDiff = 0; CumPSize = 0;
        }

        /// <summary>
        /// Calculate vwap and std
        /// </summary>
        /// <param name="tickVol"></param>
        /// <param name="price"></param>
        /// <param name="updateCum"></param>
        /// <returns></returns>
        public (double vwap, double std) Cal(double tickVol, double price, bool updateCum = false)
        {
            var cumVol = tickVol + CumVol;
            var cumPriceVol = price * tickVol + CumPriceVol;

            var vwap = cumVol == 0 ? price : cumPriceVol / cumVol;
            var cumSqrDiff = Math.Pow(price - vwap, 2) + CumSqrDiff;
            var cumPSize = 1 + CumPSize;

            if (updateCum)
            {
                CumVol = cumVol; CumPriceVol = cumPriceVol; CumSqrDiff = cumSqrDiff; CumPSize = cumPSize;
            }

            var std = Math.Sqrt(cumSqrDiff / cumPSize);
            return (vwap, std);
        }

    }

    public enum Anchors { h1, h4, h8, h12, D1, W1, Month1 };


}

dhnhuy's avatar
dhnhuy

Joined on 03.04.2023

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: LT_Ind_VWAP.algo
  • Rating: 5
  • Installs: 719
Comments
Log in to add a comment.
DY
dylandaviss123 · 6 months ago

Good indicator. I've been using indicators at TradingView.

mfejza's avatar
mfejza · 8 months ago

Very interesting logic, I like it.