Strasmore Research
เจาะลึกข้อมูล Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-07-24

วิกฤต COVID 2020 และการหยุดซื้อขาย

เจาะลึกวิกฤต COVID ในปี 2020 กับเหตุการณ์ระงับการซื้อขาย 4 ครั้งภายใน 8 วัน พร้อมวิเคราะห์การดิ่งลงของดัชนี SPY จากจุดสูงสุดถึงจุดต่ำสุด

วิกฤต COVID ในปี 2020 ส่งผลให้ S&P 500 ปรับตัวลดลงจากระดับปิดสูงสุดเป็นประวัติการณ์เมื่อวันที่ 19 กุมภาพันธ์ ไปสู่การขาดทุนจากจุดสูงสุดถึงจุดต่ำสุดที่ -34.2% ภายใน 23 วันทำการ โดยมีการระงับการซื้อขายชั่วคราว (circuit-breaker) ทั่วทั้งตลาดทั้งหมดสี่ครั้ง ซึ่งถือเป็นครั้งแรกนับตั้งแต่ปี 1997 หน้าเว็บนี้จะแสดงลำดับเหตุการณ์ทั้งหมดจากข้อมูลการซื้อขาย ได้แก่ แผนผังการดิ่งลงของตลาด, รายละเอียดการระงับการซื้อขายรายนาทีในวันที่ 9 มีนาคม (รวมถึงช่วงเวลาที่ข้อมูลขาดหายไปซึ่งเป็นหลักฐานที่ดีที่สุดในหน้านี้), รายชื่อหลักทรัพย์ที่ราคาลดลงรุนแรงที่สุด รวมถึงความเคลื่อนไหวของพันธบัตร Treasuries และตลาด options ในช่วงเวลาเดียวกัน ทุกตัวเลขมาจากการดึงข้อมูลโดยตรง คุณสามารถขยายส่วนต่างๆ เพื่อดูคำสั่ง SQL ได้

สรุปภาพรวมการดิ่งลงของตลาดในแถวเดียว

ก่อนจะเกิดเหตุการณ์ครั้งใหญ่ในวันเดียว นี่คือแผนผังแสดงเหตุการณ์ การใช้ข้อมูลราคาปิดช่วงการซื้อขายปกติรายวันของ SPY เพียงชุดเดียว สามารถระบุทั้งจุดสูงสุด จุดต่ำสุด ความเร็ว และการฟื้นตัว โดยมีการเปรียบเทียบกับข้อมูลชุดเดียวกันของตลาดหมีในปี 2008 เพื่อให้เห็นภาพขนาดของเหตุการณ์

คำสั่งดึงข้อมูลวิกฤต COVID จากจุดสูงสุดสู่จุดต่ำสุดและการฟื้นตัว — ราคาปิดรายวันของ SPY, แถวเดียว
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 dailies

ราคาปิดจุดสูงสุดของ SPY อยู่ที่ $338.31 เมื่อวันที่ 2020-02-19 ส่วนราคาปิดจุดต่ำสุดอยู่ที่ $222.51 เมื่อวันที่ 2020-03-23 ซึ่งต่ำกว่าจุดสูงสุดอยู่ -34.2% โดยสภาวะตลาดหมีนี้เกิดขึ้นภายในระยะเวลาเพียง 23 วันทำการ หรือคิดเป็น 33 วันตามปฏิทิน ข้อความที่มักถูกอ้างถึงว่า "เป็นการดิ่งลงรุนแรง (drawdown) ที่รวดเร็วที่สุดในประวัติศาสตร์ที่ระดับ 30%" นั้นมีหลักฐานยืนยันในแถวข้อมูลเดียวกัน คือราคาปิดของ SPY หลุดระดับ 30% จากจุดสูงสุดหลังจากผ่านไปเพียง 22 วันทำการ ในขณะที่ตลาดหมีปี 2008 ซึ่งวัดด้วยเกณฑ์เดียวกันจากราคาปิดจุดสูงสุดในเดือนตุลาคม 2007 ต้องใช้เวลาถึง 250 วันทำการเพื่อลดลงในระดับ 30% เท่ากัน สิ่งที่ต้องใช้เวลาประมาณหนึ่งปีในปี 2008 ใช้เวลาเพียงประมาณหนึ่งเดือนในปี 2020

