Idea in brief
Rob Hanna has researched the short-term behavior of the US market for more than twenty years and publishes the Quantifiable Edges newsletter. One of the topics is seasonality: days of the week, holidays, employment report days and Fed decision days.
According to Hanna's research, the day an FOMC decision is released is bullish on average. The effect is strongest when there was fear in the market before the decision: the index closed at a 3-, 5- or 10-day low or at the very bottom of the day's range. If the market ran up before the decision and closed at a 20-day high, there is almost no effect.
The second part of the finding concerns time. Most of the profit accrues from the prior close to 14:00 ET, when the decision is released. After the release the market can move sharply in either direction, but over a long history it stays flat on average. Hence the rule: buy at the close the day before and exit before the release.
At this point in the interview Hanna does not name an instrument. Hanna builds models on research of the S&P 500 and NASDAQ, so the S&P 500 is used below: ES futures, SPY or a CFD.
Why it might work
The author's explanation is tied to the behavior of the Fed itself. For many years the Fed considered calming panic its job: soothing the market, promising rate cuts. And conversely, cooling down a market that was too strong. Some participants sell the day before because they do not want to hold a position through the announcement. If the Fed tends to reassure, this discount is recovered even before the release. The host adds that by the time of the announcement informed participants have already traded, and Hanna agrees.
There are no figures in the interview. Hanna says this has been covered on the blog several times. We have not checked the blog, so the strength of the effect and its stability are not confirmed here.
Rules
Event calendar
FOMC decision dates cannot be computed by a formula, they are set as a list. Source: the official Federal Reserve website, the meeting calendar page (federalreserve.gov/monetarypolicy/fomccalendars.htm) and the archive of materials by year (federalreserve.gov/monetarypolicy/fomc_historical_year.htm). There are eight scheduled meetings a year, most of them two-day meetings, and the decision is released on the second day. Unscheduled decisions are also in the archive and must be marked separately.
FedDays = [release dates of decisions from scheduled meetings, from the Fed archive]
// Finetiq: unscheduled decisions are excluded, test them separately
PreFedDay = last trading day before FedDay
AnnounceET = 14:00 ET // author: "2 PM"
// Finetiq: for older years check the release time against the press release in the archive,
// it has changed over history
Fear filter
// daily S&P 500 bars, calculated at the PreFedDay close
Fear3 = Close <= Lowest(Close, 3) // author: close at a 3-day low
Fear5 = Close <= Lowest(Close, 5) // author: 5-day
Fear10 = Close <= Lowest(Close, 10) // author: 10-day
// Finetiq: lowest close, the current bar is included in the window.
// Variant: Close < Lowest(Low, N)[1]
RangePos = (Close - Low) / (High - Low)
LowInRange = RangePos <= 0.25 // author: "near the bottom of the day's range"; Finetiq: 25% threshold
Fear = Fear3 OR LowInRange
// Finetiq: a close at a 5- or 10-day low is always also at a 3-day low,
// so Fear3 already includes the others. The author lists them as different
// ways of marking fear, test each one separately
RunUp = Close >= Highest(Close, 20) // author: close at a 20-day high, almost no effect
Entry and exit
IF Date = PreFedDay AND Fear AND NOT RunUp
BUY AT CLOSE // author: measured from the close of the day before
// Finetiq: in practice a market-on-close order or a buy 5 minutes before the session ends
IF Date = FedDay AND Time >= 13:55 ET // Finetiq: start of the last 5-minute bar before the release
EXIT AT MARKET // author: exit before 14:00
// the author has no stop-loss, the holding period is less than a day
// Finetiq: a variant for testing, StopLoss = EntryPrice - 1.5 * ATR(14) of daily bars
Control groups (Finetiq)
These rules are not for trading. They show where the result comes from.
AllFed = every PreFedDay without filters, same entry and exit
RunUpFed = only PreFedDay with RunUp
FearOnly = Fear AND NOT RunUp on regular days without a Fed decision,
exit the next day at 13:55 ET
Parameters
| Parameter | Value | Source |
|---|---|---|
| Event | decisions from scheduled FOMC meetings | author |
| Instrument | S&P 500: ES, SPY, CFD | Finetiq (the author researches the S&P 500 and NASDAQ) |
| Entry | close of the last trading day before the decision | author |
| Fear: lowest close | 3, 5 or 10 days | author |
| Fear: bottom of the day's range | lower 25% | author (threshold by Finetiq) |
| Entry ban | close at a 20-day high | author |
| Exit | before 14:00 ET, 13:55 ET bar | author (minute by Finetiq) |
| Stop | none, variant 1.5 × ATR(14) | Finetiq |
| Unscheduled decisions | exclude | Finetiq |
What to test
- Three groups of Fed days. All decisions, decisions after fear, and decisions after a close at a 20-day high. Hanna claims the result declines in exactly this order: fear, all days, run-up. If the difference between the groups is within the noise, the filter adds nothing.
- Which fear. The 3-, 5-, 10-day low and the bottom of the range separately. Look not only at the average trade but also at the number of events: the stricter the filter, the fewer the dates.
- Fed or an ordinary pullback. The same fear filter on regular days with an exit the next day at 13:55 ET. Buying a short-term S&P 500 low often gives a bounce on its own. The Fed effect is the difference between decision days and regular days, not the whole result of decision days.
- Exit time. 13:55 ET versus the close of decision day. If an exit at 16:00 is no worse, the claim that the market stays flat after the release is not confirmed on your data.
- Entry time. The prior close versus the open of decision day. Futures and CFDs trade overnight, and part of the result may come from the overnight move.
- Periods. Rate-cutting years and rate-hiking years separately, for example 2022. The author's explanation relies on how the Fed behaved for many years. If that behavior has changed, the effect may have weakened.
Platform notes
TradingView (Pine Script)
- There is no event calendar. Store the dates as an array of timestamps, one per decision from the Fed archive:
array.from(timestamp("America/New_York", year, month, day, 14, 0), ...). - The rule needs two timeframes: a filter on the daily close and an exit at 13:55 ET. On a 5-minute chart the close of the last bar of the session is the daily close. Lowest closes over 3-20 days are easier to accumulate yourself.
- Buying at the close requires
process_orders_on_close = true. By default an order from the last bar of the day fills at the open of the next session, that is, already on decision day. That is a different variant of the rule. - Intraday history is limited by plan. Only a few years of 5-minute bars may fit, which is a couple of dozen decisions.
- The ES session starts at 18:00 ET the previous day. The day's range and close differ between the futures session and the cash session. Choose one and keep it in all runs.
MultiCharts and TradeStation (EasyLanguage)
- Store the dates in an array and compare them with
Date. In EasyLanguage a date is a YYYMMDD number with the year counted from 1900: March 15, 2024 is1240315. - If you calculate the filter on a daily series
Data2, keep in mind that while the session is in progress the daily bar is not closed, andClose of Data2at 15:55 shows the previous day. Calculate the current session's low, high and close from intraday bars. Timeis the bar's close time. The 13:50-13:55 bar hasTime = 1355, andIf Date = FedDate and Time >= 1355 then Sell next bar at marketfills at the open at 13:55.- In TradeStation, a futures daily bar closes at the settlement, not at the last trade. A filter on daily closes and one on intraday bar closes can select different dates.
MetaTrader 5 (MQL5)
- Set the dates as a
datetimearray in ET and convert them to the broker's server time, accounting for daylight saving time on both sides. In the testerTimeGMT()equals server time and does not help. - MQL5 has economic calendar functions, but for a historical test it is more reliable to hardcode the dates as an array.
- A daily bar of an S&P 500 CFD is built on server time and includes hours after 16:00 ET. A close at a 5-day low on such a bar and on the cash index may not match. Calculate daily closes at 16:00 ET yourself from intraday bars.
- The position is held overnight, which means a swap on a CFD. Check the spread specifically at the minutes of entry and exit.
Where the idea can break
- There are few events. Eight scheduled decisions a year, and several times fewer after the fear filter. Even over 20 years the sample is small, and one or two strong days can make the entire result.
- There is not a single figure in the interview. The effect is described in words and can only be verified independently.
- The explanation relies on the Fed's habits. A change of leadership, a rate-hiking cycle or a new communication format can change the market's reaction.
- The fear filter by itself selects short-term S&P 500 pullbacks, which often bounce without the Fed. Without a control group it is easy to attribute ordinary mean reversion to the Fed.
- A calendar error breaks the whole test. A mixed-up day of a two-day meeting or a wrong release time for older years shifts the entry and exit.