← All ideas
#034Mean reversionSwing

Three higher closes in a row: selling the pullback based on streak statistics

After three daily closes in a row, each above the previous one, look to sell the pullback. Based on a broker's tip to Brent Penfold and on Penfold's close streak statistics: about 2.4 days on all markets. We set the entry, stop and exit.

The Algorithmic Advantage · Brent Penfold · Watch video

Markets

Indices, Futures, Forex, Commodities, Stocks

Timeframe

D1

Data

OHLC

Rules

Partly formalised

Difficulty

Easy

Status

Untested

Some rules were added by us and are marked in the text.

TradingView ports directly
EasyLanguage has pitfalls
MetaTrader 5 has pitfalls

Idea in brief

Brent Penfold traded Elliott waves for twelve years and blew up the trading account twice. The turning point came after a conversation with broker Jeff Morgan. Morgan calmly said that the futures on the Australian SPI index had just made their median move, three closes in a row higher, so Morgan expected a pullback and was looking for a place to sell. The next day the market fell. After that, Penfold started looking for statistics instead of opinions and became a mechanical trader.

Later Penfold measured the length of streaks of closes in one direction on the 30 markets the author trades. According to Penfold's data, one standard deviation of streak length is about 2.4 days, two are about 5 days, and the figure barely changes across markets, sectors and decades. Hence a simple hypothesis: a streak of three higher closes is already longer than typical, and the next day more often goes against it.

The card takes the setup (three higher closes, wait for a pullback) and the streak statistics from the author. The entry, stop, exit and the mirror side are ours.

Why it might work

Penfold explains it this way. If you strip the names off markets and look only at the price series, they are the same: all traders essentially trade volatility, and volatility has a stable rhythm. The author recalls George Taylor, a grain trader of the 1930s–40s. Taylor divided the market into a three-day cycle: a buying day, a selling day and a short-selling day. Sometimes the cycle stretched to a fourth or fifth day. Penfold believes the 2.4-day figure describes the same phenomenon.

A Finetiq caveat. Streak statistics by themselves do not prove a reversal. Suppose up and down days are equally likely and independent of each other. Then half of all streaks are 1 day long, a quarter are 2 days, and another quarter are 3 days or longer. In such a model 75% of streaks are no longer than two days, and about 97% are no longer than five. This is close to the author's numbers if you read them as shares of streaks. Identical figures on different markets may only mean that daily changes resemble coin flips.

There is an edge only if, after three higher closes, a lower close the next day occurs noticeably more often than usual. This can be checked in one evening without any trading system, see "What to test".

Rules

Close streaks

// daily bars
IF Close > Close[1]       THEN UpStreak = UpStreak[1] + 1;  DnStreak = 0
ELSE IF Close < Close[1]  THEN DnStreak = DnStreak[1] + 1;  UpStreak = 0
ELSE                           UpStreak = 0;  DnStreak = 0
// Finetiq: a close equal to the previous one breaks both streaks

Entry

Setup = UpStreak == 3              // author: three higher closes in a row, wait for a pullback
// Finetiq: exactly 3, not "3 or more", so that one streak gives one signal

// Variant A: immediate entry
IF Setup AND MarketPosition == 0
    SELL SHORT AT NEXT BAR OPEN                        // Finetiq

// Variant B: entry only if the pullback has started
IF Setup AND MarketPosition == 0
    SELL SHORT STOP at Low - 1 tick                     // Finetiq: break of the third bar's low
    // the order lives for the next bar only, then CANCEL

Stop and exit (Finetiq)

StopLoss = Highest(High, 3) + 0.5 * ATR(14)             // above the streak high
EXIT STOP at StopLoss

IF UpStreak >= 5      THEN EXIT AT NEXT BAR OPEN        // the streak reached the author's two deviations
IF Close < Close[1]   THEN EXIT AT NEXT BAR OPEN        // the pullback happened: first lower close
IF BarsSinceEntry >= 3 THEN EXIT AT NEXT BAR OPEN       // per the three-day cycle from the author's story

Mirror side (Finetiq)

// the author only talks about selling after a rise. Buying after a decline is our symmetry
IF DnStreak == 3 AND MarketPosition == 0
    BUY AT NEXT BAR OPEN
// stop below the streak low, exits mirrored

Recalculating the streak statistics (Finetiq)

// when a streak ends, record its length
IF UpStreak[1] > 0 AND UpStreak == 0 THEN Add(UpLengths, UpStreak[1])
IF DnStreak[1] > 0 AND DnStreak == 0 THEN Add(DnLengths, DnStreak[1])

MeanLen  = Average(UpLengths)
StdLen   = StdDev(UpLengths)
Share2   = share of streaks 1–2 days long
Share5   = share of streaks 1–5 days long

// the question the whole idea depends on
P_all    = share of days where Close < Close[1]
P_after3 = share of days where Close < Close[1], among days with UpStreak[1] == 3

// control: the same daily changes in random order, 100 permutations
// for each permutation recalculate StdLen, Share2, Share5 and P_after3

Parameters

