Volume profile based off pre-market session

shakib3585

Active member
VIP
Hello All,

Can anyone please help me with a script to find the volume profile based off pre market session only. I would like to have the VAH, VAL and POC based off pre market trading and plot them as horizontal lines on the current day. The aggregate period should be starting from 1 min till 4 hours. @SleepyZ would you care to step in.

Thank you
 
Last edited:
Solution
Thank you very much, King!!

With left axis box checked, this will overlay the /ES VWAP onto a chart of SPY, It uses the inrange snippet which allows the /ES VWAP to start at 1800 and continue throughout the trading day.

The upper image is the /ES VWAP on the SPY and for comparison, the lower panel is the ?ES VWAP on /ES

Screenshot 2024-01-27 090822.png
Code:
#
# TD Ameritrade IP Company, Inc. (c) 2011-2023
#

input numDevDn = -2.0;
input numDevUp = 2.0;
input timeFrame = {default DAY, WEEK, MONTH};
def volume = volume("/ES");
def vwap   = vwap("/ES");

def cap = getAggregationPeriod();
def errorInAggregation =
    timeFrame == timeFrame.DAY and cap >= AggregationPeriod.WEEK or
    timeFrame == timeFrame.WEEK and cap >= AggregationPeriod.MONTH...
Hello All,

Can anyone please help me with a script to find the volume profile based off pre market session only. I would like to have the VAH, VAL and POC based off pre market trading and plot them as horizontal lines on the current day. The aggregate period should be starting from 1 min till 4 hours. @SleepyZ would you care to step in.

Thank you

This will plot extended lines for premarket times for Volumeprofile POC/VAH/VAL levels.

The intraday premarket times are defined for 1m to 4hrs for the TOS standard, preset chart timeframes.

There is an option to just show lines for the last profile. For the higher timeframes, please make sure that the right time axis expansion is set for very few bars so that the last profile properly displays.

Screenshot 2023-12-27 135546.png
Code:
#Premarket_VolumeProfiles_Preset_Intraday_Times
input showlastprofileonly = yes;

def begin;
def end;
if GetAggregationPeriod() == AggregationPeriod.FOUR_MIN {
    begin = 0400;
    end   = 0928;
} else if GetAggregationPeriod() == AggregationPeriod.HOUR {
    begin = 0400;
    end   = 0900;
} else if GetAggregationPeriod() == AggregationPeriod.TWO_HOURS {
    begin = 0300;
    end   = 0900;
} else if GetAggregationPeriod() == AggregationPeriod.FOUR_HOURS {
    begin = 0100;
    end   = 0900;
} else {
    begin = 0400;
    end   = 0930;
}

def sec1 = SecondsFromTime(begin);
def sec2 = SecondsFromTime(end);
def isTime1 = (sec1 >= 0 and sec1[1] < 0) or (sec1 < sec1[1] and sec1 >= 0);
def isTime2 = (sec2 >= 0 and sec2[1] < 0) or (sec2 < sec2[1] and sec2 >= 0);
def inRange = CompoundValue(1, if isTime1 then 1 else if isTime2 then 0 else inRange[1], 0);
def tradingzones  = if inRange
                    then 1
                    else 0;

input pricePerRowHeightMode = { AUTOMATIC, default TICKSIZE};
input multiplier = 1;
input onExpansion = no;
input profiles = 1000;
input valueAreaPercent = 70;

def cond          = tradingzones[1] != tradingzones;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
}

profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);

def pc = if IsNaN(close) then pc[1] else if IsNaN(vol.GetPointOfControl()) and con then pc[1] else if tradingzones == 1 then vol.GetPointOfControl() else pc[1];
def hVA = if IsNaN(close) then hVA[1] else if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else if tradingzones == 1 then vol.GetHighestValueArea() else hVA[1];
def lVA = if IsNaN(close) then lVA[1] else if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else if tradingzones == 1 then vol.GetLowestValueArea() else lVA[1];

plot POC    = if showlastprofileonly and profiletoday > 1 then Double.NaN else pc;
plot VAHigh = if showlastprofileonly and profiletoday > 1 then Double.NaN else hVA;
plot VALow  = if showlastprofileonly and profiletoday > 1 then Double.NaN else lVA;

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

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"));

input bubbles = yes;
input bubblemover = 0;
def b  = bubblemover;
def b1 = b + 1;

