Scan Help POC close to VAH or VAL

MHCain

New member
VIP
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......
 

Optionsguy

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......
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:

XeoNoX

Well-known member
VIP
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:

Optionsguy

New member
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?
 

BenTen

Administrative
Staff member
Staff
VIP
@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.
 

XeoNoX

Well-known member
VIP
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;
 

MHCain

New member
VIP
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!!!
 

AlexsOptions

New member
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!
 

Similar threads

Top