Parameter Value Source
Timeframe daily bars author
Streak length for the signal 3 higher closes in a row author
Direction sell after a rise author
Buy after three lower closes mirrored Finetiq
Equal close breaks the streak Finetiq
Entry next bar's open or a stop below the third bar's low Finetiq
Stop high of three bars + 0.5 × ATR(14) Finetiq
Streak length exit 5 higher closes in a row Finetiq (author's number: two deviations)
Pullback exit first close below the previous one Finetiq
Time exit 3 bars Finetiq

What to test

  1. Recalculate the author's statistics on your own data. Using the block above, collect the lengths of all streaks, the mean, the standard deviation, and the shares of streaks up to 2 and up to 5 days. Then shuffle the order of daily changes (do not touch the changes themselves) and calculate the same 100 times. If the real figures lie within the range of the shuffled ones, streaks on your market behave like random ones, and 2.4 days says nothing about a reversal.
  2. Conditional probability without trading. Compare P_after3 with P_all and with the same value on shuffled series. Repeat for streaks of 2, 4 and 5. If a decline after three higher closes is no more frequent than usual, entry and exit rules will not create an edge.
  3. Streak length neighborhood. Run the entry after 2, 3, 4 and 5 closes. The author singles out 3. If the result exists only at 3, it looks like sampling luck.
  4. Immediate entry or on a break of the low. Variant A versus variant B. The second skips trades where the pullback never started, but enters lower and pays with missed moves.
  5. Sides and regime separately. Count sells after rises and buys after declines separately, and separately above and below SMA(200). Stock indices have a long upward drift, and a short against it can lose even when the short-term pullback is real.
  6. Costs. With random days, a streak of three or more higher closes occurs about 15 times a year per market, and as many downward. A trade lasts 1–3 days. Add spread, commission and CFD swap, and see whether the average trade stays positive.
  7. Market uniformity. The author claims that markets are the same. Run the same rules without tuning on indices, rates, currencies and commodities. Look at the median by sector, not at the best market.

Platform notes

TradingView (Pine Script)

  • The streak is tracked with a counter: var int up = 0 and up := close > close[1] ? up + 1 : 0. On instruments with a large tick size equal closes are common, so check that the reset matches your definition.
  • Variant A matches the default execution: signal on the close, entry at the next bar's open (process_orders_on_close = false). The entry price includes the overnight gap.
  • The variant B stop order via strategy.entry(..., stop = low) stays active until canceled. By the rule it lives for one bar, so strategy.cancel is needed on the next bar.
  • There are many short trades. Set commission_value and slippage in strategy(), otherwise the test will show a result without costs.

MultiCharts and TradeStation (EasyLanguage)

  • For futures in TradeStation, the close of a daily bar is the settlement, while a 1440-minute bar closes on the last trade. Close streaks on the two kinds of bar come out different, and the signals diverge. Test and trade on the same kind of bar.
  • Sell Short next bar at Low stop lives exactly one bar. This matches variant B without a separate cancel.
  • Set the stop as a price: Buy to Cover next bar at StopLoss stop. SetStopLoss is set in money and can produce a different level.
  • Time exit: If BarsSinceEntry >= 3 then Buy to Cover next bar at market.

MetaTrader 5 (MQL5)

  • The daily bar is built on the broker's server time. Servers not on GMT+2/+3 may have short Sunday bars. They add extra closes and shift the streak count. Compare the broker's daily closes with the exchange closes.
  • The price of an index CFD differs from the futures close. Streaks on a CFD may not match the streaks in the author's data.
  • Calculate the signal on the closed bar (index 1), once per new daily bar.
  • Holding a CFD position overnight incurs swap. With a holding period of 1–3 days it noticeably cuts into a small average trade.

Where the idea can break

  • The author has no test of these rules. There is one SPI episode and the streak length statistics. The trading rules are entirely our formalization.
  • The same 2.4 days on all markets may be a property of a random series rather than of reversals. Test 1 will show this.
  • The author talks about the median move, the standard deviation and 68% of streaks as if they were the same thing. The interview does not say how the author calculated them. Your figures may differ from the author's even on the same markets.
  • Shorting after a rise on stock indices goes against a multi-year drift. A combined result for both sides can hide that only one side works.
  • The average trade is short and small. Slippage at the open, spread and CFD swap eat it faster than in trend systems.
  • The author's data: 30 futures markets since 1980. On a short CFD history, streak shares and conditional probabilities are unstable.

Sources

Author's claims

These figures and statements are the author's. We have not verified them.

  • One standard deviation of the length of close streaks in one direction is about 2.4 days, two are about 5 days. According to the author, this holds for the 30 futures markets the author trades and for stocks.
  • By decade since 1980, the author gets 2.3–2.6. By sector: indices, rates and currencies 2.4, sugar and oil 2.3–2.6. According to the author, 68% of all streaks fall within this value.
  • Over the last 5, 10 and 15 years, according to the author, it is the same 2.4 days. The author's data starts in 1980.
  • An episode from the late 90s: broker Jeff Morgan told the author that SPI futures had made a median move of three higher closes and that it was time to look for a sell. The next day the market fell. This is a single case, not a test.

Related ideas

Updated: 2026-09-10