AddChartBubble(bubbles and IsNaN(close[b]) and !IsNaN(close[b1]), POC[b1], "POC", POC.TakeValueColor());
AddChartBubble(bubbles and IsNaN(close[b]) and !IsNaN(close[b1]), VAHigh[b1], "VAH", VAHigh.TakeValueColor());
AddChartBubble(bubbles and IsNaN(close[b]) and !IsNaN(close[b1]), VALow[b1], "VAL", VALow.TakeValueColor(), no);

#
 

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

This will plot extended lines for premarket times for Volumeprofile POC/VAH/VAL levels.

The intraday premarket times are defined for 1m to 4hrs for the TOS standard, preset chart timeframes.

There is an option to just show lines for the last profile. For the higher timeframes, please make sure that the right time axis expansion is set for very few bars so that the last profile properly displays.
Thank you for the awesome indicator @SleepyZ . Two queries please

1) If I say showlastprofileonly = "no" then will it show all the previous day's pre market VAH, VAL, POC
2) In case of no pre market data , how will this indicator work

Thank you
 
Thank you for the awesome indicator @SleepyZ . Two queries please

1) If I say showlastprofileonly = "no" then will it show all the previous day's pre market VAH, VAL, POC
2) In case of no pre market data , how will this indicator work

Thank you

1. Yes, it should plot these. It will extend the lines to the beginning of the next day's premarket start. Some of the premarket periods are so narrow, it will appear to show less than 3 lines (See image) as some of the lines will overlap each other.

If you wanted these to extend to the right edge of the chart, it would require separate plots for each day's 3 lines.

2. I have not seen any without it in my developing/testing the code, so I would have to assume that nothing will appear. I just set the chart to not show extended hours and nothing from this script appears on the chart.
 
1. Yes, it should plot these. It will extend the lines to the beginning of the next day's premarket start. Some of the premarket periods are so narrow, it will appear to show less than 3 lines (See image) as some of the lines will overlap each other.


If you wanted these to extend to the right edge of the chart, it would require separate plots for each day's 3 lines.

2. I have not seen any without it in my developing/testing the code, so I would have to assume that nothing will appear. I just set the chart to not show extended hours and nothing from this script appears on the chart.
Thank you king!!
 
Thank you king!!
Hello @SleepyZ , I have a query. I am willing to scan the following where the active close price on a 1 min aggregation is greater than the pre market VAH. Please suggest if the attached code is right

Code:
def begin = 0400 ;
def end   = 0930;
def showlastprofileonly = no;

def sec1 = SecondsFromTime(begin);
def sec2 = SecondsFromTime(end);
def isTime1 = (sec1 >= 0 and sec1[1] < 0) or (sec1 < sec1[1] and sec1 >= 0);
def isTime2 = (sec2 >= 0 and sec2[1] < 0) or (sec2 < sec2[1] and sec2 >= 0);
def inRange = CompoundValue(1, if isTime1 then 1 else if isTime2 then 0 else inRange[1], 0);
def tradingzones  = if inRange
                    then 1
                    else 0;

input multiplier = 1;
input onExpansion = no;
input profiles = 1000;
input valueAreaPercent = 70;

def cond          = tradingzones[1] != tradingzones;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height = PricePerRow.TICKSIZE ;


profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);

def pc = if IsNaN(close) then pc[1] else if IsNaN(vol.GetPointOfControl()) and con then pc[1] else if tradingzones == 1 then vol.GetPointOfControl() else pc[1];
def hVA = if IsNaN(close) then hVA[1] else if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else if tradingzones == 1 then vol.GetHighestValueArea() else hVA[1];
def lVA = if IsNaN(close) then lVA[1] else if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else if tradingzones == 1 then vol.GetLowestValueArea() else lVA[1];

def POC    = if showlastprofileonly and profiletoday > 1 then Double.NaN else pc;
def VAHigh = if showlastprofileonly and profiletoday > 1 then Double.NaN else hVA;
def VALow  = if showlastprofileonly and profiletoday > 1 then Double.NaN else lVA;

def tph = VAHigh;
plot scan = close>=tph;
 
Hello @SleepyZ , I have a query. I am willing to scan the following where the active close price on a 1 min aggregation is greater than the pre market VAH. Please suggest if the attached code is right

Code:
def begin = 0400 ;
def end   = 0930;
def showlastprofileonly = no;

def sec1 = SecondsFromTime(begin);
def sec2 = SecondsFromTime(end);
def isTime1 = (sec1 >= 0 and sec1[1] < 0) or (sec1 < sec1[1] and sec1 >= 0);
def isTime2 = (sec2 >= 0 and sec2[1] < 0) or (sec2 < sec2[1] and sec2 >= 0);
def inRange = CompoundValue(1, if isTime1 then 1 else if isTime2 then 0 else inRange[1], 0);
def tradingzones  = if inRange
                    then 1
                    else 0;

