Strasmore Research
Deep Dives Matt ConnorBy Matt Connor · Updated 2026-07-26

March 9, 2009: The Bottom, On the Tape

March 9, 2009 was the exact bottom of the financial crisis, and the tape shows a quiet, unremarkable Monday. What generational lows actually look like up close.

March 9, 2009 is one of the most important dates in modern market history: the closing low of the financial crisis, -56.5% below the October 2007 peak, and the first day of a bull market that ran for over a decade. The history books cite the index levels from that Monday: 676.53 on the S&P 500, 6,547 on the Dow. The receipts below use SPY, the S&P 500 ETF, whose minute-by-minute tape this database stores back to 2003. And here is the uncomfortable truth that tape preserves: nothing about the session announced it. No capitulation crescendo, no reversal fireworks, a quiet, grinding red Monday that happened to be the last one. Every number is a stored query; expand any panel for the SQL.

The road to the bottom

The crisis arrived in stages, and the dates matter for reading everything below. Bear Stearns was sold to JPMorgan in March 2008. Lehman Brothers filed for bankruptcy on Monday, September 15, 2008, a session with its own page here. Congress passed TARP, the $700 billion bank-rescue fund, on October 3. AIG's government rescue was expanded twice. Citigroup took its second federal backstop in November. A winter rally faded, and by late February 2009 the averages had broken their November lows and kept falling. One row compresses that seventeen-month run:

QueryPeak to trough to round trip: the whole crisis in one row
peak_closepeak_datetrough_closetrough_datedecline_pctrecovered_date
156.412007-10-0968.072009-03-09-56.52013-03-14
The exact SQL behind every number
WITH daily AS (
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
        argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS close_usd
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= toDateTime('2007-01-02 00:00:00') AND window_start < toDateTime('2013-07-01 00:00:00')
    GROUP BY et_date
),
(SELECT max(close_usd) FROM daily WHERE et_date < toDate('2008-01-01')) AS peak_close_usd
SELECT
    round(peak_close_usd, 2) AS peak_close,
    toString(argMaxIf(et_date, (close_usd, et_date), et_date < toDate('2008-01-01'))) AS peak_date,
    round(minIf(close_usd, et_date BETWEEN toDate('2008-07-01') AND toDate('2009-06-30')), 2) AS trough_close,
    toString(argMinIf(et_date, (close_usd, et_date), et_date BETWEEN toDate('2008-07-01') AND toDate('2009-06-30'))) AS trough_date,
    round((minIf(close_usd, et_date BETWEEN toDate('2008-07-01') AND toDate('2009-06-30')) / peak_close_usd - 1) * 100, 1) AS decline_pct,
    toString(minIf(et_date, et_date > toDate('2009-03-09') AND close_usd >= peak_close_usd)) AS recovered_date
FROM daily
Run this yourself

From a closing peak of $156.41 on 2007-10-09, SPY fell to $68.07 on 2009-03-09, a -56.5% decline, the deepest since the 1930s. The same row carries the number long-term investors ask about next: the round trip. SPY did not close above its 2007 peak again until 2013-03-14, four years after the low, five and a half after the top. Both halves of that arithmetic get their own receipts below.

The day, on one row

QuerySPY on March 9, 2009: the generational low, receipted
prior_closerth_opengap_pctrth_highhigh_etrth_lowlow_etrth_closeday_change_pctday_shares_mavg20_shares_mavg60_shares_mvol_vs_20d_pctrth_minute_bars
68.8467.95-1.37010:1367.7315:1768.07-1.1357.4406.3337.9-12390
The exact SQL behind every number
WITH
    (
        SELECT argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)
        FROM global_markets.delayed_stocks_minute_aggs
        WHERE ticker = 'SPY'
          AND window_start >= toDateTime('2009-03-06 00:00:00') AND window_start < toDateTime('2009-03-09 04:00:00')
    ) AS prior_rth_close,
    (
        SELECT round(avg(day_shares) / 1e6, 1)
        FROM (
            SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d, toFloat64(sum(volume)) AS day_shares
            FROM global_markets.delayed_stocks_minute_aggs
            WHERE ticker = 'SPY'
              AND window_start >= toDateTime('2008-12-01 00:00:00') AND window_start < toDateTime('2009-03-09 04:00:00')
            GROUP BY d
            ORDER BY d DESC
            LIMIT 20
        )
    ) AS avg20_shares,
    (
        SELECT round(avg(day_shares) / 1e6, 1)
        FROM (
            SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS d, toFloat64(sum(volume)) AS day_shares
            FROM global_markets.delayed_stocks_minute_aggs
            WHERE ticker = 'SPY'
              AND window_start >= toDateTime('2008-12-01 00:00:00') AND window_start < toDateTime('2009-03-09 04:00:00')
            GROUP BY d
            ORDER BY d DESC
            LIMIT 60
        )
    ) AS avg60_shares
