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
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
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).