Anchored VWAP with Standard Deviation For ThinkOrSwim

adam13

New member
I am looking for a code for anchored VWAP with standard deviation bands.

Goals for this code:
-I want an anchored vwap with standard deviation bands.
-I want 2 sets of deviation bands, and to be able to change the deviation numbers in the study settings.
-I also would like the study to give me the option to set an end date where the VWAP would end and not begin a new one, but the default option would be for the study to be ongoing
 
Last edited by a moderator:
Here is the Anchored VWAP modified with the items you requested

The image's upper chart is with an optional End_Anchor set to yes and the lower chart set to no
Screenshot 2023-07-05 074146.png
Code:
####yakBro AVWAP Plotter 2020
#hint: avwap plotters
#20230705 Modified per @Usethinkscript request by @adam13

input anchorDate = 20230501;#hint: anchor Date year/month/day
input anchorTime = 0930;#hint: anchor Time
input End_Anchor = yes;
input anchorEnd  = 20230531;
input showCloud  = no;       # plot cloud
input showAVWAPColor = no;  # Dynamic AVWAP color
input showPriceColor = no;  # Dynamic Price Color
input deviattionNum1 = 1.0; #deviation
input deviattionNum2 = 2.0; #deviation


def postAnchorDate = GetYYYYMMDD() >= anchorDate;
def postAnchorTime = SecondsFromTime(anchorTime) >= 0;


def volumeVwapSum  = TotalSum(if postAnchorDate and postAnchorTime then volume else 0);
def volumeVwap2Sum = TotalSum(if postAnchorDate and postAnchorTime then Sqr(HLC3) * volume  else 0);

plot AVWAP = if End_Anchor and GetYYYYMMDD() > anchorEnd then Double.NaN
             else TotalSum(if postAnchorDate and postAnchorTime then HLC3 * volume
                           else 0) / volumeVwapSum;
def deviationScaledMovAvg = Sqrt(volumeVwap2Sum / volumeVwapSum - Sqr(AVWAP));

plot UpperBand1 = AVWAP + deviattionNum1 * deviationScaledMovAvg;
plot LowerBand1 = AVWAP + (-deviattionNum1) * deviationScaledMovAvg; #dont forget - minus
plot UpperBand2 = AVWAP + deviattionNum2 * deviationScaledMovAvg;
plot LowerBand2 = AVWAP + (-deviattionNum2) * deviationScaledMovAvg; #dont forget - minus


AVWAP.SetStyle(Curve.FIRM);
AVWAP.SetLineWeight(2);
AVWAP.SetDefaultColor(Color.WHITE);
AVWAP.AssignValueColor(if showAVWAPColor and close > AVWAP then Color.GREEN else if showAVWAPColor and close < AVWAP then Color.RED else Color.CURRENT);

AssignPriceColor(if showPriceColor and close > AVWAP then Color.GREEN else if showPriceColor and close < AVWAP then Color.RED else Color.CURRENT);

def up = if showCloud then hl2 else 0;
def downsideGapThreeMethods = if showCloud then AVWAP else 0;
AddCloud(up, downsideGapThreeMethods, Color.DARK_GREEN, Color.DARK_RED);

#labels
AddLabel(yes, "YTD AVWAP: " + AsDollars(AVWAP), Color.WHITE);

#end
 
Last edited by a moderator:
Hello, I am using the below listed AVWAP indicator and I think it works great. I am curious to find out, if there is anyway to be able to get an alert either via TOS or text or both, when the price of a stock reaches SD 2 or -2. This alert would obviously have to be dynamic, as SD on VWAP moves in relation to price action. Is this even possible?

#VWAP Anchored to Date/Time

input usehigher = {default current, higher};
input agg = AggregationPeriod.FIFTEEN_MIN;
input startdate = 20211015;
input starttime = 0930;
def bn = BarNumber();
def c = close;
def v = volume(period = agg);
def vw = vwap(period = agg);
def anchor;
def volumesum;
def volumevwapsum;
def volumevwap2sum;
def price;
def deviation;

