Daily Range Indicator – Text Overwrite at each Change of Bar

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #260010 quote
    GraHal
    Participant
    Master

    For the Indicator code below, at each new bar the text showing % of ADR prints on top of the previous entry and so it quickly gets like a blob of paint and is illegible! 🙂 See attached for 1 print over.


    Is there a fix for this please?

    (An aside:

    why are there no tooltips showing when I hover the icons in the above toolbar? I hope I have picked the correct icon for insert PRT code?? hahah I did pick the correct icon, but tooltips would be useful)

    // --- Indicator: Midnight Reset Pro (ADR % Flag) ---
    // --- USER OPTIONS ---
    Offset    = 5
    ADRPeriod = 14
    // --------------------
    
    
    // 1. Midnight Reset
    ONCE TodayHigh = High
    ONCE TodayLow  = Low
    ONCE StartBar  = BarIndex
    
    
    IF OpenDay <> OpenDay THEN
        StartBar  = BarIndex
        TodayHigh = High
        TodayLow  = Low
    ELSE
        TodayHigh = MAX(TodayHigh, High)
        TodayLow  = MIN(TodayLow, Low)
    ENDIF
    
    
    // 2. Calculations
    CurrentRange = TodayHigh - TodayLow
    MidPoint     = ROUND((TodayHigh + TodayLow) / 2)
    MyADR        = ROUND(Average[ADRPeriod](DHigh(1) - DLow(1)))
    
    
    // Calculate Range as % of ADR
    IF MyADR > 0 THEN
        PctOfADR = (CurrentRange / MyADR) * 100
    ELSE
        PctOfADR = 0
    ENDIF
    
    
    // 3. DRAW VISUALS
    IF IsLastBarUpdate THEN
        // Vertical line at Midnight
        DRAWVLINE(StartBar) coloured(150,150,150) style(dottedline,1)
        
        // Level Segments
        DRAWSEGMENT(StartBar, TodayHigh, BarIndex + Offset, TodayHigh) coloured(0,255,0) style(line,3)
        DRAWSEGMENT(StartBar, TodayLow,  BarIndex + Offset, TodayLow)  coloured(255,0,0) style(line,3)
        DRAWSEGMENT(StartBar, MidPoint,  BarIndex + Offset, MidPoint)  coloured(255,255,0) style(dottedline,2)
        
        // Logic for Color & Label
        IF PctOfADR >= 90 THEN
            r = 255
            g = 165
            b = 0
            BACKGROUNDCOLOR(255, 165, 0, 20) // Light orange background
        ELSE
            r = 255
            g = 255
            b = 255
        ENDIF
        
        // Rounded label for visual clarity
        DisplayPct = ROUND(PctOfADR)
        DRAWTEXT("#DisplayPct#% ADR", BarIndex + Offset, TodayHigh + 5*pipsize, SansSerif, Bold, 12) coloured(r, g, b)
    ENDIF
    
    
    // 4. Return values for the price scale
    IF IsLastBarUpdate THEN
        ShowHigh = TodayHigh
        ShowLow  = TodayLow
        ShowMid  = MidPoint
        ShowADR  = MyADR
    ELSE
        ShowHigh = UNDEFINED
        ShowLow  = UNDEFINED
        ShowMid  = UNDEFINED
        ShowADR  = UNDEFINED
    ENDIF
    
    
    RETURN ShowHigh AS "High" COLOURED(0,255,0), ShowLow AS "Low" COLOURED(255,0,0), ShowMid AS "Mid" COLOURED(255,255,0), ShowADR AS "ADR" COLOURED(200,200,200)
    
    
    
    fAhQufZHTc.png fAhQufZHTc.png
    #260014 quote
    Nicolas
    Keymaster
    Master

    There are actually two things fixed in the corrected version below. First, DEFPARAM DrawOnLastBarOnly = True is added at the top and this is the main fix, it makes the entire indicator execute only once per bar instead of on every incoming tick, which is exactly what stops the text from piling up. Second, I noticed your original day-change detection IF OpenDay <> OpenDay was comparing the variable to itself (always false), so it was silently broken. It should be OpenDay <> OpenDay[1] to compare today against yesterday.

    DEFPARAM DrawOnLastBarOnly = True
    
    
    // --- Indicator: Midnight Reset Pro (ADR % Flag) ---
    // --- USER OPTIONS ---
    Offset    = 5
    ADRPeriod = 14
    // --------------------
    
    
    // 1. Midnight Reset
    ONCE TodayHigh = High
    ONCE TodayLow  = Low
    ONCE StartBar  = BarIndex
    
    
    IF OpenDay <> OpenDay[1] THEN
        StartBar  = BarIndex
        TodayHigh = High
        TodayLow  = Low
    ELSE
        TodayHigh = MAX(TodayHigh, High)
        TodayLow  = MIN(TodayLow, Low)
    ENDIF
    
    
    // 2. Calculations
    CurrentRange = TodayHigh - TodayLow
    MidPoint     = ROUND((TodayHigh + TodayLow) / 2)
    MyADR        = ROUND(Average[ADRPeriod](DHigh(1) - DLow(1)))
    
    
    // Calculate Range as % of ADR
    IF MyADR > 0 THEN
        PctOfADR = (CurrentRange / MyADR) * 100
    ELSE
        PctOfADR = 0
    ENDIF
    
    
    // 3. DRAW VISUALS
    // Vertical line at Midnight
    DRAWVLINE(StartBar) coloured(150,150,150) style(dottedline,1)
    
    
    // Level Segments
    DRAWSEGMENT(StartBar, TodayHigh, BarIndex + Offset, TodayHigh) coloured(0,255,0) style(line,3)
    DRAWSEGMENT(StartBar, TodayLow,  BarIndex + Offset, TodayLow)  coloured(255,0,0) style(line,3)
    DRAWSEGMENT(StartBar, MidPoint,  BarIndex + Offset, MidPoint)  coloured(255,255,0) style(dottedline,2)
    
    
    // Logic for Color & Label
    IF PctOfADR >= 90 THEN
        r = 255
        g = 165
        b = 0
        BACKGROUNDCOLOR(255, 165, 0, 20)
    ELSE
        r = 255
        g = 255
        b = 255
    ENDIF
    
    
    // Rounded label for visual clarity
    DisplayPct = ROUND(PctOfADR)
    DRAWTEXT("#DisplayPct#% ADR", BarIndex + Offset, TodayHigh + 5*pipsize, SansSerif, Bold, 12) coloured(r, g, b)
    
    
    // 4. Return values for the price scale
    RETURN TodayHigh AS "High" COLOURED(0,255,0), TodayLow AS "Low" COLOURED(255,0,0), MidPoint AS "Mid" COLOURED(255,255,0), MyADR AS "ADR" COLOURED(200,200,200)
    
    GraHal and Iván González thanked this post
    #260024 quote
    GraHal
    Participant
    Master

    Please can the code above be amended so that the High, Med and Low lines only show as horizontal lines for today only (and not not staircase back over previous days etc as currently).


    Also please could the High Med and Low lines start at midnight (not 5am as currently) for a UTC+1 timezone … be good if this could be a ‘user adjusted setting’??

    #260026 quote
    Nicolas
    Keymaster
    Master

    I’m not sure I had the perfect picture, but here is a new draft version:

    The three changes made:

    1. Today-only lines — DEFPARAM DrawOnLastBarOnly = True means every drawing is redrawn from scratch on the last bar only, so DRAWSEGMENT always draws a fresh single segment anchored to StartBar. The staircase on previous days came from the RETURN series plotting a continuous connected line across all history. Fixed by returning 0 for all bars before StartBar, so the price-scale series has no values before today’s session.
    2. Midnight detection — replaced OpenDay <> OpenDay[1] with a time-based check using OpenTime and a calculated ResetTimeOpenTime is in UTC on PRT servers. For UTC+1 local midnight = 23:00 UTC the previous day, so ResetTime = MOD(24 - UTCOffset, 24) * 10000.
    3. UTCOffset is a user-adjustable parameter at the top. Set it to 0 for UTC, 1 for UTC+1, 2 for UTC+2, -5 for UTC-5 etc.
    DEFPARAM DrawOnLastBarOnly = True
    
    
    // --- Indicator: Midnight Reset Pro (ADR % Flag) ---
    // --- USER OPTIONS ---
    Offset    = 5      // Bars to extend lines to the right of current bar
    ADRPeriod = 14
    UTCOffset = 1      // Your timezone offset from UTC (e.g. 1 for UTC+1, 0 for UTC, -5 for UTC-5)
    // --------------------
    
    
    // Calculate the reset time expressed in platform UTC time
    // Midnight local (UTC+X) = hour (24 - UTCOffset) mod 24 in UTC
    // e.g. UTCOffset=1 => ResetTime=230000 (23:00 UTC = midnight UTC+1)
    ResetHour = MOD(24 - UTCOffset, 24)
    ResetTime = ResetHour * 10000
    
    
    // Detect the first bar at or just past the timezone-adjusted midnight
    IsNewDay = (OpenTime = ResetTime) OR (OpenTime > ResetTime AND OpenTime[1] < ResetTime)
    
    
    // 1. Track today's session high/low from the adjusted midnight
    ONCE TodayHigh = High
    ONCE TodayLow  = Low
    ONCE StartBar  = BarIndex
    
    
    IF IsNewDay THEN
        StartBar  = BarIndex
        TodayHigh = High
        TodayLow  = Low
    ELSE
        TodayHigh = MAX(TodayHigh, High)
        TodayLow  = MIN(TodayLow, Low)
    ENDIF
    
    
    // 2. Calculations
    CurrentRange = TodayHigh - TodayLow
    MidPoint     = (TodayHigh + TodayLow) / 2
    MyADR        = ROUND(Average[ADRPeriod](DHigh(1) - DLow(1)))
    
    
    IF MyADR > 0 THEN
        PctOfADR = (CurrentRange / MyADR) * 100
    ELSE
        PctOfADR = 0
    ENDIF
    
    
    // 3. DRAW VISUALS
    // Vertical dotted line at the timezone-adjusted midnight bar
    DRAWVLINE(StartBar) coloured(150,150,150) style(dottedline,1)
    
    
    // Horizontal segments from midnight bar to Offset bars beyond current bar
    // DrawOnLastBarOnly redraws these fresh every tick — no staircase, today only
    DRAWSEGMENT(StartBar, TodayHigh, BarIndex + Offset, TodayHigh) coloured(0,255,0) style(line,3)
    DRAWSEGMENT(StartBar, TodayLow,  BarIndex + Offset, TodayLow)  coloured(255,0,0) style(line,3)
    DRAWSEGMENT(StartBar, MidPoint,  BarIndex + Offset, MidPoint)  coloured(255,255,0) style(dottedline,2)
    
    
    // Colour logic and label
    IF PctOfADR >= 90 THEN
        r = 255
        g = 165
        b = 0
        BACKGROUNDCOLOR(255, 165, 0, 20)
    ELSE
        r = 255
        g = 255
        b = 255
    ENDIF
    
    
    DisplayPct = ROUND(PctOfADR)
    DRAWTEXT("#DisplayPct#% ADR", BarIndex + Offset, TodayHigh + 5*pipsize, SansSerif, Bold, 12) coloured(r, g, b)
    
    
    // 4. Return series for the price scale
    // Only feed values for today's bars (BarIndex >= StartBar)
    // Bars before today return 0, preventing the series lines extending back over history
    IF BarIndex >= StartBar THEN
        RetHigh = TodayHigh
        RetLow  = TodayLow
        RetMid  = ROUND(MidPoint)
    ELSE
        RetHigh = 0
        RetLow  = 0
        RetMid  = 0
    ENDIF
    
    
    RETURN RetHigh AS "High" COLOURED(0,255,0), RetLow AS "Low" COLOURED(255,0,0), RetMid AS "Mid" COLOURED(255,255,0), MyADR AS "ADR" COLOURED(200,200,200)
    

    A note on UTCOffset and DST: PRT platform servers run UTC. If your broker feeds tick data in UTC this works precisely. If your platform is set to a local timezone, OpenTime will reflect that offset automatically and you may need to set UTCOffset = 0 in that case and instead rely purely on the IsNewDay time comparison against 000000. The safest way to verify is to check what value OpenTime shows at what you know to be midnight on the chart then adjust UTCOffset so that ResetTime matches.

    Also, make sure the instrument has *really* 24 hours (not the case for Futures), so amend the formula at line 13 with the amount of hours available on the time axis.

    GraHal thanked this post
    #260032 quote
    GraHal
    Participant
    Master

    Why does the % ADR shown above the right hand end of the High Line vary depending on what Timeframe the Chart is running at?

    ss1 at 27% ADR at 5 secTF and ss2 at 5min TF are only seconds apart and price had not moved that much.


    Surely % ADR should be independent of chart timeframe Today as ADR is based on:

    MyADR        = ROUND(Average[ADRPeriod](DHigh(1) - DLow(1))) 
    
    P62XjW7DfV.png P62XjW7DfV.png cTtZn5RP5f.png cTtZn5RP5f.png
    #260036 quote
    GraHal
    Participant
    Master

    Why does the most recent code above show an error on Line 15 as attached?


    Z4mEvocrBD.png Z4mEvocrBD.png
    #260037 quote
    GraHal
    Participant
    Master

    Re the above error, AI tells me Line 15 should be:

    ResetHour = (24 - UTCOffset) MOD 24
    

    No error now!


    #260042 quote
    GraHal
    Participant
    Master

    Fixed code below if you want to try it anybody.

    I’ve found it useful during my manual trading knowing where current price is relative to the High and Low of Today.

    The % ADR label helps also as there is often a reversal when price approaches 100% ADR.

    As you can see from attached on 1 Hour TF … US30 raced past 100% ADR and is in the early stages of a pullback (let’s see? 🙂 ).

     DEFPARAM DrawOnLastBarOnly = True
    
    
    
    
    // --- Indicator: Midnight Reset Pro (ADR % Flag) ---
    // --- USER OPTIONS ---
    Offset    = 5      // Bars to extend lines to the right of current bar
    ADRPeriod = 14
    UTCOffset = 1      // Your timezone offset from UTC (e.g. 1 for UTC+1, 0 for UTC, -5 for UTC-5)
    // --------------------
    
    
    
    
    // Calculate the reset time expressed in platform UTC time
    // Midnight local (UTC+X) = hour (24 - UTCOffset) mod 24 in UTC
    // e.g. UTCOffset=1 => ResetTime=230000 (23:00 UTC = midnight UTC+1)
    ResetHour = (24 - UTCOffset) MOD 24
    ResetTime = ResetHour * 10000
    
    
    
    
    // Detect the first bar at or just past the timezone-adjusted midnight
    IsNewDay = (OpenTime = ResetTime) OR (OpenTime > ResetTime AND OpenTime[1] < ResetTime)
    
    
    
    
    // 1. Track today's session high/low from the adjusted midnight
    ONCE TodayHigh = High
    ONCE TodayLow  = Low
    ONCE StartBar  = BarIndex
    
    
    
    
    IF IsNewDay THEN
    StartBar  = BarIndex
    TodayHigh = High
    TodayLow  = Low
    ELSE
    TodayHigh = MAX(TodayHigh, High)
    TodayLow  = MIN(TodayLow, Low)
    ENDIF
    
    
    
    
    // 2. Calculations
    CurrentRange = TodayHigh - TodayLow
    MidPoint     = (TodayHigh + TodayLow) / 2
    MyADR        = ROUND(Average[ADRPeriod](DHigh(1) - DLow(1)))
    
    
    
    
    IF MyADR > 0 THEN
    PctOfADR = (CurrentRange / MyADR) * 100
    ELSE
    PctOfADR = 0
    ENDIF
    
    
    
    
    // 3. DRAW VISUALS
    // Vertical dotted line at the timezone-adjusted midnight bar
    DRAWVLINE(StartBar) coloured(150,150,150) style(dottedline,1)
    
    
    
    
    // Horizontal segments from midnight bar to Offset bars beyond current bar
    // DrawOnLastBarOnly redraws these fresh every tick — no staircase, today only
    DRAWSEGMENT(StartBar, TodayHigh, BarIndex + Offset, TodayHigh) coloured(0,255,0) style(line,3)
    DRAWSEGMENT(StartBar, TodayLow,  BarIndex + Offset, TodayLow)  coloured(255,0,0) style(line,3)
    DRAWSEGMENT(StartBar, MidPoint,  BarIndex + Offset, MidPoint)  coloured(255,255,0) style(dottedline,2)
    
    
    
    
    // Colour logic and label
    IF PctOfADR >= 90 THEN
    r = 255
    g = 165
    b = 0
    BACKGROUNDCOLOR(255, 165, 0, 20)
    ELSE
    r = 255
    g = 255
    b = 255
    ENDIF
    
    
    
    
    DisplayPct = ROUND(PctOfADR)
    DRAWTEXT("#DisplayPct#% ADR", BarIndex + Offset, TodayHigh + 5*pipsize, SansSerif, Bold, 12) coloured(r, g, b)
    
    
    
    
    // 4. Return series for the price scale
    // Only feed values for today's bars (BarIndex >= StartBar)
    // Bars before today return 0, preventing the series lines extending back over history
    IF BarIndex >= StartBar THEN
    RetHigh = TodayHigh
    RetLow  = TodayLow
    RetMid  = ROUND(MidPoint)
    ELSE
    RetHigh = 0
    RetLow  = 0
    RetMid  = 0
    ENDIF
    
    
    
    
    RETURN RetHigh AS "High" COLOURED(0,255,0), RetLow AS "Low" COLOURED(255,0,0), RetMid AS "Mid" COLOURED(255,255,0), MyADR AS "ADR" COLOURED(200,200,200)
    
    
    
    robertogozzi thanked this post
    uIzHqAoD61.png uIzHqAoD61.png
Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.

Daily Range Indicator – Text Overwrite at each Change of Bar


ProBuilder: Indicators & Custom Tools

New Reply
Author
Summary

This topic contains 7 replies,
has 2 voices, and was last updated by GraHal
14 hours, 7 minutes ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 04/09/2026
Status: Active
Attachments: 4 files
Logo Logo
Loading...