ลำดับเหตุการณ์ของการดิ่งลงของตลาด โดยตัวเลขทั้งหมดอ้างอิงจากข้อมูลในหน้านี้:

  • 19 กุมภาพันธ์ 2020 — ราคาปิดสูงสุดเป็นประวัติการณ์ของ SPY อยู่ที่ $338.31
  • 9 มีนาคม — เกิดการหยุดซื้อขายชั่วคราว (circuit breaker) ทั่วทั้งตลาดเป็นครั้งแรกนับตั้งแต่ปี 1997 โดย SPY ปิดลบ -7.7% รายละเอียดแสดงแบบนาทีต่อนาทีอยู่ด้านล่าง
  • 12, 16 และ 18 มีนาคม — เกิดการหยุดซื้อขายชั่วคราวระดับ Level-1 เพิ่มอีกสามครั้ง โดยวันที่ 16 มีนาคม ปิดลบ -11.6% ซึ่งเป็นวันที่แย่ที่สุดในเหตุการณ์นี้
  • 23 มีนาคม — จุดต่ำสุดของราคาปิด: $222.51 หรือต่ำกว่าจุดสูงสุด -34.2%
  • 24 มีนาคม — จุดเปลี่ยนของตลาด การฟื้นตัวจากการกระตุ้นเศรษฐกิจเมื่อวันที่ 24 มีนาคม เป็นจุดเริ่มต้นของการกลับตัว
  • 2020-08-18 — SPY ปิดเหนือระดับสูงสุดของเดือนกุมภาพันธ์อีกครั้ง หลังจากจุดต่ำสุดผ่านไป 103 วันทำการ

9 มีนาคม 2020: เซสชันที่ทำให้เกิดการหยุดซื้อขายชั่วคราว

กลไก Circuit Breaker ของตลาดโดยรวมอ้างอิงจาก S&P 500 ดังนั้นข้อมูลในส่วนนี้จึงแสดงการหยุดซื้อขายผ่าน SPY หรือ S&P 500 ETF แทนการใช้ดัชนีอื่น ในช่วงสุดสัปดาห์ก่อนหน้า การปรับราคาใหม่เนื่องจากสถานการณ์แพร่ระบาดได้เกิดขึ้นพร้อมกับภาวะอุปทานน้ำมันช็อก (รายละเอียดเพิ่มเติมอยู่ด้านล่าง) ส่งผลให้ตลาดไม่สามารถเปิดการซื้อขายได้อย่างเป็นระเบียบ

คำสั่งดึงข้อมูลSPY เมื่อวันที่ 9 มีนาคม 2020 — วันที่มีการใช้ circuit-breaker, ข้อมูลธุรกรรม
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')

มีตัวเลขสำคัญสองประการ ประการแรกคือช่องว่างราคา (gap): SPY เปิดที่ $275.3 ซึ่งต่ำกว่าราคาปิดของวันศุกร์ที่ $297.42 อยู่ถึง -7.4% และภายในไม่กี่นาทีแรก ดัชนี S&P 500 ได้ลดลงจนแตะระดับเกณฑ์ Level-1 ที่ 7% ประการที่สองซึ่งเป็นข้อมูลที่สำคัญกว่าคือ มี 376 แท่งกราฟรายนาทีในเซสชันปกติ แทนที่จะเป็น 390 แท่งตามปกติ การบันทึกข้อมูลหยุดลงหลังเวลา 9:34 am: โดยเริ่มตั้งแต่เวลา 09:35 ET ไม่มีการบันทึกแท่งกราฟเลยต่อเนื่องกัน 14 นาที ไม่มีการซื้อขายเกิดขึ้นในทุกแห่ง ช่องว่างของข้อมูลนี้คือสิ่งที่บ่งบอกถึงการเกิด Circuit Breaker เซสชันนี้ปิดที่ $274.4 ลดลง -7.7% ด้วยปริมาณการซื้อขาย 304.6 ล้านหุ้น

ลักษณะของเซสชันที่ถูกระงับการซื้อขาย