if usehigher == usehigher.current and GetAggregationPeriod() < AggregationPeriod.DAY or
usehigher == usehigher.higher and agg < AggregationPeriod.DAY {

anchor = if GetYYYYMMDD() == startdate and
SecondsFromTime(starttime)[1] <= 0 and
SecondsFromTime(starttime) >= 0
then bn else anchor[1];

volumesum = if bn >= HighestAll(anchor) then volumesum[1] + volume else 0;
volumevwapsum = if bn >= HighestAll(anchor) then volumevwapsum[1] + volume * vwap else 0;
volumevwap2sum = if bn >= HighestAll(anchor) then volumevwap2sum[1] + volume * Sqr(vwap) else 0;
price = volumevwapsum / volumesum;
deviation = Sqrt(Max(volumevwap2sum / volumesum - Sqr(price), 0));

} else {

anchor = if GetYYYYMMDD() >= startdate then 1 else 0;

volumesum = if anchor then CompoundValue(1, volumesum[1] + v, v) else 0;
volumevwapsum = if anchor then CompoundValue(1, volumevwapsum[1] + v * vw, v * vw) else 0;
volumevwap2sum = if anchor then CompoundValue(1, volumevwap2sum[1] + v * Sqr(vw), v * Sqr(vw))
else 0;
price = volumevwapsum / volumesum;
deviation = Sqrt(Max(volumevwap2sum / volumesum - Sqr(price), 0));
}

plot VWAP = price;
VWAP.SetDefaultColor(GetColor(0));

input showbands = yes;
input numDev1 = 1.0;
input numDev2 = 2.0;
input numDev3 = 3.0;

plot UpperBand1 = if !showbands then Double.NaN else VWAP + numDev1 * deviation;
plot LowerBand1 = if !showbands then Double.NaN else VWAP - numDev1 * deviation;
plot UpperBand2 = if !showbands then Double.NaN else VWAP + numDev2 * deviation;
plot LowerBand2 = if !showbands then Double.NaN else VWAP - numDev2 * deviation;
plot UpperBand3 = if !showbands then Double.NaN else VWAP + numDev3 * deviation;
plot LowerBand3 = if !showbands then Double.NaN else VWAP - numDev3 * deviation;

VWAP.SetDefaultColor(Color.CYAN);
UpperBand1.SetDefaultColor(Color.GREEN);
LowerBand1.SetDefaultColor(Color.RED);
UpperBand2.SetDefaultColor(Color.GREEN);
LowerBand2.SetDefaultColor(Color.RED);
UpperBand3.SetDefaultColor(Color.GREEN);
LowerBand3.SetDefaultColor(Color.RED);
VWAP.HideBubble();
UpperBand1.HideBubble();
LowerBand1.HideBubble();
UpperBand2.HideBubble();
LowerBand2.HideBubble();
UpperBand3.HideBubble();
LowerBand3.HideBubble();

input showclouds = yes;
AddCloud(if showclouds then UpperBand3 else Double.NaN, UpperBand2, Color.LIGHT_GREEN, Color.LIGHT_GREEN);
AddCloud(if showclouds then LowerBand3 else Double.NaN, LowerBand2, Color.LIGHT_RED, Color.LIGHT_RED);


input showbubblesline = yes;
input bubblemoverVWAP_Labels = 5;#Hint bubblemoverVWAP_Labels: Number of Spaces bubble offset in expansion area
def n = bubblemoverVWAP_Labels;
def n1 = n + 1;

AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] ,
"V:\n" + Round(price[n1] , 2),
Color.ORANGE);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] + numDev1 * deviation[n1] ,
"V1:\n" + Round((price[n1] + numDev1 * deviation[n1]), 2),
Color.GREEN);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] + numDev2 * deviation[n1] ,
"V2:\n" + Round(price[n1] + numDev2 * deviation[n1], 2),
Color.GREEN);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] + numDev3 * deviation[n1] ,
"V3:\n" + Round(price[n1] + numDev3 * deviation[n1], 2),
Color.GREEN);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] - numDev1 * deviation[n1] ,
"V1:\n" + Round(price[n1] - numDev1 * deviation[n1], 2),
Color.RED, no);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] - numDev2 * deviation[n1] ,
"V2:\n" + Round(price[n1] - numDev2 * deviation[n1] , 2),
Color.RED, no);
AddChartBubble(showbubblesline and IsNaN(c[n]) and !IsNaN(c[n1]) ,
price[n1] - numDev3 * deviation[n1] ,
"V3:\n" + Round(price[n1] - numDev3 * deviation[n1] , 2),
Color.RED, no);


input showbubblescurrSTD = no;
input bubblemoverVSTD = 1;#Hint bubblemoverVSTD: Number of Spaces VSTD bubble offset in expansion
def p = bubblemoverVSTD;
def p1 = p + 1;

