Indicator · Pine Script v6 · On the chart

Capital41 PDH/PDL Levels

by damianpitt· code credited to Capital41 | MIT License

This indicator plots previous-day high, low, and midpoint on the price chart, with optional previous-week and previous-month highs and lows.

View on GitHub

GitHub stars6on the repository
Pine versionv6current
Lines of code186
Settings12inputs
LicenceMIT
Last update8 weeks ago31 Aug 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

186 lines of Pine Script v6 from Capital41_PDH_PDL/Capital41_PDH_PDL_v3.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

Capital41_PDH_PDL_v3.pine
// Copyright (c) 2026 Capital41 | MIT License
// CAPITAL41 PREVIOUS DAY/WEEK/MONTH LEVELS v3

// What it does:
// - Plots Previous Day High/Low (PDH/PDL) with midpoint.
// - Optional Previous Week High/Low (PWH/PWL) with midpoint.
// - Optional Previous Month High/Low (PMH/PML).
// - Right-edge labels for quick identification.
// - Alerts when price touches or breaks key levels.
//
// v2 changes (expanded from 43-line original):
// - ADDED: Midpoint levels for daily and weekly ranges.
// - ADDED: Previous month high/low.
// - ADDED: Right-edge labels on all levels for easy identification.
// - ADDED: Optional fill between high/low levels.
// - ADDED: Alert conditions for touch and breakout of each level.
// - ADDED: Status badge showing distance to PDH/PDL and position in range.
// - ADDED: User-configurable colors for each timeframe.
//
// v3 changes:
// - FIXED: Touch and breakout conditions gated by barstate.isconfirmed, so
//          alerts fire on bar close instead of repainting intra-bar.
//
// TradingView setup:
// 1) Open TradingView -> Pine Editor.
// 2) Paste this script, Save, and Add to chart.
// 3) Use 30m or 4h on BTC or US stocks.
//
// Usage guide (30m/4h):
// - PDH/PDL act as natural liquidity targets and reversal zones.
// - Midpoints often serve as intraday support/resistance.
// - PWH/PWL and PMH/PML frame larger range context.
// - Combine with sweeps and confluence signals for higher confidence.



//@version=6
indicator("Capital41 PDH/PDL Levels v3", overlay = true, max_labels_count = 50, max_lines_count = 50)

// Inputs
showPD     = input.bool(true, "Show previous day levels")
showPDM    = input.bool(true, "Show previous day midpoint")
showPW     = input.bool(false, "Show previous week levels")
showPWM    = input.bool(false, "Show previous week midpoint")
showPMo    = input.bool(false, "Show previous month levels")
showFill   = input.bool(true, "Show level fills")
showLabels = input.bool(true, "Show right-edge labels")
showBadge  = input.bool(true, "Show status badge")
touchTol   = input.float(0.1, "Touch tolerance (%)", minval = 0.01, maxval = 1.0, step = 0.01)

colorPD    = input.color(color.blue, "Daily color")
colorPW    = input.color(color.purple, "Weekly color")
colorPMo   = input.color(color.orange, "Monthly color")

// Previous Day levels
pdh = request.security(syminfo.tickerid, "D", high[1])
pdl = request.security(syminfo.tickerid, "D", low[1])
pdm = math.avg(pdh, pdl)

// Previous Week levels
pwh = request.security(syminfo.tickerid, "W", high[1])
pwl = request.security(syminfo.tickerid, "W", low[1])
pwm = math.avg(pwh, pwl)

// Previous Month levels
pmh = request.security(syminfo.tickerid, "M", high[1])
pml = request.security(syminfo.tickerid, "M", low[1])

// Plots
pdhPlot = plot(showPD ? pdh : na, title = "PDH", color = colorPD, linewidth = 1, style = plot.style_line)
pdlPlot = plot(showPD ? pdl : na, title = "PDL", color = colorPD, linewidth = 1, style = plot.style_line)
plot(showPD and showPDM ? pdm : na, title = "PD Mid", color = color.new(colorPD, 50), linewidth = 1, style = plot.style_circles)

pwhPlot = plot(showPW ? pwh : na, title = "PWH", color = colorPW, linewidth = 1, style = plot.style_line)
pwlPlot = plot(showPW ? pwl : na, title = "PWL", color = colorPW, linewidth = 1, style = plot.style_line)
plot(showPW and showPWM ? pwm : na, title = "PW Mid", color = color.new(colorPW, 50), linewidth = 1, style = plot.style_circles)

plot(showPMo ? pmh : na, title = "PMH", color = colorPMo, linewidth = 1, style = plot.style_line)
plot(showPMo ? pml : na, title = "PML", color = colorPMo, linewidth = 1, style = plot.style_line)

