Idea in brief
The first minutes after an index cash session opens are noisy: overnight orders get filled, and price jerks both ways. Tom Hougaard does not trade the first 15-minute candle. Hougaard waits for the second one to close and places two pending orders: a buy above its high and a sell below its low. Whichever side triggers shows where the market went after the first half hour.
For context, Tom marks the overnight range (the high and low before the open) and the prior day close. If the breakout takes price beyond the overnight range, it is a signal in that direction. If the signal triggers inside the range, Tom suggests testing the opposite trade. On the streams it is called Anti.
The name comes from the British "school run": the New York open falls at the time when parents in England collect their children from school.
Why it might work
The logic is the same as for any opening range breakout. By the end of the first half hour the overnight information is already priced in, and a move beyond the extreme of the second candle more often shows a directional move than noise. The overnight range acts as a filter. Beyond it, the market needs a new decision from participants. Inside it, price moves between levels that are already known, and breakouts return more often.
Tom calls the setup an entry technique and does not fix a stop or an exit in the definition. Andi says plainly on the stream that anyone automating it will have to define them. Below they are defined and marked.
Rules
Time and reference candles
// cash session open, exchange time
SessionOpen = 09:00 CET (DAX)
| 08:00 UK (FTSE)
| 09:30 ET (Dow, NASDAQ, S&P 500)
Bar1 = 15-minute bar [SessionOpen; SessionOpen + 15 min)
Bar2 = the next 15-minute bar
// overnight range: everything traded between the prior cash session close and SessionOpen
ON_High = high over this period
ON_Low = low over this period
// on Tom's DAX charts the range usually runs from midnight to 08:00 (time zone not specified in the source),
// Andi counts the whole time between sessions as "overnight". This is a parameter, test both variants
Entry: classic School Run (author)
// after Bar2 closes
BuyLevel = Bar2.High + Offset
SellLevel = Bar2.Low - Offset
BUY STOP at BuyLevel // author
SELL SHORT STOP at SellLevel
// OCO orders: when one is filled, the other is canceled
// overnight range filter (author)
IF BuyLevel <= ON_High THEN CANCEL BUY STOP // a buy inside the range is not a classic signal
IF SellLevel >= ON_Low THEN CANCEL SELL SHORT STOP
Entry: Anti inside the overnight range (partly author)
Tom formulated Anti as a hypothesis to test, and Andi trades it depending on the situation. The entry and exit levels below are ours.
// the signal would trigger inside the overnight range → enter the opposite way
IF SellLevel >= ON_Low AND SellLevel <= ON_High
BUY LIMIT at SellLevel // Finetiq: buy where the sell would have been
IF BuyLevel >= ON_Low AND BuyLevel <= ON_High
SELL SHORT LIMIT at BuyLevel // Finetiq
AntiTarget = opposite boundary of the overnight range // Finetiq, following a viewer's example on V114
AntiStop = EntryPrice ∓ (Bar2.High - Bar2.Low) // Finetiq: stop equal to the size of the second candle
Stop and exit for the classic signal
// stop: opposite side of the second candle (Andi, V114; community report, V70)
Long: StopLoss = Bar2.Low
Short: StopLoss = Bar2.High
// target: two stop distances (community, V70)
Long: Target = EntryPrice + 2 * (EntryPrice - StopLoss)
Short: Target = EntryPrice - 2 * (StopLoss - EntryPrice)
// close anything still open before the end of the cash session
EXIT at SessionClose - 5 min // Finetiq
Inside bar filter (author)
// Tom skipped the signal because candles 2, 3, 4 and 5 were inside bars
Inside(n) = High[n] <= High[n-1] AND Low[n] >= Low[n-1]
IF orders are still unfilled at the close of Bar5
AND Inside(Bar2) AND Inside(Bar3) AND Inside(Bar4) AND Inside(Bar5)
CANCEL all orders for the day
// Finetiq: we read "inside" as "inside the previous candle".
// Variant to test: candles 3–5 inside Bar2
Position size (community)
RiskMoney = Equity * 1%
Lots = RiskMoney / (|EntryPrice - StopLoss| * PointValue)
// recalculate every session
Parameters
| Parameter | Value | Source |
|---|---|---|
| Timeframe | 15 minutes | author |
| Reference candle | second after the open | author |
| Offset | 0–2 points | Finetiq (in other setups Tom uses 2 points on the DAX) |
| Overnight range | between sessions or 00:00–08:00 | author and Andi, two versions |
| Stop | opposite side of the second candle | community (Andi) |
| Target | 2 × stop | community (V70 backtest) |
| Anti target | opposite boundary of the overnight range | Finetiq |
| Anti stop | size of the second candle | Finetiq |
| Inside bar filter | candles 2–5 | author |
| Time exit | 5 minutes before the end of the cash session | Finetiq |
| Risk per trade | 1% | community |
What to test
- Is the overnight range needed. Three runs: a plain breakout of the second candle with no filter, only classic signals beyond the range, classic signals plus Anti. This is Tom's main question from V48.
- Two definitions of overnight. The range between sessions versus the 00:00–08:00 window. On CFDs and futures with different trading hours the results can differ a lot.
- Exit. A 2:1 target versus 1:1, versus closing at the end of the session, versus moving the stop to breakeven after +1R. Tom says the results rest on position management, not on the entry.
- Inside bar filter. Compare the days canceled by the filter with the rest. If the canceled days are not worse on average, the filter only reduces the number of trades.
- Length of the second candle. A long candle means a large stop. Split trades by the ratio
(Bar2.High − Bar2.Low) / daily ATR(14). Tom mentions candle length as a possible filter. - Days when both sides triggered. Count how often both the buy and the sell were filled on the same day. Tom calls exactly this case the most unpleasant one.
- Different indices. DAX, FTSE, Dow, NASDAQ separately. Andi notes that the setup does not work on gold: gold has no clear open.
Platform notes
TradingView (Pine Script)
- Set the session window with the exchange time zone:
time(timeframe.period, "0900-0930", "Europe/Berlin"). Daylight saving transitions are then handled automatically. Europe and the US change their clocks on different dates, so a fixed 6-hour offset breaks for 2–3 weeks a year. - OCO order pair:
strategy.entry("L", strategy.long, stop = buyLevel, oca_name = "SR", oca_type = strategy.oca.cancel)and the same entry for the short. - If both the entry and the stop or target are hit within one 15-minute bar, the tester does not know the order. Enable
use_bar_magnifier = true(requires a paid plan) or test on lower timeframe data. - CFD symbols and futures have different session boundaries. Check that Bar1 really starts at 09:00 exchange time.
MultiCharts and TradeStation (EasyLanguage)
Timein EasyLanguage is the bar's close time. The second DAX candle (09:15–09:30) hasTime = 930. In Pine and MQL5 bars are stamped with their open time.Buy next bar at X stoplives for one bar. Resend the order on every bar while it is valid, and stop sending the opposite one onceMarketPosition <> 0.- Chart time can be exchange time or local time, depending on the symbol settings. Check this before testing, otherwise the 09:00 window will shift.
- For the order of fills inside a 15-minute bar, use Intrabar Order Generation or test on 1-minute data.
MetaTrader 5 (MQL5)
- Bars are stamped with the broker's server time, usually GMT+2/+3. 09:00 CET is 10:00 on such a server, but only while both sides are on the same daylight saving schedule.
- In the tester
TimeGMT()does not return real GMT, it equals server time. The offset and the daylight saving dates have to be calculated manually. - A "point" for Tom is one index unit.
_Pointon an index CFD is often 0.1 or 0.01. A 40-point stop on the DAX is40.0in price, not40 * _Point. - Pending
BuyStopandSellStopgo throughCTrade, and OCO has to be built yourself inOnTradeTransaction. CFD spreads widen at the open, so test on real ticks.
Where the idea can break
- The author described only the entry. The stop, target and position size come from the community and from our formalization. Tom's live results include discretionary trade management, which the rules do not contain.
- The only backtest mentioned covers four and a half months of 2026, and the stream host does not know its methodology.
- Andi takes Anti depending on the situation: a deep pullback, overlapping candles, a range. The mechanical version above may work worse than the discretionary one.
- Stops and offsets in points do not scale. Ten years ago the DAX stood at 10–11 thousand, now it is more than twice as high. Andi notes that over long history fixed point values need to be reduced.
- Spreads and slippage are wide at the open. For CFDs this can eat a noticeable part of the result.