AddChartBubble(showbubblescurrSTD and IsNaN(c[p]) and !IsNaN(c[p1]) ,
c[p1],
Round(((c[p1] - price[p1]) / deviation[p1]), 1) +
"\n" + Round(c[p1], 2) ,
if c[p1] > VWAP[p1]
then Color.GREEN
else Color.RED,
if c[p1] > VWAP[p1]
then yes else no );
#
 
Not sure if this is what you want exactly but should alert in TOS when the price crosses the 2 STD lines

Alert(Crosses(close, UpperBand2, CrossingDirection.ABOVE), "Price Above 2 STD",Alert.bar,sound.Ding);
Alert(Crosses(close, LowerBand2, CrossingDirection.BELOW), "Price Below 2 STD",Alert.bar,sound.Ding);
 
Not sure if this is what you want exactly but should alert in TOS when the price crosses the 2 STD lines

Alert(Crosses(close, UpperBand2, CrossingDirection.ABOVE), "Price Above 2 STD",Alert.bar,sound.Ding);
Alert(Crosses(close, LowerBand2, CrossingDirection.BELOW), "Price Below 2 STD",Alert.bar,sound.Ding);
thank you, I will try this and report back!
 
Not sure if this is what you want exactly but should alert in TOS when the price crosses the 2 STD lines

Alert(Crosses(close, UpperBand2, CrossingDirection.ABOVE), "Price Above 2 STD",Alert.bar,sound.Ding);
Alert(Crosses(close, LowerBand2, CrossingDirection.BELOW), "Price Below 2 STD",Alert.bar,sound.Ding);
Is there a way to setup these alerts using TOS standard VWAP?
 
As long as you can create a condition that can evaluate to be true at some point, then alerts can be used to visually and audibly notify you.
 
Hello,

New to this forum, so please excuse if this is not being posted at the correct location.
I'm simply trying to display VWAP standard deviation values in a watchlist column or on a chart label.

I can use one of the custom fields to show a period VWAP itself as a watchlist column like so:
plot Custom1 = vwap(period = AggregationPeriod.WEEK);

To add the deviation value to VWAP, I tried to mod the built-in VWAP indicator code (pasted below, and it looks like it's been enhanced in some excellent ways over time in this forum). All I'm trying to do is get at, say, 1 standard deviation up for daily VWAP, and simply display the current value (chart label or watchlist column), but the code is above my pay grade in thinkscript. I tried to cancel the user inputs and simplify because I don't need the optionality of choosing timeframes, but I haven't been able to strip the code to simply capture the deviation value, as in "plot UpperBand = price + numDevUp * deviation;" where price = vwap, without errors. I know how to create the chart label once I have the value. Any help would be much appreciated.

Here's the familiar code:

Code:
input numDevDn = -2.0;
input numDevUp = 1.0;
input timeFrame = {default DAY, WEEK, MONTH};


def cap = getAggregationPeriod();
def errorInAggregation =
    timeFrame == timeFrame.DAY and cap >= AggregationPeriod.WEEK or
    timeFrame == timeFrame.WEEK and cap >= AggregationPeriod.MONTH;
assert(!errorInAggregation, "timeFrame should be not less than current chart aggregation period");

def yyyyMmDd = getYyyyMmDd();
def periodIndx;
switch (timeFrame) {
case DAY:
    periodIndx = yyyyMmDd;
case WEEK:
    periodIndx = Floor((daysFromDate(first(yyyyMmDd)) + getDayOfWeek(first(yyyyMmDd))) / 7);
case MONTH:
    periodIndx = roundDown(yyyyMmDd / 100, 0);
}
def isPeriodRolled = compoundValue(1, periodIndx != periodIndx[1], yes);

def volumeSum;
def volumeVwapSum;
def volumeVwap2Sum;

if (1 == 2) {
    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));

plot VWAP = price;
plot UpperBand = price + numDevUp * deviation;
plot LowerBand = price + numDevDn * deviation;

VWAP.setDefaultColor(getColor(0));
UpperBand.setDefaultColor(getColor(2));
LowerBand.setDefaultColor(getColor(4));
 
Last edited by a moderator:
Hello,

New to this forum, so please excuse if this is not being posted at the correct location.
I'm simply trying to display VWAP standard deviation values in a watchlist column or on a chart label.