// Fills
fill(pdhPlot, pdlPlot, color = showPD and showFill ? color.new(colorPD, 94) : na)
fill(pwhPlot, pwlPlot, color = showPW and showFill ? color.new(colorPW, 94) : na)

// Right-edge labels (using var to avoid accumulation)
var label pdhLbl = na, var label pdlLbl = na, var label pdmLbl = na
var label pwhLbl = na, var label pwlLbl = na, var label pwmLbl = na
var label pmhLbl = na, var label pmlLbl = na

if barstate.islast and showLabels
    // Daily labels
    if showPD
        label.delete(pdhLbl)
        label.delete(pdlLbl)
        pdhLbl := label.new(bar_index + 3, pdh, "PDH", style = label.style_label_left,
                  color = color.new(colorPD, 70), textcolor = color.white, size = size.tiny)
        pdlLbl := label.new(bar_index + 3, pdl, "PDL", style = label.style_label_left,
                  color = color.new(colorPD, 70), textcolor = color.white, size = size.tiny)
        if showPDM
            label.delete(pdmLbl)
            pdmLbl := label.new(bar_index + 3, pdm, "PD\u00BD", style = label.style_label_left,
                      color = color.new(colorPD, 80), textcolor = color.white, size = size.tiny)

    // Weekly labels
    if showPW
        label.delete(pwhLbl)
        label.delete(pwlLbl)
        pwhLbl := label.new(bar_index + 3, pwh, "PWH", style = label.style_label_left,
                  color = color.new(colorPW, 70), textcolor = color.white, size = size.tiny)
        pwlLbl := label.new(bar_index + 3, pwl, "PWL", style = label.style_label_left,
                  color = color.new(colorPW, 70), textcolor = color.white, size = size.tiny)
        if showPWM
            label.delete(pwmLbl)
            pwmLbl := label.new(bar_index + 3, pwm, "PW\u00BD", style = label.style_label_left,
                      color = color.new(colorPW, 80), textcolor = color.white, size = size.tiny)

    // Monthly labels
    if showPMo
        label.delete(pmhLbl)
        label.delete(pmlLbl)
        pmhLbl := label.new(bar_index + 3, pmh, "PMH", style = label.style_label_left,
                  color = color.new(colorPMo, 70), textcolor = color.white, size = size.tiny)
        pmlLbl := label.new(bar_index + 3, pml, "PML", style = label.style_label_left,
                  color = color.new(colorPMo, 70), textcolor = color.white, size = size.tiny)


// Touch and breakout detection (confirmed so alerts cannot retract mid-bar)
tol = close * touchTol / 100.0

touchPDH = showPD and barstate.isconfirmed and math.abs(close - pdh) <= tol
touchPDL = showPD and barstate.isconfirmed and math.abs(close - pdl) <= tol
touchPWH = showPW and barstate.isconfirmed and math.abs(close - pwh) <= tol
touchPWL = showPW and barstate.isconfirmed and math.abs(close - pwl) <= tol

breakPDH = showPD and barstate.isconfirmed and close > pdh and close[1] <= pdh
breakPDL = showPD and barstate.isconfirmed and close < pdl and close[1] >= pdl
breakPWH = showPW and barstate.isconfirmed and close > pwh and close[1] <= pwh
breakPWL = showPW and barstate.isconfirmed and close < pwl and close[1] >= pwl

// Status badge
var table status = table.new(position.top_right, 3, 1, border_width = 1)
if barstate.islast
    if showBadge and showPD
        pdhDist = pdh != 0 ? (close - pdh) / pdh * 100 : 0
        pdlDist = pdl != 0 ? (close - pdl) / pdl * 100 : 0

        table.cell(status, 0, 0, " PDH " + str.tostring(pdhDist, "#.##") + "% ",
                   bgcolor = pdhDist > 0 ? color.new(color.lime, 70) : color.new(color.red, 70),
                   text_color = color.white, text_size = size.tiny)
        table.cell(status, 1, 0, " PDL " + str.tostring(pdlDist, "#.##") + "% ",
                   bgcolor = pdlDist > 0 ? color.new(color.lime, 70) : color.new(color.red, 70),
                   text_color = color.white, text_size = size.tiny)

        pos   = close > pdh ? "ABOVE" : close < pdl ? "BELOW" : "IN RNG"
        posBg = close > pdh ? color.new(color.lime, 65) : close < pdl ? color.new(color.red, 65) : color.new(color.gray, 75)
        table.cell(status, 2, 0, " " + pos + " ", bgcolor = posBg,
                   text_color = color.white, text_size = size.tiny)
    else
        for i = 0 to 2
            table.cell(status, i, 0, "", bgcolor = color.new(color.black, 100), text_color = color.new(color.black, 100))