คำสั่งดึงข้อมูลSPY ทุกๆ ครึ่งชั่วโมง — ช่วงเวลาซื้อขายปกติของวันที่ 9 มีนาคม 2020
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 ET เป็นเพียงการทดสอบระดับราคาเดิมของช่วงเช้าเท่านั้น หลังจากเปิดการซื้อขายใหม่ ราคาแทบไม่มีการเคลื่อนไหว: ราคาปิดในทุกๆ ครึ่งชั่วโมงเคลื่อนที่อยู่ภายในกรอบไม่กี่ดอลลาร์จากราคาเปิดใหม่ และความเสียหายของวันเกิดขึ้นในช่วงนาทีแรกๆ ของเวลาซื้อขาย ปริมาณการซื้อขายบ่งชี้ในทิศทางตรงกันข้าม — ช่วงครึ่งชั่วโมงสุดท้ายที่มีปริมาณ 46.7 ล้านหุ้น เป็นช่วงที่มีปริมาณการซื้อขายหนาแน่นที่สุดของวันเนื่องจากมีกระแสคำสั่งซื้อขายช่วงปิดตลาดเข้ามามาก กลไก Circuit breakers ถูกออกแบบมาเพื่อให้เกิดลักษณะเช่นนี้โดยเฉพาะ: เพื่อหยุดการดิ่งลงของราคา บังคับให้เกิดการประมูลเพื่อเปิดการซื้อขายใหม่ และปล่อยให้การซื้อขายแบบต่อเนื่องดำเนินต่อไปที่ระดับราคาใหม่ นาฬิกาของตลาด ได้ติดตั้งกลไกนี้ไว้อย่างถาวรแล้วในปัจจุบัน

การหยุดซื้อขายสี่ครั้งภายในแปดเซสชัน

วันที่ 9 มีนาคม เป็นเพียงครั้งแรกเท่านั้น

คำสั่งดึงข้อมูลการใช้ circuit-breaker ทั้ง 4 ครั้งในเดือนมีนาคม 2020 — ราคาปิด, การเปลี่ยนแปลง, ปริมาณการซื้อขายของ SPY
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

Level-1 breakers เกิดขึ้นในวันที่ 12 มีนาคม (ปิดที่ -9.6%), วันที่ 16 มีนาคม (ปิดที่ -11.6% ที่ $239.41 ซึ่งเป็นการลดลงเป็นเปอร์เซ็นต์รายวันที่ใหญ่ที่สุดของ S&P นับตั้งแต่ปี 1987) และวันที่ 18 มีนาคม (หยุดการซื้อขายระหว่างวัน และปิดที่ -5.2%) เกิดการหยุดซื้อขายทั่วทั้งตลาดสี่ครั้งภายในแปดวันทำการ หลังจากที่ไม่มีการหยุดซื้อขายเลยตลอดยี่สิบสามปีที่ผ่านมา ข้อสังเกตคือสิ่งที่ไม่ได้เกิดขึ้น: การหยุดซื้อขายทุกครั้งเป็นแบบ Level 1 หรือระดับ 7% เท่านั้น ไม่มีการแตะระดับ 13% และ 20% แม้ในวันที่ 16 มีนาคม แรงเทขายที่ลดลงอย่างรวดเร็วก็ชะลอตัวลงหลังจากการหยุดซื้อขาย และจบเซสชันภายในเส้น Level-2

กลุ่มที่ปรับตัวลดลงรุนแรงที่สุด

ดัชนีเพียงตัวเลขเดียวไม่สามารถแสดงถึงความแตกต่างของหุ้นแต่ละตัวที่อยู่ภายในได้ การคำนวณค่าเฉลี่ยจากราคาปิดรายวันของหุ้นขนาดใหญ่ที่เป็นตัวแทนกลุ่ม จะช่วยให้เห็นภาพความเสียหายที่เกิดขึ้นจริง ทั้งในวันที่ 9 มีนาคม และตลอดช่วงที่ตลาดปรับตัวลดลงตั้งแต่วันที่ 19 กุมภาพันธ์ ถึง 23 มีนาคม

คำสั่งดึงข้อมูลความเคลื่อนไหวของกลุ่ม Cruise, Airline, Energy, Bank, Tech, Staples เทียบกับ SPY ในวันที่ 9 มีนาคม และช่วงวิกฤต
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 (Carnival ผู้ให้บริการเรือสำราญ) ซึ่งราคาลดลง -19.9% เฉพาะในวันที่ 9 มีนาคม และลดลงถึง -72.3% จากจุดสูงสุดถึงจุดต่ำสุด United Airlines ราคาลดลง -66.9% ในช่วงที่ตลาดดิ่งลง; ExxonMobil ลดลง -47.9%; JPMorgan ลดลง -42.6% ในขณะที่การลดลงของ SPY ที่ระดับ -34.2% ดูเบาบางมาก Apple ปรับตัวลดลงใกล้เคียงกับตลาดที่ระดับ -31% และ Walmart ซึ่งเป็นกลุ่มสินค้าอุปโภคบริโภคที่จำเป็นและยังคงเปิดดำเนินการในช่วงล็อกดาวน์ ปิดช่วงเวลาดังกล่าวด้วยการลดลงเพียง -2.9% เท่านั้น กลุ่มการท่องเที่ยวและพลังงานถูกปรับราคาใหม่ตามสภาวะโลกที่หยุดชะงัก ในขณะที่กลุ่มสินค้าอุปโภคบริโภคจำเป็นแทบไม่มีการเปลี่ยนแปลง