input multiplier = 1;
input onExpansion = no;
input profiles = 1000;
input valueAreaPercent = 70;

def cond          = tradingzones[1] != tradingzones;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height = PricePerRow.TICKSIZE ;


profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);

def pc = if IsNaN(close) then pc[1] else if IsNaN(vol.GetPointOfControl()) and con then pc[1] else if tradingzones == 1 then vol.GetPointOfControl() else pc[1];
def hVA = if IsNaN(close) then hVA[1] else if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else if tradingzones == 1 then vol.GetHighestValueArea() else hVA[1];
def lVA = if IsNaN(close) then lVA[1] else if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else if tradingzones == 1 then vol.GetLowestValueArea() else lVA[1];

def POC    = if showlastprofileonly and profiletoday > 1 then Double.NaN else pc;
def VAHigh = if showlastprofileonly and profiletoday > 1 then Double.NaN else hVA;
def VALow  = if showlastprofileonly and profiletoday > 1 then Double.NaN else lVA;

def tph = VAHigh;
plot scan = close>=tph;

As the market is closed, I tested the code in the scanner and it did produce results, but I was not able to see if it was accurately working on a chart.

I tested it on a chart in ONDemand and it appeared to work. The image shows the full code in the upper pane and your scan code below. The image shows the close above the tph in the upper pane and a true/1 result in the lower pane. I tested it when close was below tph and got a correct, false/0 result in the lower scan code.

 
As the market is closed, I tested the code in the scanner and it did produce results, but I was not able to see if it was accurately working on a chart.

I tested it on a chart in ONDemand and it appeared to work. The image shows the full code in the upper pane and your scan code below. The image shows the close above the tph in the upper pane and a true/1 result in the lower pane. I tested it when close was below tph and got a correct, false/0 result in the lower scan code.
Thank you King!!
 
Thank you King!!
Hello @SleepyZ , apologies for seeking help from you again. I was wondering if you could please help me with a code to plot any given previous day's pre-market VAH, VAL, and POC and plot them as lines. I would request a similar one that you have made for me before, except now it's for the previous day's pre-market VAH, VAL, and POC, starting from 1 minute until 4 hours of aggregation. Please note that I also plan to use the code in my scanner. Thank you very much and sorry again for bothering you.
 
Hello @SleepyZ , apologies for seeking help from you again. I was wondering if you could please help me with a code to plot any given previous day's pre-market VAH, VAL, and POC and plot them as lines. I would request a similar one that you have made for me before, except now it's for the previous day's pre-market VAH, VAL, and POC, starting from 1 minute until 4 hours of aggregation. Please note that I also plan to use the code in my scanner. Thank you very much and sorry again for bothering you.

This extends the prior day's values to the current day. You can uncomment the addlabels to verify the values.

Code:
def begin = 0400 ;
def end   = 0930;
def showlastprofileonly = yes;

def ymd = GetYYYYMMDD();
def count = if IsNaN(close) and ymd != ymd[1] then count[1] + 1 else count[1];
def countcond  = HighestAll(count) - count;

def sec1 = SecondsFromTime(begin);
def sec2 = SecondsFromTime(end);
def isTime1 = (sec1 >= 0 and sec1[1] < 0) or (sec1 < sec1[1] and sec1 >= 0);
def isTime2 = (sec2 >= 0 and sec2[1] < 0) or (sec2 < sec2[1] and sec2 >= 0);
def inRange = CompoundValue(1, if isTime1 then 1 else if isTime2 then 0 else inRange[1], 0);
def tradingzones  = if inRange
                    then 1
                    else 0;

input multiplier = 1;
input onExpansion = no;
input profiles = 1000;
input valueAreaPercent = 70;

def cond          = tradingzones[1] != tradingzones;
def profilecount  = if cond then profilecount[1] + 1 else profilecount[1];
def profiletoday  = HighestAll(profilecount) - profilecount ;

def height = PricePerRow.TICKSIZE ;


profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = no, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);


def pc = if IsNaN(close) then pc[1] else if IsNaN(vol.GetPointOfControl()[1]) and con then pc[1] else if  tradingzones == 1 then vol.GetPointOfControl() else pc[1];
def pc1 = if pc != pc[1] then pc else pc1[1];
def pc2 = if IsNaN(close) then pc2[1] else if pc1[1] != pc1 then pc1[1] else pc2[1];
#AddLabel(1, pc1[1] + " " + pc2[1]);

