The rules at a glance
- Levels: yesterday's high (PDH) and low (PDL) from the daily candle
- Entry: the first 15-minute candle that closes above the PDH (or below the PDL) by at least a tenth of the ATR, when the candle before it closed inside the level; enter at that close
- Stop loss: the breakout candle's low, or half an ATR back inside the level, whichever is further away (mirrored for shorts)
- Target: twice the risk (2R); skip the trade if the stop would be more than 2.5 × ATR away
- Hours: new trades from 8 a.m. to 3 p.m. London time (12:30 to 19:30 IST in summer, 13:30 to 20:30 IST in winter); anything open is closed at 5 p.m. London time
- Filter: longs only above the 200 EMA, shorts only below it; each level is traded once
Why yesterday's high and low matter
Every trader looking at a chart can see where the price turned yesterday. Sellers defended the high, buyers defended the low, and stop orders pile up just beyond both. That makes the previous day's high (PDH) and low (PDL) natural decision points. The two classic ways to trade them are opposites:
| Breakout (this page) | Liquidity sweep | |
|---|---|---|
| What happens | A candle closes beyond the level and the price keeps going | A candle pokes through the level and closes back inside |
| Trade | With the break | Against the poke |
| Stop | Back inside the level | Beyond the wick |
| Page | This one | Liquidity sweep strategy |
Both scripts use the same levels, so running them side by side on one market shows you which behaviour it shows more often. That's more useful than any opinion about which one "works".
The rules, step by step
1. Mark the levels
Draw yesterday's high and low before London opens. On most TradingView forex and gold feeds the daily candle closes at 5 p.m. New York time, so "yesterday" is the day that ended then. The script reads the levels from the daily chart and never looks ahead.
2. Wait for a clear close beyond a level
A long needs a 15-minute candle that closes above the PDH by at least a tenth of the 14-period ATR, and the candle before it must have closed below the level. That makes it the first close beyond, not a later candle in a move that already happened. A wick through the level doesn't count; that's the sweep setup.
3. Enter at the close, stop back inside
Enter as the breakout candle closes. The stop goes at the candle's low or half an ATR below the PDH, whichever is further away. If the price falls back inside yesterday's range, the breakout has failed. Skip the trade if that puts the stop more than 2.5 × ATR away; a huge breakout candle leaves too little room for a 2R target.
4. Target twice the risk
The target is 2R. With the trend filter on, take longs only above the 200 EMA and shorts only below it.
5. Trade the main hours, once per level
Look for breakouts between 8 a.m. and 3 p.m. London time and close anything still open at 5 p.m. London time. Each level is traded once: if the PDH breakout fails, the script doesn't try it again that day.
Worked example: XAUUSD, 15-minute chart
Yesterday's high is 4,286.70. All morning gold presses up under it without touching it. At 12:00 London time (16:30 IST in summer), a strong candle closes at 4,291.20, $4.50 above the PDH and well clear of the tenth-of-an-ATR buffer. Assume the price is above the 200 EMA, as the default setting requires. The candle's low, 4,281.60, is further away than half an ATR below the level, so that's the stop.
| XAUUSD long | |
|---|---|
| Entry | 4,291.20 |
| Stop loss (breakout candle's low) | 4,281.60, $9.60 away |
| Target (2R) | 4,310.40, $19.20 away |
| Account and risk | $10,000, risking 1% = $100 |
| Lot size | $100 ÷ ($9.60 × 100 ounces) = 0.104, rounded down to 0.10 lots (the script itself trades the unrounded 10.4 ounces) |
| Loss if the stop is hit | $96.00 |
| Profit at the target | $192.00 |
Gold climbs steadily and reaches the target at 15:00 London time, before the 5 p.m. cut-off. Plenty of PDH breaks look exactly like this for an hour and then fall back into yesterday's range; the stop below the breakout candle is there for those. The XAUUSD lot size calculator does the sizing for any stop.
What makes a breakout more or less likely to hold
- How the price got there. A slow grind up to the level, with higher lows underneath, often holds better than one wild spike into it. That's an observation to test, not a rule.
- The session. Breaks in the London and New York hours carry more volume than ones in the quiet Asian hours. The market hours clock shows them in IST.
- News. A break caused by a US data release at 8:30 a.m. New York time (18:00 IST in summer, 19:00 IST in winter) can run far, or reverse just as fast. See gold news trading.
- The size of yesterday's range. After a very narrow day, the PDH and PDL are close together and both can get hit. After a huge day, a break of the extreme is rarer.
Risk management
- Size from the stop. On gold, $1 is $100 a lot. A $9.60 stop at 1% risk on $10,000 is 0.10 lots, not 1 lot.
- Two trades a day at most. One on each level, and only if the first one is closed.
- Watch the spread at the break. Spreads widen around news, and a breakout candle on gold can fill your market order a little worse than its close.
- On a prop firm account, check the news rules: some firms restrict trading a few minutes either side of big releases.
Common mistakes
- Buying the first tick above the level. That's exactly where false breaks catch people. Wait for the close.
- Confusing a sweep with a breakout. If the candle closes back inside, it isn't a breakout.
- Chasing a breakout that's already far away. The script only takes the first close beyond the level for this reason.
- Using the wrong day. If your broker's daily candle closes at a different time, its PDH can differ from TradingView's. Use one source.
Backtest it yourself on TradingView
This page doesn't quote a win rate or a profit figure, and you should be wary of anyone who does without showing the test. Results change with the market, the dates, the data feed and the costs you put in. The honest way is to run the test yourself, and the free script below does the work in a couple of minutes.
- Open the chart. On TradingView, open XAUUSD on the 15-minute chart.
- Add the script. Open the Pine Editor from the Pine icon in the panel on the right of the chart (older layouts have it as a tab under the chart), delete the code that's already there, paste this strategy's code and click "Add to chart".
- Put in your costs. Open the strategy's settings and go to Properties. Enter your broker's commission and a little slippage. A test without costs flatters every strategy, and short-term ones most of all.
- Read the Strategy Tester. The panel under the chart shows the net profit, the maximum drawdown, the profit factor, the number of trades and a list of every trade. Click a few trades and check on the chart that each one follows the rules. Trade sizes are shown in units rather than lots: 100,000 units is one lot of a forex pair, and 100 ounces is one lot of gold.
- Change one setting at a time. Compare the trend filter on and off, the breakout buffer (0 to 0.3 × ATR), the stop distance behind the level, and the 2R target against 1.5R. Then run the liquidity sweep script on the same dates and compare. Try EURUSD and GBPUSD too.
As a rough guide, don't trust a result with fewer than 100 trades, a profit factor under 1 once costs are in, or a drawdown you couldn't sit through with real money. Settings tuned to look good on one stretch of history often fail on the next, so check the same settings on dates you didn't tune them on, then demo trade the strategy for a few weeks. How much history you can test depends on your TradingView plan: the free plan loads 5,000 candles, which is a few months of 15-minute candles but years of daily ones.
The script sizes each trade from the stop loss and your risk percentage, starts with $10,000 and assumes 1:100 leverage (a 1% margin setting), so the tester doesn't flag margin calls on normal forex trade sizes. Change these under Properties to match your account. By default TradingView fills orders at the open of the candle after the signal, so the fill can differ a little from the signal candle's close.
Download the free Pine Script and PDF
The script is written in Pine Script version 6 for this guide and follows the rules above. It can't read the economic calendar, so skipping news days is up to you. It's free to use, change and share. The PDF is a one-page cheat sheet with the rules, the hours in IST, a worked example and a checklist, to keep next to your chart.
Show the code (Pine Script v6, 66 lines)
//@version=6
// Previous Day High and Low breakout strategy by PipLedger (https://pipledgerfx.com/previous-day-high-low-strategy)
// Trades the first candle that closes beyond the previous day's high or low during London and New York hours.
// Free to use and change. For education and backtesting only; not financial advice.
strategy("PipLedger: Previous Day High/Low Breakout", shorttitle="PDH/PDL Breakout", overlay=true, initial_capital=10000, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=1, margin_long=1, margin_short=1, currency=currency.USD)
// ---------- Inputs
sess = input.session("0800-1500", "Breakout window (London time)")
tz = input.string("Europe/London", "Session time zone")
closeHour = input.int(17, "Close any open trade at (hour, London time)", minval=1, maxval=23)
bufAtr = input.float(0.1, "Close beyond the level by at least (x ATR)", minval=0.0, step=0.05)
stopAtr = input.float(0.5, "Stop at least this far behind the level (x ATR)", minval=0.0, step=0.1)
maxStopAtr = input.float(2.5, "Skip if the stop is further than (x ATR)", minval=0.5, step=0.25)
rr = input.float(2.0, "Target (R multiple)", minval=0.5, step=0.25)
useTrend = input.bool(true, "Only trade in the direction of the 200 EMA")
riskPct = input.float(1.0, "Risk per trade (% of equity)", minval=0.1, maxval=5.0, step=0.1)
// ---------- Helpers
fx = strategy.convert_to_account(1.0) // one unit of the chart's quote currency in account currency (1 on USD-quoted charts)
calcQty(float entry, float stop) =>
float dist = math.abs(entry - stop)
dist > 0 and not na(fx) ? strategy.equity * riskPct / 100 / (dist * syminfo.pointvalue * fx) : 0.0
atr = ta.atr(14)
ema200 = ta.ema(close, 200)
pdh = request.security(syminfo.tickerid, "D", high[1], lookahead=barmerge.lookahead_on)
pdl = request.security(syminfo.tickerid, "D", low[1], lookahead=barmerge.lookahead_on)
inSess = not na(time(timeframe.period, sess, tz))
cutoff = timestamp(tz, year(time, tz), month(time, tz), dayofmonth(time, tz), closeHour, 0)
// each level is traded once: remember the last level used on each side
var float usedHi = na
var float usedLo = na
// the first close beyond the level, by a small margin, from a candle that closed inside it last time
breakUp = not na(pdh) and close[1] <= pdh and close > pdh + atr * bufAtr
breakDn = not na(pdl) and close[1] >= pdl and close < pdl - atr * bufAtr
longSl = math.min(low, pdh - atr * stopAtr)
shortSl = math.max(high, pdl + atr * stopAtr)
longQty = calcQty(close, longSl)
shortQty = calcQty(close, shortSl)
longGo = breakUp and inSess and time_close < cutoff and (na(usedHi) or pdh != usedHi) and (not useTrend or close > ema200) and close - longSl <= maxStopAtr * atr and longQty > 0 and strategy.position_size == 0
shortGo = breakDn and inSess and time_close < cutoff and (na(usedLo) or pdl != usedLo) and (not useTrend or close < ema200) and shortSl - close <= maxStopAtr * atr and shortQty > 0 and strategy.position_size == 0
// ---------- Orders
if longGo
strategy.entry("Long", strategy.long, qty=longQty)
strategy.exit("Long exit", "Long", stop=longSl, limit=close + (close - longSl) * rr)
usedHi := pdh
if shortGo
strategy.entry("Short", strategy.short, qty=shortQty)
strategy.exit("Short exit", "Short", stop=shortSl, limit=close - (shortSl - close) * rr)
usedLo := pdl
// the candle that closes at the cut-off sends the order, so it fills at the cut-off time
if strategy.position_size != 0 and time_close >= cutoff
strategy.close_all(comment="Session end")
// ---------- Chart
plot(pdh, "Previous day high", color=color.new(color.teal, 0), style=plot.style_linebr)
plot(pdl, "Previous day low", color=color.new(color.orange, 0), style=plot.style_linebr)
plot(useTrend ? ema200 : na, "200 EMA", color=color.new(color.gray, 0))
plotshape(longGo, "Breakout above the high", shape.triangleup, location.belowbar, color.teal, size=size.small)
plotshape(shortGo, "Breakout below the low", shape.triangledown, location.abovebar, color.red, size=size.small)Trading this from India
The rules work on any gold chart, and TradingView's XAUUSD chart is a fine place to learn and backtest them. To trade gold legally from India, though, use MCX gold futures, including the smaller Gold Mini and Gold Petal contracts, through a SEBI-registered broker. Trading XAUUSD as a CFD with an offshore forex platform isn't allowed for residents under FEMA. MCX gold trades from 9 a.m. to 11:30 p.m. IST while the US is on daylight saving time and to 11:55 p.m. in the US winter, which covers the London session and the New York morning. The contract is priced in rupees, and the script works in ATR rather than pips, so it needs no pip setting. The full picture is in is forex trading legal in India and XAUUSD market timings in India.
Related strategies: London breakout, opening range breakout, ICT kill zones, XAUUSD London session, XAUUSD New York session, break and retest, inside bar. All 34 strategies are compared on one page in forex trading strategies.