input timeFrame = {MINUTE, MIN2, MIN3, MIN5, MIN10, MIN15, MIN20, MIN30, MIN45, HOUR, TWOHOUR, FOURHOUR, default DAY, WEEK, MONTH, CHART};
input num1stDevUp = 1.0;
def num1stDevDn = -num1stDevUp;
input multiplier = 1;#Hint multiplier: Change to +/- number of "Days", "Weeks", etc
input lines = {limited_curve, default limited_horizontal, full_curve};
def cap = GetAggregationPeriod();
def errorInAggregation =
timeFrame == timeFrame.DAY and cap >= AggregationPeriod.WEEK or
timeFrame == timeFrame.WEEK and cap >= AggregationPeriod.MONTH;
Assert(!errorInAggregation, "vwap timeFrame should be not less than current chart aggregation period");
def yyyyMmDd = GetYYYYMMDD();
def periodIndx;
def seconds = SecondsFromTime(0);
def day_number = DaysFromDate(First(yyyyMmDd)) + GetDayOfWeek(First(yyyyMmDd));
switch (timeFrame) {
case MINUTE:
periodIndx = Floor(seconds / 60 + day_number * 24 * 60);
case MIN2:
periodIndx = Floor(seconds / 120 + day_number * 24);
case MIN3:
periodIndx = Floor(seconds / 180 + day_number * 24);
case MIN5:
periodIndx = Floor(seconds / 300 + day_number * 24);
case MIN10:
periodIndx = Floor(seconds / 600 + day_number * 24);
case MIN15:
periodIndx = Floor(seconds / 900 + day_number * 24);
case MIN20:
periodIndx = Floor(seconds / 1200 + day_number * 24);
case MIN30:
periodIndx = Floor(seconds / 1800 + day_number * 24);
case MIN45:
periodIndx = Floor(seconds / 2700 + day_number * 24);
case HOUR:
periodIndx = Floor(seconds / 3600 + day_number * 24);
case TWOHOUR:
periodIndx = Floor(seconds / 7200 + day_number * 24);
case FOURHOUR:
periodIndx = Floor(seconds / 14400 + day_number * 24);
case DAY:
periodIndx = CountTradingDays(Min(First(yyyyMmDd), yyyyMmDd), yyyyMmDd) - 1;
case WEEK:
periodIndx = Floor((DaysFromDate(First(yyyyMmDd)) + GetDayOfWeek(First(yyyyMmDd))) / 7);
case MONTH:
periodIndx = RoundDown(yyyyMmDd / 100, 0);
case CHART:
periodIndx = 0;
}
def countindx = CompoundValue(1, if periodIndx != periodIndx[1] then (countindx[1] + periodIndx - periodIndx[1]) % multiplier else countindx[1], 0);
def isPeriodRolled = countindx < countindx[1] + periodIndx - periodIndx[1];
#def isPeriodRolled = CompoundValue(1, periodIndx != periodIndx[1], yes);
input num_vwap_displayed = 1;
def Count = num_vwap_displayed;
def cond = if isPeriodRolled
then 1
else Double.NaN;
def dataCount = CompoundValue(1, if !IsNaN(cond)
then dataCount[1] + 1
else dataCount[1], 0);
rec volumeSum;
rec volumeVwapSum;
rec volumeVwap2Sum;
if (isPeriodRolled) {
volumeSum = volume;
volumeVwapSum = volume * vwap;
volumeVwap2Sum = volume * Sqr(vwap);
} else {
volumeSum = CompoundValue(1, volumeSum[1] + volume, volume);
volumeVwapSum = CompoundValue(1, volumeVwapSum[1] + volume * vwap, volume * vwap);
volumeVwap2Sum = CompoundValue(1, volumeVwap2Sum[1] + volume * Sqr(vwap), volume * Sqr(vwap));
}
def price = volumeVwapSum / volumeSum;
def deviation = Sqrt(Max(volumeVwap2Sum / volumeSum - Sqr(price), 0));
rec v = if IsNaN(vwap) then v[1] else price;
rec v1 = if IsNaN(vwap) then v1[1] else price + num1stDevUp * deviation;
rec v2 = if IsNaN(vwap) then v2[1] else price - num1stDevUp * deviation;
plot VWAP;
plot FirstUpperBand;
plot FirstLowerBand;
input showlineinchartlength = 31;
input showlines = yes;
if (!errorInAggregation) and
lines == lines.limited_curve {
VWAP = if IsNaN(close[-showlineinchartlength]) and
HighestAll(dataCount) - dataCount <= Count - 1
then v
else Double.NaN ;
FirstUpperBand = if IsNaN(close[-showlineinchartlength]) and
HighestAll(dataCount) - dataCount <= Count - 1
then v1
else Double.NaN ;
FirstLowerBand = if IsNaN(close[-showlineinchartlength]) and
HighestAll(dataCount) - dataCount <= Count - 1
then v2
else Double.NaN ;
} else if (!errorInAggregation) and
lines == lines.full_curve {
VWAP = v;
FirstUpperBand = v1;
FirstLowerBand = v2;
} else if (!errorInAggregation) and
lines == lines.limited_horizontal and IsNaN(close[-showlineinchartlength]) {
VWAP = HighestAll(if IsNaN(close) then v else Double.NaN );
FirstUpperBand = HighestAll(if IsNaN(close) then v1 else Double.NaN );
FirstLowerBand = HighestAll(if IsNaN(close) then v2 else Double.NaN );
} else {
VWAP = Double.NaN;
FirstUpperBand = Double.NaN;
FirstLowerBand = Double.NaN;
}
VWAP.SetDefaultColor(Color.magenta);
FirstUpperBand.SetDefaultColor(Color.cyan);
FirstLowerBand.SetDefaultColor(Color.cyan);
VWAP.SetPaintingStrategy(PaintingStrategy.LINE);
FirstUpperBand.SetStyle(Curve.SHORT_DASH);
FirstLowerBand.SetStyle(Curve.SHORT_DASH);
VWAP.SetLineWeight(2);
FirstUpperBand.SetLineWeight(1);
FirstLowerBand.SetLineWeight(1);
VWAP.HideBubble();
FirstUpperBand.HideBubble();
FirstLowerBand.HideBubble();
FirstUpperBand.sethiding(!showlines);
FirstLowerBand.sethiding(!showlines);
input showbubblesLine = yes;
input showbubblesVSTD = yes;
input bubblemoverVWAP_Labels = 15;#Hint bubblemoverVWAP_Labels: Number of Spaces bubble offset in expansion area
def n = bubblemoverVWAP_Labels;
def n1 = n + 1;
AddChartBubble(showbubblesLine and IsNaN(close[n]) and !IsNaN(close[n1]) ,
price[n1] ,
"V:" + Round(price[n1] , 2),
Color.ORANGE);
AddChartBubble(showbubblesLine and IsNaN(close[n]) and !IsNaN(close[n1]) ,
price[n1] + num1stDevUp * deviation[n1] ,
"V1:" + Round((price[n1] + num1stDevUp * deviation[n1]), 2),
Color.GREEN);
AddChartBubble(showbubblesLine and IsNaN(close[n]) and !IsNaN(close[n1]) ,
price[n1] + num1stDevDn * deviation[n1] ,
"V1:" + Round(price[n1] + num1stDevDn * deviation[n1], 2),
Color.RED);
input showclouds = yes;
def green = if close > VWAP
then 1
else if green[1] == 1 and high >= VWAP
then 1
else 0;
def g = green;
AddCloud(if showclouds and g
then FirstUpperBand
else Double.NaN,
VWAP,
Color.Light_green, Color.Light_green);
AddCloud(if showclouds and g
then FirstUpperBand
else Double.NaN,
VWAP,
Color.Light_green, Color.Light_green);
AddCloud(if showclouds and !g
then VWAP
else Double.NaN,
FirstLowerBand,
Color.PINK, Color.PINK);