def hVA = if IsNaN(close) then hVA[1] else if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else if tradingzones == 1 then vol.GetHighestValueArea() else hVA[1];
def hva1 = if hVA != hVA[1] then hVA[1] else hva1[1];
def hva2 = if isnan(close) then hva2[1] else if hva1 != hva1[1] then hVA[1] else hva2[1];
#AddLabel(1, hva1 + " " + hva2[1]);

def lVA = if IsNaN(close) then lVA[1] else if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else
if tradingzones == 1 then vol.GetLowestValueArea() else lVA[1];
def lva1 = if lVA != lVA[1] then lVA[1] else lva1[1];
def lva2 = if isnan(close) then lva2[1] else if lva1 != lva1[1] then lVA[1] else lva2[1];
#AddLabel(1, lva1 + " " + lva2[1]);

def POC    = if showlastprofileonly and profiletoday > 3 then Double.NaN else pc;
def VAHigh = if showlastprofileonly and profiletoday > 1 then Double.NaN else hVA;
def VALow  = if showlastprofileonly and profiletoday > 1 then Double.NaN else lVA;

def poc1    = if showlastprofileonly and profiletoday > 1 then Double.NaN else pc2[1];
def VAHigh1 = if showlastprofileonly and profiletoday > 1 then Double.NaN else hVA2[1];
def VALow1  = if showlastprofileonly and profiletoday > 1 then Double.NaN else lVA2[1];

def tph1 = VAHigh1;
plot scan = close>=tph1;

#
 
This extends the prior day's values to the current day. You can uncomment the addlabels to verify the values.

Thank you very much, King!!
Brothers you might like to see this script that allows you a script to adjust to any time that you set on the charts. That also saves your computer a little resources by not having to declare the different timeframes.

Thank you

https://usethinkscript.com/threads/automating-aggregation-selection-for-thinkorswim.3183/#post-29405
 
Hello All,

Can anyone please help me with a script to find the volume profile based off pre market session only. I would like to have the VAH, VAL and POC based off pre market trading and plot them as horizontal lines on the current day. The aggregate period should be starting from 1 min till 4 hours. @SleepyZ would you care to step in.

Thank you
Why not show the PDHi (Previous Days High) and PDLow (Previous Days Low) on your chart. Everyone might like these? This is my code for those:

https://usethinkscript.com/threads/agaig-previous-day-high-low-for-thinkorswim.17621/
 
Last edited by a moderator:
Thank you very much, King!!

With left axis box checked, this will overlay the /ES VWAP onto a chart of SPY, It uses the inrange snippet which allows the /ES VWAP to start at 1800 and continue throughout the trading day.

The upper image is the /ES VWAP on the SPY and for comparison, the lower panel is the ?ES VWAP on /ES

Screenshot 2024-01-27 090822.png
Code:
#
# TD Ameritrade IP Company, Inc. (c) 2011-2023
#

input numDevDn = -2.0;
input numDevUp = 2.0;
input timeFrame = {default DAY, WEEK, MONTH};
def volume = volume("/ES");
def vwap   = vwap("/ES");

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");

##### Inrange
input begin = 1800 ;
input end   = 1700;


def ymd = GetYYYYMMDD();
def count = if IsNaN(close) and ymd != ymd[1] then count[1] + 1 else count[1];
def countcond  = HighestAll(count) - count;

def sec1 = SecondsFromTime(begin);
def sec2 = SecondsFromTime(end);
def isTime1 = (sec1 >= 0 and sec1[1] < 0) or (sec1 < sec1[1] and sec1 >= 0);
def isTime2 = (sec2 >= 0 and sec2[1] < 0) or (sec2 < sec2[1] and sec2 >= 0);
def inRange = CompoundValue(1, if isTime1 then 1 else if isTime2 then 0 else inRange[1], 0);
#######

def yyyyMmDd = getYyyyMmDd();
def periodIndx;
switch (timeFrame) {
case DAY:
    periodIndx = inrange;
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 (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));

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));
 
Solution
With left axis box checked, this will overlay the /ES VWAP onto a chart of SPY, It uses the inrange snippet which allows the /ES VWAP to start at 1800 and continue throughout the trading day.

The upper image is the /ES VWAP on the SPY and for comparison, the lower panel is the ?ES VWAP on /ES
Behold the King!!
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
373 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