// Alerts
alertcondition(touchPDH, title = "Touch PDH",
               message = "PDH/PDL: price touching Previous Day High on {{ticker}} ({{interval}})")

alertcondition(touchPDL, title = "Touch PDL",
               message = "PDH/PDL: price touching Previous Day Low on {{ticker}} ({{interval}})")

alertcondition(breakPDH, title = "Break PDH",
               message = "PDH/PDL: price broke above Previous Day High on {{ticker}} ({{interval}})")

alertcondition(breakPDL, title = "Break PDL",
               message = "PDH/PDL: price broke below Previous Day Low on {{ticker}} ({{interval}})")

alertcondition(touchPWH, title = "Touch PWH",
               message = "PDH/PDL: price touching Previous Week High on {{ticker}} ({{interval}})")

alertcondition(touchPWL, title = "Touch PWL",
               message = "PDH/PDL: price touching Previous Week Low on {{ticker}} ({{interval}})")

alertcondition(breakPWH, title = "Break PWH",
               message = "PDH/PDL: price broke above Previous Week High on {{ticker}} ({{interval}})")

alertcondition(breakPWL, title = "Break PWL",
               message = "PDH/PDL: price broke below Previous Week Low on {{ticker}} ({{interval}})")

Overview

Capital41 PDH/PDL Levels fills the high-low ranges, places right-edge labels, and shows a status badge for distance to the daily extremes and position inside the range. Users can toggle each period, fills, labels, badge, colors, and a percentage touch tolerance. Confirmed-bar alerts fire when price touches or breaks a level.

Details

Published by

damianpitt on GitHub

Code credit

Capital41 | MIT License, as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Support & resistance

Markets

Crypto, Stocks

Timeframes

M15-H1, H4 and above

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

cryptoindicatorsmarket-structureorder-blockspinescriptsmart-moneytechnical-analysistechnical-analysis-indicatorstradingtradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Show previous day levelsbooltrueshowPD
Show previous day midpointbooltrueshowPDM
Show previous week levelsboolfalseshowPW
Show previous week midpointboolfalseshowPWM
Show previous month levelsboolfalseshowPMo
Show level fillsbooltrueshowFill
Show right-edge labelsbooltrueshowLabels
Show status badgebooltrueshowBadge
Touch tolerance (%)float0.1touchTol
Daily colorcolorcolor.bluecolorPD
Weekly colorcolorcolor.purplecolorPW
Monthly colorcolorcolor.orangecolorPMo
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

948 stars

Moving Average Channel plots separate simple moving averages for upper and lower bands on the price chart. It fills the space between bands with semi-transparent color and colors bars green above the upper band, red below the lower band, or gray in between. Us

Indicator v4 Moving averagesSupport & resistance
Updated 10 days ago · GPL-3.0 GitHub repository of Moving Average Channel

ICT Equal Highs and Lows

by ArunKBhaskar
575 stars

This overlay indicator finds pivot highs and lows on the price chart and compares the last two highs and the last two lows. When the percentage difference between a pair is below the Equal HL threshold, it treats them as equal levels and draws a box. Left and

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Equal Highs and Lows
330 stars

This indicator monitors multiple cryptocurrency symbols for trading signals. It calculates and plots entry prices, take profit, and stop loss levels for each symbol including BTCUSDT, ETHUSDT, BNBUSDT and others. Price crossovers trigger buy, sell or close ale

Indicator v5 Support & resistanceScreeners & dashboards
Updated 2 months ago · None stated GitHub repository of Multi Alert Long/Short [Alorse]

This overlay indicator draws a fixed-range volume profile on the price chart, splitting traded activity into up and down volume at each price level. It also plots a sentiment profile, a developing point of control, and value-area high and low around a configur

Indicator v5 VolumeSupport & resistance
Updated 2 months ago · MIT GitHub repository of Volume Profile and Indicator by DGT

BZ-tracker

by Allen1212
303 stars

The BZ-tracker indicator marks ARK Invest buy and sell transactions on stock charts with labels. It plots green labels for purchases and red labels for sales, each annotated with a multiplier such as X1 or X2 to show the number of ARK ETFs trading the stock on

Indicator v4 Support & resistanceScreeners & dashboards
Updated 2 years ago · None stated GitHub repository of BZ-tracker

Function - Linear Regression

by ricardosantos79
261 stars

This indicator fits a linear regression through stored pivot highs and lows and draws the resulting channel on the price chart. A function returns predicted values, maximum and minimum deviations, and the average absolute deviation. Confirmed two-bar pivots up

Indicator v5 TrendSupport & resistance
Updated 4 years ago · None stated GitHub repository of Function - Linear Regression

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers