// 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.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Show previous day levels
bool
true
showPD
Show previous day midpoint
bool
true
showPDM
Show previous week levels
bool
false
showPW
Show previous week midpoint
bool
false
showPWM
Show previous month levels
bool
false
showPMo
Show level fills
bool
true
showFill
Show right-edge labels
bool
true
showLabels
Show status badge
bool
true
showBadge
Touch tolerance (%)
float
0.1
touchTol
Daily color
color
color.blue
colorPD
Weekly color
color
color.purple
colorPW
Monthly color
color
color.orange
colorPMo
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.
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
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
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
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
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
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