I can use one of the custom fields to show a period VWAP itself as a watchlist column like so:
plot Custom1 = vwap(period = AggregationPeriod.WEEK);

To add the deviation value to VWAP, I tried to mod the built-in VWAP indicator code (pasted below, and it looks like it's been enhanced in some excellent ways over time in this forum). All I'm trying to do is get at, say, 1 standard deviation up for daily VWAP, and simply display the current value (chart label or watchlist column), but the code is above my pay grade in thinkscript. I tried to cancel the user inputs and simplify because I don't need the optionality of choosing timeframes, but I haven't been able to strip the code to simply capture the deviation value, as in "plot UpperBand = price + numDevUp * deviation;" where price = vwap, without errors. I know how to create the chart label once I have the value. Any help would be much appreciated.

Here's the familiar code:

input numDevDn = -2.0;
input numDevUp = 1.0;
input timeFrame = {default DAY, WEEK, MONTH};


def cap = getAggregationPeriod();
def errorInAggregation =
timeFrame == timeFrame.DAY and cap >= AggregationPeriod.WEEK or
timeFrame == timeFrame.WEEK and cap >= AggregationPeriod.MONTH;
assert(!errorInAggregation, "timeFrame should be not less than current chart aggregation period");

def yyyyMmDd = getYyyyMmDd();
def periodIndx;
switch (timeFrame) {
case DAY:
periodIndx = yyyyMmDd;
case WEEK:
periodIndx = Floor((daysFromDate(first(yyyyMmDd)) + getDayOfWeek(first(yyyyMmDd))) / 7);
case MONTH:
periodIndx = roundDown(yyyyMmDd / 100, 0);
}
def isPeriodRolled = compoundValue(1, periodIndx != periodIndx[1], yes);

def volumeSum;
def volumeVwapSum;
def volumeVwap2Sum;

if (1 == 2) {
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));

plot VWAP = price;
plot UpperBand = price + numDevUp * deviation;
plot LowerBand = price + numDevDn * deviation;

VWAP.setDefaultColor(getColor(0));
UpperBand.setDefaultColor(getColor(2));
LowerBand.setDefaultColor(getColor(4));

Here is a chart label breakdown of the VWAP. You could make watchlist columns from this.

Screenshot-2023-03-22-135230.png
Code:
input timeFrame = {default DAY, WEEK, MONTH};

def v    = reference VWAP("time frame" = timeFrame);

def vub1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).UpperBand;
def vub2 = reference VWAP("time frame" = timeFrame).UpperBand;

def vlb1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).LowerBand;
def vlb2 = reference VWAP("time frame" = timeFrame).LowerBand;

AddLabel(1, "UB2: " + AsDollars(vub2) + " | UB1: " + AsDollars(vub1), Color.GREEN);
AddLabel(1, "Vwap: " + AsDollars(v), Color.WHITE);
AddLabel(1, "LB1: " + AsDollars(vlb1) + " | LB2: " + AsDollars(vlb2), Color.RED);
 
Here is a chart label breakdown of the VWAP. You could make watchlist columns from this.
Thank you! This works totally fine as a set of chart labels. However, what do I actually use in thinkscript editor for the watchlist column to display the current value of, say, daily VWAP 1 SD upper band, since the watchlist column can only display a single value?

Tried single statement in custom column definition:
plot Custom1 = reference VWAP("num dev up" = 1.0, "time frame" = "DAY"); # Where it appears "DAY" has to be a string. AggregationPeriod.DAY, etc. does not work.

(This is typically how I do it, btw. There may be better ways, but if I'm looking for, say, the value of 8 EMA as a custom column, I'd simply say:
plot Custom1 = ExpAverage("data" = close, "length" = 8);
then select the aggregation and whether it's RTH or ETH.

Then tried:
plot Custom1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = "DAY").UpperBand;

This one looks like it should work. But it simply returns the value of VWAP itself (as in reference VWAP() ), not the value of its 1 SD upper band.

Tried the entire script slightly modified to prevent obvious errors, pasted into custom watchlist column definition:

Code:
#input timeFrame = {default DAY, WEEK, MONTH};

def v    = reference VWAP("time frame" = "DAY");

def vub1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).UpperBand;
def vub2 = reference VWAP("time frame" = timeFrame).UpperBand;

def vlb1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).LowerBand;
def vlb2 = reference VWAP("time frame" = timeFrame).LowerBand;

# This is what should do the job:
plot Custom1 = vub1;

