COVID Crash 2020: Four Halts From Peak to Trough
COVID crash 2020 wey carry S&P 500 from peak reach trough: March 9 halt minutes missing, four circuit breakers for eight days, plus SPY map.
COVID crash wey happen for 2020 carry S&P 500 from record close on February 19 reach -34.2% peak-to-trough loss inside 23 trading days. Four market-wide circuit-breaker halts happen along the way. Na the first ones since 1997. This page replay the full movement from the tape: map of the crash, March 9 halt session minute by minute, including the minutes wey missing for the data and wey be the strongest evidence for this page, the names wey fall pass, plus wetin Treasuries and options tape do alongside. Every number come from stored query. Expand any panel to see the SQL.
Crash whole, for one row
Before that famous one-day move, make we first look the full map. One query on SPY daily regular-session closes show the peak, trough, speed and recovery. E use the same measurement for the 2008 bear market so we fit compare the scale.
| peak date | peak close | trough date | trough close | decline pct | sessions from peak reach trough | calendar days | sessions reach minus 30 | GFC 2008 sessions reach minus 30 | recovery date | sessions from trough reach recovery |
|---|---|---|---|---|---|---|---|---|---|---|
| 2020-02-19 | 338.31 | 2020-03-23 | 222.51 | -34.2 | 23 | 33 | 22 | 250 | 2020-08-18 | 103 |
The exact SQL behind every number
WITH dailies AS (
SELECT
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
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 c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= toDateTime('2020-02-01 00:00:00') AND window_start < toDateTime('2020-09-01 00:00:00')
GROUP BY d
),
peak AS (SELECT argMax(d, (c, -toInt32(d))) AS pd, max(c) AS pc FROM dailies WHERE d < toDate('2020-03-01')),
trough AS (SELECT argMin(d, (c, toInt32(d))) AS td, min(c) AS tc FROM dailies WHERE d < toDate('2020-04-01')),
gfc AS (
SELECT
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
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 c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= toDateTime('2007-06-01 00:00:00') AND window_start < toDateTime('2009-01-01 00:00:00')
GROUP BY d
),
gpeak AS (SELECT argMax(d, (c, -toInt32(d))) AS pd, max(c) AS pc FROM gfc WHERE d < toDate('2008-01-01'))
SELECT
toString((SELECT pd FROM peak)) AS peak_date,
round((SELECT pc FROM peak), 2) AS peak_close,
toString((SELECT td FROM trough)) AS trough_date,
round((SELECT tc FROM trough), 2) AS trough_close,
round(((SELECT tc FROM trough) / (SELECT pc FROM peak) - 1) * 100, 1) AS decline_pct,
countIf(d > (SELECT pd FROM peak) AND d <= (SELECT td FROM trough)) AS sessions_peak_to_trough,
dateDiff('day', (SELECT pd FROM peak), (SELECT td FROM trough)) AS calendar_days,
countIf(d > (SELECT pd FROM peak) AND d <= (SELECT min(d) FROM dailies WHERE c <= 0.7 * (SELECT pc FROM peak))) AS sessions_to_minus_30,
(SELECT countIf(d > (SELECT pd FROM gpeak) AND d <= (SELECT min(d) FROM gfc WHERE c <= 0.7 * (SELECT pc FROM gpeak))) FROM gfc) AS gfc_2008_sessions_to_minus_30,
toString((SELECT min(d) FROM dailies WHERE d > (SELECT td FROM trough) AND c >= (SELECT pc FROM peak))) AS recovery_date,
countIf(d > (SELECT td FROM trough) AND d <= (SELECT min(d) FROM dailies WHERE d > (SELECT td FROM trough) AND c >= (SELECT pc FROM peak))) AS sessions_trough_to_recovery
FROM dailiesSPY peak close na $338.31 on 2020-02-19. Trough close, $222.51 on 2020-03-23, dey -34.2% below am. Na bear market wey compress into 23 trading sessions and 33 calendar days. People often call am the “fastest thirty-percent drawdown on record.” The same row confirm am: SPY close first break 30% below the peak just 22 sessions after. The 2008 bear market, measured the same way from the October 2007 peak close, need 250 sessions to lose that same 30%. Wetin take roughly one year in 2008 happen in about one month for 2020.
The crash timeline, with every number sourced from the panels for this page:
- February 19, 2020, SPY record close, $338.31.
- March 9, the first market-wide circuit breaker since 1997; SPY close -7.7% down. The minute-by-minute evidence dey below.
- March 12, 16, and 18, three more Level-1 halts. March 16 close -11.6%, the worst single session of the crash.
- March 23, the closing low: $222.51, -34.2% from the peak.
- March 24, the turn. The stimulus rally of March 24 carry that tape.
- 2020-08-18, SPY close above the February peak again, 103 sessions after the low.
March 9, 2020: session wey trip breaker
Market-wide circuit breakers dey use S&P 500 as reference, so this panel dey read the halt through SPY, the S&P 500 ETF, instead of any other proxy. Over the weekend before am, pandemic repricing collide with oil-supply shock (we go talk more about that below), and market no really open in orderly way.
| previous close | RTH open | gap pct | first missing ET for halt | halt missing minutes | RTH low | low ET | RTH close | day change pct | day shares m | RTH minute bars |
|---|---|---|---|---|---|---|---|---|---|---|
| 297.42 | 275.3 | -7.4 | 09:35 | 14 | 273.45 | 14:44 | 274.4 | -7.7 | 304.6 | 376 |
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('2020-03-06 00:00:00') AND window_start < toDateTime('2020-03-09 04:00:00')
) AS prior_rth_close,
(
SELECT (formatDateTime(toTimeZone(addMinutes(prev_bar, 1), 'America/New_York'), '%H:%i'), gap_minutes - 1)
FROM (
SELECT
lagInFrame(window_start) OVER (ORDER BY window_start ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_bar,
dateDiff('minute', prev_bar, window_start) AS gap_minutes
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= toDateTime('2020-03-09 04:00:00') AND window_start < toDateTime('2020-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
)
WHERE prev_bar > toDateTime('2020-03-09 00:00:00')
ORDER BY gap_minutes DESC
LIMIT 1
) AS halt_gap
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,
halt_gap.1 AS halt_first_missing_et,
halt_gap.2 AS halt_missing_minutes,
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,
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('2020-03-09 04:00:00') AND window_start < toDateTime('2020-03-09 23:59:00')Make we start with two numbers. First, the gap: SPY open at $275.3, -7.4% below Friday close of $297.42, and within the first minutes, S&P 500 decline reach the 7% Level-1 threshold. Second, and better: 376 regular-session minute bars instead of the usual 390. Tape stop after 9:34 am: starting from 09:35 ET, 14 consecutive minutes print no bars at all. Nothing trade anywhere. The gap for this data na the circuit breaker. Session close at $274.4, -7.7% down, on 304.6 million shares.
The shape of a halted session
| ET time | bucket close | bucket low | shares m |
|---|---|---|---|
| 09:30 | 279.93 | 273.5 | 17.4 |
| 10:00 | 280.72 | 275.6 | 23.4 |
| 10:30 | 278.61 | 275.5 | 19.1 |
| 11:00 | 281.03 | 275.5 | 17.2 |
| 11:30 | 282.69 | 280.06 | 19.1 |
| 12:00 | 281.01 | 280.95 | 17.2 |
| 12:30 | 279.71 | 275.95 | 13.4 |
| 13:00 | 278.59 | 278.24 | 11.5 |
| 13:30 | 275.84 | 275.34 | 19.4 |
| 14:00 | 274.95 | 274.06 | 21.2 |
| 14:30 | 276.59 | 273.45 | 25.9 |
| 15:00 | 277.9 | 275.55 | 24.5 |
| 15:30 | 274.4 | 274.37 | 50.2 |
The exact SQL behind every number
SELECT
b.et_time AS et_time,
b.bucket_close AS bucket_close,
b.bucket_low AS bucket_low,
round((b.bar_shares + if(b.et_time = '15:30', p.print_shares, 0)) / 1e6, 1) AS shares_m
FROM
(
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,
toFloat64(sum(volume)) AS bar_shares
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= toDateTime('2020-03-09 04:00:00') AND window_start < toDateTime('2020-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
) AS b
CROSS JOIN
(
SELECT toFloat64(maxIf(size, has(conditions, 8))) AS print_shares
FROM global_markets.stocks_trades
WHERE ticker = 'SPY'
AND sip_timestamp >= toDateTime('2020-03-09 20:00:00', 'UTC')
AND sip_timestamp < toDateTime('2020-03-09 20:15:00', 'UTC')
) AS p
ORDER BY et_timeThe opening bucket carry the crash, the halt and the resumption all together. Its low of $273.5 dey just a few cents near the full day low of $273.45. The afternoon print for 14:44 ET only retest the morning level. After the market reopen, the tape almost no move. Every half-hour close stay within a few dollars of the reopening price. The day’s damage happen within the first few minutes.
Volume tell the same story from the other side. The final half hour, at 50.2 million shares, na the heaviest bucket of the day as closing flows cross. Circuit breakers dey designed to create exactly this shape. Dem stop the waterfall, force a reopening auction, then allow continuous trading to resume at the repriced level. The market clock don get this machinery permanently built inside am now.
Four halts for eight sessions
March 9 na only the beginning.
| session | close USD | change pct | shares m |
|---|---|---|---|
| 2020-03-09 | 274.4 | -7.7 | 304.6 |
| 2020-03-12 | 248.1 | -9.6 | 389.3 |
| 2020-03-16 | 239.41 | -11.6 | 291.5 |
| 2020-03-18 | 241.01 | -5.2 | 324.7 |
The exact SQL behind every number
SELECT
toString(et_date) AS session,
close_usd,
change_pct,
shares_m
FROM (
SELECT et_date, close_usd, shares_m,
round((close_usd / lagInFrame(close_usd) OVER (ORDER BY et_date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1) * 100, 1) AS change_pct
FROM (
SELECT
toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
round(argMaxIf(toFloat64(close), window_start, (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959), 2) AS close_usd,
round(toFloat64(sum(volume)) / 1e6, 1) AS shares_m
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= toDateTime('2020-03-06 00:00:00') AND window_start < toDateTime('2020-03-19 00:00:00')
GROUP BY et_date
)
)
WHERE toString(et_date) IN ('2020-03-09', '2020-03-12', '2020-03-16', '2020-03-18')
ORDER BY et_dateLevel-1 breakers trip again on March 12 (market close -9.6%), March 16 (market close -11.6% at $239.41, the S&P biggest one-day percentage drop since 1987), and March 18 (halt during trading, market close -5.2%). Market-wide halt happen four times for eight trading days, after twenty-three years wey no get any. Make you note wetin no happen: every halt na Level 1, the 7% tier. Dem no ever reach the 13% and 20% tiers, even on March 16. After the halt, the selloff slow down and the session end inside the Level-2 line.
Wetin fall pass
One index number fit hide the different levels of movement wey dey underneath. If we use the same daily-close calculation for some representative large-cap stocks, e go show where the crash really hit, both on March 9 and across the full February 19 to March 23 slide.
| ticker | Mar 9 pct | crash pct |
|---|---|---|
| CCL | -19.9 | -72.3 |
| UAL | -10.4 | -66.9 |
| XOM | -12.2 | -47.9 |
| JPM | -13.7 | -42.6 |
| SPY | -7.7 | -34.2 |
| AAPL | -7.9 | -31 |
| WMT | -0.1 | -2.9 |
The exact SQL behind every number
WITH dailies AS (
SELECT
ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS d,
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 c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('UAL', 'CCL', 'XOM', 'JPM', 'AAPL', 'WMT', 'SPY')
AND window_start >= toDateTime('2020-02-18 00:00:00') AND window_start < toDateTime('2020-03-25 00:00:00')
GROUP BY ticker, d
)
SELECT
ticker,
round((anyIf(c, d = toDate('2020-03-09')) / anyIf(c, d = toDate('2020-03-06')) - 1) * 100, 1) AS mar9_pct,
round((anyIf(c, d = toDate('2020-03-23')) / anyIf(c, d = toDate('2020-02-19')) - 1) * 100, 1) AS crash_pct
FROM dailies
GROUP BY ticker
ORDER BY crash_pct ASCThe stock wey suffer pass for the group, CCL (Carnival, the cruise operator), lose -19.9% on March 9 alone and -72.3% from peak to trough. United Airlines give up -66.9% during the crash; ExxonMobil -47.9%; JPMorgan -42.6%. For comparison, SPY's -34.2% look almost mild, Apple fall roughly in line with the market at -31%, while Walmart, wey sell groceries and essential goods and remain open during lockdowns, finish the same period at only -2.9%. Travel and energy prices adjust for a world wey stop; staple stocks barely move.
Oil-price war, small explanation
The energy matter wey dey above need one short explanation, because “oil-price war” na the other half of the March 9 story. Production talks between Saudi Arabia and Russia under OPEC+ end without agreement on Friday, March 6, 2020. Over the weekend, Saudi Arabia cut its official selling prices and announce plan to increase output, even as travel demand for the world dey already shut down. So supply shock join demand shock. Monday equity market open carry both shocks at the same time. The result dey for the panel above: ExxonMobil fall -12.2% that Monday, compared with SPY wey fall -7.7%.
Safety go lead the market, then e break for one week
Equities na only half of the story. The other half na the Treasury market, where the usual flight to safety reach record level, then reverse direction for one remarkable week.
| date | 10-year pct | three-month pct |
|---|---|---|
| 2020-02-18 | 1.55 | 1.58 |
| 2020-02-19 | 1.56 | 1.58 |
| 2020-02-20 | 1.52 | 1.58 |
| 2020-02-21 | 1.46 | 1.56 |
| 2020-02-24 | 1.38 | 1.53 |
| 2020-02-25 | 1.33 | 1.53 |
| 2020-02-26 | 1.33 | 1.53 |
| 2020-02-27 | 1.3 | 1.45 |
| 2020-02-28 | 1.13 | 1.27 |
| 2020-03-02 | 1.1 | 1.13 |
| 2020-03-03 | 1.02 | 0.95 |
| 2020-03-04 | 1.02 | 0.72 |
| 2020-03-05 | 0.92 | 0.62 |
| 2020-03-06 | 0.74 | 0.45 |
| 2020-03-09 | 0.54 | 0.33 |
| 2020-03-10 | 0.76 | 0.44 |
| 2020-03-11 | 0.82 | 0.42 |
| 2020-03-12 | 0.88 | 0.33 |
| 2020-03-13 | 0.94 | 0.28 |
| 2020-03-16 | 0.73 | 0.24 |
The exact SQL behind every number
SELECT
toString(date) AS date,
round(yield_10_year, 2) AS ten_year_pct,
round(yield_3_month, 2) AS three_month_pct
FROM global_markets.treasury_yields
WHERE date >= '2020-02-18' AND date <= '2020-03-31'
AND isNotNull(yield_10_year)
ORDER BY dateThe 10-year yield stand at 1.56% on the February 19 equity peak. By March 9, the halt session, e close at 0.54%, the lowest level ever recorded. Buyers accept half a percent per year for 10 years in exchange for safety. Then the pattern turn upside down: by March 18, the 10-year yield rise to 1.18% while equities still dey fall. Na the "dash for cash" — one week when funds, companies, and foreign holders sell anything wey get liquidity, including Treasuries, to raise dollars. Meanwhile, the 3-month bill close that day at 0.02%, with cash equivalents pinned near zero. When the safest asset and the riskiest asset fall together, wetin investors dey buy na liquidity itself. The yield curve carry this episode permanently for its history.
Wetin the options tape dey show
SPY listed options, wey be the market’s main hedging venue, show say panic enter dem too. The timing na the interesting part.
| session | put contracts m | call contracts m | put-call ratio |
|---|---|---|---|
| 2020-03-02 | 3.74 | 2.54 | 1.47 |
| 2020-03-03 | 3.14 | 2.24 | 1.4 |
| 2020-03-04 | 3.06 | 2.27 | 1.35 |
| 2020-03-05 | 3.14 | 1.82 | 1.73 |
| 2020-03-06 | 4.64 | 2.38 | 1.95 |
| 2020-03-09 | 4.35 | 2.38 | 1.83 |
| 2020-03-10 | 3.61 | 2.4 | 1.5 |
| 2020-03-11 | 3.75 | 2.44 | 1.54 |
| 2020-03-12 | 4.53 | 3.43 | 1.32 |
| 2020-03-13 | 4.63 | 3.27 | 1.41 |
The exact SQL behind every number
SELECT
toString(toDate(toTimeZone(sip_timestamp, 'America/New_York'))) AS session,
round(sumIf(toFloat64(size), substring(ticker, 12, 1) = 'P') / 1e6, 2) AS put_contracts_m,
round(sumIf(toFloat64(size), substring(ticker, 12, 1) = 'C') / 1e6, 2) AS call_contracts_m,
round(sumIf(toFloat64(size), substring(ticker, 12, 1) = 'P') / sumIf(toFloat64(size), substring(ticker, 12, 1) = 'C'), 2) AS put_call_ratio
FROM global_markets.options_trades
WHERE ticker >= 'O:SPY2' AND ticker < 'O:SPY3'
AND sip_timestamp >= toDateTime('2020-03-02 00:00:00') AND sip_timestamp < toDateTime('2020-03-14 00:00:00')
GROUP BY session
ORDER BY sessionPut/call volume ratio reach peak of 1.95 on Friday, March 6. Almost two puts trade for every call, before the halt session. On March 9, 4.35 million puts trade against 2.38 million calls, giving ratio of 1.83. By March 12, a -9.6% session, ratio don ease to 1.32 as call volume rise together with puts. The strongest put skew happen at the beginning of the cascade, no be for the bottom: investors buy protection early, while the later and bigger down days trade on options tape wey get more balance between puts and calls.
How market-wide halt really dey work
The mechanics dey rare, so people fit forget how dem work between one use and another. Market-wide breakers dey use the S&P 500 decline from the previous close. If the fall reach 7% (Level 1) or 13% (Level 2), dem trigger 15-minute halt, as long as e happen before 3:25 pm ET. A 20% fall (Level 3) end the session completely. During the halt, nothing dey trade for any exchange. Orders dey queue for reopening auction. The auction gather all the accumulated buying and selling interest into one price, the same way opening auction dey do every morning. This design come after the 2010 flash crash, wey show say the older thresholds too loose to trigger even when genuine market cascade dey happen.
March 2020 na the first, and so far only, live test of this design. The verdict dey for the panels above: four Level-1 halts, and each one get orderly reopening. Level 2 and Level 3 never happen. The market still function for all the 23 sessions during the fastest large drawdown in the index history. Dem leave the rules unchanged afterward. The same 7/13/20 thresholds, based on the S&P 500, still dey apply today. The system bend, but the market plumbing hold.
COVID crash FAQ
March 9, 2020 trigger wey make circuit breaker activate na wetin?
S&P 500 fall 7% from the previous close within the opening minutes. This one reach Level-1 market-wide threshold. Trading stop for 15 minutes across the market, then e reopen through auction. You fit see the halt for this page minute tape as 14 consecutive missing bars wey start from 09:35 ET.
Stock market fall reach how much during COVID crash?
If we measure am with SPY daily closes, -34.2%. E move from $338.31 on February 19, 2020 go $222.51 on March 23, 2020, across 23 trading sessions.
How many circuit breakers activate for March 2020?
Four market-wide Level-1 halts: March 9, 12, 16, and 18. Na the first ones since October 1997.
Level 2 or Level 3 circuit breakers ever activate for 2020?
No. All four 2020 halts na Level 1 (7%). No Level-2 (13%) or Level-3 (20%) market-wide halt don ever activate under the current design, even on March 16, wey be the crash worst session at -11.6%.
Market fully recover from COVID crash?
Yes. SPY close above e February 19, 2020 peak on 2020-08-18, after 103 trading sessions from the March 23 low. Na one of the fastest full recoveries from bear market wey reach this depth.
Every panel above na stored, versioned query wey use historical tape. Expand the SQL to see how dem measure each one. You wan experience this day instead of just reading about am? E dey among the playable scenarios for the Strasmore Labs trading simulator.