Volume Profile Indicator & POCs For ThinkOrSwim

I was curious to see if I could scrap together an EMA that used the bar POC's. This is what I got. It doesn't seem to like my input of POC as price. Says no such function: POC at 5:15... Any idea where I went wrong?
Code:
#
def poc = reference VolumeProfile("price per row height mode" = "TICKSIZE", "on expansion" = No, "time per profile" = "BAR");

input price = poc;
input length = 9;
input displace = 0;
input showBreakoutSignals = no;

plot AvgExp = ExpAverage(price[-displace], length);
plot UpSignal = price crosses above AvgExp;
plot DownSignal = price crosses below AvgExp;

UpSignal.SetHiding(!showBreakoutSignals);
DownSignal.SetHiding(!showBreakoutSignals);

AvgExp.SetDefaultColor(GetColor(1));
UpSignal.SetDefaultColor(Color.UPTICK);
UpSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
DownSignal.SetDefaultColor(Color.DOWNTICK);
DownSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Just change input price = poc; to def price = poc;
 
@shih90 @stockpsyop
Did you know that by clicking on a member's name, you can easily check when they were last seen on the uTS forum? It's a great way to keep track of who's been around recently, and who hasn't. Speaking of which, it looks like @John808 is no longer active. :(
 
Does anyone knows how to move volume profile to the right by 1 bar so i have more space between candle and volume profile on expansion?
 
Does anyone knows how to move volume profile to the right by 1 bar so i have more space between candle and volume profile on expansion?
Probably can change the offset in the price axis settings menu to accomplish this. Just go to settings and price axis menu. Should be able to find it from there.
 
I dont see anything on time axis that would move the expansion area to start a few bars to right of last candle rather than right after last candle, only option on there to make expansion area bigger
 
This might work on most symbols and timeframes that match the periods you requested. The way this works is to assign different values to each period, which remain the same until the next period. The variable cond then prints a new volume profile when the values change.
Is it possible to do this with TPO?
 
Tradingview volume color(up/down) on the TPOProfile indicator
tradingview indicator Like this
g7nsn93.png

Bi4Abl0.png

tradingview indicator in this video:
 
Last edited by a moderator:
Does anyone knows how to move volume profile to the right by 1 bar so i have more space between candle and volume profile on expansion?

As mentioned above, there does not appear to be a way to move the volume profile when displayed on expansion.

However, the monkeybars indicator has a volume profile within it that may provide some visual assistance. It displays the volume profile right to left. I have made some modifications to the standard monkeybar indicator to highlight the volume profile usage.

Screenshot-2023-03-12-081924.png
Ruby:
#
# TD Ameritrade IP Company, Inc. (c) 2010-2023
#
# Modifications to MonkeyBars to highlight VolumeProfile Indicator within it ... 20230312 Sleepyz

input pricePerRowHeightMode = {default AUTOMATIC, TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input aggregationPeriod = {"1 min", "2 min", "3 min", "4 min", "5 min", "10 min", "15 min", "20 min", default "30 min", "1 hour", "2 hours", "4 hours", "Day", "2 Days", "3 Days", "4 Days", "Week", "Month", "Quarter", "Year"};
input timePerProfile = { CHART, MINUTE, HOUR, default DAY, WEEK, MONTH, "OPT EXP", BAR, YEAR};
input multiplier = 1;
input onExpansion = yes;
input profiles = 1;
input showMonkeyBar = no;
input showThePlayground = no;
input showProfileHighLow = no;
input thePlaygroundPercent = 70;
input opacity = 100;
input emphasizeFirstDigit = no;
input markOpenPrice = no;
input markClosePrice = no;
input volumeShowStyle = MonkeyVolumeShowStyle.last;
input showVolumeVA = yes;
input showVolumePoc = yes;
input theVolumePercent = 70;
input showInitialBalance = no;
input initialBalanceRange = 3;

def period;
def yyyymmdd = getYyyyMmDd();
def seconds = secondsFromTime(0);
def year = getYear();
def month = year * 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);
def periodMin = Floor(seconds / 60 + day_number * 24 * 60);
def periodHour = Floor(seconds / 3600 + day_number * 24);
def periodDay = countTradingDays(Min(first(yyyymmdd), yyyymmdd), yyyymmdd) - 1;
def periodWeek = Floor(day_number / 7);
def periodMonth = month - first(month);
def periodQuarter = Ceil(month / 3) - first(Ceil(month / 3));
def periodYear = year - first(year);

switch (timePerProfile) {
case CHART:
    period = 0;
case MINUTE:
    period = periodMin;
case HOUR:
    period = periodHour;
case DAY:
    period = periodDay;
case WEEK:
    period = periodWeek;
case MONTH:
    period = periodMonth;
case "OPT EXP":
    period = exp_opt - first(exp_opt);
case BAR:
    period = barNumber() - 1;
case YEAR:
    period = periodYear;
}

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

def timeInterval;
def aggMultiplier;
switch (aggregationPeriod) {
case "1 min":
    timeInterval = periodMin;
    aggMultiplier = 1;
case "2 min":
    timeInterval = periodMin;
    aggMultiplier = 2;
case "3 min":
    timeInterval = periodMin;
    aggMultiplier = 3;
case "4 min":
    timeInterval = periodMin;
    aggMultiplier = 4;
case "5 min":
    timeInterval = periodMin;
    aggMultiplier = 5;
case "10 min":
    timeInterval = periodMin;
    aggMultiplier = 10;
case "15 min":
    timeInterval = periodMin;
    aggMultiplier = 15;
case "20 min":
    timeInterval = periodMin;
    aggMultiplier = 20;
case "30 min":
    timeInterval = periodMin;
    aggMultiplier = 30;
case "1 hour":
    timeInterval = periodHour;
    aggMultiplier = 1;
case "2 hours":
    timeInterval = periodHour;
    aggMultiplier = 2;
case "4 hours":
    timeInterval = periodHour;
    aggMultiplier = 4;
case "Day":
    timeInterval = periodDay;
    aggMultiplier = 1;
case "2 Days":
    timeInterval = periodDay;
    aggMultiplier = 2;
case "3 Days":
    timeInterval = periodDay;
    aggMultiplier = 3;
case "4 Days":
    timeInterval = periodDay;
    aggMultiplier = 4;
case "Week":
    timeInterval = periodWeek;
    aggMultiplier = 1;
case "Month":
    timeInterval = periodMonth;
    aggMultiplier = 1;
case "Quarter":
    timeInterval = periodQuarter;
    aggMultiplier = 1;
case "Year":
    timeInterval = periodYear;
    aggMultiplier = 1;
}

def agg_count = compoundvalue(1, if timeInterval != timeInterval[1] then (getValue(agg_count, 1) + timeInterval - timeInterval[1]) % aggMultiplier else getValue(agg_count, 1), 0);
def agg_cond = compoundvalue(1,  agg_count < agg_count[1] + timeInterval - timeInterval[1], yes);

def digit = compoundValue(1, if cond then 1 else agg_cond + getValue(digit, 1), 1);

profile monkey = monkeyBars(digit, "startNewProfile" = cond, "onExpansion" = onExpansion,
"numberOfProfiles" = profiles, "pricePerRow" = height, "the playground percent" = thePlaygroundPercent,
"emphasize first digit" = emphasizeFirstDigit, "volumeProfileShowStyle" = volumeShowStyle, "volumePercentVA" = theVolumePercent,
 "show initial balance" = showInitialBalance, "initial balance range" = initialBalanceRange);
def con = compoundValue(1, onExpansion, no);
def mbar = compoundvalue(1, if IsNaN(monkey.getPointOfControl()) and con then getValue(mbar, 1) else monkey.getPointOfControl(), monkey.getPointOfControl());
def hPG = compoundvalue(1, if IsNaN(monkey.getHighestValueArea()) and con then getValue(hPG, 1) else monkey.getHighestValueArea(), monkey.getHighestValueArea());
def lPG = compoundvalue(1, if IsNaN(monkey.getLowestValueArea()) and con then getValue(lPG, 1) else monkey.getLowestValueArea(), monkey.getLowestValueArea());

def hProfile = compoundvalue(1, if IsNaN(monkey.getHighest()) and con then getValue(hProfile, 1) else monkey.getHighest(), monkey.getHighest());
def lProfile = compoundvalue(1, if IsNaN(monkey.getLowest()) and con then getValue(lProfile, 1) else monkey.getLowest(), monkey.getLowest());
def plotsDomain = IsNaN(close) == onExpansion;

plot MB = if plotsDomain then mbar else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot PGHigh = if plotsDomain then hPG else Double.NaN;
plot PGLow = if plotsDomain then lPG else Double.NaN;

DefineGlobalColor("Monkey Bar", GetColor(4));
DefineGlobalColor("The Playground", GetColor(3));
DefineGlobalColor("Open Price", GetColor(1));
DefineGlobalColor("Close Price", GetColor(1));
DefineGlobalColor("Volume", color.cyan);
DefineGlobalColor("Volume Value Area", color.yellow);
DefineGlobalColor("Volume Point of Control", GetColor(2));
DefineGlobalColor("Initial Balance", GetColor(7));

monkey.show(color.red, if showMonkeyBar then globalColor("Monkey Bar") else color.current,
 if showThePlayground then globalColor("The Playground") else color.current,
 opacity, if markOpenPrice then globalColor("Open Price") else color.current,
 if markClosePrice then globalColor("Close Price") else color.current,
 if showInitialBalance then globalColor("Initial Balance") else color.current,
 globalColor("Volume"),
 if showVolumeVA then globalColor("Volume Value Area") else color.current,
 if showVolumePOC then globalColor("Volume Point of Control") else color.current);
MB.SetDefaultColor(globalColor("Monkey Bar"));
MB.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PGHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PGLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PGHigh.SetDefaultColor(globalColor("The Playground"));
PGLow.SetDefaultColor(globalColor("The Playground"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
MB.sethiding(!showMonkeyBar);
PGHigh.sethiding(!showThePlayground);
PGLow.sethiding(!showThePlayground);
ProfileHigh.hide();
ProfileLow.hide();
 
Tradingview volume color(up/down) on the TPOProfile indicator
tradingview indicator Like this
g7nsn93.png

Bi4Abl0.png

tradingview indicator in this video:

We do not have control over coloring the native profile indicators, nor contol over tracking up/down volume, in either case as above.

However we have made a pseudo buying selling study by BenTen to try to emulate buying/selling behavior. It is used in a relatively new function that TOS provided, dataprofile().

The DataProfile uses coloring based upon the input buyingselling method chosen. Green is 'buying' and Red is the 'selling' beyond the 'buying'. (The Red is actually the total of buying and selling with the buying overlaid on the red)

Screenshot-2023-03-12-115704.png

Code:
#DataProfile_BuyingSelling_CloseOpen
#DataProfile - Using Close based upon the input method. Green is 'buying' and Red is the 'selling' beyond the 'buying'. (The Red is actually the total of buying and selling with the buying overlaid on the red)
#20211130 Sleepyz; updated 20230312 Sleepyz

input method = {default buying_selling_pressure, buying_selling_volume};
def c = close;
def o = open;
def h = high;
def l = low;
def v = volume;

# Buying vs. Selling Power
# Assembled by BenTen at UseThinkScript.com
# Converted from https://www.tradingview.com/script/XZ3UXRvL-buy-vs-sell-power-x/

input s = 5;
input m = 9;
input len = 14;
input paintbar = yes;

def source = close;
def hilow = ((high - low) * 100);
def openclose = ((close - open) * 100);
def vol = (close / hilow);
def spreadv = (openclose * close);
def pt = spreadv + TotalSum(spreadv);

def a = ExpAverage(pt, len) - ExpAverage(pt, m);
def b = ExpAverage(pt, s) - ExpAverage(pt, m);
def p = a + b;

def blue = b;
def red = p;

def bullishRule = b >= p;
def bearishRule = b <= p;

AssignPriceColor(if paintbar and bullishRule then Color.CYAN else if paintbar and bearishRule then Color.MAGENTA else Color.CURRENT);

def test;
switch (method) {
case buying_selling_volume:
    test = if ((c - l) / (h - l) * volume) >= ((h - c) / (h - l) * volume) then close else if ((c - l) / (h - l) * volume) < ((h - c) / (h - l) * volume) then Double.NaN else test[1];
case buying_selling_pressure:
    test = if b >= p then close else if b < p then Double.NaN else test[1];
}

def buy   = test;
def Data  = close;


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

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 datatype = DataProfile("data" = Data, "startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(datatype.GetPointOfControl()) and con then pc[1] else datatype.GetPointOfControl();
def hVA = if IsNaN(datatype.GetHighestValueArea()) and con then hVA[1] else datatype.GetHighestValueArea();
def lVA = if IsNaN(datatype.GetLowestValueArea()) and con then lVA[1] else datatype.GetLowestValueArea();

def hProfile = if IsNaN(datatype.GetHighest()) and con then hProfile[1] else datatype.GetHighest();
def lProfile = if IsNaN(datatype.GetLowest()) and con then lProfile[1] else datatype.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", Color.LIGHT_RED);
DefineGlobalColor("Point Of Control", Color.CYAN);
DefineGlobalColor("Value Area", Color.LIGHT_RED);

datatype.Show(GlobalColor("Profile"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT);
POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.SetLineWeight(2);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VALow.SetDefaultColor(GlobalColor("Value Area"));
VAHigh.SetLineWeight(2);
VALow.SetLineWeight(2);
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
ProfileHigh.Hide();
ProfileLow.Hide();


profile datatype2 = DataProfile("data" = test, "startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);

def con2 = CompoundValue(1, onExpansion, no);
def pc2 = if IsNaN(datatype2.GetPointOfControl()) and con2 then pc2[1] else datatype2.GetPointOfControl();
def hVA2 = if IsNaN(datatype2.GetHighestValueArea()) and con2 then hVA2[1] else datatype2.GetHighestValueArea();
def lVA2 = if IsNaN(datatype2.GetLowestValueArea()) and con2 then lVA2[1] else datatype2.GetLowestValueArea();

def hProfile2 = if IsNaN(datatype2.GetHighest()) and con2 then hProfile2[1] else datatype2.GetHighest();
def lProfile2 = if IsNaN(datatype2.GetLowest()) and con2 then lProfile2[1] else datatype2.GetLowest();
def plotsDomain2 = IsNaN(close) == onExpansion;

plot POC2 = if plotsDomain2 then pc2 else Double.NaN;
plot ProfileHigh2 = if plotsDomain2 then hProfile2 else Double.NaN;
plot ProfileLow2 = if plotsDomain2 then lProfile2 else Double.NaN;
plot VAHigh2 = if plotsDomain2 then hVA2 else Double.NaN;
plot VALow2 = if plotsDomain2 then lVA2 else Double.NaN;

DefineGlobalColor("Profile2", Color.GREEN);
DefineGlobalColor("Point Of Control2", Color.CYAN);
DefineGlobalColor("Value Area2", Color.GREEN);

datatype2.Show(GlobalColor("Profile2"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT, opacity);

POC2.SetDefaultColor(GlobalColor("Point Of Control2"));
POC2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC2.SetLineWeight(2);
VAHigh2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh2.SetDefaultColor(GlobalColor("Value Area2"));
VALow2.SetDefaultColor(GlobalColor("Value Area2"));
VAHigh2.SetLineWeight(2);
VALow2.SetLineWeight(2);
ProfileHigh2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh2.SetDefaultColor(GetColor(3));
ProfileLow2.SetDefaultColor(GetColor(3));
ProfileHigh2.Hide();
ProfileLow2.Hide();
 
We do not have control over coloring the native profile indicators, nor contol over tracking up/down volume, in either case as above.

However we have made a pseudo buying selling study by BenTen to try to emulate buying/selling behavior. It is used in a relatively new function that TOS provided, dataprofile().

The DataProfile uses coloring based upon the input buyingselling method chosen. Green is 'buying' and Red is the 'selling' beyond the 'buying'. (The Red is actually the total of buying and selling with the buying overlaid on the red)

Here is a Multi_Time_Frame version of the above script with optional bubbles added
[Edit to add showbubbles]

Screenshot-2023-03-15-085654.png

Ruby:
#VolumeProfile_using_DataProfile_BuyingSelling_MTF
#DataProfile - Using Close based upon the input method. Green is 'buying' and Red is the 'selling' beyond the 'buying'. (The Red is actually the total of buying and selling with the buying overlaid on the red)
#20211130 Sleepyz; updated 20230312 Sleepyz

input agg = AggregationPeriod.FIVE_MIN;
input method = {default buying_selling_pressure, buying_selling_volume};
def c = close(period = agg);
def o = open(period = agg);
def h = high(period = agg);
def l = low(period = agg);
def v = volume(period = agg);

# Buying vs. Selling Power
# Assembled by BenTen at UseThinkScript.com
# Converted from https://www.tradingview.com/script/XZ3UXRvL-buy-vs-sell-power-x/

input s = 2;#5;
input m = 4;#9;
input len = 6;#14;
input paintbar = no;

def source = c;
def hilow = ((h - l) * 100);
def openclose = ((c - o) * 100);
def vol = (c / hilow);
def spreadv = (openclose * c);
def pt = spreadv + TotalSum(spreadv);

def a = ExpAverage(pt, len) - ExpAverage(pt, m);
def b = ExpAverage(pt, s) - ExpAverage(pt, m);
def p = a + b;

def blue = b;
def red = p;

def bullishRule = b >= p;
def bearishRule = b <= p;

AssignPriceColor(if paintbar and bullishRule then Color.CYAN else if paintbar and bearishRule then Color.MAGENTA else Color.CURRENT);

def test;
switch (method) {
case buying_selling_volume:
    test = if ((c - l) / (h - l) * v) >= ((h - c) / (h - l) * v) then c else if ((c - l) / (h - l) * v) < ((h - c) / (h - l) * v) then Double.NaN else test[1];
case buying_selling_pressure:
    test = if b >= p then c else if b < p then Double.NaN else test[1];
}

def buy   = Round(test, 2);
def Data  = Round(c, 2);


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

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 datatype = DataProfile("data" = Data, "startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(datatype.GetPointOfControl()) and con then pc[1] else datatype.GetPointOfControl();
def hVA = if IsNaN(datatype.GetHighestValueArea()) and con then hVA[1] else datatype.GetHighestValueArea();
def lVA = if IsNaN(datatype.GetLowestValueArea()) and con then lVA[1] else datatype.GetLowestValueArea();

def hProfile = if IsNaN(datatype.GetHighest()) and con then hProfile[1] else datatype.GetHighest();
def lProfile = if IsNaN(datatype.GetLowest()) and con then lProfile[1] else datatype.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", Color.RED);
DefineGlobalColor("Point Of Control", Color.CYAN);
DefineGlobalColor("Value Area", Color.RED);

datatype.Show(GlobalColor("Profile"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT);
POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC.SetLineWeight(2);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VALow.SetDefaultColor(GlobalColor("Value Area"));
VAHigh.SetLineWeight(2);
VALow.SetLineWeight(2);
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
ProfileHigh.Hide();
ProfileLow.Hide();


profile datatype2 = DataProfile("data" = test, "startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);

def con2 = CompoundValue(1, onExpansion, no);
def pc2 = if IsNaN(datatype2.GetPointOfControl()) and con2 then pc2[1] else datatype2.GetPointOfControl();
def hVA2 = if IsNaN(datatype2.GetHighestValueArea()) and con2 then hVA2[1] else datatype2.GetHighestValueArea();
def lVA2 = if IsNaN(datatype2.GetLowestValueArea()) and con2 then lVA2[1] else datatype2.GetLowestValueArea();

def hProfile2 = if IsNaN(datatype2.GetHighest()) and con2 then hProfile2[1] else datatype2.GetHighest();
def lProfile2 = if IsNaN(datatype2.GetLowest()) and con2 then lProfile2[1] else datatype2.GetLowest();
def plotsDomain2 = IsNaN(close) == onExpansion;

plot POC2 = if plotsDomain2 then pc2 else Double.NaN;
plot ProfileHigh2 = if plotsDomain2 then hProfile2 else Double.NaN;
plot ProfileLow2 = if plotsDomain2 then lProfile2 else Double.NaN;
plot VAHigh2 = if plotsDomain2 then hVA2 else Double.NaN;
plot VALow2 = if plotsDomain2 then lVA2 else Double.NaN;

DefineGlobalColor("Profile2", Color.GREEN);
DefineGlobalColor("Point Of Control2", Color.CYAN);
DefineGlobalColor("Value Area2", Color.GREEN);

datatype2.Show(GlobalColor("Profile2"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT, opacity);

POC2.SetDefaultColor(GlobalColor("Point Of Control2"));
POC2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
POC2.SetLineWeight(2);
VAHigh2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh2.SetDefaultColor(GlobalColor("Value Area2"));
VALow2.SetDefaultColor(GlobalColor("Value Area2"));
VAHigh2.SetLineWeight(2);
VALow2.SetLineWeight(2);
ProfileHigh2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh2.SetDefaultColor(GetColor(3));
ProfileLow2.SetDefaultColor(GetColor(3));
ProfileHigh2.Hide();
ProfileLow2.Hide();

input showbubbles = yes;
input bubblemover = 2;
def bm  = bubblemover;
def bm1 = bm + 1;
def mover = showbubbles and IsNaN(close[bm]) and !IsNaN(close[bm1]);

AddChartBubble(mover, POC[bm1], "APOC", POC.TakeValueColor());#All POC
AddChartBubble(mover, POC2[bm1], "UPOC", POC.TakeValueColor());#Up POC
AddChartBubble(mover, VAHigh[bm1], "AVAH", VAHigh.TakeValueColor());
AddChartBubble(mover, VAHigh2[bm1], "UVAH", VAHigh2.TakeValueColor());
AddChartBubble(mover, VALow[bm1], "AVAL", VALow.TakeValueColor());
AddChartBubble(mover, VALow2[bm1], "UVAL", VALow2.TakeValueColor());
 
Last edited:
Does anyone know how to scan for stocks where the current day volume profile is inside the previous day volume profile?

Such that the current day VAH is equal to or lower than previous day VAH and the current day VAL is equal to or higher than previous day VAL.

Like an inside bar scan, but for the volume profile study
 
@Point of controller Try this:

Code:
#Courtesy of Pete Hahn
#visit link below on how to use
# https://www.hahn-tech.com/thinkorswim-scan-volume-profile/


input scanUpperVaLimit = 100.0;
input scanUpperVaRange = 20.0;
input scanLowerVaLimit = 0.0;
input scanLowerVaRange = 20.00;
input scanLookbackBars = 3;
input pricePerRowHeightMode = {default AUTOMATIC, TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input timePerProfile = { MINUTE, HOUR, DAY,default WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input onExpansion = no;
input profiles = 50;
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 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;

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

rec priorPOC = if period != period[1] then pc[1] else priorPOC[1] ;
rec priorVAHigh = if period!= period[1] then VAHigh[1] else priorVAHigh[1];
rec priorVALow = if period != period[1] then VALow[1] else priorVALow[1];

def aboveVaHigh = lowest(low[1], scanLookbackBars) > priorVAHigh;
def belowVaLow = highest(high[1], scanLookbackBars) < priorVALow;
def insideVA = highest(high[1], scanLookbackBars) < priorVAHigh and lowest(low[1], scanLookbackBars) > priorVALow;

# now we need to define a percentile value expressing the relative
# position of the close as compared to the value area
def prctOfVA = ((close - priorVALow) / (priorVAHigh - priorVALow)) * 100;

def upperVaRange = prctOfVA < scanUpperVaLimit and prctOfVA > (scanUpperVaLimit - scanUpperVaRange);
def lowerVaRange = prctOfVa > scanLowerVaLimit and prctOfVA < (scanLowerVaLimit + scanLowerVaRange);

def condition1 = VAHigh <= VAHIGH[1];
def condition2 = VALOW >= VALOW[1];
plot scan = condition1 and condition2;
 
@Point of controller Try this:

Code:
#Courtesy of Pete Hahn
#visit link below on how to use
# https://www.hahn-tech.com/thinkorswim-scan-volume-profile/


input scanUpperVaLimit = 100.0;
input scanUpperVaRange = 20.0;
input scanLowerVaLimit = 0.0;
input scanLowerVaRange = 20.00;
input scanLookbackBars = 3;
input pricePerRowHeightMode = {default AUTOMATIC, TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input timePerProfile = { MINUTE, HOUR, DAY,default WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input onExpansion = no;
input profiles = 50;
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 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;

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

rec priorPOC = if period != period[1] then pc[1] else priorPOC[1] ;
rec priorVAHigh = if period!= period[1] then VAHigh[1] else priorVAHigh[1];
rec priorVALow = if period != period[1] then VALow[1] else priorVALow[1];

def aboveVaHigh = lowest(low[1], scanLookbackBars) > priorVAHigh;
def belowVaLow = highest(high[1], scanLookbackBars) < priorVALow;
def insideVA = highest(high[1], scanLookbackBars) < priorVAHigh and lowest(low[1], scanLookbackBars) > priorVALow;

# now we need to define a percentile value expressing the relative
# position of the close as compared to the value area
def prctOfVA = ((close - priorVALow) / (priorVAHigh - priorVALow)) * 100;

def upperVaRange = prctOfVA < scanUpperVaLimit and prctOfVA > (scanUpperVaLimit - scanUpperVaRange);
def lowerVaRange = prctOfVa > scanLowerVaLimit and prctOfVA < (scanLowerVaLimit + scanLowerVaRange);

def condition1 = VAHigh <= VAHIGH[1];
def condition2 = VALOW >= VALOW[1];
plot scan = condition1 and condition2;

Thank you for the response. I have pasted that code into the TOS stock hacker with the 'is true' designation and received 1800+ results. When I cross-checked a few of the results they did not meet the criteria of the inside previous day volume profile that I was hoping for. I know AAPL, OXY, ABNB have a volume profile that is completely inside yesterday's profile, for example, to show what I am looking for.

Maybe my inputs have to be adjusted or I am missing something -- any recommendations?
 
Last edited:
Okay I have a few screenshots. First off, I was able to get my scan to have the same number of results as yours. (sorted by volume)

Screen-Shot-2023-03-18-at-9-01-05-PM.png


Second, I have loaded Ford chart with the volume profile. You will see the current day volume profile is not within the prior day volume profile.

Screen-Shot-2023-03-18-at-9-01-45-PM.png


I am only hoping for results where the current day volume profile is completely within the prior day volume profile. (OXY example)

Screen-Shot-2023-03-18-at-9-02-17-PM.png



So in recap, I was able to run the scan successfully. Once again thank you for your persistent help. I greatly appreciate it. I am hoping for the results list to only contain stocks like OXY (and AAPL, ABNB to name a few that I found in my own search from yesterday).

Thanks BenTen

The script you were using may have caused some of the issues you were having. For one, It was set to "WEEK" instead of "DAY".

The following seems to work.

It has an input daysago you can change to compare previous days to each other. For example, if set to 1, it will allow you to scan today and see the inside results based upon the previous 2 days to be able to observe breakouts in the current day.

TOS has different results for volume profiles between timeframes. Since you are showing that you are viewing the results on a 30m chart, you should run your scan using 30m instead of Day. The volumeprofile in the scan code though is set to Day.

The scan code when added to the chart you are viewing for testing the results will have 2 labels. They will both appear green if the result is an inside.

Scan code
Screenshot-2023-03-19-101056.png
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];
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];
plot scan = vah1 >= vah0 and val0 >= val1;
Chart Code
Screenshot-2023-03-19-101852.png
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;
 
Last edited:
The script you were using may have caused some of the issues you were having. For one, It was set to "WEEK" instead of "DAY".

The following seems to work.

It has an input daysago you can change to compare previous days to each other. For example, if set to 1, it will allow you to scan today and see the inside results based upon the previous 2 days to be able to observe breakouts in the current day.

TOS has different results for volume profiles between timeframes. Since you are showing that you are viewing the results on a 30m chart, you should run your scan using 30m instead of Day. The volumeprofile in the scan code though is set to Day.

The scan code when added to the chart you are viewing for testing the results will have 2 labels. They will both appear green if the result is an inside.

Scan code

Chart Code

This is awesome, SleepyZ. I have tried the codes and it appears they both give me the criteria I am looking for. Full disclosure, when looking for inside day volume profiles, I was finding some of my manual search results from tradingview -- so that would explain some of the profile discrepancies.

I never would have thought to test the results with the chart code you provided so kudos to you. I am going to play around with this today and if I have any questions I will post them here, but as of now it looks like this is pointing me in the right direction.

Thank you so much!
 
Here is the following code in a watchlist
Hi SleepyZ, I wondered if there's a way to accurately customize the 'input multiplier' for the Point of Control WL code.

For instance, in my WL I want to see the VPOC value under a Daily aggregation & 30-day lookback.
I naively thought I could modify your code with either:
1. adding 'multiplier' = 30 to each VolumeProfile reference in the code
2. layering 'input multiplier = 30' atop your code

Neither of these approaches worked, sorry for being a noob.
 
Hi SleepyZ, I wondered if there's a way to accurately customize the 'input multiplier' for the Point of Control WL code.

For instance, in my WL I want to see the VPOC value under a Daily aggregation & 30-day lookback.
I naively thought I could modify your code with either:
1. adding 'multiplier' = 30 to each VolumeProfile reference in the code
2. layering 'input multiplier = 30' atop your code

Neither of these approaches worked, sorry for being a noob.

I have previously used a workaround to accomplish your request. Below is the code for the WL and the image shows the workaround code displaying the plots for testing.

Screenshot-2023-05-07-132130.png
Code:
input lookback = 30;
def ymd        = GetYYYYMMDD();
def ok         = !IsNaN(close);
def capture    = ok and ymd != ymd[1];
def dayCount   = CompoundValue(1, if capture
                                then dayCount[1] + 1
                                else dayCount[1], 0);
def thisDay  = (HighestAll(dayCount) - dayCount) + 1;
def profiles = lookback;
def cond = thisDay > lookback - 1;
profile vol = VolumeProfile( pricePerRow = PricePerRow.TICKSIZE, startNewProfile = cond, onExpansion = no, numberOfProfiles = profiles);
def con = no;
def poc    = if IsNaN(vol.GetPointOfControl()) and con then poc[1] else vol.GetPointOfControl();
def vahigh = if IsNaN(vol.GetHighestValueArea()) and con then vahigh[1] else vol.GetHighestValueArea();
def valow = if IsNaN(vol.GetLowestValueArea()) and con then valow[1] else vol.GetLowestValueArea();

AddLabel(1, poc, Color.BLACK);
AssignBackgroundColor(if close > poc and close < vahigh then Color.GREEN else if close > poc and close > vahigh then Color.DARK_GREEN else if close < poc and close > valow then Color.RED else if close < poc and close < valow then Color.DARK_RED else Color.BLACK);
 
is there a way to offset volume profile to the right on the current time frame? e.g if using the monthly volume profile i want to see May 23 drawn over June 23. I generally draw custom lines myself but it will be cool to have it done automatically. I have tried to play with the scripts but even though i have programming knowledge i have zero context of thinkscript and how to go about correctly offset it.

I have seen some twitter screenshots and while going through rabbit hole ended up seeing some youtube of a custom indicator which does this but seems like those are not open source.
 
is there a way to offset volume profile to the right on the current time frame? e.g if using the monthly volume profile i want to see May 23 drawn over June 23. I generally draw custom lines myself but it will be cool to have it done automatically. I have tried to play with the scripts but even though i have programming knowledge i have zero context of thinkscript and how to go about correctly offset it.

I have seen some twitter screenshots and while going through rabbit hole ended up seeing some youtube of a custom indicator which does this but seems like those are not open source.

This extends the HVA, LVA and POC from the prior timeframe selected (in this case Month) to the next period selected.

The image includes a native TOS Volumeprofile to test code

Screenshot 2023-06-28 113640.png
Code:
#VolumeProfile_PreviousDay_displayed_NextDau
#20190426 Sleepyz

def height = PricePerRow.AUTOMATIC;
input timePerProfile = {CHART, MINUTE, HOUR, default DAY, WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input profiles = 1000;
input valueAreaPercent = 70;

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];
profile vol = VolumeProfile("startNewProfile" = cond, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent, onExpansion = no);

#Prior Day High/Low ValueAreas
def HVA = if IsNaN(vol.GetHighestValueArea()) then HVA[1] else vol.GetHighestValueArea();
def pHVA = CompoundValue(1, if cond then HVA[1] else pHVA[1], Double.NaN);
def LVA = if IsNaN(vol.GetLowestValueArea()) then LVA[1] else vol.GetLowestValueArea();
def pLVA = CompoundValue(1, if cond then LVA[1] else pLVA[1], Double.NaN);

plot PrevHVA = if isnan(close) then double.nan else pHVA;
plot PrevLVA = if isnan(close) then double.nan else pLVA;
PrevHVA.SetDefaultColor(Color.YELLOW);
PrevLVA.SetDefaultColor(Color.YELLOW);
PrevHVA.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PrevLVA.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);

#Prior Day POC Calculated
def POC = if IsNaN(vol.GetPointOfControl()) and cond then POC[1] else vol.GetPointOfControl();
def pPOC = CompoundValue (1, if cond then POC[1] else pPOC[1], Double.NaN);

plot PrevPOC = pPOC;
PrevPOC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PrevPOC.SetDefaultColor(Color.MAGENTA);
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
166 Online
Create Post

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