#AddLabel(1, "UB2: " + AsDollars(vub2) + " | UB1: " + AsDollars(vub1), Color.GREEN);
#AddLabel(1, "Vwap: " + AsDollars(v), Color.WHITE);
#AddLabel(1, "LB1: " + AsDollars(vlb1) + " | LB2: " + AsDollars(vlb2), Color.RED);

Once again returns the value of VWAP itself. I must be missing something simple / obvious.
 
Thank you! This works totally fine as a set of chart labels. However, what do I actually use in thinkscript editor for the watchlist column to display the current value of, say, daily VWAP 1 SD upper band, since the watchlist column can only display a single value?

Tried single statement in custom column definition:
plot Custom1 = reference VWAP("num dev up" = 1.0, "time frame" = "DAY"); # Where it appears "DAY" has to be a string. AggregationPeriod.DAY, etc. does not work.

(This is typically how I do it, btw. There may be better ways, but if I'm looking for, say, the value of 8 EMA as a custom column, I'd simply say:
plot Custom1 = ExpAverage("data" = close, "length" = 8);
then select the aggregation and whether it's RTH or ETH.

Then tried:
plot Custom1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = "DAY").UpperBand;

This one looks like it should work. But it simply returns the value of VWAP itself (as in reference VWAP() ), not the value of its 1 SD upper band.

Tried the entire script slightly modified to prevent obvious errors, pasted into custom watchlist column definition:

Code:
#input timeFrame = {default DAY, WEEK, MONTH};

def v    = reference VWAP("time frame" = "DAY");

def vub1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).UpperBand;
def vub2 = reference VWAP("time frame" = timeFrame).UpperBand;

def vlb1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).LowerBand;
def vlb2 = reference VWAP("time frame" = timeFrame).LowerBand;

# This is what should do the job:
plot Custom1 = vub1;

#AddLabel(1, "UB2: " + AsDollars(vub2) + " | UB1: " + AsDollars(vub1), Color.GREEN);
#AddLabel(1, "Vwap: " + AsDollars(v), Color.WHITE);
#AddLabel(1, "LB1: " + AsDollars(vlb1) + " | LB2: " + AsDollars(vlb2), Color.RED);

Once again returns the value of VWAP itself. I must be missing something simple / obvious.

Here are 3 watchlists. One with the 2 upperbands, 1 vwap and 2 lowerbands

Screenshot-2023-03-22-155105.png


Upperband
Code:
input timeFrame = {default DAY, WEEK, MONTH};

def vub1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).UpperBand;
def vub2 = reference VWAP("time frame" = timeFrame).UpperBand;

AddLabel(1, astext(vub2) + " /  " + astext(vub1), Color.GREEN);

VWAP

Code:
input timeFrame = {default DAY, WEEK, MONTH};

def v    = reference VWAP("time frame" = timeFrame);

AddLabel(1, astext(v), Color.WHITE);

Lowerband

Code:
input timeFrame = {default DAY, WEEK, MONTH};

def vlb1 = reference VWAP("num dev dn" = -1.0, "num dev up" = 1.0, "time frame" = timeFrame).LowerBand;
def vlb2 = reference VWAP("time frame" = timeFrame).LowerBand;

AddLabel(1, astext(vlb1) + " / " + astext(vlb2), Color.RED);
 
This works. Thank you again. I was able to replicate a single custom watchlist column for the daily VWAP and its bands. For the weekly and monthly, since there is no user input / edit properties dialog in custom columns to toggle the aggregation, I simply changed the timeFrame default order and it works.

I did not realize you can insert more than one value into a single column by using 'astext', nor that you can use AddLabel inside a watchlist column, but new to thinkscript here. This is useful because there are only 19 custom columns and 'stuffing' more data into each one helps. Added an anchored VWAP to the same column.

I export watchlists into Excel for the real computations - it's just a hack to get data out of TOS. With this method, we get multiple values imported into a single Excel cell, but I can use Excel functions (LEFT, RIGHT, MID, etc.) and a delimiter to parse and split the values. Appreciate the help.
 
This works. Thank you again. I was able to replicate a single custom watchlist column for the daily VWAP and its bands. For the weekly and monthly, since there is no user input / edit properties dialog in custom columns to toggle the aggregation, I simply changed the timeFrame default order and it works.

