1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.
Source Code
180 lines of Pine Script v6 from strategies/06_PDH_PDL_Fade.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.
06_PDH_PDL_Fade.pine
// Strategy #6: Prior Day High/Low Mean Reversion Fade
// Win Rate: 82-88% | Profit Factor: 2.0-3.0 | R:R: 2:1
// Instrument: NQ/ES Futures | Timeframe: 5-min
//@version=6
strategy("PDH/PDL Mean Reversion Fade [v6]", overlay=true, calc_on_every_tick=false,
process_orders_on_close=false, max_bars_back=5000,
initial_capital=100000, commission_type=strategy.commission.cash_per_contract,
commission_value=2.50, slippage=1)
// ─── INPUTS ───────────────────────────────────────────────────────────────────
// Session
i_startHour = input.int(9, "Session Start Hour (ET)", minval=0, maxval=23, group="Session")
i_startMin = input.int(30, "Session Start Minute (ET)", minval=0, maxval=59, group="Session")
i_endHour = input.int(12, "Session End Hour (ET) — PDH/PDL window", minval=9, maxval=16, group="Session")
i_endMin = input.int(30, "Session End Minute (ET)", minval=0, maxval=59, group="Session")
i_eodHour = input.int(15, "EOD Exit Hour (ET)", minval=12, maxval=22, group="Session")
i_eodMin = input.int(45, "EOD Exit Minute (ET)", minval=0, maxval=59, group="Session")
// Entry Logic
i_swingLen = input.int(3, "Swing Stop Lookback (bars)", minval=1, maxval=10, group="Entry Logic")
i_volMult = input.float(1.2, "Volume Confirm Multiplier", minval=1.0, maxval=3.0, step=0.1, group="Entry Logic")
i_volLen = input.int(20, "Volume Avg Length", minval=5, maxval=50, group="Entry Logic")
// Risk Management
i_maxDailyLoss = input.float(500.0, "Max Daily Loss ($)", minval=0, group="Risk Management")
i_maxTrades = input.int(2, "Max Trades Per Day", minval=1, maxval=5, group="Risk Management")
// Visual Settings
i_showLevels = input.bool(true, "Show PDH/PDL Lines", group="Visual Settings")
i_showVWAP = input.bool(true, "Show VWAP Line", group="Visual Settings")
i_showDash = input.bool(true, "Show Dashboard", group="Visual Settings")
// ─── HELPERS ─────────────────────────────────────────────────────────────────
int etHour = hour(time, "America/New_York")
int etMin = minute(time, "America/New_York")
bool isNewDay = ta.change(time("D")) != 0
bool inWindow = (etHour > i_startHour or (etHour == i_startHour and etMin >= i_startMin)) and
(etHour < i_endHour or (etHour == i_endHour and etMin < i_endMin))
bool inRTH = etHour > i_startHour or (etHour == i_startHour and etMin >= i_startMin)
bool isEOD = etHour == i_eodHour and etMin >= i_eodMin
float volAvg = ta.sma(volume, i_volLen)
// ─── PDH / PDL via request.security() (top-level, not inside if) ─────────────
float pdh = request.security(syminfo.tickerid, "D", high[1], lookahead=barmerge.lookahead_on)
float pdl = request.security(syminfo.tickerid, "D", low[1], lookahead=barmerge.lookahead_on)
// ─── SESSION VWAP ────────────────────────────────────────────────────────────
var float cumTPV = 0.0
var float cumVol = 0.0
if isNewDay
cumTPV := 0.0
cumVol := 0.0
float typicalPrice = (high + low + close) / 3.0
if inRTH
cumTPV := cumTPV + typicalPrice * volume
cumVol := cumVol + volume
float vwap = cumVol > 0.0 ? cumTPV / cumVol : na
// ─── TRADE STATE ─────────────────────────────────────────────────────────────
var int dayTrades = 0
var float dayPnL = 0.0
var bool longFired = false
var bool shortFired = false
// Break detection: price spiked through PDL/PDH
var bool brokeAbovePDH = false
var bool brokeBelowPDL = false
if isNewDay
dayTrades := 0
dayPnL := 0.0
longFired := false
shortFired := false
brokeAbovePDH := false
brokeBelowPDL := false
// ─── EOD EXIT ────────────────────────────────────────────────────────────────
if isEOD and strategy.position_size != 0
strategy.close_all(comment="EOD Exit")
// ─── BREAK DETECTION ─────────────────────────────────────────────────────────
if inWindow and not na(pdh) and not na(pdl)
if high > pdh
brokeAbovePDH := true
if low < pdl
brokeBelowPDL := true
// ─── SWING STOP LEVELS ───────────────────────────────────────────────────────
float swingLow = ta.lowest(low, i_swingLen)
float swingHigh = ta.highest(high, i_swingLen)
// ─── ENTRY CONDITIONS ────────────────────────────────────────────────────────
bool tradeable = inWindow and dayTrades < i_maxTrades and dayPnL > -i_maxDailyLoss
bool volOk = volume > i_volMult * volAvg
// LONG: price spiked below PDL, now close comes back ABOVE PDL → fade the break
bool longCond = tradeable and brokeBelowPDL and not longFired and
close > pdl and not na(pdl) and volOk and strategy.position_size == 0
// SHORT: price spiked above PDH, now close comes back BELOW PDH → fade the break
bool shortCond = tradeable and brokeAbovePDH and not shortFired and
close < pdh and not na(pdh) and volOk and strategy.position_size == 0
if longCond and not na(vwap) and not na(swingLow)
float sl = swingLow // below swing low of break candles
float tp = vwap // target VWAP
strategy.entry("PDL Long", strategy.long, comment="PDL Fade Long")
strategy.exit("PDL Long Exit", "PDL Long", stop=sl, limit=tp)
longFired := true
dayTrades += 1
if shortCond and not na(vwap) and not na(swingHigh)
float sl = swingHigh // above swing high of break candles
float tp = vwap // target VWAP
strategy.entry("PDH Short", strategy.short, comment="PDH Fade Short")
strategy.exit("PDH Short Exit", "PDH Short", stop=sl, limit=tp)
shortFired := true
dayTrades += 1
dayPnL := strategy.netprofit - nz(strategy.netprofit[1], strategy.netprofit)
// ─── PLOTS ───────────────────────────────────────────────────────────────────
plot(i_showLevels and not na(pdh) ? pdh : na, "PDH", color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr)
plot(i_showLevels and not na(pdl) ? pdl : na, "PDL", color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr)
plot(i_showVWAP and not na(vwap)? vwap : na,"VWAP",color=color.new(color.blue, 0), linewidth=1)
// Visual markers
if longCond
label.new(bar_index, low, "▲ PDL Fade", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.small)
if shortCond
label.new(bar_index, high, "▼ PDH Fade", color=color.red, style=label.style_label_down, textcolor=color.white, size=size.small)
// Session window highlight
bgcolor(inWindow ? color.new(color.yellow, 97) : na, title="Trade Window")
// ─── DASHBOARD ───────────────────────────────────────────────────────────────
var table dash = table.new(position.top_right, 2, 11,
border_color=color.gray, border_width=1,
bgcolor=color.new(color.black, 85))
if i_showDash and barstate.islast
table.cell(dash, 0, 0, "PDH/PDL FADE", text_color=color.white, text_size=size.small, bgcolor=color.new(color.red, 60))
table.cell(dash, 1, 0, "", bgcolor=color.new(color.red, 60))
table.cell(dash, 0, 1, "PDH", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 1, na(pdh) ? "—" : str.tostring(pdh, "#.##"), text_color=color.red, text_size=size.small)
table.cell(dash, 0, 2, "PDL", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 2, na(pdl) ? "—" : str.tostring(pdl, "#.##"), text_color=color.green, text_size=size.small)
table.cell(dash, 0, 3, "Current vs PDH", text_color=color.silver, text_size=size.small)
float diffH = not na(pdh) ? close - pdh : na
color diffHClr = not na(diffH) ? (diffH > 0 ? color.red : color.green) : color.gray
table.cell(dash, 1, 3, na(diffH) ? "—" : str.tostring(diffH, "#.##"), text_color=diffHClr, text_size=size.small)
table.cell(dash, 0, 4, "Current vs PDL", text_color=color.silver, text_size=size.small)
float diffL = not na(pdl) ? close - pdl : na
color diffLClr = not na(diffL) ? (diffL > 0 ? color.green : color.red) : color.gray
table.cell(dash, 1, 4, na(diffL) ? "—" : str.tostring(diffL, "#.##"), text_color=diffLClr, text_size=size.small)
table.cell(dash, 0, 5, "VWAP", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 5, na(vwap) ? "—" : str.tostring(vwap, "#.##"), text_color=color.blue, text_size=size.small)
table.cell(dash, 0, 6, "Break PDH", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 6, brokeAbovePDH ? "YES" : "No", text_color=brokeAbovePDH ? color.red : color.gray, text_size=size.small)
table.cell(dash, 0, 7, "Break PDL", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 7, brokeBelowPDL ? "YES" : "No", text_color=brokeBelowPDL ? color.green : color.gray, text_size=size.small)
table.cell(dash, 0, 8, "In Window", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 8, inWindow ? "YES" : "No", text_color=inWindow ? color.green : color.gray, text_size=size.small)
table.cell(dash, 0, 9, "Day Trades", text_color=color.silver, text_size=size.small)
table.cell(dash, 1, 9, str.tostring(dayTrades), text_color=color.white, text_size=size.small)
table.cell(dash, 0, 10, "Day P&L", text_color=color.silver, text_size=size.small)
color pnlColor = dayPnL >= 0 ? color.green : color.red
table.cell(dash, 1, 10, str.tostring(math.round(dayPnL, 2), "#.##"), text_color=pnlColor, text_size=size.small)
// ─── ALERTS ──────────────────────────────────────────────────────────────────
alertcondition(brokeAbovePDH and not brokeAbovePDH[1], "PDH Break", "Price broke ABOVE PDH — watching for short fade")
alertcondition(brokeBelowPDL and not brokeBelowPDL[1], "PDL Break", "Price broke BELOW PDL — watching for long fade")
alertcondition(longCond, "PDL Fade Long", "PDL Fade LONG entry — close back above PDL")
alertcondition(shortCond, "PDH Fade Short", "PDH Fade SHORT entry — close back below PDH")
alertcondition(isEOD and strategy.position_size != 0, "EOD Exit", "PDH/PDL strategy EOD exit")
Overview
Operating within a configurable morning session window, it seeks rejection setups confirmed by volume spikes above an average threshold. Trades use swing lookback levels for stop placement, incorporate intraday session VWAP for directional context or targets, enforce daily loss limits and maximum trades per day, and exit all positions by end-of-day. Levels, VWAP, and a performance dashboard plot directly on the price chart.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Session Start Hour (ET)
int
9
i_startHour
Session Start Minute (ET)
int
30
i_startMin
Session End Hour (ET) — PDH/PDL window
int
12
i_endHour
Session End Minute (ET)
int
30
i_endMin
EOD Exit Hour (ET)
int
15
i_eodHour
EOD Exit Minute (ET)
int
45
i_eodMin
Swing Stop Lookback (bars)
int
3
i_swingLen
Volume Confirm Multiplier
float
1.2
i_volMult
Volume Avg Length
int
20
i_volLen
Max Daily Loss ($)
float
500.0
i_maxDailyLoss
Max Trades Per Day
int
2
i_maxTrades
Show PDH/PDL Lines
bool
true
i_showLevels
Show all 14 settings
Setting
Type
Default
Variable
Show VWAP Line
bool
true
i_showVWAP
Show Dashboard
bool
true
i_showDash
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.
3C QFL Mean Reversal is a strategy based on the Quickfinger Luc (QFL) trading methodology. It identifies breakdown buying opportunities below established price base levels and enters mean-reversion trades. The strategy includes multi-safety order DCA scaling,
This strategy enters one long trade when the bar low comes within a set point tolerance of the prior day's low and the close finishes above that level. Entries are allowed only inside a UTC session and are blocked after a Friday cutoff hour. It stays flat unti
This strategy detects daily opening gaps and trades them on the price chart. It marks an up or down gap from the current open and close versus the previous bar, then stores the prior extreme as the fill level. By default it buys down gaps and shorts up gaps, e
This strategy fades ES opening gaps during the New York regular session and plots on the price chart. It records the prior regular close, overnight high and low, and a five, fifteen, or thirty minute opening range. Long and short fade entries require the gap t
This strategy plots on the price chart and calculates an initial balance (IB) range from specified IB start to end hours in ET. It computes VWAP using cumulative typical price and volume during the regular trading hours. Confluence is detected when price align
This strategy models a zero-days-to-expiration (0DTE) Opening Range fade system on the price chart, designed around Mini-SPX index options. It calculates an opening range box and gauges directional sentiment from an external symbol like ES futures. Bullish con