Description
Volume-Weighted Average Price (VWAP) Indicator
Enhanced version based on the earlier work of cysecsbin.01
- VWAP with Daily, Weekly and Monthly WAPS Indicator and
- VWAP with Bands Indicator
Version history:
v1.0 - initial release
v1.1 - candle coloring added
v1.2 - coloring issue fixed
// VWAP (Volume-Weighted Average Price) v1.0 by VFX
// https://ctrader.com/algos/indicators/show/2693
// Version history:
// v1.0 - initial release
// v1.1 - candle coloring added
// v1.2 - coloring issue fixed
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, AutoRescale = false, TimeZone = TimeZones.CentralEuropeanStandardTime, AccessRights = AccessRights.None)]
public class VWAP : Indicator
{
[Parameter("Time Period", Group = "General", DefaultValue = vwapTimeFrame.Daily)]
public vwapTimeFrame parTF { get; set; }
[Parameter("Thime Shift (Hours)", Group = "General", DefaultValue = 0, MinValue = -12, MaxValue = 12)]
public int parHoursShift { get; set; }
[Parameter("Use Typical Price", Group = "General", DefaultValue = true)]
public bool parUseTypicalPrice { get; set; }
[Parameter("Show RSI Arrow", Group = "General", DefaultValue = true)]
public bool parShowRSIArrow { get; set; }
[Parameter("Candle Coloring", Group = "General", DefaultValue = coloringType.Directional)]
public coloringType parCandleColoring { get; set; }
[Parameter("Show StDevs", Group = "StDev Lines", DefaultValue = false)]
public bool parShowSTDs { get; set; }
[Parameter("Multiplier 1", Group = "StDev Lines", DefaultValue = 1)]
public double parSTD1M { get; set; }
[Parameter("Multiplier 2", Group = "StDev Lines", DefaultValue = 2)]
public double parSTD2M { get; set; }
[Parameter("Multiplier 3", Group = "StDev Lines", DefaultValue = 3)]
public double parSTD3M { get; set; }
[Output("Main", LineColor = "Orange", Thickness = 3, PlotType = PlotType.Points)]
public IndicatorDataSeries Result { get; set; }
[Output("Previous Limit", LineColor = "Orange", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries Previous { get; set; }
[Output("Upper Dev 1", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD1U { get; set; }
[Output("Lower Dev 1", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD1D { get; set; }
[Output("Upper Dev 2", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD2U { get; set; }
[Output("Lower Dev 2", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD2D { get; set; }
[Output("Upper Dev 3", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD3U { get; set; }
[Output("Lower Dev 3", LineColor = "SkyBlue", Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries STD3D { get; set; }
private bool isCurrentData = true, isFullData = true;
private int startIndex, prevStartIndex, prevIndex;
private double cptv, cv, err, prevResult;
private Bars BarsTF;
private RelativeStrengthIndex rsi;
public enum vwapTimeFrame
{
Daily,
Weekly,
Monthly,
Yearly
}
public enum coloringType
{
Directional,
All,
None
}
protected override void Initialize()
{
isCurrentData = false;
isFullData = false;
prevIndex = 0;
startIndex = 0;
prevStartIndex = -1;
cptv = 0;
cv = 0;
err = 0;
prevResult = double.NaN;
if (parShowRSIArrow)
rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14);
BarsTF = MarketData.GetBars(TimeFrame.Daily);
DateTime dayStartTime = BarsTF.OpenTimes[BarsTF.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue.AddHours(-(double)parHoursShift))].AddHours((double)parHoursShift);
DateTime currentStartDate = (parTF == vwapTimeFrame.Yearly ? new DateTime(dayStartTime.Year, 1, 1) : (parTF == vwapTimeFrame.Monthly ? new DateTime(dayStartTime.Year, dayStartTime.Month, 1) : (parTF == vwapTimeFrame.Weekly ? dayStartTime.AddDays(-(((int)dayStartTime.DayOfWeek + 6) % 7)) : dayStartTime))).AddHours(4).Date;
DateTime fullStartDate = (parTF == vwapTimeFrame.Yearly ? currentStartDate.AddYears(-1) : (parTF == vwapTimeFrame.Monthly ? currentStartDate.AddMonths(-1) : (parTF == vwapTimeFrame.Weekly ? currentStartDate.AddDays(-7) : currentStartDate.AddDays(-1))));
if (Bars.OpenTimes[0] <= currentStartDate)
isCurrentData = true;
if (Bars.OpenTimes[0] <= fullStartDate)
isFullData = true;
}
public override void Calculate(int index)
{
if (!isCurrentData)
return;
if (index > prevIndex)
{
DateTime dayStartTime = BarsTF.OpenTimes[BarsTF.OpenTimes.GetIndexByTime(Bars.OpenTimes[index].AddHours(-(double)parHoursShift))].AddHours((double)parHoursShift);
DateTime dayDate = dayStartTime.AddHours(4).Date;
int elapsedDays = (parTF == vwapTimeFrame.Yearly ? dayDate.DayOfYear : (parTF == vwapTimeFrame.Monthly ? dayDate.Day - 1 : (parTF == vwapTimeFrame.Weekly ? ((int)dayDate.DayOfWeek + 6) % 7 : 0)));
startIndex = Bars.OpenTimes.GetIndexByTime(dayStartTime.AddDays(-elapsedDays));
// calculate the final version of the previous point
cptv += Bars.TypicalPrices[index - 1] * Bars.TickVolumes[index - 1];
cv += Bars.TickVolumes[index - 1];
if (cv == 0)
Print("cv = 0");
Result[index - 1] = cptv / cv;
if (parCandleColoring != coloringType.None)
SetBarColor(index - 1);
// Standard Deviation
if (parShowSTDs)
{
err += Math.Pow((parUseTypicalPrice ? Bars.TypicalPrices[index - 1] : Bars.ClosePrices[index - 1]) - Result[index - 1], 2);
double squaredErrors = Math.Sqrt(err / (index - 1 - startIndex + 1));
STD1U[index - 1] = squaredErrors * parSTD1M + Result[index - 1];
STD2U[index - 1] = squaredErrors * parSTD2M + Result[index - 1];
STD3U[index - 1] = squaredErrors * parSTD3M + Result[index - 1];
STD1D[index - 1] = Result[index - 1] - squaredErrors * parSTD1M;
STD2D[index - 1] = Result[index - 1] - squaredErrors * parSTD2M;
STD3D[index - 1] = Result[index - 1] - squaredErrors * parSTD3M;
}
// New Bar on the higher TF = new cycle
if (startIndex > prevStartIndex)
{
prevResult = Result[index - 1];
prevStartIndex = startIndex;
cptv = 0;
cv = 0;
err = 0;
}
if (isFullData)
{
Previous[index] = prevResult;
ChartText text = Chart.DrawText("PrevVWAP", " last " + parTF.ToString().ToUpper().Substring(0, 1), index, prevResult, Color.FromArgb(192, Color.Orange));
text.VerticalAlignment = VerticalAlignment.Center;
text.HorizontalAlignment = HorizontalAlignment.Right;
}
prevIndex = index;
}
if (IsLastBar)
{
// last point, arrows, and stDev bands (redrawn on every tick)
Result[index] = (cptv + (parUseTypicalPrice ? Bars.TypicalPrices[index] : Bars.ClosePrices[index]) * Bars.TickVolumes[index]) / (cv + Bars.TickVolumes[index]);
if (parCandleColoring != coloringType.None)
SetBarColor(index);
// RSI Arrow
if (parShowRSIArrow)
{
string rsiArrow = rsi.Result.IsRising() ? "▲" : (rsi.Result.IsFalling() ? "▼" : "►");
Color rsiAColor = Color.FromArgb(192, rsi.Result.IsRising() ? Color.LimeGreen : (rsi.Result.IsFalling() ? Color.Crimson : Color.Orange));
Color rsiRColor = Color.FromArgb(192, Color.Orange);
if (rsi.Result[index] >= 55 && rsi.Result[index] <= 70)
rsiRColor = Color.FromArgb(192, Color.LimeGreen);
else if (rsi.Result[index] <= 45 && rsi.Result[index] >= 30)
rsiRColor = Color.FromArgb(192, Color.Crimson);
Chart.DrawText("RSIBackground", new string((char)9608, 5), index, Result[index], Color.FromArgb(128, Color.Black)).VerticalAlignment = VerticalAlignment.Center;
Chart.DrawText("RSIArrow", new string((char)160, 1) + rsiArrow, index, Result[index], rsiAColor).VerticalAlignment = VerticalAlignment.Center;
Chart.DrawText("RSIResult", new string((char)160, 5) + rsi.Result[index].ToString("F1"), index, Result[index], rsiRColor).VerticalAlignment = VerticalAlignment.Center;
}
else
Chart.DrawText("VWAPType", new string((char)160, 1) + parTF.ToString().ToUpper().Substring(0, 1), index, Result[index], Color.FromArgb(192, Color.Orange)).VerticalAlignment = VerticalAlignment.Center;
// Standard Deviation
if (parShowSTDs)
{
double squaredErrors = Math.Sqrt((err + Math.Pow((parUseTypicalPrice ? Bars.TypicalPrices[index] : Bars.ClosePrices[index]) - Result[index], 2)) / (index - startIndex + 1));
STD1U[index] = squaredErrors * parSTD1M + Result[index];
STD2U[index] = squaredErrors * parSTD2M + Result[index];
STD3U[index] = squaredErrors * parSTD3M + Result[index];
STD1D[index] = Result[index] - squaredErrors * parSTD1M;
STD2D[index] = Result[index] - squaredErrors * parSTD2M;
STD3D[index] = Result[index] - squaredErrors * parSTD3M;
}
}
}
private void SetBarColor(int i)
{
if (Bars[i].Close > Result[i] && (Bars[i].Close > Bars[i].Open || parCandleColoring == coloringType.All))
{
// Green Candle
Chart.SetBarOutlineColor(i, Color.FromHex("FF00843B"));
Chart.SetBarFillColor(i, Color.FromHex("FF005727"));
}
else if (Bars[i].Close < Result[i] && (Bars[i].Close < Bars[i].Open || parCandleColoring == coloringType.All))
{
// Red Candle
Chart.SetBarOutlineColor(i, Color.FromHex("FF842B00"));
Chart.SetBarFillColor(i, Color.FromHex("FF571700"));
}
else
{
// White Candle
Chart.SetBarOutlineColor(i, Color.FromHex("FF808080"));
Chart.SetBarFillColor(i, Color.FromHex("FF595959"));
}
}
}
}
vitofx
Joined on 08.03.2021
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: VFX_VWAP_v1.2.algo
- Rating: 5
- Installs: 2041
- 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.
Comments
Log in to add a comment.
No comments found.