I did not realize you can insert more than one value into a single column by using 'astext', nor that you can use AddLabel inside a watchlist column, but new to thinkscript here. This is useful because there are only 19 custom columns and 'stuffing' more data into each one helps. Added an anchored VWAP to the same column.

I export watchlists into Excel for the real computations - it's just a hack to get data out of TOS. With this method, we get multiple values imported into a single Excel cell, but I can use Excel functions (LEFT, RIGHT, MID, etc.) and a delimiter to parse and split the values. Appreciate the help.

You're welcome! Thanks for sharing how you use the data.

The astext was used to make the numbers have a trailing zero. For example, instead of 10.4, it becomes 10.40. This allows more uniform columns.

You can make more custom columns by using the share tool. Here is some information on sharing
 
That's interesting! I did not know you could create more custom columns via share tool. Will definitely look into that shortly.

But yes, all this watchlist business is just to get the data into Excel so I can do the real computations there and distill a lot of data into what is for me tier-1 info. The raw data is too much for the eye.

On that note, one final question. Trying to get 3 pieces of profile data from the daily volume profile into a watchlist column (and from there into Excel). Today's (developing) POC, VA high and VA low - and ideally also last session's POC, VA high and VA low (which I'm hoping might be as easy as the [-1] versions of the former). All I need are the numerical values of these 3 (6) variables in a watchlist column.

I've tried the built-in / official volume profile script pasted below as well as 3 other scripts from this site and elsewhere. I can get past the multiple 'plot' statements erroring out in a watchlist column, but any one of them (e.g. POC, VAH, VAL) returns NaN on the watchlist or else the value is inaccurate regardless of the aggregation I choose for the watchlist column. The script works perfectly fine on a chart and I've confirmed through 2 other platforms that its values are accurate with default settings (time per profile = DAY, VA% = 70, etc).

Code:
#
# TD Ameritrade IP Company, Inc. (c) 2010-2023
#

input pricePerRowHeightMode = {default AUTOMATIC, TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input timePerProfile = {default CHART, MINUTE, HOUR, DAY, WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input onExpansion = yes;
input profiles = 1000;
input showPointOfControl = yes;
input showValueArea = yes;
input valueAreaPercent = 70;
input opacity = 50;

def period;
def yyyymmdd = getYyyyMmDd();
def seconds = secondsFromTime(0);
def month = getYear() * 12 + getMonth();
def day_number = daysFromDate(first(yyyymmdd)) + getDayOfWeek(first(yyyymmdd));
def dom = getDayOfMonth(yyyymmdd);
def dow = getDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
switch (timePerProfile) {
case CHART:
    period = 0;
case MINUTE:
    period = floor(seconds / 60 + day_number * 24 * 60);
case HOUR:
    period = floor(seconds / 3600 + day_number * 24);
case DAY:
    period = countTradingDays(min(first(yyyymmdd), yyyymmdd), yyyymmdd) - 1;
case WEEK:
    period = floor(day_number / 7);
case MONTH:
    period = floor(month - first(month));
case "OPT EXP":
    period = exp_opt - first(exp_opt);
case BAR:
    period = barNumber() - 1;
}

def count = CompoundValue(1, if period != period[1] then (count[1] + period - period[1]) % multiplier else count[1], 0);
def cond = count < count[1] + period - period[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
case CUSTOM:
    height = customRowHeight;
}

profile vol = volumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = compoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.getPointOfControl()) and con then pc[1] else vol.getPointOfControl();
def hVA = if IsNaN(vol.getHighestValueArea()) and con then hVA[1] else vol.getHighestValueArea();
def lVA = if IsNaN(vol.getLowestValueArea()) and con then lVA[1] else vol.getLowestValueArea();

def hProfile = if IsNaN(vol.getHighest()) and con then hProfile[1] else vol.getHighest();
def lProfile = if IsNaN(vol.getLowest()) and con then lProfile[1] else vol.getLowest();
def plotsDomain = IsNaN(close) == onExpansion;

plot POC = if plotsDomain then pc else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

DefineGlobalColor("Profile", GetColor(1));
DefineGlobalColor("Point Of Control", GetColor(5));
DefineGlobalColor("Value Area", GetColor(8));

vol.show(globalColor("Profile"), if showPointOfControl then globalColor("Point Of Control") else color.current, if showValueArea then globalColor("Value Area") else color.current, opacity);
POC.SetDefaultColor(globalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(globalColor("Value Area"));
VALow.SetDefaultColor(globalColor("Value Area"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
ProfileHigh.hide();
ProfileLow.hide();
 
Last edited by a moderator:
That's interesting! I did not know you could create more custom columns via share tool. Will definitely look into that shortly.

But yes, all this watchlist business is just to get the data into Excel so I can do the real computations there and distill a lot of data into what is for me tier-1 info. The raw data is too much for the eye.

On that note, one final question. Trying to get 3 pieces of profile data from the daily volume profile into a watchlist column (and from there into Excel). Today's (developing) POC, VA high and VA low - and ideally also last session's POC, VA high and VA low (which I'm hoping might be as easy as the [-1] versions of the former). All I need are the numerical values of these 3 (6) variables in a watchlist column.

I've tried the built-in / official volume profile script pasted below as well as 3 other scripts from this site and elsewhere. I can get past the multiple 'plot' statements erroring out in a watchlist column, but any one of them (e.g. POC, VAH, VAL) returns NaN on the watchlist or else the value is inaccurate regardless of the aggregation I choose for the watchlist column. The script works perfectly fine on a chart and I've confirmed through 2 other platforms that its values are accurate with default settings (time per profile = DAY, VA% = 70, etc).

Code:
#
# TD Ameritrade IP Company, Inc. (c) 2010-2023
#

input pricePerRowHeightMode = {default AUTOMATIC, TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input timePerProfile = {default CHART, MINUTE, HOUR, DAY, WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input onExpansion = yes;
input profiles = 1000;
input showPointOfControl = yes;
input showValueArea = yes;
input valueAreaPercent = 70;
input opacity = 50;

def period;
def yyyymmdd = getYyyyMmDd();
def seconds = secondsFromTime(0);
def month = getYear() * 12 + getMonth();
def day_number = daysFromDate(first(yyyymmdd)) + getDayOfWeek(first(yyyymmdd));
def dom = getDayOfMonth(yyyymmdd);
def dow = getDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
switch (timePerProfile) {
case CHART:
    period = 0;
case MINUTE:
    period = floor(seconds / 60 + day_number * 24 * 60);
case HOUR:
    period = floor(seconds / 3600 + day_number * 24);
case DAY:
    period = countTradingDays(min(first(yyyymmdd), yyyymmdd), yyyymmdd) - 1;
case WEEK:
    period = floor(day_number / 7);
case MONTH:
    period = floor(month - first(month));
case "OPT EXP":
    period = exp_opt - first(exp_opt);
case BAR:
    period = barNumber() - 1;
}

def count = CompoundValue(1, if period != period[1] then (count[1] + period - period[1]) % multiplier else count[1], 0);
def cond = count < count[1] + period - period[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
case CUSTOM:
    height = customRowHeight;
}

profile vol = volumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = compoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.getPointOfControl()) and con then pc[1] else vol.getPointOfControl();
def hVA = if IsNaN(vol.getHighestValueArea()) and con then hVA[1] else vol.getHighestValueArea();
def lVA = if IsNaN(vol.getLowestValueArea()) and con then lVA[1] else vol.getLowestValueArea();

def hProfile = if IsNaN(vol.getHighest()) and con then hProfile[1] else vol.getHighest();
def lProfile = if IsNaN(vol.getLowest()) and con then lProfile[1] else vol.getLowest();
def plotsDomain = IsNaN(close) == onExpansion;

plot POC = if plotsDomain then pc else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

DefineGlobalColor("Profile", GetColor(1));
DefineGlobalColor("Point Of Control", GetColor(5));
DefineGlobalColor("Value Area", GetColor(8));

vol.show(globalColor("Profile"), if showPointOfControl then globalColor("Point Of Control") else color.current, if showValueArea then globalColor("Value Area") else color.current, opacity);
POC.SetDefaultColor(globalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(globalColor("Value Area"));
VALow.SetDefaultColor(globalColor("Value Area"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
ProfileHigh.hide();
ProfileLow.hide();

This link should help with your volumeprofile question. https://usethinkscript.com/threads/volume-profile-indicator-pocs-for-thinkorswim.8153/post-122079

It creates the vah and val for the current period and period before it. I created the poc for you as it was not part of the link user's request.

[
Code:
def daysago = 0;# 0 compares today to yesterday; 1 compares yessterday to the day before it; etc....

def vah = reference VolumeProfile("time per profile" = "DAY", "on expansion" = no).VAHigh;

def vah0 = if GetDay() == GetLastDay() - daysago then vah else vah0[1];
def vah1 = if GetDay() == GetLastDay() - daysago - 1 then vah else vah1[1];
AddLabel(1, "VAH | " + vah1 + "  >=  " + vah0, if vah1 > vah0 then Color.GREEN else Color.RED);

def val = reference VolumeProfile("time per profile" = "DAY", "on expansion" = no).VALow;

def val0 = if GetDay() == GetLastDay() - daysago then val else val0[1];
def val1 = if GetDay() == GetLastDay() - daysago - 1 then val else val1[1];

AddLabel(1, "VAL | " + val0 + "  >=  " + val1, if val0 > val1 then Color.GREEN else Color.RED);

plot scan = vah1 >= vah0 and val0 >= val1;

Here is the POC portion as if it was not part of the above

Code:
def daysago = 0;# 0 compares today to yesterday; 1 compares yessterday to the day before it; etc....

def poc = reference VolumeProfile("time per profile" = "DAY", "on expansion" = no).poc;

def poc0 = if GetDay() == GetLastDay() - daysago then poc else poc0[1];
def poc1 = if GetDay() == GetLastDay() - daysago - 1 then vah else poc1[1];
AddLabel(1, "POC | " + poc1 + "  >=  " + poc, if poc1 > poc0 then Color.GREEN else Color.RED);
 
Hello All,

I have an attached code that shows the anchored VWAP concerning the date and time. I would like to add an upper and lower band with this vwap at the desired anchored date and time. I would like to request anyone, please, to help me modify the script to add upper and lower bands. @halcyonguy would you please see to solve the problem.

Thank you
Code:
@Date
input anchorDate = 20240216;
input anchorTime = 0222;
input numDevUp = 1.0;
input numDevDN = -1.0;

def postAnchorDate = if GetYYYYMMDD() >= anchorDate then 1 else 0;
def postAnchorTime = if SecondsTillTime(anchorTime) == 0 then 1 else if GetYYYYMMDD() < anchorDate then 0 else postAnchorTime[1];

def v1 = (high + low + close) / 3;
def v2 = volume;
def v3 = v2 * v1;
def v4 = v2 * Sqr(v1);

plot anchoredVWAP = TotalSum(if postAnchorDate and postAnchorTime then (v1) * (v2) else 0) / TotalSum(if postAnchorDate and postAnchorTime then v2 else 0);

anchoredVWAP.SetStyle(Curve.FIRM);
anchoredVWAP.SetLineWeight(3);
anchoredVWAP.SetDefaultColor(Color.CYAN);

Thinkorswim has a default anchored VWAP indicator but that anchors date only, not time. I have attached an image and link to the study for reference. I am requesting the same; instead, I want to anchor time, too.

http://tos.mx/!lz8EZkS5

1708294723288.png
 
Last edited by a moderator:
Hello All,

I have an attached code that shows the anchored VWAP concerning the date and time. I would like to add an upper and lower band with this vwap at the desired anchored date and time. I would like to request anyone, please, to help me modify the script to add upper and lower bands. @halcyonguy would you please see to solve the problem.

Thank you
Code:
@Date
input anchorDate = 20240216;
input anchorTime = 0222;
input numDevUp = 1.0;
input numDevDN = -1.0;

def postAnchorDate = if GetYYYYMMDD() >= anchorDate then 1 else 0;
def postAnchorTime = if SecondsTillTime(anchorTime) == 0 then 1 else if GetYYYYMMDD() < anchorDate then 0 else postAnchorTime[1];

def v1 = (high + low + close) / 3;
def v2 = volume;
def v3 = v2 * v1;
def v4 = v2 * Sqr(v1);

plot anchoredVWAP = TotalSum(if postAnchorDate and postAnchorTime then (v1) * (v2) else 0) / TotalSum(if postAnchorDate and postAnchorTime then v2 else 0);

anchoredVWAP.SetStyle(Curve.FIRM);
anchoredVWAP.SetLineWeight(3);
anchoredVWAP.SetDefaultColor(Color.CYAN);

Thinkorswim has a default anchored VWAP indicator but that anchors date only, not time. I have attached an image and link to the study for reference. I am requesting the same; instead, I want to anchor time, too.

http://tos.mx/!lz8EZkS5

View attachment 21101
Can you make this work?
https://usethinkscript.com/threads/anchored-vwap-with-standard-deviation-for-thinkorswim.15840/
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
448 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top