Krach COVID-19 2020: cztery wstrzymania handlu
Krach COVID-19 z 2020 roku: brakujące minuty sesji 9 marca, cztery wstrzymania handlu w osiem dni oraz mapa spadku SPY od szczytu do dołka.
Krach wywołany pandemią COVID-19 sprowadził indeks S&P 500 od rekordowego zamknięcia 19 lutego do -34.2% straty od szczytu do dołka w ciągu 23 sesji giełdowych. Po drodze doszło do czterech wstrzymań handlu na całym rynku, po raz pierwszy od 1997 roku. Na tej stronie odtworzono pełny przebieg wydarzeń na podstawie danych transakcyjnych: mapę krachu, sesję z 9 marca, podczas której wstrzymano handel, przedstawioną minuta po minucie — w tym minuty brakujące w danych, stanowiące najlepszy dowód na tej stronie — nazwy spółek, które najbardziej traciły, a także zachowanie obligacji skarbowych i rynku opcji. Każda liczba pochodzi z zapisanego zapytania. Aby wyświetlić kod SQL, należy rozwinąć dowolny panel.
Cały krach w jednym wierszu
Przed słynnym pojedynczym dniem warto spojrzeć na całą mapę. Jedno zapytanie dotyczące dziennych kursów zamknięcia SPY w regularnych godzinach sesji wskazuje szczyt, dołek, tempo spadku i odbudowę. Zawiera również identyczny pomiar dla bessy z 2008 roku, aby zapewnić punkt odniesienia.
| data szczytu | kurs zamknięcia na szczycie | data dołka | kurs zamknięcia w dołku | spadek (%) | sesje od szczytu do dołka | dni kalendarzowe | sesje do spadku o 30% | sesje do spadku o 30% podczas kryzysu finansowego 2008 r. | data odrobienia strat | sesje od dołka do odrobienia strat |
|---|---|---|---|---|---|---|---|---|---|---|
| 2020-02-19 | 338.31 | 2020-03-23 | 222.51 | -34.2 | 23 | 33 | 22 | 250 | 2020-08-18 | 103 |
Dokładny kod SQL dla każdej liczby
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 dailiesKurs zamknięcia SPY osiągnął szczyt na poziomie $338.31 w dniu 2020-02-19. Kurs zamknięcia w dołku, $222.51 w dniu 2020-03-23, znajdował się -34.2% poniżej tego poziomu. Była to bessa skompresowana do 23 sesji giełdowych i 33 dni kalendarzowych. Często przytaczane stwierdzenie o „najszybszym w historii spadku o trzydzieści procent” znajduje potwierdzenie w tym samym wierszu: kurs zamknięcia SPY po raz pierwszy spadł o ponad 30% poniżej szczytu już po 22 sesjach. Bessa z 2008 roku, mierzona w identyczny sposób od szczytu kursu zamknięcia z października 2007 roku, potrzebowała 250 sesji, aby odnotować taki sam spadek o 30%. To, co w 2008 roku zajęło około roku, w 2020 roku trwało około miesiąca.
Chronologia krachu, przy czym każda liczba pochodzi z paneli na tej stronie:
- 19 lutego 2020 roku — rekordowy kurs zamknięcia SPY: $338.31.
- 9 marca — pierwszy od 1997 roku ogólnorynkowy wyłącznik obwodu; SPY zamyka sesję na poziomie -7.7% niższym. Szczegółowe potwierdzenie minuta po minucie znajduje się poniżej.
- 12, 16 i 18 marca — trzy kolejne wstrzymania handlu poziomu 1. 16 marca kurs zamknięcia spadł o -11.6%, co oznaczało najgorszą pojedynczą sesję podczas krachu.
- 23 marca — minimum na zamknięciu: $222.51, czyli -34.2% poniżej szczytu.
- 24 marca — punkt zwrotny. Rajd stymulacyjny z 24 marca odzwierciedlał tę sesję.
- 2020-08-18 — SPY ponownie zamyka sesję powyżej lutowego szczytu, 103 sesji po ustanowieniu dołka.
9 marca 2020 r.: sesja, która uruchomiła ograniczenie obrotu
Giełdowe wyłączniki bezpieczeństwa są uruchamiane na podstawie indeksu S&P 500, dlatego w tej sekcji zatrzymanie obrotu analizowane jest przez pryzmat SPY, ETF-u na indeks S&P 500, a nie innego instrumentu referencyjnego. W poprzedni weekend doszło do zderzenia przeszacowania aktywów w związku z pandemią z szokiem podażowym na rynku ropy naftowej (więcej na ten temat poniżej), a otwarcie rynku od początku nie przebiegało w uporządkowany sposób.
| poprzednie zamknięcie | otwarcie RTH | luka (%) | początek braku danych ET | brak danych (min) | minimum RTH | minimum ET | zamknięcie RTH | zmiana dzienna (%) | dzienny wolumen (mln akcji) | minutowe słupki RTH |
|---|---|---|---|---|---|---|---|---|---|---|
| 297.42 | 275.3 | -7.4 | 09:35 | 14 | 273.45 | 14:44 | 274.4 | -7.7 | 304.6 | 376 |
Dokładny kod SQL dla każdej liczby
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')Na początek dwa fakty. Po pierwsze, luka: SPY otworzył się na poziomie 275.3 USD, czyli -7.4% poniżej piątkowego zamknięcia na poziomie 297.42 USD. W ciągu pierwszych minut spadek indeksu S&P 500 osiągnął próg 7% dla poziomu 1. Po drugie, korzystniejszy element: 376 jednominutowych świec z regularnej sesji, zamiast standardowych 390. Notowania kończą się po godzinie 9:34: od godziny 09:35 czasu ET przez 14 kolejnych minut nie odnotowano żadnych transakcji. Nigdzie nie zawarto transakcji. Luka w danych jest skutkiem wyłącznika bezpieczeństwa. Sesja zakończyła się na poziomie 274.4 USD, przy spadku o -7.7%, a wolumen wyniósł 304.6 mln akcji.
Kształt sesji przerwanej
| czas ET | zamknięcie przedziału | minimum przedziału | wolumen (mln akcji) |
|---|---|---|---|
| 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 | 46.7 |
Dokładny kod SQL dla każdej liczby
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_timePierwszy przedział czasowy obejmuje jednocześnie załamanie, wstrzymanie notowań i ich wznowienie. Jego minimum na poziomie 273.5 USD znajdowało się o kilka centów od dziennego minimum wynoszącego 273.45 USD. Transakcja zawarta po południu o 14:44 czasu ET jedynie ponownie przetestowała poranny poziom. Po wznowieniu notowań kurs niemal się nie zmieniał. Kurs zamknięcia każdego półgodzinnego przedziału mieścił się w odległości kilku USD od ceny z momentu wznowienia notowań. Cała dzienna strata powstała w pierwszych minutach sesji. Wolumen potwierdzał ten sam obraz, ale w odwrotnej kolejności. Ostatnie pół godziny, z wolumenem 46.7 mln akcji, było najbardziej aktywnym przedziałem dnia, ponieważ przepływy zleceń na zamknięcie sesji krzyżowały się. Mechanizmy ograniczników zmienności są zaprojektowane tak, aby dokładnie taki przebieg wywoływać: zatrzymać gwałtowną wyprzedaż, wymusić aukcję wznowieniową i umożliwić powrót do notowań ciągłych na przeszacowanym poziomie. Zegar rynku ma obecnie na stałe wbudowany ten mechanizm.
Cztery zawieszenia obrotu w ciągu ośmiu sesji
9 marca był dopiero początkiem.
| sesja | zamknięcie (USD) | zmiana (%) | wolumen (mln akcji) |
|---|---|---|---|
| 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 |
Dokładny kod SQL dla każdej liczby
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_dateWyłączniki pierwszego poziomu zadziałały również 12 marca (zamknięcie na poziomie -9.6%), 16 marca (zamknięcie na poziomie -11.6% przy 239.41 USD; był to największy jednodniowy procentowy spadek indeksu S&P od 1987 roku) oraz 18 marca (zawieszenie obrotu w trakcie sesji, zamknięcie na poziomie -5.2%). Oznacza to cztery zawieszenia obrotu na całym rynku w ciągu ośmiu dni sesyjnych, po dwudziestu trzech latach bez żadnego takiego zdarzenia. Warto zwrócić uwagę na to, co się nie wydarzyło: za każdym razem uruchomiony został wyłącznie pierwszy poziom, czyli próg 7%. Progi 13% i 20% nigdy nie zostały osiągnięte. Dotyczyło to również 16 marca. Po zawieszeniu obrotu spadkowa kaskada wyhamowała, a sesja zakończyła się poniżej progu drugiego poziomu.
Kto odnotował największe spadki
Liczba indeksowa ukrywa skalę rozbieżności. Te same obliczenia na podstawie cen zamknięcia, przeprowadzone dla kilku reprezentatywnych spółek o dużej kapitalizacji, pokazują, gdzie faktycznie skoncentrował się krach — zarówno 9 marca, jak i w całym okresie spadków od 19 lutego do 23 marca.
| ticker | 9 marca (%) | Spadek (%) |
|---|---|---|
| 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 |
Dokładny kod SQL dla każdej liczby
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 ASCNajwiększe straty w analizowanej grupie odnotowała spółka CCL (Carnival, operator rejsów wycieczkowych). Jej kurs spadł w samym dniu 9 marca o -19.9%, a od szczytu do dołka o -72.3%. United Airlines straciła -66.9% w trakcie krachu, ExxonMobil -47.9%, a JPMorgan -42.6%. Na ich tle spadek SPY o -34.2% wygląda niemal łagodnie. Apple zniżkowała podobnie jak cały rynek — o około -31%. Walmart, obejmujący artykuły spożywcze i podstawowe oraz działający w okresie lockdownów, zakończył ten sam okres spadkiem o zaledwie -2.9%. Sektor podróży i energetyka zostały przeszacowane z uwzględnieniem świata, w którym aktywność została wstrzymana, natomiast spółki z sektora dóbr podstawowych niemal się nie zmieniły.
Wojna cenowa na rynku ropy — w skrócie
Powyższy wątek dotyczący rynku energii zasługuje na krótkie wyjaśnienie w jednym akapicie, ponieważ określenie „wojna cenowa na rynku ropy” stanowi drugą część historii z 9 marca. W piątek, 6 marca 2020 roku, rozmowy OPEC+ między Arabią Saudyjską a Rosją w sprawie poziomu wydobycia zakończyły się bez porozumienia. W weekend Arabia Saudyjska obniżyła oficjalne ceny sprzedaży i ogłosiła plany zwiększenia wydobycia, mimo że popyt na podróże już się załamywał. Szok podażowy nałożył się na szok popytowy. Poniedziałkowe otwarcie rynku akcji uwzględniło oba te czynniki. Potwierdzają to dane w powyższym panelu: kurs ExxonMobil spadł w ten poniedziałek o -12.2%, podczas gdy SPY stracił -7.7%.
Ucieczka do bezpieczeństwa i tydzień, w którym się załamała
Akcje to tylko połowa obrazu. Drugą połowę stanowił rynek obligacji skarbowych, na którym klasyczna ucieczka do bezpieczeństwa osiągnęła rekordowy poziom, a następnie, w ciągu jednego niezwykłego tygodnia, odwróciła kierunek.
| Data | 10-letnie (%) | 3-miesięczne (%) |
|---|---|---|
| 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 |
Dokładny kod SQL dla każdej liczby
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 dateRentowność obligacji 10-letnich wynosiła 1.56% w dniu szczytu na rynku akcji, 19 lutego. Do 9 marca, w dniu sesji zakończonej zawieszeniem notowań, spadła do 0.54%, osiągając historyczne minimum. Inwestorzy akceptowali rentowność na poziomie pół procent rocznie przez dekadę w zamian za bezpieczeństwo. Następnie sytuacja się odwróciła: do 18 marca rentowność obligacji 10-letnich wzrosła do 1.18%, podczas gdy akcje nadal spadały. Była to „ucieczka do gotówki” — tydzień, w którym fundusze, przedsiębiorstwa i zagraniczni posiadacze sprzedawali wszystko, co było płynne, w tym obligacje skarbowe, aby pozyskać USD. Tymczasem rentowność bonów 3-miesięcznych wyniosła tego dnia 0.02%, a ekwiwalenty gotówki pozostawały zakotwiczone na poziomie zera. Gdy najbezpieczniejszy i najbardziej ryzykowny aktyw spadają jednocześnie, kupowana jest sama płynność. Krzywa rentowności zachowała ten epizod na stałe w swojej historii.
Co pokazuje taśma opcyjna
Notowane opcje na SPY, będące głównym miejscem zabezpieczania pozycji przez rynek, odzwierciedliły skalę paniki. Interesujący jest moment, w którym to nastąpiło.
| sesja | Kontrakty put (mln) | Kontrakty call (mln) | Wskaźnik put/call |
|---|---|---|---|
| 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 |
Dokładny kod SQL dla każdej liczby
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 sessionWskaźnik wolumenu put/call osiągnął szczyt na poziomie 1.95. W piątek 6 marca, przed sesją z zawieszeniem notowań, na każde call zawierane były niemal dwie transakcje put. 9 marca zawarto transakcje na 4.35 mln put wobec 2.38 mln call, a wskaźnik wyniósł 1.83. 12 marca, podczas sesji -9.6%, wskaźnik obniżył się do 1.32, ponieważ wolumen call wzrósł wraz z wolumenem put. Największa przewaga put wystąpiła na początku kaskady spadków, a nie w jej punkcie kulminacyjnym. Zabezpieczenia kupowano wcześnie, natomiast podczas późniejszych, większych sesji spadkowych transakcje na opcjach były bardziej dwustronne.
Jak faktycznie działa zatrzymanie całego rynku
Mechanizm jest uruchamiany na tyle rzadko, że między kolejnymi użyciami łatwo o nim zapomnieć: ograniczniki dla całego rynku odnoszą się do spadku S&P 500 względem poprzedniego zamknięcia. Spadek o 7% (Poziom 1) lub 13% (Poziom 2) uruchamia 15-minutowe zatrzymanie, jeśli nastąpi przed 15:25 ET. Spadek o 20% (Poziom 3) kończy sesję. W czasie zatrzymania na żadnej giełdzie nie są zawierane transakcje. Zlecenia trafiają do kolejki na aukcję ponownego otwarcia, która skupia skumulowany popyt i podaż w jednej cenie, podobnie jak aukcja otwarcia każdego ranka. Obecna konstrukcja systemu pochodzi z okresu po gwałtownym załamaniu rynku w 2010 roku, które wykazało, że wcześniejsze progi były zbyt wysokie, aby uruchomić mechanizm nawet podczas rzeczywistej kaskady wyprzedaży.
Marzec 2020 roku był pierwszym, a dotychczas jedynym, testem tego systemu w praktyce. Wnioski przedstawiono w powyższych panelach: cztery zatrzymania na Poziomie 1, po każdym z nich uporządkowane ponowne otwarcie, bez osiągnięcia Poziomu 2 ani Poziomu 3 oraz sprawnie działający rynek podczas każdej z 23 sesji najszybszego dużego spadku w historii indeksu. Po tym okresie zasady pozostały bez zmian: te same progi 7/13/20, odnoszące się do S&P 500, nadal obowiązują. System uległ napięciu, ale infrastruktura wytrzymała.
FAQ dotyczące załamania wywołanego pandemią COVID-19
Co uruchomiło bezpiecznik giełdowy 9 marca 2020 r.?
Spadek indeksu S&P 500 o 7% względem poprzedniego zamknięcia, czyli próg Level-1 dla całego rynku, nastąpił w pierwszych minutach sesji. Obrót na całym rynku wstrzymano na 15 minut, a następnie wznowiono go w drodze aukcji. Wstrzymanie jest widoczne na minutowym zapisie transakcji na tej stronie jako 14 kolejnych brakujących słupków, począwszy od 09:35 czasu ET.
Jak bardzo spadł rynek akcji podczas załamania wywołanego pandemią COVID-19?
W ujęciu dziennych kursów zamknięcia SPY spadek wyniósł -34.2% — z 338.31 USD 19 lutego 2020 r. do 222.51 USD 23 marca 2020 r. — w ciągu 23 sesji giełdowych.
Ile bezpieczników giełdowych uruchomiono w marcu 2020 r.?
Cztery wstrzymania obrotu na całym rynku na poziomie Level-1: 9, 12, 16 i 18 marca. Były to pierwsze takie przypadki od października 1997 r.
Czy w 2020 r. uruchomiono kiedykolwiek bezpieczniki giełdowe Level-2 lub Level-3?
Nie. Wszystkie cztery wstrzymania w 2020 r. miały poziom Level-1 (7%). Żadne wstrzymanie całego rynku na poziomie Level-2 (13%) ani Level-3 (20%) nie zostało dotąd uruchomione w ramach obecnego systemu. Nie stało się tak nawet 16 marca, podczas najgorszej sesji załamania, kiedy spadek wyniósł -11.6%.
Czy rynek w pełni odrobił straty po załamaniu wywołanym pandemią COVID-19?
Tak. Kurs zamknięcia SPY znalazł się powyżej szczytu z 19 lutego 2020 r. w dniu 2020-08-18, po 103 sesjach giełdowych od minimum z 23 marca. Było to jedno z najszybszych pełnych odrobień strat po bessie o tej skali.
Każdy przedstawiony powyżej panel jest zapisanym, wersjonowanym zapytaniem dotyczącym historycznego zapisu transakcji. Aby zobaczyć poszczególne pomiary, należy rozwinąć kod SQL. Zamiast o tym czytać, można odtworzyć przebieg tego dnia. Jest to jeden z dostępnych scenariuszy w symulatorze handlu Strasmore Labs.