The turn week: SPY, Citigroup, and the 10-year yield, March 9-13
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-07-26, from March 9, 2009: The Bottom, On the Tape.
| session | spy_close | spy_change_pct | spy_shares_m | citi_close | ten_year_pct |
|---|---|---|---|---|---|
| 2009-03-09 | 68.07 | -1.1 | 357.4 | 1.05 | 2.89 |
| 2009-03-10 | 72.21 | 6.1 | 401.3 | 1.44 | 2.99 |
| 2009-03-11 | 72.6 | 0.5 | 350.1 | 1.54 | 2.95 |
| 2009-03-12 | 75.51 | 4 | 407.4 | 1.66 | 2.89 |
| 2009-03-13 | 76.09 | 0.8 | 332.7 | 1.78 | 2.89 |
- Rows × columns
- 5 × 6
- Period covered
- to
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
session |
date | 2009-03-09 to 2009-03-13 | |
spy_close |
number | 68.07 to 76.09 | US dollars |
spy_change_pct |
number | -1.1 to 6.1 | percent |
spy_shares_m |
number | 332.7 to 407.4 | count |
citi_close |
number | 1.05 to 1.78 | US dollars |
ten_year_pct |
number | 2.89 to 2.99 | percent |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
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 your own version of this
The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.
More from this analysisMarch 9, 2009: The Bottom, On the Tape
SPY by half-hour: March 9, 2009 regular session
series 13×4
→
Four major lows: SPY forward returns at three and twelve months
series 4×4
→
Sixteen weeks after the low: weekly lows, closes, and the running minimum
ranking 16×4
→
One year off the low: the crisis epicenter vs the broad market
table 9×5
→
Peak to trough to round trip: the whole crisis in one row
scalar 1×6
→
SPY on March 9, 2009: the generational low, receipted
scalar 1×14
→
See all 2,170 queries →