SELECT
    round(prior_rth_close, 2) AS prior_close,
    round(toFloat64(argMinIf(open, window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)), 2) AS rth_open,
    round((toFloat64(argMinIf(open, window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)) / prior_rth_close - 1) * 100, 1) AS gap_pct,
    round(maxIf(toFloat64(high), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 2) AS rth_high,
    formatDateTime(toTimeZone(argMaxIf(window_start, (toFloat64(high), -toInt64(toUnixTimestamp(window_start))), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 'America/New_York'), '%H:%i') AS high_et,
    round(minIf(toFloat64(low), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 2) AS rth_low,
    formatDateTime(toTimeZone(argMinIf(window_start, (toFloat64(low), toInt64(toUnixTimestamp(window_start))), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 'America/New_York'), '%H:%i') AS low_et,
    round(toFloat64(argMaxIf(close, window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)), 2) AS rth_close,
    round((toFloat64(argMaxIf(close, window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959)) / prior_rth_close - 1) * 100, 1) AS day_change_pct,
    round(toFloat64(sum(volume)) / 1e6, 1) AS day_shares_m,
    avg20_shares AS avg20_shares_m,
    avg60_shares AS avg60_shares_m,
    round((toFloat64(sum(volume)) / 1e6 / avg20_shares - 1) * 100, 0) AS vol_vs_20d_pct,
    countIf((toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS rth_minute_bars
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
  AND window_start >= toDateTime('2009-03-09 04:00:00') AND window_start < toDateTime('2009-03-09 23:59:00')
Run this yourself

SPY opened at $67.95, a -1.3% gap down from Friday's $68.84 close, touched $70 at 10:13 ET, sagged to a $67.73 low late in the day (15:17 ET), and closed at $68.07, -1.1% on the day. The whole session's range was about two dollars. The most consequential closing print of a generation arrived without a single dramatic minute.

Volume answers a question the raw number alone can't: were 357.4 million shares loud or quiet? For March 2009, quiet. The trailing twenty sessions had averaged 406.3 million SPY shares a day, the bottom printed -12% relative to that average, and the trailing sixty averaged 337.9 million. Capitulation lore says generational lows arrive on climactic, record-setting turnover. The most famous bottom of the modern era traded less than an ordinary day of its own month.

The shape of the session

QuerySPY by half-hour: March 9, 2009 regular session
et_timebucket_closebucket_lowshares_m
09:3068.9567.9540.5
10:0069.4968.931.8
10:3068.968.8225.6
11:0068.9968.621.6
11:3068.9568.7118.7
12:0069.1368.8314.5
12:3068.7968.6515.7
13:0068.3468.1321.1
13:3068.4868.2515.7
14:0068.5768.3325.9
14:3068.4367.9524.5
15:0068.0567.7328.3
15:3068.0767.7844.3
The exact SQL behind every number
SELECT
    formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE), '%H:%i') AS et_time,
    round(toFloat64(argMax(close, window_start)), 2) AS bucket_close,
    round(min(toFloat64(low)), 2) AS bucket_low,
    round(toFloat64(sum(volume)) / 1e6, 1) AS shares_m
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
  AND window_start >= toDateTime('2009-03-09 04:00:00') AND window_start < toDateTime('2009-03-09 23:59:00')
  AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY et_time
ORDER BY et_time
Run this yourself

The half-hour path corrects a detail most retellings flatten: March 9 was not a one-way slide. After the gap down, SPY rallied through mid-morning, the 10:00 ET bucket closed at $69.49, just under the $70 day high printed at 10:13, then spent the afternoon giving it back, drifting down to the $67.73 low at 15:17 and bouncing modestly into the close. Rally, fade, small bounce: an utterly ordinary shape. No waterfall, no panic volume signature, no v-bottom. Compare it with Lehman Monday's close-on-the-low urgency or the flash crash's air pocket: this is a third species entirely, the exhausted tape. The multi-percent crashes of that winter had all happened in the preceding weeks. The bottom itself was the day sellers simply ran out.

What turned the tape

Nothing in Monday's data explains Tuesday, the turn arrived with the news cycle, not the tape. Before Tuesday's open, an internal memo from Citigroup chief executive Vikram Pandit leaked to the press: the bank, it said, had been profitable in January and February 2009, its best two-month stretch since 2007. Citigroup, the crisis's epicenter, trading at $1.05 at Monday's close, had not produced a piece of primary-source good news in months. Here is what the tape records for the five sessions that followed the low:

QueryThe turn week: SPY, Citigroup, and the 10-year yield, March 9-13
sessionspy_closespy_change_pctspy_shares_mciti_closeten_year_pct
2009-03-0968.07-1.1357.41.052.89
2009-03-1072.216.1401.31.442.99
2009-03-1172.60.5350.11.542.95
2009-03-1275.514407.41.662.89
2009-03-1376.090.8332.71.782.89
The exact SQL behind every number
WITH daily AS (
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
        argMaxIf(toFloat64(close), window_start, ticker = 'SPY' AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS spy_close_raw,
        round(argMaxIf(toFloat64(close), window_start, ticker = 'C' AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 2) AS citi_close,
        round(toFloat64(sumIf(volume, ticker = 'SPY')) / 1e6, 1) AS spy_shares_m
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'C')
      AND window_start >= toDateTime('2009-03-06 04:00:00') AND window_start < toDateTime('2009-03-14 00:00:00')
    GROUP BY et_date
)
SELECT
    toString(d.et_date) AS session,
    round(d.spy_close_raw, 2) AS spy_close,
    round((d.spy_close_raw / d.prev_close - 1) * 100, 1) AS spy_change_pct,
    d.spy_shares_m,
    d.citi_close,
    t.ten_year_pct
FROM (
    SELECT *, lagInFrame(spy_close_raw) OVER (ORDER BY et_date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
    FROM daily
) AS d
LEFT JOIN (
    SELECT date, round(toFloat64(yield_10_year), 2) AS ten_year_pct
    FROM global_markets.treasury_yields
    WHERE date BETWEEN '2009-03-09' AND '2009-03-13'
) AS t ON d.et_date = t.date
WHERE d.et_date >= toDate('2009-03-09')
ORDER BY d.et_date
Run this yourself

March 10 opened higher and never gave it back: SPY closed at $72.21, up 6.1%, on 401.3 million shares, heavier volume than the bottom day itself. Citigroup closed at $1.44. By Friday, SPY stood at $76.09 and Citigroup at $1.78. The 10-year Treasury yield rose from 2.89% to 2.99% over that same Tuesday, money moving out of the safest asset alongside the equity rally, the flight-to-quality trade running in reverse.

The honest caveat: several multi-percent rallies had already come and failed that winter, and nothing on March 10 certified this one as different. The Pandit memo is the marker historians attach to the turn; what the tape can show, and does, above, is the coincidence of timing.

Did the low hold?

A bottom is only a bottom if the market never goes back. This panel tracks SPY week by week through the end of June 2009, each week's lowest trade and final close, with the running minimum in the last column:

QuerySixteen weeks after the low: weekly lows, closes, and the running minimum
week_ofweek_lowweek_closelowest_low_after_mar9
2009-03-0969.3776.0969.37
2009-03-1675.4576.7169.37
2009-03-2378.3181.6269.37
2009-03-3077.9684.2569.37
2009-04-0681.5185.8269.37
2009-04-1383.6187.1169.37
2009-04-2082.7586.6569.37
2009-04-2784.7687.8769.37
2009-05-0488.3893.0469.37
2009-05-1188.1588.769.37
2009-05-1888.2689.0669.37
2009-05-2588.3292.6569.37
2009-06-0187.5394.5369.37
2009-06-0893.0495.1269.37
2009-06-1590.8391.9769.37
2009-06-2288.8591.7869.37
The exact SQL behind every number
WITH daily AS (
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
        minIf(toFloat64(low), (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS day_low,
        argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS day_close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= toDateTime('2009-03-10 04:00:00') AND window_start < toDateTime('2009-06-27 00:00:00')
    GROUP BY et_date
)
SELECT
    week_of,
    week_low,
    week_close,
    round(min(week_low) OVER (), 2) AS lowest_low_after_mar9
FROM (
    SELECT
        toString(toMonday(et_date)) AS week_of,
        round(min(day_low), 2) AS week_low,
        round(argMax(day_close, et_date), 2) AS week_close
    FROM daily
    GROUP BY week_of
)
ORDER BY week_of
Run this yourself

The lowest SPY traded in the sixteen weeks after March 9 was $69.37, and that print came in the first week off the low (2009-03-09). SPY never traded below its March 9 close of $68.07 again, let alone the $67.73 intraday low. There was no retest, no second chance, no pullback to the old level: by the week of 2009-05-04 SPY closed at $93.04, a third above the bottom in nine weeks. Waiting for confirmation had a price, and the panel states it exactly.

Who led the year off the low

The banks at the center of the damage were also the center of the rebound. One year from the bottom close to March 9, 2010:

QueryOne year off the low: the crisis epicenter vs the broad market
tickerclose_mar9_2009close_mar9_2010pct_1yrfinancial
BAC3.7516.823491
C1.053.832651
WFC1028.971901
AAPL83.15223.171680
JPM15.942.391671
XLF6.3515.31411
GS73.86168.971291
SPY68.07114.45680
XOM64.5666.7930
The exact SQL behind every number
SELECT
    ticker,
    round(b_close, 2) AS close_mar9_2009,
    round(y_close, 2) AS close_mar9_2010,
    round((y_close / b_close - 1) * 100, 0) AS pct_1yr,
    fin AS financial
FROM (
    SELECT
        ticker,
        argMaxIf(toFloat64(close), window_start, toDate(toTimeZone(window_start, 'America/New_York')) = toDate('2009-03-09') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS b_close,
        argMaxIf(toFloat64(close), window_start, toDate(toTimeZone(window_start, 'America/New_York')) = toDate('2010-03-09') AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS y_close,
        max(ticker IN ('C', 'BAC', 'WFC', 'JPM', 'GS', 'XLF')) AS fin
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('C', 'BAC', 'WFC', 'JPM', 'GS', 'XLF', 'SPY', 'AAPL', 'XOM')
      AND ((window_start >= toDateTime('2009-03-09 04:00:00') AND window_start < toDateTime('2009-03-10 04:00:00'))
        OR (window_start >= toDateTime('2010-03-09 04:00:00') AND window_start < toDateTime('2010-03-10 04:00:00')))
    GROUP BY ticker
)
ORDER BY pct_1yr DESC
Run this yourself

The top of the board: BAC at +349%, C at +265% (from $1.05 a share), WFC at +190%, the most damaged large financials, tripling and quadrupling off prices that had assumed the worst. The board is not all banks, AAPL returned 168% over the same year, but the panel's bounded assertion is that the single best performer is a financial. Meanwhile the broad market (SPY) gained 68%, and XOM, the defensive giant that had held up best on the way down, gained just 3%. The rebound inverted the decline's leaderboard almost exactly.

How it compares with other bottoms

The minute tape here begins in September 2003, so the October 2002 dot-com low sits outside receipt range. Against the three deepest closing lows since, March 2009 looks like this:

QueryFour major lows: SPY forward returns at three and twelve months
bottom_sessionbottom_closeplus_3mo_pctplus_1yr_pct
2009-03-0968.0738.568.1
2011-10-03109.9216.131.4
2018-12-24234.3719.137.1
2020-03-23222.5139.675.1
The exact SQL behind every number
WITH daily AS (
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
        argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS close_usd
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND ((window_start >= toDateTime('2009-03-09 04:00:00') AND window_start < toDateTime('2010-03-17 00:00:00'))
        OR (window_start >= toDateTime('2011-10-03 04:00:00') AND window_start < toDateTime('2012-10-10 00:00:00'))
        OR (window_start >= toDateTime('2018-12-24 04:00:00') AND window_start < toDateTime('2019-12-31 00:00:00'))
        OR (window_start >= toDateTime('2020-03-23 04:00:00') AND window_start < toDateTime('2021-03-30 00:00:00')))
    GROUP BY et_date
)
SELECT
    bottom_session,
    round(argMin(close_usd, et_date), 2) AS bottom_close,
    round((argMinIf(close_usd, et_date, et_date >= toDate(bottom_session) + 91) / argMin(close_usd, et_date) - 1) * 100, 1) AS plus_3mo_pct,
    round((argMinIf(close_usd, et_date, et_date >= toDate(bottom_session) + 365) / argMin(close_usd, et_date) - 1) * 100, 1) AS plus_1yr_pct
FROM (
    SELECT
        multiIf(et_date >= toDate('2020-03-23'), '2020-03-23',
                et_date >= toDate('2018-12-24'), '2018-12-24',
                et_date >= toDate('2011-10-03'), '2011-10-03',
                '2009-03-09') AS bottom_session,
        et_date,
        close_usd
    FROM daily
)
GROUP BY bottom_session
ORDER BY bottom_session
Run this yourself

From the 2009 bottom, SPY gained 38.5% in three months and 68.1% in a year, the strongest twelve months most investors alive had ever seen, starting on the most ordinary-looking day of the crisis. Only the March 2020 COVID low is in the same class, at +75.1% in its first year, a turn whose 2020 stimulus rally anatomy has its own page. The 2011 and 2018 correction lows, genuine panics in the moment, returned 31.4% and 37.1% in their first years. The pattern across all four: the deeper the hole, the steeper the first leg out, and the first leg was always the steepest of the recovery.

Why bottoms are only visible backward

The honest mechanics: a bottom is defined by what doesn't happen afterward, no lower low, which is unknowable in real time by construction. Every quantitative "bottom signal" ever proposed fired repeatedly on the way down through late 2008; the March 9 session itself scored unremarkably on all of them, ordinary shape, below-average volume, a news catalyst that arrived only the next morning. Anyone claiming their indicator called this day is describing survivorship, and the many prior "bottoms" it also called are the receipt for that.

What the day does teach: position for ranges of outcomes rather than points. The investors who did well from March 2009 were, overwhelmingly, those who had been buying through the entire miserable winter on schedule, the approach return-measurement conventions quietly assume, not those who found the pixel-perfect low. The tape's role in that discipline is calibration, not prophecy: knowing what ordinary looks like is what keeps a quiet Monday from being mistaken for one more day of a fall that had, in fact, just ended.

March 2009 bottom FAQ

What was the exact bottom of the 2008-2009 crash?

The closing low printed Monday, March 9, 2009: SPY at $68.07, the S&P 500 index at its widely cited 676.53. The famous intraday "666" on the index had printed one session earlier, on the prior Friday, March 6.

How much did the stock market fall from 2007 to 2009?

SPY fell -56.5% on a closing basis, from $156.41 on 2007-10-09 to $68.07 on 2009-03-09, the deepest US equity drawdown since the 1930s.

What happened on March 10, 2009?

The first session after the bottom: SPY rose 6.1% following the overnight leak of a Citigroup internal memo stating the bank had been profitable in January and February. Citigroup itself closed at $1.44, up from $1.05 at the low.

How fast did the market recover from the 2009 bottom?

The first year was historic: SPY gained 68.1% from the bottom close. Recovering the entire crisis drawdown took much longer, the first close back above the October 2007 peak came on 2013-03-14.

Did anything signal the bottom in advance?

Nothing on the tape distinguished March 9 from the weeks around it, the session was quiet and volume ran below its own 20-day average. The bottom became a bottom retroactively, by never being undercut: the lowest trade of the following sixteen weeks stayed above even the March 9 close.


Every panel above is a stored, versioned query over the historical tape, expand the SQL to see each measurement. Want to feel this day instead of reading it? It is one of the playable scenarios in the Strasmore Labs trading simulator.

#market history#2009 bottom#financial crisis#bull markets#spy