Price returning to a previous demand zone, not just the lowest

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #261342 quote
    MrMagic
    Participant
    Average

    Hi everyone,

    I’m hoping someone can help me refine this screener.

    Ivan kindly helped me with an earlier version, but I think the code is still mainly detecting the lowest low within the lookback period. That makes sense technically, but it misses what I’m actually trying to find visually on the chart.


    What I’m looking for is not just a single support line or the absolute lowest wick.


    I’m trying to screen for stocks where price has formed a previous demand area/base, moved away strongly, and has now returned back into that same zone.


    So ideally the screener would detect something like:

    • a cluster/base/consolidation area
    • price moves away from that area
    • price later comes back into or close to that same zone
    • stock price below $20
    • average volume above 1,000,000

    I’ve attached examples of the sort of zones I mean. The blue box is the area I’d like the screener to approximate.


    I appreciate ProScreener may not be able to identify discretionary demand zones perfectly, so even a practical approximation would be really helpful.


    For example, maybe using:

    • recent consolidation/base area
    • similar lows within a tolerance
    • breakout then retest
    • or price returning to a prior support range rather than the exact lowest low


    Any suggestions on how best to code this would be really appreciated.


    Thanks again.

    Screenshot-2026-05-19-at-11.45.17.png Screenshot-2026-05-19-at-11.45.17.png Screenshot-2026-05-19-at-11.45.40.png Screenshot-2026-05-19-at-11.45.40.png Screenshot-2026-05-19-at-11.45.44.png Screenshot-2026-05-19-at-11.45.44.png Screenshot-2026-05-19-at-11.45.53.png Screenshot-2026-05-19-at-11.45.53.png Screenshot-2026-05-19-at-11.46.09.png Screenshot-2026-05-19-at-11.46.09.png Screenshot-2026-05-19-at-11.46.14.png Screenshot-2026-05-19-at-11.46.14.png
    #261344 quote
    Nicolas
    Keymaster
    Legend

    Can you point us (or give code) of the earlier previous version made by Ivan please? That could help as a base or improved variant.

    MrMagic thanked this post
    #261351 quote
    MrMagic
    Participant
    Average

    // ————————————

    // INPUTS

    // ————————————

    // Price and Volume constraints

    priceCap = 20

    volCap = 1000000

    volLength = 20 // Moving average period for volume

    // Lookback period for the demand zone (Support)

    lookback = 50

    // Tolerance to define “touching” or “very close” (0.02 = 2%)

    tolerance = 0.02

    // ————————————

    // FILTERS CALCULATION

    // ————————————

    // Calculate Average Volume

    avgVol = Average[volLength](Volume)

    // Conditions for Price and Volume

    c1 = Close < priceCap

    c2 = avgVol > volCap

    // ————————————

    // DEMAND ZONE IDENTIFICATION

    // ————————————

    supportLevel = Lowest[lookback](Low)[1]

    // ————————————

    // PROXIMITY LOGIC

    // ————————————

    // Upper limit and lower limit

    zoneTop = supportLevel * (1 + tolerance)

    zoneBot = supportLevel * (1 – tolerance)

    c3 = Low <= zoneTop AND Close >= zoneBot

    // ————————————

    SCREENER[c1 AND c2 AND c3] ((Close – supportLevel) / supportLevel * 100 AS “% Dist to Supp”)


    #261354 quote
    Iván González
    Moderator
    Legend

    maybe this screener can do what you want:

    //---------------------------------------------------
    //PRC_Wick Pressure Zones by BigBeluga
    //version = 0
    //09.09.2025
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    //---------------------------------------------------
    
    //---------------------------------------------------
    // inputs
    //---------------------------------------------------
    lookback = 200
    threshold = 80
    extendBars = 20
    maxLevels  = 10
    rsiLen = 14
    
    //---------------------------------------------------
    // Variables auxiliares
    //---------------------------------------------------
    bodyTop = MAX(open, close)
    bodyBot = MIN(open, close)
    // Mechas relativas (evitar división por 0)
    denUp = MAX(bodyTop, 0.0000001)
    denLo = MAX(low,     0.0000001)
    upperWick = (high - bodyTop) / denUp
    lowerWick = (bodyBot - low)  / denLo
    
    maxUpper = HIGHEST[lookback](upperWick)
    maxLower = HIGHEST[lookback](lowerWick)
    
    sizeUpWick = 0
    sizeLoWick = 0
    IF maxUpper > 0 THEN
       sizeUpWick = FLOOR( (upperWick / maxUpper) * 100 )
    ENDIF
    IF maxLower > 0 THEN
       sizeLoWick = FLOOR( (lowerWick / maxLower) * 100 )
    ENDIF
    //---------------------------------------------------
    myrsi = RSI[rsiLen](close)
    
    //---------------------------------------------------
    // Separación mínima entre zonas
    ONCE startidx = -100000
    //---------------------------------------------------
    // Boxes
    //---------------------------------------------------
    ONCE n = 0
    
    newUpper = sizeUpWick >= threshold AND NOT (sizeLoWick >= threshold) AND myrsi > 50 AND (BarIndex - startidx > extendBars)
    newLower = sizeLoWick >= threshold AND NOT (sizeUpWick >= threshold) AND myrsi < 50 AND (BarIndex - startidx > extendBars)
    
    // Crear zona superior
    IF newUpper THEN
       startidx = BarIndex
       n = n + 1
       $side[n] = 1
       $left[n] = BarIndex - 1
       $top[n]  = high
       $bot[n]  = bodyTop
       $right[n] = barindex + 1
       $broken[n] = 0
       $volume[n] = volume
       // Límite de zonas: mantener sólo las más recientes
       IF n > maxLevels THEN
          // Shift a la izquierda
          FOR k = 1 TO n - 1 DO
             $side[k] = $side[k+1]
             $left[k] = $left[k+1]
             $top[k]  = $top[k+1]
             $bot[k]  = $bot[k+1]
             $right[k] = $right[k+1]
             $broken[k] = $broken[k+1]
             $volume[k] = $volume[k+1]
          NEXT
          n = maxLevels
       ENDIF
    ENDIF
    
    // Crear zona inferior
    IF newLower THEN
       startidx = BarIndex
       n = n + 1
       $side[n] = -1
       $left[n] = BarIndex - 1
       $top[n]  = bodyBot
       $bot[n]  = low
       $right[n] = barindex + 1
       $broken[n] = 0
       $volume[n] = volume
       
       IF n > maxLevels THEN
          FOR k = 1 TO n - 1 DO
             $side[k] = $side[k+1]
             $left[k] = $left[k+1]
             $top[k]  = $top[k+1]
             $bot[k]  = $bot[k+1]
             $right[k] = $right[k+1]
             $broken[k] = $broken[k+1]
             $volume[k] = $volume[k+1]
          NEXT
          n = maxLevels
       ENDIF
    ENDIF
    
    //---------------------------------------------------
    // DIBUJO y GESTIÓN
    //---------------------------------------------------
    IF islastbarupdate THEN
       
       FOR i = 1 TO n DO
          for j=barindex-$right[i] downto 0 do
             IF $side[i] = 1 AND low[j] > $top[i] THEN
                $broken[i] = 1
                $right[i] = barindex[j]
                break
             ELSIF $side[i] = -1 AND high[j] < $bot[i] THEN
                $broken[i] = 1
                $right[i] = barindex[j]
                break
             ENDIF
          next
          
          if $broken[i]=0 AND $side[i]=1 and close>$bot[i] and close< $top[i] THEN
             
             setup = 1
             
          ELSIF $broken[i]=0 AND $side[i]=-1 and close>$bot[i] and close< $top[i] THEN
             setup = -1
             
          ENDIF
          
       NEXT
    ENDIF
    
    screener[setup<>0](setup)
    

    This is the indicator:

    //---------------------------------------------------
    //PRC_Wick Pressure Zones by BigBeluga
    //version = 0
    //09.09.2025
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    //---------------------------------------------------
    DEFPARAM DrawOnLastBarOnly = true
    //---------------------------------------------------
    // inputs
    //---------------------------------------------------
    lookback = 200
    threshold = 80
    extendBars = 20
    maxLevels  = 10
    rsiLen = 14
    upR = 255
    upG = 0
    upB = 0
    dnR = 0
    dnG = 255
    dnB = 0
    //---------------------------------------------------
    // Variables auxiliares
    //---------------------------------------------------
    bodyTop = MAX(open, close)
    bodyBot = MIN(open, close)
    // Mechas relativas (evitar división por 0)
    denUp = MAX(bodyTop, 0.0000001)
    denLo = MAX(low,     0.0000001)
    upperWick = (high - bodyTop) / denUp
    lowerWick = (bodyBot - low)  / denLo
    
    maxUpper = HIGHEST[lookback](upperWick)
    maxLower = HIGHEST[lookback](lowerWick)
    
    sizeUpWick = 0
    sizeLoWick = 0
    IF maxUpper > 0 THEN
       sizeUpWick = FLOOR( (upperWick / maxUpper) * 100 )
    ENDIF
    IF maxLower > 0 THEN
       sizeLoWick = FLOOR( (lowerWick / maxLower) * 100 )
    ENDIF
    //---------------------------------------------------
    myrsi = RSI[rsiLen](close)
    vol = volume
    //---------------------------------------------------
    // Separación mínima entre zonas
    ONCE startidx = -100000
    //---------------------------------------------------
    // Boxes
    //---------------------------------------------------
    ONCE n = 0
    
    newUpper = sizeUpWick >= threshold AND NOT (sizeLoWick >= threshold) AND myrsi > 50 AND (BarIndex - startidx > extendBars)
    newLower = sizeLoWick >= threshold AND NOT (sizeUpWick >= threshold) AND myrsi < 50 AND (BarIndex - startidx > extendBars)
    
    // Crear zona superior
    IF newUpper THEN
       startidx = BarIndex
       n = n + 1
       $side[n] = 1
       $left[n] = BarIndex - 1
       $top[n]  = high
       $bot[n]  = bodyTop
       $right[n] = barindex + 1
       $broken[n] = 0
       $volume[n] = volume
       // Límite de zonas: mantener sólo las más recientes
       IF n > maxLevels THEN
          // Shift a la izquierda
          FOR k = 1 TO n - 1 DO
             $side[k] = $side[k+1]
             $left[k] = $left[k+1]
             $top[k]  = $top[k+1]
             $bot[k]  = $bot[k+1]
             $right[k] = $right[k+1]
             $broken[k] = $broken[k+1]
             $volume[k] = $volume[k+1]
          NEXT
          n = maxLevels
       ENDIF
    ENDIF
    
    // Crear zona inferior
    IF newLower THEN
       startidx = BarIndex
       n = n + 1
       $side[n] = -1
       $left[n] = BarIndex - 1
       $top[n]  = bodyBot
       $bot[n]  = low
       $right[n] = barindex + 1
       $broken[n] = 0
       $volume[n] = volume
       
       IF n > maxLevels THEN
          FOR k = 1 TO n - 1 DO
             $side[k] = $side[k+1]
             $left[k] = $left[k+1]
             $top[k]  = $top[k+1]
             $bot[k]  = $bot[k+1]
             $right[k] = $right[k+1]
             $broken[k] = $broken[k+1]
             $volume[k] = $volume[k+1]
          NEXT
          n = maxLevels
       ENDIF
    ENDIF
    
    //---------------------------------------------------
    // DIBUJO y GESTIÓN
    //---------------------------------------------------
    IF islastbarupdate THEN
       
       FOR i = 1 TO n DO
          for j=barindex-$right[i] downto 0 do
             IF $side[i] = 1 AND low[j] > $top[i] THEN
                $broken[i] = 1
                $right[i] = barindex[j]
                break
             ELSIF $side[i] = -1 AND high[j] < $bot[i] THEN
                $broken[i] = 1
                $right[i] = barindex[j]
                break
             ENDIF
          next
          
          vol=$volume[i]
          
          if $broken[i]=1 and $side[i]=1 then
             drawrectangle($left[i],$bot[i],$left[i]+2,$top[i])coloured("red")
             drawsegment($left[i],$top[i],$right[i],$top[i])coloured("grey",125)style(line,3)
          ELSIF $broken[i]=0 AND $side[i]=1 THEN
             leftX  = $left[i]
             rightX = barindex
             topY   = $top[i]
             botY   = $bot[i]
             height = ABS(topY - botY)
             IF height > 0 THEN
                steps  = 10
                stepH  = height / steps
                DRAWRECTANGLE(leftX, topY, leftX + 2, botY) COLOURED(upR,upG,upB)
                FOR s = 0 TO steps - 1 DO
                   segBot   = botY + stepH * s
                   segTop   = segBot + stepH
                   alphaVal = 30 + s * 12
                   IF s = steps - 1 THEN
                      alphaVal = 160
                   ENDIF
                   DRAWRECTANGLE(leftX, segTop, rightX, segBot) COLOURED(upR,upG,upB, 0)fillcolor(upR,upG,upB, alphaVal)
                NEXT
                midY = botY + height * 0.5
                DRAWTEXT("#vol#", rightX, midY)
             ENDIF
          elsif $broken[i]=1 and $side[i]=-1 then
             drawrectangle($left[i],$bot[i],$left[i]+2,$top[i])coloured("green")
             drawsegment($left[i],$bot[i],$right[i],$bot[i])coloured("grey",125)style(line,3)
          ELSIF $broken[i]=0 AND $side[i]=-1 THEN
             leftX  = $left[i]
             rightX = barindex
             topY   = $top[i]
             botY   = $bot[i]
             height = ABS(topY - botY)
             IF height > 0 THEN
                steps  = 10
                stepH  = height / steps
                DRAWRECTANGLE(leftX, topY, leftX + 2, botY) COLOURED(dnR,dnG,dnB)
                FOR s = 0 TO steps - 1 DO
                   segBot   = botY + stepH * s
                   segTop   = segBot + stepH
                   alphaVal = 160 - s * 12
                   IF s = 0 THEN
                      alphaVal = 160
                   ENDIF
                   DRAWRECTANGLE(leftX, segTop, rightX, segBot) COLOURED(dnR,dnG,dnB, 0)fillcolor(dnR,dnG,dnB, alphaVal)
                NEXT
                midY = botY + height * 0.5
                DRAWTEXT("#vol#", rightX, midY)
             ENDIF
          endif
       NEXT
    ENDIF
    
    RETURN
    


    MrMagic and Nicolas thanked this post
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.

Price returning to a previous demand zone, not just the lowest


ProScreener: Market Scanners & Detection

New Reply
Author
author-avatar
MrMagic @mrmagic Participant
Summary

This topic contains 3 replies,
has 3 voices, and was last updated by Iván González
1 week, 3 days ago.

Topic Details
Forum: ProScreener: Market Scanners & Detection
Language: English
Started: 05/19/2026
Status: Active
Attachments: 6 files
Logo Logo
Loading...