Scan Help POC close to VAH or VAL

MHCain

New member
Hey All, I was wanting to be able to scan stocks where the POC (Ref Volume Profile) is close to the VAHigh or VALow. I have been messing around with scripts with success. Below is a scan from Price close to the POC. I hope this logic could be utilized or help in some way.

close is greater than (reference VolumeProfile("on expansion" = No)."POC" * 0.98) and close is less than (reference VolumeProfile("on expansion" = No)."POC" * 1.02)

Thank for the help, stay healthy......
 
Hey All, I was wanting to be able to scan stocks where the POC (Ref Volume Profile) is close to the VAHigh or VALow. I have been messing around with scripts with success. Below is a scan from Price close to the POC. I hope this logic could be utilized or help in some way.

close is greater than (reference VolumeProfile("on expansion" = No)."POC" * 0.98) and close is less than (reference VolumeProfile("on expansion" = No)."POC" * 1.02)

Thank for the help, stay healthy......
This can be a very helpful scan, thank you for posting. Does anyone know how to change the time period to 1 hour:20 days instead of daily on a scan for the POC in relation to price?
 
Last edited:

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

Hey All, I was wanting to be able to scan stocks where the POC (Ref Volume Profile) is close to the VAHigh or VALow. I have been messing around with scripts with success. Below is a scan from Price close to the POC. I hope this logic could be utilized or help in some way.

close is greater than (reference VolumeProfile("on expansion" = No)."POC" * 0.98) and close is less than (reference VolumeProfile("on expansion" = No)."POC" * 1.02)

Thank for the help, stay healthy......



Update in POST #7 of this thread
 
Last edited:
Just comment out (or comment in) the 2 lines of code as desired if you want to scan for VA low or VA high

Code:
#Price is within X% max of the Value Area High or Value Area Low
#### Change percentvalue to decirect % in decimal format
###  Example .02 is 2%  and .025 is 2.5%
# By XeoNoX via usethinkscript.com
def percentvalue = .01;
def valh = reference VolumeProfile()."VAHigh";
def vall = reference VolumeProfile()."VAlow";


##############  Price close is with X percent of VALUE AREA HIGH  #################

#def scanhigh = valh*percentvalue;
#plot scan_high = absvalue(close - scanhigh) is less than or equal to scanhigh;



#############  Price close is with X percent of VALUE AREA LOW  ##############

def scanlow = vall*percentvalue;
plot scan_low = absvalue(close - scanlow) is less than or equal to scanlow;
Thank you for this! Can you give an example of comment in or comment out 2 lines? Would it be the lines just below VALUE AREA HIGH or VALUE AREA LOW?
 
@Optionsguy Commenting out code is done by putting "#" at the start of a line.

Example:

Code:
#def scanlow = vall*percentvalue;
#plot scan_low = absvalue(close - scanlow) is less than or equal to scanlow;

This will disable the "scan_low" variable.
 
I didn't check it, I assumed that the OP's code worked. After testing the OPs code I noticed it didn't work because the VolumeProfile code is missing manual data points. Therefore my code didn't work.

Here is a scan by Peter Hahn with video on how to use thinkorswim scan for Volume Profile Value Area High Value Area Low and POC better known as point of control. https://www.hahn-tech.com/thinkorswim-scan-volume-profile/

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 AboveVaLong = upperVaRange and aboveVaHigh;
# use this scan to find stocks that have traded above the value area high
# and are retracing into it for a potential long setup
plot scan = AboveVaLong;

def InsideVaLong = lowerVaRange and insideVA;
# use this scan to find stocks that have traded within the value area
# and are approaching the value area low for a potential long setup
#plot scan = InsideVaLong;

def BelowVaShort = lowerVaRange and belowVaLow;
# use this scan to find stocks that have traded below the value area low
# and are retracing into it for a potential short setup
#plot scan = BelowVaShort;

def InsideVaShort = upperVaRange and insideVA;
# use this scan to find stocks that have traded within the value area
# and are approaching the value area high for a potential short setup
#plot scan = InsideVaShort;
 
I didn't check it, I assumed that the OP's code worked. After testing the OPs code I noticed it didn't work because the VolumeProfile code is missing manual data points. Therefore my code didn't work.

Here is a scan by Peter Hahn with video on how to use thinkorswim scan for Volume Profile Value Area High Value Area Low and POC better known as point of control. https://www.hahn-tech.com/thinkorswim-scan-volume-profile/

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 AboveVaLong = upperVaRange and aboveVaHigh;
# use this scan to find stocks that have traded above the value area high
# and are retracing into it for a potential long setup
plot scan = AboveVaLong;

def InsideVaLong = lowerVaRange and insideVA;
# use this scan to find stocks that have traded within the value area
# and are approaching the value area low for a potential long setup
#plot scan = InsideVaLong;

def BelowVaShort = lowerVaRange and belowVaLow;
# use this scan to find stocks that have traded below the value area low
# and are retracing into it for a potential short setup
#plot scan = BelowVaShort;

def InsideVaShort = upperVaRange and insideVA;
# use this scan to find stocks that have traded within the value area
# and are approaching the value area high for a potential short setup
#plot scan = InsideVaShort;
Awesome,Thank you!!!
 
Trying to create a scan similar to trendspiders "volume shelf" scan which gives you stocks that are sitting in a high volume area (a previous or current consolidation)

Examples shown below

$PLTR
jLzNeL6.png

$XL
TDsYVTo.png


As you can see the price is sitting on a 'shelf'

I've tried creating the scanner but using the "POC" or 'point of control' value given by the TOS Volume Profile indicator but it does not give any results which leads me to believe that it isn't a number value and is a range / area.

There's a lot of skilled users here so I'm guessing someone has a fix / workaround

Thanks in advance for any help with this problem!
 

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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