สรุปสถานการณ์สงครามราคาพ่นน้ำมัน

ความขัดแย้งด้านพลังงานข้างต้นจำเป็นต้องมีการอธิบายเพิ่มเติม เนื่องจากคำว่า "สงครามราคาพ่นน้ำมัน" คืออีกครึ่งหนึ่งของเรื่องราวเมื่อวันที่ 9 มีนาคม การเจรจาเรื่องกำลังการผลิตของ OPEC+ ระหว่างซาอุดีอาระเบียและรัสเซียสิ้นสุดลงโดยไม่มีข้อตกลงเมื่อวันศุกร์ที่ 6 มีนาคม 2020 ในช่วงสุดสัปดาห์ ซาอุดีอาระเบียได้ปรับลดราคาขายอย่างเป็นทางการ และประกาศแผนที่จะเพิ่มกำลังการผลิตในขณะที่ความต้องการเดินทางทั่วโลกกำลังลดลงอย่างรวดเร็ว ซึ่งถือเป็นการเพิ่มอุปทาน (supply shock) ซ้ำเติมภาวะความต้องการที่ลดลง (demand shock) ตลาดหุ้นที่เปิดทำการในวันจันทร์ได้รับผลกระทบจากทั้งสองปัจจัยพร้อมกัน ดังที่ปรากฏในตารางด้านบน: ExxonMobil ปรับตัวลดลง -12.2% ในวันจันทร์นั้น เมื่อเทียบกับ SPY ที่ลดลง -7.7%

การเคลื่อนย้ายเงินทุนเข้าสู่สินทรัพย์ปลอดภัย — และสัปดาห์ที่เกิดการเปลี่ยนแปลง

ตลาดหุ้นเป็นเพียงส่วนหนึ่งของสถานการณ์เท่านั้น อีกส่วนที่สำคัญคือตลาด Treasury ซึ่งมีการเคลื่อนย้ายเงินทุนเข้าสู่สินทรัพย์ปลอดภัยตามปกติจนทำสถิติสูงสุด — แต่แล้วในช่วงสัปดาห์ที่น่าจดจำสัปดาห์หนึ่ง ทิศทางกลับพลิกผัน

คำสั่งดึงข้อมูลอัตราผลตอบแทนพันธบัตร 10 ปี และ 3 เดือน ตลอดช่วงวิกฤต, ราคาปิดรายวัน
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 date

อัตราผลตอบแทนพันธบัตรอายุ 10 ปี อยู่ที่ 1.56% ณ จุดสูงสุดของตลาดหุ้นเมื่อวันที่ 19 กุมภาพันธ์ ต่อมาในวันที่ 9 มีนาคม ซึ่งเป็นช่วงที่ตลาดหยุดการซื้อขายชั่วคราว อัตราผลตอบแทนปิดที่ 0.54% ซึ่งเป็นระดับต่ำสุดเป็นประวัติการณ์ โดยผู้ซื้อยอมรับผลตอบแทนเพียงครึ่งเปอร์เซ็นต์ต่อปีเป็นเวลาหนึ่งทศวรรษเพื่อแลกกับความปลอดภัย หลังจากนั้นรูปแบบดังกล่าวได้พลิกกลับ: จนถึงวันที่ 18 มีนาคม อัตราผลตอบแทน 10 ปี ปรับตัวสูงขึ้น ไปอยู่ที่ 1.18% ในขณะที่ตลาดหุ้นยังคงดิ่งลงอย่างต่อเนื่อง ซึ่งเป็นปรากฏการณ์ "dash for cash" หรือสัปดาห์ที่กองทุน บริษัท และผู้ถือครองชาวต่างชาติ ต่างเทขายสินทรัพย์ที่มีสภาพคล่องสูงทุกประเภท รวมถึงพันธบัตร Treasury เพื่อระดมเงินดอลลาร์ ในขณะเดียวกัน ตั๋วเงินคลังอายุ 3 เดือนปิดที่ระดับ 0.02% ในวันนั้น ซึ่งเป็นระดับที่สินทรัพย์เทียบเท่าเงินสดถูกกดไว้ที่ศูนย์ เมื่อสินทรัพย์ที่ปลอดภัยที่สุดและสินทรัพย์ที่มีความเสี่ยงที่สุดปรับตัวลดลงพร้อมกัน สิ่งที่กำลังถูกซื้อก็คือสภาพคล่องนั่นเอง เส้นอัตราผลตอบแทน ได้บันทึกเหตุการณ์นี้ไว้ในประวัติศาสตร์อย่างถาวร

