2020年新冠崩盤:四次熔斷全記錄
逐筆成交重現標普500史上最快三成回檔:3月9日熔斷缺失分鐘記錄、八天內四次觸發,附SPY峰谷對照。
2020 年新冠疫情崩盤讓標普 500 指數從 2 月 19 日的歷史收盤高點,在 23 個交易日內創下 -34.2% 的高點至谷底跌幅——期間觸發四次全市場熔斷,為 1997 年以來首見。本頁從逐筆成交明細重現整段走勢:崩盤的分布圖、3 月 9 日熔斷時段的逐分鐘記錄(包括資料中缺失的那幾分鐘,正是本頁最有力的佐證)、跌幅最深的個股,以及同期美國公債與選擇權市場的動向。每一項數字皆來自預存查詢;展開任一區塊即可查看 SQL。
整場崩跌,濃縮在一行
在名留青史的那一天之前,先看這張圖。單一查詢,鎖定SPY每日正常交易時段收盤價,標出頂點、谷底、跌速與復甦——再加上同一套測量方法套用在2008年熊市上的數據,作為對照。
每個數據背後的精確 SQL 語法
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的收盤高點為$338.31,落在2020-02-19。收盤谷底$222.51,落在2020-03-23,較高點低-34.2%——一場熊市,壓縮在23個交易日、33個日曆日之內。那句常被引用的「有紀錄以來最快三成回檔」的說法,在同一行數據裡就能找到憑據:SPY收盤價首次跌破高點30%,僅僅發生在22個交易日之後。2008年熊市,從2007年10月的高點收盤價以相同方式測量,跌掉同樣的30%需要250個交易日。2008年耗時約一年,2020年只用了約一個月。
這場崩跌的逐日骨架,每個數字都源自本頁各區塊的數據:
- 2020年2月19日——SPY的歷史收盤高點,$338.31。
- 3月9日——1997年以來首次全市場熔斷;SPY收盤跌-7.7%。下方有逐分鐘的詳細記錄。
- 3月12日、16日與18日——又三次一級熔斷。3月16日收盤跌-11.6%,是這場崩跌中單日表現最差的一天。
- 3月23日——收盤低點:$222.51,自高點回落-34.2%。
- 3月24日——轉折點。3月24日的刺激方案反彈記錄了當日的走勢。
- 2020-08-18——SPY收盤再度突破2月高點,距谷底103個交易日。
2020年3月9日:觸發熔斷的那個交易時段
全市場熔斷機制以標普500指數為基準,因此這張圖表透過SPY——標普500 ETF——來解讀暫停交易,而非其他替代指標。在前一個週末,疫情引發的重新定價與石油供給衝擊(詳見下文)相互疊加,市場從未真正以有序的方式開盤。
每個數據背後的精確 SQL 語法
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')先看兩個數字。首先是跳空缺口:SPY開盤價為$275.3,較上週五收盤價$297.42低了-7.4%——且在最初幾分鐘內,標普500指數的跌幅即達到7%的第一級門檻。其次,也是較好的一面:376根正常交易時段分鐘K線,而非平常的390根。報價在上午9:34之後停止:自美東時間09:35起,連續14分鐘完全沒有任何K線產生。全市場無任何交易。數據中的這段空白就是熔斷機制。該交易時段收於$274.4,下跌-7.7%,成交量304.6百萬股。
暫停交易時段的樣貌
每個數據背後的精確 SQL 語法
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('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
ORDER BY et_time開盤集合競價同時包含了崩跌、暫停與恢復交易:其低點 $273.5 與全日低點 $273.45 僅差幾分錢——下午 14:44(美東時間)的成交價,僅僅是重新測試了上午的價位。恢復交易後,走勢幾乎原地踏步:每半小時的收盤價都落在恢復交易價格的幾塊錢之內,而全日的跌幅在時鐘上的頭幾分鐘就已造成。成交量則反向訴說著同一個故事——最後半小時成交量達 46.7 萬股,是當日成交最密集的時段,因收盤撮合流量在此交會。熔斷機制的設計目的,正是要塑造出這種樣貌:阻止瀑布式下跌、強制進行恢復交易競價,並讓連續交易在重新定價後的價位恢復進行。市場的時鐘如今已永久內建了這套機制。
八個交易日內四次熔斷
3月9日只是開端。
每個數據背後的精確 SQL 語法
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_date一級熔斷機制隨後在3月12日(收盤-9.6%)、3月16日(收盤-11.6%,報239.41美元——標普500指數自1987年以來最大單日百分比跌幅)以及3月18日(盤中觸發熔斷,收盤-5.2%)再度啟動。在長達二十三年未曾出現全市場熔斷之後,短短八個交易日內便發生了四次。請注意一個從未發生的情況:每一次熔斷都僅限於一級,即7%的門檻。13%和20%的門檻從未被觸及——即使在3月16日,跌勢在熔斷後也隨之放緩,該交易日最終收在二級熔斷線之內。
誰跌得最重
指數數字隱藏了底下的離散程度。將相同的每日收盤計算,套用在少數具代表性的大型股上,就能看出這波重挫實際落在何處——不論是3月9日當天,還是整個2月19日至3月23日的跌勢期間。
每個數據背後的精確 SQL 語法
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 ASC觀察名單中受創最深的個股,CCL(郵輪營運商嘉年華)光在3月9日就跌掉-19.9%,從高點到谷底更損失了-72.3%。聯合航空在這波重挫中跌掉-66.9%;埃克森美孚-47.9%;摩根大通-42.6%。相較之下,SPY的-34.2%看起來幾乎算溫和,蘋果大致隨大盤下跌,幅度為-31%,而沃爾瑪——販售雜貨、必需品,封城期間仍持續營業——在同一段期間僅收在-2.9%。旅遊與能源股為了一個停擺的世界重新定價;民生必需品幾乎紋風不動。
油價戰,簡述
上述的能源事件值得用一段話說明,因為「油價戰」承載了3月9日報導的另一半故事。2020年3月6日週五,沙烏地阿拉伯與俄羅斯之間的OPEC+產量會談無協議破局。週末期間,沙烏地阿拉伯調降官方售價,並宣布在旅行需求已然停滯的全球環境中提高產量——這是在需求衝擊之上,再疊加一個供給衝擊。週一開盤時,股市同時承受兩者,而結果就在上方圖表中:當日ExxonMobil下跌-12.2%,對比SPY的-7.7%。
資金湧向安全資產——以及這個模式瓦解的那一週
股市只說了一半的故事。另一半在美國公債市場,典型的避險買盤一度將價格推至歷史紀錄——然後,在令人矚目的一週裡,這個模式徹底逆轉。
每個數據背後的精確 SQL 語法
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 date2月19日股市觸頂時,10年期公債殖利率為 1.56%。到了3月9日——觸發熔斷的那個交易日——收盤跌至 0.54%,創下歷史新低,買方願意接受十年期每年僅半個百分點的利息,以換取安全。隨後模式反轉:進入3月18日,10年期公債殖利率上升至 1.18%,而股市持續下跌——這正是「美元搶奪潮」,在那一週,基金、企業及外國持有者為了籌集美元,拋售所有能變現的資產,包括美國公債。與此同時,3個月期國庫券當天收在 0.02%——現金等價物被牢牢壓在零附近。當最安全的資產與風險最高的資產同步下跌,市場真正追逐的標的就是流動性本身。殖利率曲線的歷史軌跡中,永久刻下了這段插曲。
選擇權報價透露的線索
SPY 的掛牌選擇權——市場公認的避險場域——留下了恐慌的痕跡,而時間點正是耐人尋味之處。
每個數據背後的精確 SQL 語法
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 session賣權/買權成交量比在 3 月 6 日週五——也就是暫停交易之前——達到 1.95 的峰值,幾乎是每成交一筆買權就對應兩筆賣權。3 月 9 日當天,4.35 百萬口賣權對上 2.38 百萬口買權,比率為 1.83。到了 3 月 12 日——一個 -9.6% 的交易日——比率已回落至 1.32,因為買權成交量與賣權同步增加。最極端的賣權偏斜出現在這波跌勢的前段,而非底部:避險買盤進場得早,後續跌幅更大的日子,選擇權報價反而更趨雙向。
全市場暫停交易的實際運作方式
由於這套機制極少啟動,以至於在兩次使用之間常被遺忘,其運作原理如下:全市場斷路器以標普500指數相對於前一日收盤價的跌幅為基準——7%(第1級)和13%(第2級)若在美東時間下午3:25前觸及,各自觸發15分鐘暫停;20%(第3級)則直接結束當日交易。暫停期間,任何交易所均無交易;訂單排隊等候重新開盤競價,這會將累積的買賣意願集中於單一價格,就像每個早晨的開盤競價一樣。這項設計源自2010年閃電崩盤之後的檢討,當時暴露出舊的觸發門檻過於寬鬆,以至於即使在真正的連鎖暴跌中也無法啟動。
2020年3月是這項設計的首次——也是迄今唯一一次——實戰考驗,而結論就呈現在上方圖表中:四次第1級暫停,每次之後都跟隨著有序的重新開盤,從未觸及第2級或第3級,並且在該指數史上最快的大型回檔期間,23個交易日中的每一個交易日,市場都保持運作。這些規則事後被保留下來:相同的7/13/20門檻,以標普500指數為基準,至今仍然有效。系統承受了壓力;市場基礎設施挺住了。
COVID 崩盤常見問答
2020年3月9日的熔斷機制是什麼觸發的?
標普500指數在開盤幾分鐘內,從前一交易日收盤價下跌7%——觸及全市場一級門檻。全市場交易暫停15分鐘,隨後以競價方式重新開盤。暫停在此頁面的分鐘K線圖上,表現為從美東時間 09:35 開始,連續 14 根缺失的K線。
COVID 崩盤期間股市下跌了多少?
以SPY的每日收盤價衡量,下跌了 -34.2%——從2020年2月19日的 $338.31 跌至2020年3月23日的 $222.51,歷經 23 個交易日。
2020年3月觸發了幾次熔斷?
四次全市場一級暫停:3月9日、12日、16日及18日。這是自1997年10月以來的首次。
2020年是否曾觸發二級或三級熔斷?
沒有。2020年四次暫停均為一級(7%)。在現行機制設計下,從未觸發過二級(13%)或三級(20%)的全市場暫停——即使在3月16日、該次崩盤中跌幅達 -11.6% 的最糟糕交易日也未觸發。
市場是否已從COVID崩盤中完全恢復?
是的。SPY在 2020-08-18 收復了2020年2月19日的高點——距離3月23日的低點僅 103 個交易日,是同等深度的熊市中,最快速的完全復甦之一。
上方每個面板都是對歷史逐筆數據的已儲存、帶版本號的查詢——展開SQL即可查看各項衡量指標。想親身感受這一天,而不只是閱讀?這是 Strasmore Labs 交易模擬器 中可遊玩的場景之一。