ข้อมูลจากตลาดออปชันบ่งชี้อะไร

ออปชันที่จดทะเบียนใน SPY ซึ่งเป็นช่องทางหลักในการทำ Hedging ของตลาด ได้แสดงสัญญาณความตื่นตระหนกออกมา โดยช่วงเวลาที่เกิดสัญญาณนั้นเป็นประเด็นที่น่าสนใจ

คำสั่งดึงข้อมูลSPY options: ปริมาณการซื้อขาย puts เทียบกับ calls, 2–13 มีนาคม 2020 (ล้านสัญญา)
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

อัตราส่วนปริมาณการซื้อขาย Put/Call พุ่งขึ้นไปแตะระดับ 1.95 หรือเกือบจะเป็นการซื้อ Put สองสัญญาต่อ Call หนึ่งสัญญา เมื่อวันศุกร์ที่ 6 มีนาคม ก่อน ช่วงที่มีการระงับการซื้อขายชั่วคราว ต่อมาในวันที่ 9 มีนาคม มีการซื้อขาย Put จำนวน 4.35 ล้านสัญญา เทียบกับ Call จำนวน 2.38 ล้านสัญญา คิดเป็นอัตราส่วนที่ 1.83 จนกระทั่งถึงวันที่ 12 มีนาคม ซึ่งเป็นช่วง -9.6% อัตราส่วนดังกล่าวลดลงมาอยู่ที่ 1.32 เนื่องจากปริมาณการซื้อขาย Call เพิ่มขึ้นพร้อมกับ Put สัญญาที่ซื้อขายกันอย่างหนักหน่วงที่สุดในช่วงเริ่มต้นของการเทขาย ไม่ใช่ช่วงท้ายของการเทขาย การซื้อประกันความเสี่ยงเกิดขึ้นตั้งแต่ช่วงแรก และในช่วงที่ตลาดปรับตัวลดลงอย่างรุนแรงในภายหลัง ปริมาณการซื้อขายออปชันมีลักษณะที่สมดุลทั้งสองด้านมากขึ้น

กลไกการหยุดซื้อขายทั่วทั้งตลาดทำงานอย่างไร

เนื่องจากกลไกนี้ไม่ได้เกิดขึ้นบ่อยนักจนอาจถูกลืมเลือน: ตัวตัดวงจร (breakers) ทั่วทั้งตลาดจะทำงานเมื่อดัชนี S&P 500 ปรับตัวลดลงจากราคาปิดก่อนหน้า โดยหากลดลงถึง 7% (Level 1) และ 13% (Level 2) จะส่งผลให้เกิดการหยุดซื้อขายเป็นเวลา 15 นาที หากเกิดขึ้นก่อนเวลา 15:25 น. ตามเวลา ET ส่วนหากลดลงถึง 20% (Level 3) จะเป็นการปิดตลาดทันที ในระหว่างการหยุดซื้อขาย จะไม่มีการซื้อขายเกิดขึ้นในทุกตลาดหลักทรัพย์ คำสั่งซื้อขายจะถูกจัดลำดับเพื่อรอการประมูลเพื่อเปิดการซื้อขายใหม่ ซึ่งจะรวบรวมความต้องการซื้อขายที่สะสมไว้ให้กลายเป็นราคาเดียว เช่นเดียวกับที่ การประมูลเปิดตลาด ทำในทุกเช้า รูปแบบนี้ถูกออกแบบขึ้นภายหลังเหตุการณ์ flash crash ปี 2010 ซึ่งเผยให้เห็นว่าเกณฑ์เดิมนั้นหละหลวมเกินไป และไม่ทำงานแม้ในสภาวะตลาดดิ่งลงอย่างรุนแรง

เดือนมีนาคม 2020 คือการทดสอบระบบจริงครั้งแรกและครั้งเดียวจนถึงปัจจุบัน ซึ่งผลลัพธ์ปรากฏตามแผนภาพด้านบน: มีการหยุดซื้อขายระดับ Level 1 ทั้งหมดสี่ครั้ง โดยแต่ละครั้งตามด้วยการเปิดการซื้อขายใหม่อย่างเป็นระเบียบ ไม่มีการแตะระดับ Level 2 หรือ Level 3 และตลาดสามารถดำเนินต่อไปได้ในทุกๆ 23 เซสชัน ท่ามกลางการปรับตัวลดลงอย่างรุนแรงและรวดเร็วที่สุดในประวัติศาสตร์ของดัชนี หลังจากนั้นกฎเกณฑ์ดังกล่าวยังคงถูกใช้ต่อไป: เกณฑ์ 7/13/20 ที่อ้างอิงจาก S&P 500 ยังคงมีผลบังคับใช้จนถึงปัจจุบัน ระบบอาจมีการยืดหยุ่นบ้าง แต่โครงสร้างพื้นฐานยังคงทำงานได้ดี

คำถามที่พบบ่อยเกี่ยวกับวิกฤต COVID

อะไรเป็นสาเหตุที่ทำให้เกิด Circuit Breaker เมื่อวันที่ 9 มีนาคม 2020?

ดัชนี S&P 500 ปรับตัวลดลง 7% จากราคาปิดก่อนหน้า ซึ่งเป็นเกณฑ์ระดับ Level-1 สำหรับทั้งตลาด ภายในช่วงเวลาไม่กี่นาทีแรกของการเปิดตลาด การซื้อขายทั่วทั้งตลาดถูกระงับเป็นเวลา 15 นาที และกลับมาเปิดอีกครั้งผ่านกระบวนการประมูล การหยุดซื้อขายนี้ปรากฏให้เห็นในข้อมูลรายนาทีของหน้านี้ โดยมีแท่งกราฟที่ขาดหายไปต่อเนื่องกัน 14 แท่ง เริ่มต้นตั้งแต่เวลา 09:35 ET

ตลาดหุ้นปรับตัวลดลงเท่าใดในช่วงวิกฤต COVID?

วัดจากราคาปิดรายวันของ SPY พบว่าลดลง -34.2% — จากราคา $338.31 เมื่อวันที่ 19 กุมภาพันธ์ 2020 ไปยัง $222.51 เมื่อวันที่ 23 มีนาคม 2020 ตลอดช่วงการซื้อขาย 23 วัน

มีการใช้ Circuit Breaker ทั้งหมดกี่ครั้งในเดือนมีนาคม 2020?

มีการหยุดซื้อขายระดับ Level-1 ทั่วทั้งตลาดทั้งหมดสี่ครั้ง ได้แก่ วันที่ 9, 12, 16 และ 18 มีนาคม ซึ่งถือเป็นครั้งแรกนับตั้งแต่เดือนตุลาคม 1997

มีการใช้ Circuit Breaker ระดับ Level 2 หรือ Level 3 ในปี 2020 หรือไม่?

ไม่มี การหยุดซื้อขายทั้งสี่ครั้งในปี 2020 เป็นระดับ Level 1 (7%) ทั้งหมด ไม่เคยมีการหยุดซื้อขายทั่วทั้งตลาดในระดับ Level-2 (13%) หรือ Level-3 (20%) ภายใต้โครงสร้างปัจจุบัน แม้แต่ในวันที่ 16 มีนาคม ซึ่งเป็นวันที่ตลาดดิ่งลงรุนแรงที่สุดที่ระดับ -11.6% ก็ตาม

ตลาดฟื้นตัวจากวิกฤต COVID ได้อย่างเต็มรูปแบบหรือไม่?

ฟื้นตัวแล้ว SPY ปิดเหนือระดับสูงสุดเมื่อวันที่ 19 กุมภาพันธ์ 2020 ในวันที่ 2020-08-18 — หลังจากจุดต่ำสุดเมื่อวันที่ 23 มีนาคม ไปเพียง 103 วันทำการ ซึ่งถือเป็นการฟื้นตัวจากตลาดหมีที่มีความรุนแรงระดับนี้ที่รวดเร็วที่สุดครั้งหนึ่ง


ทุกแผงข้อมูลด้านบนคือผลลัพธ์จากการดึงข้อมูลย้อนหลังตามเวอร์ชันที่จัดเก็บไว้ คุณสามารถขยายคำสั่ง SQL เพื่อดูรายละเอียดการวัดผลแต่ละรายการ หากต้องการสัมผัสเหตุการณ์นี้ด้วยตนเองแทนการอ่านข้อมูล สามารถทดลองเล่นได้ใน เครื่องจำลองการซื้อขายของ Strasmore Labs

#market history#covid crash#circuit breakers#spy