← กลับไปยังบทความ
July 12, 2026
อ่าน 5 นาที

DCC-GARCH: สหสัมพันธ์แบบพลวัตสำหรับการเทรดคู่และความเสี่ยงพอร์ต

#volatility
#GARCH
#DCC
#correlation
#portfolio
#pairs-trading
#crypto

ลองถามเดสก์เทรดคริปโตส่วนใหญ่ว่าสหสัมพันธ์ระหว่าง BTC กับ ETH คือเท่าไร คุณจะได้ตัวเลขเดียว — 0.8 หรืออาจจะ 0.75 — ที่คำนวณจากช่วงเวลาที่ไม่มีใครจำได้ว่าทำไมถึงเลือก ตัวเลขนั้นคือคำโกหก หรืออย่างน้อยก็เป็นการทำให้เรื่องซับซ้อนดูง่ายเกินไปอย่างอันตราย สหสัมพันธ์แบบตัวอย่าง (sample correlation) เป็นค่าเฉลี่ยตลอดช่วงเวลาที่โครงสร้างความสัมพันธ์ที่แท้จริงเคลื่อนไหวอยู่ตลอด ในตลาดที่สงบ BTC กับ ETH จะแยกตัวออกจากกันมากพอที่จะทำให้คู่เทรดแบบ market-neutral ดูน่าสนใจ แต่ในเหตุการณ์ liquidation cascade มันจะล็อกเข้าหากันและเข้าหาทุกสิ่งทุกอย่าง และความหลากหลาย (diversification) ที่คุณจ่ายเงินไปเพื่อให้ได้มาก็จะระเหยหายไปในช่วงเวลาที่คุณต้องการมันที่สุดพอดี

นี่ไม่ใช่ผลกระทบที่ละเอียดอ่อนแต่อย่างใด ลองดูช่วงตลาดร่วงในปี 2022 ช่วงไหนก็ได้ — การล่มสลายของ LUNA ในเดือนพฤษภาคม การคลี่คลายสถานะของ 3AC ในเดือนมิถุนายน หรือการล่มสลายของ FTX ในเดือนพฤศจิกายน — คุณจะเห็นสหสัมพันธ์เฉลี่ยแบบคู่ (average pairwise correlation) ของ 20 โทเคนอันดับต้น ๆ เคลื่อนจากช่วง 0.4-0.6 ไปสู่ 0.9+ ภายในไม่กี่วัน สหสัมพันธ์ไม่ใช่ค่าคงที่ที่บางครั้งถูกประมาณผิดพลาด แต่มันคืออนุกรมเวลาที่มีพลวัตของตัวมันเอง มีการรวมกลุ่ม (clustering) ของตัวมันเอง และมีระบอบ (regime) ของตัวมันเอง การปฏิบัติต่อมันเป็นสเกลาร์คือความผิดพลาดแบบหลายตัวแปรที่เทียบเท่ากับการสมมติว่าความผันผวนคงที่ — ความผิดพลาดที่เราใช้เวลาไปแล้วใน ตอนที่ 1 ของซีรีส์นี้ เพื่อรื้อทำลายมันสำหรับสินทรัพย์เดี่ยว

บทความนี้เป็นตอนที่ 3 ของซีรีส์ความผันผวนสี่ตอน ตอนที่ 1 สร้างแบบจำลอง GARCH(1,1) แบบตัวแปรเดี่ยวด้วยไลบรารี arch และแสดงให้เห็นว่าความผันผวนรวมกลุ่มและกลับสู่ค่าเฉลี่ย (mean-revert) อย่างไร ตอนที่ 2 เพิ่มความไม่สมมาตร (GJR-GARCH, EGARCH) และ Student-t innovations เพื่อจับ leverage effect และหางอ้วน (fat tails) ในตอนนี้เราจะขยับไปสู่แบบหลายตัวแปร เราจะสร้างแบบจำลองของ เมทริกซ์ความแปรปรวนร่วมแบบมีเงื่อนไขทั้งหมด HtH_t ขณะที่มันวิวัฒนาการ โดยใช้แบบจำลอง Dynamic Conditional Correlation (DCC) ของ Engle สิ่งนี้ให้สองอย่างที่สหสัมพันธ์แบบสเกลาร์ไม่มีทางให้ได้ — อัตราส่วนป้องกันความเสี่ยงแบบพลวัตสำหรับการเทรดคู่ และความแปรปรวนของพอร์ตที่แปรผันตามเวลาอย่างตรงไปตรงมาสำหรับการจัดสรรตามความเสี่ยง ตอนที่ 4 จะปิดท้ายซีรีส์ด้วยการทดสอบย้อนหลัง (backtest) แบบ volatility-targeted ที่ผูกการพยากรณ์แบบตัวแปรเดี่ยวและหลายตัวแปรเข้ากับกฎการกำหนดขนาดสถานะ (position-sizing)

เราสมมติว่าคุณได้อ่านตอนที่ 1 และ 2 มาแล้ว ดังนั้นเราจะไม่อนุพันธ์ GARCH แบบตัวแปรเดี่ยวซ้ำอีก หากคุณต้องการพฤติกรรม หาง (tail) ร่วม — ความน่าจะเป็นที่สินทรัพย์สองตัวจะทะลุควอนไทล์ 1% ของมันพร้อมกัน — นั่นเป็นคำถามของ copula ซึ่งเราครอบคลุมไว้ใน แบบจำลอง Copula สำหรับความเสี่ยงร่วม DCC และ copula เสริมกันและกัน copula ให้โครงสร้างการพึ่งพากันของหาง (tail-dependence) แบบคงที่แต่ยืดหยุ่น ในขณะที่ DCC ให้ อนุกรมเวลาที่จัดการได้ ของเมทริกซ์สหสัมพันธ์ทั้งหมด บทความนี้ว่าด้วยอย่างหลัง

ทำไมสหสัมพันธ์แบบคงที่ถึงพังในคริปโต

ก่อนเข้าเรื่องกลไก มาระบุให้ชัดเจนว่าอะไรที่ล้มเหลว สหสัมพันธ์แบบตัวอย่างเดี่ยว ρ^\hat{\rho} ตลอดหน้าต่าง [tw,t][t-w, t] ประมาณค่า

ρ^ij=s(ri,srˉi)(rj,srˉj)s(ri,srˉi)2s(rj,srˉj)2\hat{\rho}_{ij} = \frac{\sum_{s} (r_{i,s} - \bar{r}_i)(r_{j,s} - \bar{r}_j)}{\sqrt{\sum_s (r_{i,s}-\bar{r}_i)^2}\sqrt{\sum_s (r_{j,s}-\bar{r}_j)^2}}

สิ่งนี้แฝงข้อสมมติสามข้อไว้ ซึ่งทั้งหมดผิดสำหรับคริปโต

  1. ความคงที่ของการพึ่งพากัน (stationarity) หน้าต่างมี ρ\rho ที่แท้จริงเพียงค่าเดียว ในความเป็นจริงการพึ่งพากันมีระบอบ (regimes) — ระบอบตลาดสงบใกล้ 0.5 และระบอบตึงเครียดใกล้ 0.95 — และ ρ^\hat{\rho} ผสมสิ่งเหล่านี้เข้าด้วยกันจนกลายเป็นค่ากลางที่ไม่มีความหมาย
  2. ความผันผวนของขอบเขต (marginal) คงที่ สหสัมพันธ์แบบ Pearson คือความแปรปรวนร่วมที่ถูกทำให้เป็นมาตรฐาน (normalized covariance) ถ้า σi,t\sigma_{i,t} และ σj,t\sigma_{j,t} เองก็เคลื่อนไหวอยู่ (ซึ่งมันเคลื่อนไหว — นี่คือสมมติฐานทั้งหมดของตอนที่ 1 และ 2) ดังนั้นแม้แต่ความแปรปรวนร่วม คงที่ ก็ยังผลิตสหสัมพันธ์ ที่แปรผันตามเวลา และในทางกลับกัน คุณไม่สามารถแยกทั้งสองออกจากกันได้โดยไม่มีแบบจำลองความผันผวนอยู่ข้างใต้
  3. ความสมมาตรข้ามทิศทางตลาด สหสัมพันธ์เพิ่มขึ้นในช่วงตลาดร่วงมากกว่าในช่วงตลาดขึ้น นี่คือญาติแบบหลายตัวแปรของ leverage effect หน้าต่างแบบ rolling ไม่สามารถแสดงสิ่งนี้ได้โดยไม่ต้องสั้นลงจนกลายเป็นสัญญาณรบกวนล้วน ๆ

การแก้ปัญหาแบบ rolling-window — คำนวณ ρ^\hat{\rho} ใหม่ตลอด 30 หรือ 60 วันที่ผ่านมา — เป็นการแลกปัญหาหนึ่งกับอีกปัญหาหนึ่ง หน้าต่างสั้นตอบสนองไว แต่มีสัญญาณรบกวนมากและตามหลังจุดเปลี่ยนที่แท้จริง หน้าต่างยาวมีเสถียรภาพแต่ล้าสมัย ที่แย่กว่านั้น เมทริกซ์สหสัมพันธ์แบบ rolling ตลอด dd สินทรัพย์ ไม่ได้รับประกันว่าจะยังคง positive semi-definite เมื่อคุณเริ่ม shrink หรือแก้ไขมัน ซึ่งทำให้ตัวจัดสรรที่ใช้งานต่อจากมันพังทั้งหมด เราต้องการแบบจำลองที่ (ก) ขับเคลื่อนด้วยกระบวนการความผันผวนที่เหมาะสมต่อสินทรัพย์แต่ละตัว (ข) ผลิตเมทริกซ์สหสัมพันธ์ที่ถูกต้องในทุกขั้นตอนโดยธรรมชาติของโครงสร้าง และ (ค) มีพารามิเตอร์ที่เราสามารถประมาณด้วย maximum likelihood แทนที่จะเลือกความยาวหน้าต่างแบบสุ่มเดา แบบจำลองนั้นคือ DCC-GARCH

ปัญหาแบบหลายตัวแปร: เมทริกซ์ความแปรปรวนร่วมแบบมีเงื่อนไข

ให้ rtRdr_t \in \mathbb{R}^d เป็นเวกเตอร์ของผลตอบแทนสำหรับ dd สินทรัพย์ ณ เวลา tt โดยมีค่าเฉลี่ยแบบมีเงื่อนไข μt\mu_t (มักเป็นเพียงค่าคงที่หรือเทอม AR เล็ก ๆ) และส่วนตกค้าง ϵt=rtμt\epsilon_t = r_t - \mu_t เราสมมติว่า

ϵtFt1D(0,Ht)\epsilon_t \mid \mathcal{F}_{t-1} \sim \mathcal{D}(0, H_t)

โดยที่ HtH_t คือ เมทริกซ์ความแปรปรวนร่วมแบบมีเงื่อนไข ขนาด d×dd \times d ที่กำหนดโดยชุดข้อมูล Ft1\mathcal{F}_{t-1} และ D\mathcal{D} คือการแจกแจงแบบมีเงื่อนไขบางแบบ (Gaussian หรือดีกว่าสำหรับคริปโตคือ multivariate Student-t) ทุกอย่างในการสร้างแบบจำลองความผันผวนแบบหลายตัวแปรคือคำตอบที่แตกต่างกันสำหรับคำถามเดียว: คุณจะกำหนดพารามิเตอร์พลวัตของ HtH_t อย่างไรให้มันยังคง symmetric positive definite ในทุกขั้นตอนโดยไม่มีการระเบิดของจำนวนพารามิเตอร์?

คำตอบแบบคลาสสิกสองแบบแสดงให้เห็นว่าทำไมปัญหานี้ถึงยาก

VECH

แบบจำลอง VECH (Bollerslev, Engle, Wooldridge 1988) เขียน half-vectorization ของ HtH_t เป็นฟังก์ชันเชิงเส้นของส่วนตกค้างยกกำลังสองในอดีตและความแปรปรวนร่วมในอดีต

vech(Ht)=c+Avech(ϵt1ϵt1)+Bvech(Ht1)\mathrm{vech}(H_t) = c + A\,\mathrm{vech}(\epsilon_{t-1}\epsilon_{t-1}') + B\,\mathrm{vech}(H_{t-1})

โดยที่ vech()\mathrm{vech}(\cdot) เรียงสามเหลี่ยมล่างของเมทริกซ์สมมาตรเข้าเป็นเวกเตอร์ที่มีความยาว d(d+1)/2d(d+1)/2 นี่เป็นแบบทั่วไปที่สุด — ทุกความแปรปรวนและความแปรปรวนร่วมขึ้นกับทุกความแปรปรวนและความแปรปรวนร่วมในอดีต — และไร้ประโยชน์ที่สุดเมื่อเกิน d=3d=3 สำหรับ dd สินทรัพย์ AA และ BB แต่ละตัวมีขนาด d(d+1)2×d(d+1)2\frac{d(d+1)}{2} \times \frac{d(d+1)}{2} ที่ d=5d=5 นั่นคือเมทริกซ์ 15×1515\times 15 สองตัว ประมาณ 450 พารามิเตอร์ บวกกับข้อจำกัด positive-definiteness ที่ลำบากแม้แต่จะเขียนออกมา พื้นผิว likelihood เป็นหนองน้ำเลยทีเดียว

BEKK

แบบจำลอง BEKK (Engle & Kroner 1995) รับประกัน positive definiteness โดยธรรมชาติของโครงสร้างด้วยรูปแบบกำลังสอง (quadratic form)

Ht=CC+Aϵt1ϵt1A+BHt1BH_t = C'C + A'\,\epsilon_{t-1}\epsilon_{t-1}'\,A + B'\,H_{t-1}\,B

โดยที่ CC เป็นสามเหลี่ยมบน เนื่องจากทุกเทอมเป็น quadratic form Ht0H_t \succ 0 โดยอัตโนมัติตราบใดที่ CC0C'C \succ 0 BEKK ประหยัดพารามิเตอร์มากกว่า VECH แต่ก็ยังขยายตามขนาดเป็น O(d2)O(d^2) พารามิเตอร์ — เมทริกซ์ AA และ BB แต่ละตัวมีขนาด d×dd \times d สำหรับ d=10d=10 คุณกำลังประมาณพารามิเตอร์ราว 200+ ตัวพร้อมกันด้วย MLE บนข้อมูลคริปโตรายวันที่มีสัญญาณรบกวนสูง โดยไม่มีการรับประกันว่าตัวหาค่าเหมาะสมที่สุดจะลู่เข้าสู่สิ่งที่มีความหมายใด ๆ ในทางปฏิบัติ BEKK แบบเต็มรูปแบบจำกัดอยู่ที่ d4d \le 4 และแม้กระทั่งตอนนั้นผู้คนก็ใช้ข้อจำกัดแบบ "diagonal" หรือ "scalar" ซึ่งทิ้งพลวัตข้ามสินทรัพย์ส่วนใหญ่ไป

นี่คือ คำสาปแห่งมิติ (curse of dimensionality) สำหรับ GARCH แบบหลายตัวแปร: จำนวนพารามิเตอร์เพิ่มขึ้นแบบกำลังสอง แต่ปริมาณข้อมูลในข้อมูลไม่ได้เพิ่มตาม คุณจะหมดองศาความอิสระ (degrees of freedom) นานก่อนที่จะหมดสินทรัพย์ที่คุณสนใจ พอร์ตคริปโตใด ๆ ที่มี 10-30 โทเคนอยู่นอกเหนือความสามารถของ VECH หรือ BEKK โดยสิ้นเชิง

ทางออก ซึ่งเป็นผลงานของ Engle คือการหยุดพยายามสร้างแบบจำลอง HtH_t โดยตรง และแทนที่ด้วยการ แยกตัวประกอบ (factor) มันออกเป็นส่วนที่เรารู้วิธีประมาณได้อย่างประหยัดอยู่แล้ว

DCC ของ Engle (2002): การแยกส่วนสองขั้นตอน

แบบจำลอง Constant Conditional Correlation (CCC) ของ Bollerslev (1990) เป็นการแยกตัวประกอบที่ประหยัดพารามิเตอร์ตัวแรก มันเขียนว่า

Ht=DtRDtH_t = D_t\, R\, D_t

โดยที่ Dt=diag(σ1,t,,σd,t)D_t = \mathrm{diag}(\sigma_{1,t}, \ldots, \sigma_{d,t}) คือเมทริกซ์แนวทแยงของส่วนเบี่ยงเบนมาตรฐานแบบมีเงื่อนไข — GARCH แบบตัวแปรเดี่ยวหนึ่งตัวต่อสินทรัพย์หนึ่งตัว — และ RR คือเมทริกซ์สหสัมพันธ์ที่ คงที่ นี่เป็นการทำให้ง่ายขึ้นอย่างมาก คุณปรับ (fit) แบบจำลอง GARCH แบบตัวแปรเดี่ยวอิสระ dd ตัว จากนั้นประมาณเมทริกซ์สหสัมพันธ์แบบตัวอย่างเดี่ยวของส่วนตกค้างที่ถูกทำให้เป็นมาตรฐานแล้ว positive definiteness เกิดขึ้นโดยอัตโนมัติตราบใดที่ RR เป็นเมทริกซ์สหสัมพันธ์ที่ถูกต้อง และ σi,t>0\sigma_{i,t} > 0 ทั้งหมด

ปัญหาของ CCC อยู่ตรงชื่อของมันเลย — สหสัมพันธ์นั้น คงที่ ซึ่งเป็นข้อสมมติที่เราปฏิเสธไปแล้วตั้งแต่ต้นบทความนี้ Dynamic Conditional Correlation ของ Engle (2002) เก็บการแยกตัวประกอบที่สวยงามของ CCC ไว้ แต่ปล่อยให้เมทริกซ์สหสัมพันธ์หายใจได้

Ht=DtRtDtH_t = D_t\, R_t\, D_t

ตอนนี้ RtR_t แปรผันตามเวลา ความเฉียบแหลมอยู่ที่การที่ความผันผวนและสหสัมพันธ์ถูกประมาณในสองขั้นตอนแยกกัน ดังนั้นเราจึงไม่ต้องเผชิญกับการหาค่าเหมาะสมที่สุดร่วม (joint optimization) แบบ O(d2)O(d^2) เต็มรูปแบบเลย

ขั้นตอนที่ 1: GARCH แบบตัวแปรเดี่ยวต่อสินทรัพย์

สำหรับสินทรัพย์แต่ละตัว ii ให้ปรับแบบจำลอง GARCH แบบตัวแปรเดี่ยวเหมือนในตอนที่ 1 และ 2 — GARCH(1,1), GJR-GARCH หรือ EGARCH ที่มี Student-t innovations แล้วแต่ว่าอะไรเหมาะกับอนุกรมนั้นที่สุด สิ่งนี้ให้ความแปรปรวนแบบมีเงื่อนไข σi,t2\sigma_{i,t}^2 และดังนั้น Dt=diag(σ1,t,,σd,t)D_t = \mathrm{diag}(\sigma_{1,t}, \ldots, \sigma_{d,t})

จากแบบจำลองที่ปรับแล้ว เราสกัด ส่วนตกค้างที่ถูกทำให้เป็นมาตรฐาน (standardized residuals)

zi,t=ϵi,tσi,tz_{i,t} = \frac{\epsilon_{i,t}}{\sigma_{i,t}}

โดยธรรมชาติของโครงสร้าง แต่ละ zi,tz_{i,t} มีความแปรปรวนแบบมีเงื่อนไขเป็นหน่วย (unit) โดยประมาณ นำมาเรียงเป็นเวกเตอร์ zt=(z1,t,,zd,t)z_t = (z_{1,t}, \ldots, z_{d,t})' ส่วนตกค้างที่ถูกทำให้เป็นมาตรฐานเหล่านี้คือวัตถุดิบสำหรับขั้นตอนสหสัมพันธ์ — พลวัตความผันผวนเฉพาะตัวของแต่ละตัวถูกดึงออกไปแล้ว ดังนั้นการเคลื่อนไหวร่วมที่เหลืออยู่คือการพึ่งพากันล้วน ๆ ไม่ใช่สิ่งประดิษฐ์จากความผันผวน (นี่เป็นตรรกะแบบ PIT เดียวกับที่บทความ copula ใช้ก่อนปรับขอบเขต (margins) เพียงแต่ที่นี่เราหยุดที่การทำให้เป็นมาตรฐานแทนที่จะไปไกลถึงการแปลงเป็น uniforms)

ขั้นตอนที่ 2: การวนซ้ำสหสัมพันธ์ของ DCC

เราสร้างแบบจำลองของกระบวนการเสริม QtQ_t ซึ่งเป็นเมทริกซ์สมมาตร positive-definite ขนาด d×dd \times d ด้วยการวนซ้ำแบบ GARCH ที่ขับเคลื่อนโดย outer products ของส่วนตกค้างที่ถูกทำให้เป็นมาตรฐาน

Qt=(1ab)Qˉ+azt1zt1+bQt1Q_t = (1 - a - b)\,\bar{Q} + a\, z_{t-1} z_{t-1}' + b\, Q_{t-1}

โดยที่

  • Qˉ=1Tt=1Tztzt\bar{Q} = \frac{1}{T}\sum_{t=1}^{T} z_t z_t' คือเมทริกซ์สหสัมพันธ์ไร้เงื่อนไข (unconditional) ของส่วนตกค้างที่ถูกทำให้เป็นมาตรฐาน (นี่คือ correlation targeting — รายละเอียดเพิ่มเติมด้านล่าง)
  • a0a \ge 0 ควบคุมว่าสัญญาณช็อกในวันนี้ zt1zt1z_{t-1}z_{t-1}' ดึงสหสัมพันธ์แรงแค่ไหน
  • b0b \ge 0 ควบคุมความคงอยู่ (persistence) — ว่า Qt1Q_{t-1} ของเมื่อวานพาต่อมาเท่าไร
  • และข้อจำกัดการกลับสู่ค่าเฉลี่ยคือ a+b<1a + b < 1 (โดยที่ a,b>0a, b > 0) ซึ่งคล้ายคลึงโดยตรงกับ α+β<1\alpha + \beta < 1 ใน GARCH แบบตัวแปรเดี่ยว

สังเกตว่าโครงสร้างนี้เหมือนกับการวนซ้ำ GARCH(1,1) แบบสเกลาร์ทุกประการ แต่บนเมทริกซ์: จุดยึดระยะยาว Qˉ\bar{Q} เทอมช็อก และเทอมความคงอยู่ เนื่องจากมันคือ convex combination ของเมทริกซ์ positive-semi-definite (Qˉ\bar{Q}, outer product แบบ rank-1, และ Qt1Q_{t-1} ก่อนหน้า) QtQ_t จึงคงความ positive definite ไว้ตราบใดที่ Qˉ0\bar{Q} \succ 0 และน้ำหนักทั้งหมดไม่เป็นลบ นี่คือสิ่งที่ทำให้เราได้เมทริกซ์ความแปรปรวนร่วมที่ถูกต้องโดยไม่มีค่าใช้จ่ายเพิ่ม

QtQ_t เกือบจะ เป็นเมทริกซ์สหสัมพันธ์แล้ว แต่ยังไม่เชิง — แนวทแยงของมันไม่เท่ากับ 1 พอดี ดังนั้นเราจึงทำให้เป็นมาตรฐาน (normalize)

Rt=(diag(Qt))1/2Qt(diag(Qt))1/2R_t = \left(\mathrm{diag}(Q_t)\right)^{-1/2}\, Q_t\, \left(\mathrm{diag}(Q_t)\right)^{-1/2}

ในระดับสมาชิก (elementwise) สหสัมพันธ์แบบมีเงื่อนไขระหว่างสินทรัพย์ ii และ jj คือ

ρij,t=qij,tqii,tqjj,t\rho_{ij,t} = \frac{q_{ij,t}}{\sqrt{q_{ii,t}\, q_{jj,t}}}

RtR_t นี้คือเมทริกซ์สหสัมพันธ์ที่ถูกต้อง — แนวทแยงเป็นหน่วย นอกแนวทแยงอยู่ใน [1,1][-1,1] positive definite — ในทุกช่วงเวลา โดยธรรมชาติของโครงสร้าง ประกอบกลับเป็นความแปรปรวนร่วมแบบมีเงื่อนไขเต็มรูปแบบ

Ht=DtRtDt,hij,t=ρij,tσi,tσj,tH_t = D_t\, R_t\, D_t, \qquad h_{ij,t} = \rho_{ij,t}\,\sigma_{i,t}\,\sigma_{j,t}

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

แบบจำลองทั้งหมดมีพารามิเตอร์สหสัมพันธ์เพียง สอง ตัว คือ aa และ bb ไม่ว่า d=2d = 2 หรือ d=50d = 50 ด้านความผันผวนขยายตามขนาดแบบเชิงเส้น (GARCH แบบตัวแปรเดี่ยวหนึ่งตัวต่อสินทรัพย์ แต่ละตัวมีพารามิเตอร์ประมาณ 4-5 ตัว ปรับแยกกันอิสระและขนานได้อย่างง่ายดาย) นี่คือเหตุผลที่ DCC ขยายตามขนาดได้ในที่ที่ BEKK และ VECH ทำไม่ได้ คำสาปแห่งมิติถูกจำกัดอยู่ที่ Qˉ\bar{Q} ซึ่งถูก กำหนดเป้าหมาย (targeted) (ใส่เข้าไปเป็นค่าประมาณแบบตัวอย่าง) แทนที่จะถูก หาค่าเหมาะสมที่สุด (optimized)

ข้อจำกัดแบบสเกลาร์และค่าใช้จ่ายของมัน

สเกลาร์ a,ba, b หมายความว่าคู่สินทรัพย์ ทุกคู่ มีพลวัตสหสัมพันธ์เดียวกัน — ความเร็วในการปรับตัวเดียวกันและความคงอยู่เดียวกัน สหสัมพันธ์ BTC-ETH และสหสัมพันธ์ DOGE-SHIB เคลื่อนไหวในจังหวะเดียวกันแม้ว่าเศรษฐศาสตร์ของมันจะแตกต่างกัน นี่คือราคาของความจัดการได้ (tractability) และโดยปกติเป็นราคาที่ยอมรับได้ การขยายผล (Generalized DCC ด้วยเมทริกซ์ A,BA, B; asymmetric DCC ของ Cappiello-Engle-Sheppard) ผ่อนคลายข้อจำกัดนี้โดยแลกกับพารามิเตอร์และเสถียรภาพในการประมาณ เราจะกล่าวถึง aDCC ด้านล่าง

Quasi-Log-Likelihood ของ DCC

การประมาณ aa และ bb ต้องการ likelihood ผลลัพธ์สำคัญของ Engle คือ log-likelihood แบบ Gaussian แยกส่วน ออกเป็นส่วนความผันผวนและส่วนสหสัมพันธ์ ซึ่งเป็นสิ่งที่ทำให้ตัวประมาณสองขั้นตอนนี้สมเหตุสมผล โดยสมมติ ϵtFt1N(0,Ht)\epsilon_t \mid \mathcal{F}_{t-1} \sim \mathcal{N}(0, H_t) ส่วนสนับสนุน log-likelihood ณ เวลา tt คือ

t=12(dlog(2π)+logHt+ϵtHt1ϵt)\ell_t = -\frac{1}{2}\left( d\log(2\pi) + \log|H_t| + \epsilon_t' H_t^{-1} \epsilon_t \right)

แทนที่ Ht=DtRtDtH_t = D_t R_t D_t แล้ว Ht=Dt2Rt|H_t| = |D_t|^2 |R_t| และ Ht1=Dt1Rt1Dt1H_t^{-1} = D_t^{-1} R_t^{-1} D_t^{-1} และใช้ zt=Dt1ϵtz_t = D_t^{-1}\epsilon_t

t=12(dlog(2π)+2logDt+logRt+ztRt1zt)\ell_t = -\frac{1}{2}\left( d\log(2\pi) + 2\log|D_t| + \log|R_t| + z_t' R_t^{-1} z_t \right)

ตอนนี้แยกมันโดยการบวกและลบ ztztz_t'z_t

t=12(dlog(2π)+2logDt+ϵtDt2ϵt)ส่วนความผันผวน   tV  12(logRt+ztRt1ztztzt)ส่วนสหสัมพันธ์   tC\ell_t = \underbrace{-\frac{1}{2}\left( d\log(2\pi) + 2\log|D_t| + \epsilon_t' D_t^{-2}\epsilon_t \right)}_{\text{ส่วนความผันผวน }\;\ell_t^{V}} \;\underbrace{-\frac{1}{2}\left( \log|R_t| + z_t' R_t^{-1} z_t - z_t' z_t \right)}_{\text{ส่วนสหสัมพันธ์ }\;\ell_t^{C}}

ส่วนความผันผวน tV\ell_t^V ขึ้นอยู่กับพารามิเตอร์ GARCH แบบตัวแปรเดี่ยวเท่านั้น (ผ่าน DtD_t) — การหาค่าสูงสุดของมันคือการปรับแบบจำลอง GARCH แบบตัวแปรเดี่ยวอิสระ dd ตัว ซึ่งเราทำในขั้นตอนที่ 1 ส่วนสหสัมพันธ์ tC\ell_t^C ขึ้นอยู่กับ aa และ bb (ผ่าน RtR_t) เมื่อกำหนด ส่วนตกค้างที่ถูกทำให้เป็นมาตรฐานจากขั้นตอนที่ 1 ดังนั้นในขั้นตอนที่ 2 เราหาค่าสูงสุดเพียง

LC(a,b)=12t=1T(logRt+ztRt1zt)\mathcal{L}^C(a, b) = -\frac{1}{2}\sum_{t=1}^{T}\left( \log|R_t| + z_t' R_t^{-1} z_t \right)

(เทอม ztztz_t'z_t ไม่ขึ้นกับ a,ba, b ดังนั้นเราจึงตัดมันทิ้ง) นี่คือการหาค่าเหมาะสมที่สุดแบบ สองพารามิเตอร์ ไม่ว่าจะมีสินทรัพย์กี่ตัว — นั่นคือประเด็นทั้งหมด มันถูกเรียกว่า quasi-likelihood เพราะตัวประมาณสองขั้นตอนมีความสม่ำเสมอ (consistent) แต่ไม่มีประสิทธิภาพเต็มที่ (fully efficient) ค่าความคลาดเคลื่อนมาตรฐาน (standard errors) ต้องการการปรับแก้ (Engle & Sheppard 2001) แต่สำหรับการสร้างสัญญาณเทรด ค่าประมาณจุด (point estimates) คือสิ่งที่สำคัญ

สำหรับคริปโต Gaussian innovations ประเมินความเสี่ยงหางต่ำเกินไป การเปลี่ยนไปใช้ multivariate Student-t likelihood เป็นการเปลี่ยนแปลงที่ทำได้ทันทีสำหรับ t\ell_t (แทนที่ Gaussian kernel ด้วย multivariate-tt density และเพิ่มพารามิเตอร์องศาความอิสระ ν\nu) เราคงใช้ Gaussian quasi-likelihood ในตัวประมาณด้านล่างเพื่อความชัดเจน และระบุจุดที่ ν\nu เข้ามา — การทำให้เป็นมาตรฐานจากตอนที่ 1-2 ใช้ t-innovations บนขอบเขต (margins) อยู่แล้ว ซึ่งจับประโยชน์ด้านหางไว้ส่วนใหญ่แล้ว

การทำใช้จริงด้วย Python

ข้อเท็จจริงที่ตรงไปตรงมาและสำคัญ ไลบรารี arch ไม่รองรับ GARCH หรือ DCC แบบหลายตัวแปร arch เป็นเอนจินแบบตัวแปรเดี่ยวที่ยอดเยี่ยม (เราพึ่งพามันสำหรับสิ่งนั้นโดยเฉพาะ) แต่ไม่มี dcc_model อยู่ในนั้น ทางเลือกที่ใช้งานได้จริงของคุณคือ

  1. สร้าง DCC เองบนพื้นฐานของ arch — ปรับแบบจำลองตัวแปรเดี่ยวด้วย arch สกัดส่วนตกค้างที่ถูกทำให้เป็นมาตรฐาน ทำการวนซ้ำ QQ และ quasi-likelihood ของสหสัมพันธ์ใน NumPy/SciPy แล้วหาค่าเหมาะสมที่สุดของสเกลาร์ทั้งสอง นี่คือสิ่งที่เราทำด้านล่าง มันมีประมาณ 60 บรรทัดและโปร่งใสอย่างสมบูรณ์
  2. แพ็กเกจ PyPI mgarch — การทำ DCC-GARCH แบบ pure-Python ที่เบา สะดวกสำหรับการปรับแบบเร็ว แต่ยืดหยุ่นน้อยกว่าถ้าคุณต้องการ GJR margins หรือ t-innovations ที่ต่อสายอย่างแม่นยำ
  3. rmgarch ของ R (Alexios Galanos) — การทำใช้จริงแบบอ้างอิง dccspec / dccfit รองรับ DCC, aDCC, GARCH-copula, Student-t และค่าความคลาดเคลื่อนมาตรฐานที่ถูกต้อง ถ้าคุณกำลังทำวิจัยความผันผวนแบบหลายตัวแปรอย่างจริงจัง rmgarch (เรียกจาก Python ผ่าน rpy2 หากจำเป็น) คือมาตรฐานทองคำ

เราจะสร้างทางเลือกที่ 1 เพราะมันทำให้ทุกส่วนที่เคลื่อนไหวชัดเจนและนำทักษะแบบตัวแปรเดี่ยวจากตอนที่ 1-2 กลับมาใช้ใหม่

ขั้นตอนที่ 1: ปรับขอบเขต (margins) GARCH แบบตัวแปรเดี่ยวด้วย arch

import numpy as np
import pandas as pd
from arch import arch_model
from scipy.optimize import minimize

def fetch_returns(symbols, start="2022-01-01", end="2025-12-31"):
    """
    Daily log returns for a list of crypto symbols.
    Replace with your data source (ccxt for 24/7 exchange data,
    yfinance for a quick sketch).
    """
    import yfinance as yf
    px = yf.download([f"{s}-USD" for s in symbols],
                     start=start, end=end)["Close"]
    px.columns = symbols
    rets = np.log(px / px.shift(1)).dropna()
    return rets

symbols = ["BTC", "ETH", "SOL", "BNB"]
returns = fetch_returns(symbols)

def fit_univariate(series, dist="t"):
    """
    Fit GJR-GARCH(1,1) with Student-t innovations (Part 2 model).
    Returns the fitted result and the *scaled* series it was fit on.
    We scale returns by 100 for the optimizer's numerical health,
    exactly as in Parts 1 and 2.
    """
    scaled = series * 100.0
    model = arch_model(scaled, mean="Constant",
                       vol="GARCH", p=1, o=1, q=1, dist=dist)
    res = model.fit(disp="off")
    return res

fits = {s: fit_univariate(returns[s]) for s in symbols}

Z = pd.DataFrame({s: fits[s].std_resid for s in symbols}).dropna()

Sigma = pd.DataFrame({s: fits[s].conditional_volatility
                      for s in symbols}).loc[Z.index]

print(Z.describe())

การตรวจสอบความสมเหตุสมผลอย่างรวดเร็วของส่วนตกค้างที่ถูกทำให้เป็นมาตรฐานนั้นสำคัญ ถ้าคอลัมน์ใดมีส่วนเบี่ยงเบนมาตรฐานห่างจาก 1 มาก หรือมี autocorrelation ที่เหลืออยู่มากในค่ากำลังสองของมัน (Ljung-Box บน zi,t2z_{i,t}^2) ขอบเขต (margin) แบบตัวแปรเดี่ยวนั้นถูกกำหนดสเปคผิด และขั้นตอน DCC จะสืบทอดความผิดพลาดนั้นไป แก้ไขขอบเขตก่อน — นั่นคือสิ่งที่ตอนที่ 2 มีไว้เพื่อจุดประสงค์นี้

ขั้นตอนที่ 2: การวนซ้ำ DCC และ quasi-log-likelihood

def dcc_negloglik(params, Z):
    """
    Negative DCC quasi-log-likelihood (Gaussian) in (a, b).
    Z : (T, d) array of standardized residuals from Step 1.

    Implements:
        Q_t = (1-a-b) Qbar + a z_{t-1} z_{t-1}' + b Q_{t-1}
        R_t = diag(Q_t)^{-1/2} Q_t diag(Q_t)^{-1/2}
        LL  = -1/2 sum_t ( log|R_t| + z_t' R_t^{-1} z_t )
    with correlation targeting: Qbar = sample corr of Z.
    """
    a, b = params
    if a <= 0 or b <= 0 or a + b >= 1.0:
        return 1e10

    Z = np.asarray(Z)
    T, d = Z.shape
    Qbar = np.cov(Z, rowvar=False, bias=True)   # unconditional (targeted)
    dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
    Qbar = dinv @ Qbar @ dinv

    Q = Qbar.copy()          # initialize Q_1 at the target
    ll = 0.0
    for t in range(T):
        q_diag = np.sqrt(np.diag(Q))
        R = Q / np.outer(q_diag, q_diag)
        sign, logdet = np.linalg.slogdet(R)
        if sign <= 0:
            return 1e10
        z = Z[t]
        Rinv_z = np.linalg.solve(R, z)
        ll += -0.5 * (logdet + z @ Rinv_z)
        Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
    return -ll

def fit_dcc(Z):
    """Estimate (a, b) by maximizing the DCC quasi-log-likelihood."""
    res = minimize(
        dcc_negloglik, x0=[0.03, 0.94], args=(np.asarray(Z),),
        method="L-BFGS-B",
        bounds=[(1e-6, 0.5), (1e-6, 0.999)],
    )
    a, b = res.x
    print(f"DCC estimates: a = {a:.4f}, b = {b:.4f}, a+b = {a+b:.4f}")
    print(f"log-likelihood: {-res.fun:.2f}")
    return a, b

a_hat, b_hat = fit_dcc(Z)

การรันสิ่งนี้บนพอร์ต BTC/ETH/SOL/BNB ตลอดข้อมูลรายวันหลายปีจะให้ผลลัพธ์ในรูปแบบดังต่อไปนี้ (ตัวเลขด้านล่างเป็น ตัวอย่างประกอบ ไม่ได้มาจากการทดลองที่มีวันที่เฉพาะเจาะจง — รันบนข้อมูลของคุณเอง)

DCC estimates: a = 0.0287, b = 0.9401, a+b = 0.9688
log-likelihood: -3812.44

วิธีอ่านผลลัพธ์

  • a=0.029a = 0.029 มีค่าน้อย — เมทริกซ์สหสัมพันธ์ไม่กระโดดตามช็อกของวันเดียว แต่ละวันดัน RtR_t เข้าหา outer product zt1zt1z_{t-1}z_{t-1}' เพียง ~3% เท่านั้น
  • b=0.940b = 0.940 มีค่าสูง — สหสัมพันธ์มีความคงอยู่สูง เมื่อพอร์ตเชื่อมโยงกันในเหตุการณ์ตึงเครียด มันจะคงเชื่อมโยงกันไปสักพัก แล้วจึงค่อย ๆ ลดกลับสู่ Qˉ\bar{Q} อย่างช้า ๆ สิ่งนี้ตรงกับประสบการณ์จริงของตลาดคริปโตร่วง สหสัมพันธ์ไม่ได้ดีดกลับทันทีที่ราคาเริ่มนิ่ง
  • a+b=0.969<1a + b = 0.969 < 1 ยืนยันการกลับสู่ค่าเฉลี่ย กระบวนการสหสัมพันธ์มีระดับระยะยาวที่คงที่ (Qˉ\bar{Q}) ที่มันกลับไปหา โดยมีครึ่งชีวิต (half-life) ประมาณ log(0.5)/log(a+b)22\log(0.5)/\log(a+b) \approx 22 วัน ถ้าคุณเคยประมาณค่า a+ba + b ที่เท่ากับ 1 พอดี กระบวนการสหสัมพันธ์นั้น integrated — ไม่มีจุดยึดระยะยาว มักเป็นอาการของความเปลี่ยนแปลงเชิงโครงสร้าง (structural break) ในตัวอย่างของคุณที่แบบจำลองกำลังดูดซับเป็นความคงอยู่แบบไม่มีที่สิ้นสุด

ความคงอยู่ใกล้หน่วยและการโหลดช็อกที่เล็กมากคือลายนิ้วมือ (fingerprint) มาตรฐานของ DCC ในทุกกลุ่มสินทรัพย์ และคริปโตก็ไม่ใช่ข้อยกเว้น นี่ยังเป็นเหตุผลที่สหสัมพันธ์แบบ rolling 30 วันเป็นตัวทดแทนที่ไม่ดี หน้าต่างแบบ rolling สมมติ aa และ bb โดยนัยที่ไม่ตรงกับโครงสร้างการสลายตัวนี้เลย

หมายเหตุการทำใช้จริงบางประการที่ช่วยประหยัดเวลาดีบักได้จริง

  • การกำหนดค่าเริ่มต้น (initialization) การเริ่มที่ [0.03, 0.94] สะท้อนค่าประมาณทั่วไปของคริปโต คือ aa เล็ก (สหสัมพันธ์ตอบสนองต่อช็อกแต่ไม่รุนแรง) bb ใหญ่ (สหสัมพันธ์มีความคงอยู่) ถ้าตัวหาค่าเหมาะสมที่สุดของคุณเลื่อนไปที่ a+b1a+b \to 1 กระบวนการสหสัมพันธ์นั้น integrated — มักเป็นสัญญาณของความเปลี่ยนแปลงเชิงโครงสร้างในตัวอย่าง (การเปลี่ยนระบอบที่แบบจำลองกำลังพยายามอย่างหนักที่จะปรับให้พอดีเป็นความคงอยู่)
  • หลักการเรื่องเวลา (timing convention) ภายในลูปเราให้คะแนน RtR_t เทียบกับ ztz_t แล้ว จากนั้น อัปเดต QQ ด้วย ztztz_t z_t' สำหรับขั้นตอนถัดไป สิ่งนี้ทำให้ RtR_t เป็นฟังก์ชันของข้อมูลผ่าน t1t-1 เท่านั้น — ไม่มีการมองล่วงหน้า (look-ahead) การทำผิดพลาดแบบ off-by-one นี้เป็นบั๊ก DCC ที่พบบ่อยที่สุดเพียงหนึ่งเดียว และมันจะพองค่า fit ใน-ตัวอย่าง (in-sample) อย่างเงียบ ๆ
  • Correlation targeting เราใส่ Qˉ\bar{Q} เข้าไปเป็นสหสัมพันธ์แบบตัวอย่างแทนที่จะประมาณมัน นี่คือสิ่งที่ทำให้การหาค่าเหมาะสมที่สุดเป็นแบบสองมิติ ค่าใช้จ่ายคือ Qˉ\bar{Q} ใช้ตัวอย่างทั้งหมด ดังนั้นใน walk-forward ที่เข้มงวด คุณต้องประมาณมันใหม่บนหน้าต่างการฝึกเท่านั้น (ดูด้านล่าง)

ขั้นตอนที่ 3: สร้างเส้นทางสหสัมพันธ์และความแปรปรวนร่วมขึ้นใหม่

เมื่อ a,ba, b ถูกกำหนดคงที่แล้ว ให้รันการวนซ้ำอีกครั้ง คราวนี้ เก็บ เส้นทาง RtR_t (และ HtH_t) เต็มรูปแบบ เพื่อให้กลยุทธ์ปลายทางใช้งานได้

def dcc_filter(Z, Sigma, a, b):
    """
    Run the DCC recursion with fixed (a,b) and return the full paths:
      R_path : (T, d, d) conditional correlation matrices
      H_path : (T, d, d) conditional covariance matrices (scaled units)
    Sigma : (T, d) conditional volatilities aligned with Z.
    """
    Z = np.asarray(Z); Sig = np.asarray(Sigma)
    T, d = Z.shape
    Qbar = np.cov(Z, rowvar=False, bias=True)
    dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
    Qbar = dinv @ Qbar @ dinv

    Q = Qbar.copy()
    R_path = np.empty((T, d, d))
    H_path = np.empty((T, d, d))
    for t in range(T):
        q_diag = np.sqrt(np.diag(Q))
        R = Q / np.outer(q_diag, q_diag)
        R_path[t] = R
        Dt = np.diag(Sig[t])          # D_t = diag(sigma_i,t)
        H_path[t] = Dt @ R @ Dt       # H_t = D_t R_t D_t
        z = Z[t]
        Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
    return R_path, H_path

R_path, H_path = dcc_filter(Z, Sigma, a_hat, b_hat)

i, j = symbols.index("BTC"), symbols.index("ETH")
rho_btc_eth = pd.Series(R_path[:, i, j], index=Z.index, name="rho_BTC_ETH")
print(rho_btc_eth.describe())
print("min/max correlation:", rho_btc_eth.min().round(3),
      rho_btc_eth.max().round(3))

อนุกรม rho_btc_eth คือผลตอบแทนของแบบฝึกหัดทั้งหมด แทนที่จะเป็นตัวเลขเดียว ตอนนี้คุณมีสหสัมพันธ์รายวันที่คุณสามารถพล็อต ตั้งเกณฑ์ หรือป้อนเข้ากลยุทธ์ได้ ในข้อมูลคริปโตจริงคุณมักจะเห็นมันแปรผันจากประมาณ 0.5 ในช่วงเงียบสงบไปจนถึงเหนือ 0.9 ในช่วงตึงเครียด — ช่วงที่แม่นยำที่สหสัมพันธ์แบบตัวอย่างเดี่ยวเฉลี่ยเอาไป

การพยากรณ์แบบหนึ่งขั้นล่วงหน้า

สำหรับการเทรดสด คุณต้องการ Ht+1H_{t+1} หนึ่งขั้นล่วงหน้าจากข้อมูลที่มีอยู่ตอนนี้ ด้านความผันผวนมาจากการพยากรณ์หนึ่งขั้นของแบบจำลอง arch แต่ละตัว ด้านสหสัมพันธ์คือการวนซ้ำอีกหนึ่งรอบ

def dcc_forecast_next(Z, a, b, fits, symbols):
    """One-step-ahead H_{t+1} using info through the last observation."""
    Z = np.asarray(Z); T, d = Z.shape
    Qbar = np.cov(Z, rowvar=False, bias=True)
    dinv = np.diag(1.0 / np.sqrt(np.diag(Qbar)))
    Qbar = dinv @ Qbar @ dinv

    Q = Qbar.copy()
    for t in range(T):
        z = Z[t]
        Q = (1 - a - b) * Qbar + a * np.outer(z, z) + b * Q
    q_diag = np.sqrt(np.diag(Q))
    R_next = Q / np.outer(q_diag, q_diag)

    sig_next = np.array([
        np.sqrt(fits[s].forecast(horizon=1, reindex=False)
                .variance.iloc[-1, 0])
        for s in symbols
    ])
    Dt = np.diag(sig_next)
    H_next = Dt @ R_next @ Dt
    return R_next, H_next, sig_next

R_next, H_next, sig_next = dcc_forecast_next(Z, a_hat, b_hat, fits, symbols)

จำไว้ว่าทุกอย่างอยู่ในหน่วยที่ถูกสเกล (×100) เพราะเราปรับ arch บน series * 100 หารความผันผวนด้วย 100 (และความแปรปรวนร่วมด้วย 1002=10,000100^2 = 10{,}000) เพื่อกลับไปสู่หน่วยผลตอบแทนดิบก่อนที่จะป้อนเข้ากลยุทธ์ การรักษาการสเกลให้ถูกต้องนั้นน่าเบื่อแต่เป็นแหล่งบั๊กเงียบที่พบบ่อย

การประยุกต์ที่ 1: อัตราส่วนป้องกันความเสี่ยงแบบพลวัตสำหรับการเทรดคู่

คู่เทรดแบบ market-neutral คลาสสิก — ซื้อสินทรัพย์หนึ่งตัว ขายสินทรัพย์อีกตัวในปริมาณที่ถ่วงน้ำหนักด้วยเบต้า — อยู่รอดหรือตายด้วยอัตราส่วนป้องกันความเสี่ยง β\beta ประมาณมันด้วย OLS แบบคงที่ตลอดหน้าต่างการฝึก แล้วคุณจะสืบทอดปัญหาสหสัมพันธ์ล้าสมัยที่บทความทั้งหมดนี้พูดถึงพอดี การป้องกันความเสี่ยงที่ทำให้เป็นกลางต่อการเปิดรับตลาดในไตรมาสที่แล้วผิดในไตรมาสนี้

DCC ให้อัตราส่วนป้องกันความเสี่ยงแก่คุณในรูปอนุกรมเวลา การป้องกันความเสี่ยงแบบความแปรปรวนต่ำสุด (minimum-variance hedge) ของการเปิดรับ ETH โดยใช้ BTC คือสัมประสิทธิ์การถดถอยแบบมีเงื่อนไข

βt=Covt(rETH,rBTC)Vart(rBTC)=hETH,BTC,tσBTC,t2=ρETH,BTC,tσETH,tσBTC,t\beta_t = \frac{\mathrm{Cov}_t(r_{\text{ETH}}, r_{\text{BTC}})}{\mathrm{Var}_t(r_{\text{BTC}})} = \frac{h_{\text{ETH,BTC},t}}{\sigma_{\text{BTC},t}^2} = \rho_{\text{ETH,BTC},t}\,\frac{\sigma_{\text{ETH},t}}{\sigma_{\text{BTC},t}}

ทุกเทอมทางด้านขวาเป็นผลลัพธ์ของ DCC อัตราส่วนป้องกันความเสี่ยงเคลื่อนไหวด้วยสองสาเหตุที่แตกต่างกัน และ DCC แยกมันออกจากกันได้อย่างชัดเจน สหสัมพันธ์ ρt\rho_t เปลี่ยนไป (สินทรัพย์เชื่อมโยงหรือแยกจากกัน) และอัตราส่วนความผันผวน σETH,t/σBTC,t\sigma_{\text{ETH},t}/\sigma_{\text{BTC},t} เปลี่ยนไป (สินทรัพย์หนึ่งผันผวนมากขึ้นเมื่อเทียบกัน) เบต้าแบบ rolling-OLS จะเบลอผลกระทบทั้งสองเข้าด้วยกันพร้อมความล่าช้า ในขณะที่ DCC ระบุแต่ละสาเหตุได้

def dynamic_hedge_ratio(R_path, Sigma, base="BTC", target="ETH",
                        symbols=symbols, index=Z.index):
    """
    beta_t to hedge `target` exposure with `base`:
        beta_t = rho_t * sigma_target,t / sigma_base,t
    (Scaling cancels in the ratio, so scaled units are fine here.)
    """
    i = symbols.index(target)
    j = symbols.index(base)
    rho = R_path[:, i, j]
    sig = np.asarray(Sigma)
    beta = rho * sig[:, i] / sig[:, j]
    return pd.Series(beta, index=index, name=f"beta_{target}_{base}")

beta_t = dynamic_hedge_ratio(R_path, Sigma)
print(beta_t.describe())

spread = (returns["ETH"] - beta_t.shift(1) * returns["BTC"]).dropna()

ป้อน spread เข้าไปในเอนจินคู่เทรดใดก็ตามที่คุณใช้งาน การป้องกันความเสี่ยงแบบพลวัตไม่ได้สร้างความได้เปรียบด้วยตัวมันเอง — มันทำให้ สเปรดที่คุณเทรด เป็นกลางต่อตลาดอย่างแท้จริงตลอดเวลา ดังนั้นสัญญาณการกลับสู่ค่าเฉลี่ยของคุณจึงไม่ถูกปนเปื้อนด้วยการเปิดรับทิศทางที่เลื่อนไหล ถ้าคุณสร้างกลยุทธ์คู่เทรด สิ่งนี้เสียบเข้ากับกรอบงานใน Statistical Arbitrage และการเทรดคู่ในคริปโต และ แนวทางระยะทางสำหรับคู่เทรด โดยตรง แทนที่อัตราส่วนป้องกันความเสี่ยงคงที่ของมัน อนุกรมสหสัมพันธ์เองก็เป็นข้อมูลนำเข้าที่สะอาดกว่าสำหรับ สัญญาณคู่เทรดตามสหสัมพันธ์ มากกว่าหน้าต่าง rolling ใด ๆ — คุณจะได้ ρt\rho_t ที่เรียบและสอดคล้องกับแบบจำลองแทนที่จะเป็นค่าประมาณที่มีสัญญาณรบกวนจากหน้าต่าง

ข้อควรระวังสองข้อเฉพาะสำหรับการใช้ βt\beta_t ในการเทรดสด ข้อแรก ให้ล่าช้า (lag) มัน — เทรดบน βt1\beta_{t-1} ไม่เคยใช้ βt\beta_t ร่วมสมัย มิฉะนั้นคุณกำลังแอบดูล่วงหน้า ข้อสอง อัตราส่วนป้องกันความเสี่ยงที่แกว่งไปมาทุกวันสร้างการหมุนเวียน (turnover) และค่าธรรมเนียม ในตลาดคริปโตที่เปิด 24/7 พร้อมต้นทุน funding บนขาช็อต การป้องกันความเสี่ยงที่ตอบสนองมากเกินไปอาจเสียมากกว่าดริฟต์ที่มันแก้ไข ทำให้ βt\beta_t เรียบ (EWMA หรือปรับสมดุลการป้องกันความเสี่ยงเมื่อมันเคลื่อนพ้นแถบเท่านั้น) และกำหนดขนาดทั้งหมดอย่างสมเหตุสมผล การกำหนดขนาดสถานะจากสัญญาณที่มีสัญญาณรบกวนเป็นวินัยของตัวมันเอง ครอบคลุมใน การกำหนดขนาดด้วยเกณฑ์เคลลี่

การประยุกต์ที่ 2: ความแปรปรวนของพอร์ตที่แปรผันตามเวลา

สำหรับพอร์ตที่มีเวกเตอร์น้ำหนัก ww ความแปรปรวนแบบมีเงื่อนไขคือ

σp,t2=wHtw=ijwiwjρij,tσi,tσj,t\sigma_{p,t}^2 = w'\, H_t\, w = \sum_{i}\sum_{j} w_i w_j\, \rho_{ij,t}\,\sigma_{i,t}\,\sigma_{j,t}

ด้วยเมทริกซ์ความแปรปรวนร่วมแบบคงที่ — ค่าเริ่มต้นของ Markowitz — ตัวเลขนี้คือค่าคงที่ที่คุณคำนวณครั้งเดียวและแสร้งทำเป็นว่ายังคงเป็นจริงอยู่ ซึ่งไม่จริง ความเสี่ยงของพอร์ตหายใจไปตามตลาด และมันหายใจ หนักที่สุด พอดีเมื่อสหสัมพันธ์พุ่งขึ้น เพราะในตลาดร่วง ทั้งเทอม σi,t\sigma_{i,t} และเทอม ρij,t\rho_{ij,t} เพิ่มขึ้นพร้อมกันและคูณกัน พอร์ตที่ดูเหมือนมีความผันผวนรายปี 40% ในตลาดสงบอาจวิ่งอยู่ที่ 80%+ ในสัปดาห์ตึงเครียด และเมทริกซ์ความแปรปรวนร่วมแบบคงที่จะบอกคุณว่าไม่มีอะไรเปลี่ยนแปลง

def portfolio_vol_path(H_path, weights, index=Z.index, unscale=1e4):
    """
    Conditional portfolio volatility sigma_{p,t} = sqrt(w' H_t w).
    H_path is in scaled (x100) units, so covariances carry a 100^2
    factor: divide by unscale=1e4 to return to raw-return variance.
    """
    w = np.asarray(weights)
    var_t = np.einsum("i,tij,j->t", w, H_path, w) / unscale
    return pd.Series(np.sqrt(var_t), index=index, name="port_vol")

w = np.array([0.4, 0.3, 0.2, 0.1])   # BTC, ETH, SOL, BNB
pv = portfolio_vol_path(H_path, w)
pv_annual = pv * np.sqrt(365)
print(pv_annual.describe())

σp,t\sigma_{p,t} ที่แปรผันตามเวลานี้คือข้อมูลนำเข้าที่ตรงไปตรงมาที่การจัดสรรตามความเสี่ยงต้องการ การหาค่าเหมาะสมที่สุดแบบ mean-variance (Markowitz สำหรับคริปโต) ด้วยความแปรปรวนร่วมแบบตัวอย่างที่ คงที่ คือการหาค่าเหมาะสมที่สุดกับเรื่องแต่ง การป้อน HtH_t (หรือการพยากรณ์ระยะสั้นของมัน) เข้าไปทำให้ frontier ที่มีประสิทธิภาพเองแปรผันตามเวลา และบังคับให้ตัวหาค่าเหมาะสมที่สุดลดความเสี่ยงเข้าสู่ระบอบสหสัมพันธ์ที่กำลังเพิ่มขึ้นแทนที่จะทำหลังจากมัน แนวทาง risk-parity และแบบลำดับชั้น — ไปป์ไลน์ HRP + CVaR — ยังไวต่อข้อมูลนำเข้าความแปรปรวนร่วมมากกว่าอีก เพราะการจัดสรรทั้งหมด คือ ฟังก์ชันของเมทริกซ์ความเสี่ยง และถ้าคุณกำลังเปรียบเทียบตัวจัดสรรแบบเทียบกันตรง ๆ อย่างใน อัลกอริทึมการหาค่าเหมาะสมที่สุดของพอร์ตเปรียบเทียบกัน ว่ามันใช้ความแปรปรวนร่วมแบบคงที่หรือแบบพลวัต มักเป็นตัวขับเคลื่อนความเสี่ยงที่เกิดขึ้นจริง (realized risk) ที่ใหญ่กว่าการเลือกอัลกอริทึมเสียอีก

การประยุกต์ตรงคือ การกำหนดเป้าหมายความผันผวน (volatility targeting) ของพอร์ตทั้งหมด เลือกเป้าหมายความผันผวนรายปี σ\sigma^{*} และปรับขนาดการเปิดรับรวม (gross exposure) ด้วย σ/σp,t\sigma^{*} / \sigma_{p,t} ในแต่ละช่วงเวลา เพื่อให้ความเสี่ยงที่เกิดขึ้นจริงคงที่โดยประมาณแทนที่จะพองตัวในช่วงวิกฤต นั่นปิดวงจรกับ ตอนที่ 4 ซึ่งสร้างและทดสอบย้อนหลังกฎนี้อย่างแม่นยำ

การประยุกต์ที่ 3: สหสัมพันธ์ในฐานะสัญญาณระบอบ (Regime Signal)

นอกเหนือจากการป้องกันความเสี่ยงและการกำหนดขนาด เมทริกซ์สหสัมพันธ์ยังพกพาสัญญาณระดับมหภาค สเกลาร์ที่มีประโยชน์ที่สุดที่คุณสามารถสกัดได้คือ สหสัมพันธ์เฉลี่ยแบบคู่ (average pairwise correlation)

ρˉt=2d(d1)i<jρij,t\bar{\rho}_t = \frac{2}{d(d-1)}\sum_{i < j} \rho_{ij,t}

เมื่อ ρˉt\bar{\rho}_t เพิ่มขึ้นทั่วทั้งพอร์ต ตลาดกำลังเข้าสู่ระบอบ risk-off — เรื่องราวเฉพาะตัว (idiosyncratic) หยุดมีความสำคัญ และทุกอย่างเทรดเหมือนเป็นเบต้ามหภาคเดียว นี่คือลายนิ้วมือเชิงปริมาณของ "สหสัมพันธ์ไปที่ 1 ในวิกฤต" มันมักจะ นำหน้า หรือเกิดพร้อมกับตลาดร่วง ทำให้มันเป็นตัวชี้วัดระบอบที่ใช้งานได้มากกว่าการชันสูตรหลังเหตุการณ์ (postmortem) ที่ตามหลัง

def avg_pairwise_corr(R_path, index=Z.index):
    T, d, _ = R_path.shape
    iu = np.triu_indices(d, k=1)          # upper-triangle off-diagonals
    avg = R_path[:, iu[0], iu[1]].mean(axis=1)
    return pd.Series(avg, index=index, name="avg_corr")

avg_corr = avg_pairwise_corr(R_path)

roll_q = avg_corr.rolling(365, min_periods=90).quantile(0.80)
risk_off = (avg_corr > roll_q)

คุณสามารถใช้ risk_off เป็นตัวควบคุมแบบสแตนด์อโลน (ลดการเปิดรับรวม กว้างสต็อป หยุดกลยุทธ์ mean-reversion ที่จะถูกวิ่งทับเมื่อทุกอย่างเทรนด์ไปด้วยกัน) หรือเป็นฟีเจอร์ในแบบจำลองระบอบที่เป็นทางการมากขึ้น มันจับคู่ได้ตามธรรมชาติกับแนวทาง hidden-Markov ใน การตรวจจับระบอบด้วย HMM สหสัมพันธ์ DCC เฉลี่ยเป็นหนึ่งในตัวแปรสังเกต (observation variables) ที่ให้ข้อมูลมากที่สุดที่คุณสามารถส่งให้ HMM ได้ เพราะมันมองไปข้างหน้าเกี่ยวกับความเครียดเชิงระบบในแบบที่ผลตอบแทนย้อนหลังทำไม่ได้ คำเตือนที่ตรงไปตรงมา สหสัมพันธ์ที่เพิ่มขึ้นบอกคุณว่าความหลากหลายกำลังล้มเหลว ไม่ใช่ตลาดจะไปทิศทางไหน มันเป็นสัญญาณความเสี่ยง ไม่ใช่สัญญาณอัลฟา และควรถูกกำหนดขนาดตามนั้น — ดู ความไม่สมมาตรของกำไรขาดทุน ว่าทำไมการปฏิบัติต่อระบอบความเสี่ยงเป็นการเดิมพันเชิงทิศทางถึงจบลงไม่ดี

ข้อพิจารณาในทางปฏิบัติ

เสถียรภาพในการประมาณและจำนวนสินทรัพย์

DCC ขยายตามขนาดได้ดีกว่า BEKK มาก แต่ "ขยายตามขนาดได้" ไม่ได้แปลว่า "ฟรี" เมทริกซ์ correlation-targeting Qˉ\bar{Q} คือสหสัมพันธ์แบบตัวอย่างขนาด d×dd \times d และเมทริกซ์สหสัมพันธ์แบบตัวอย่างจะมีสภาพไม่ดี (ill-conditioned) เมื่อ dd เข้าใกล้จำนวนการสังเกต ด้วย 4 สินทรัพย์และ 1000 วัน คุณสบายดี ด้วย 60 สินทรัพย์และ 400 วัน Qˉ\bar{Q} เกือบจะ singular การผกผัน (inverse) ของมันใน likelihood จะระเบิด และ RtR_t อาจเบี่ยงเบนออกจาก PD จากสัญญาณรบกวนเชิงตัวเลข การแก้ไข เรียงตามความถี่ที่คุณจะต้องใช้

  • Shrink Qˉ\bar{Q} เข้าหาเป้าหมายที่มีโครงสร้าง (Ledoit-Wolf หรือเข้าหา identity / เมทริกซ์สหสัมพันธ์คงที่) ก่อนรันการวนซ้ำ นี่คือการแก้ไขที่มีประสิทธิภาพสูงสุดสำหรับพอร์ตขนาดใหญ่
  • จัดกลุ่มสินทรัพย์ เป็นไม่กี่ภาคส่วน (majors, L1s, DeFi, memes) สร้างแบบจำลองภายในและข้ามที่ระดับภาคส่วน หรือรัน DCC บนปัจจัยจากองค์ประกอบหลัก (principal components) แทนสินทรัพย์ดิบ
  • เลือกข้อมูลมากกว่าสินทรัพย์มาก DCC มีความหิวกระหายประวัติที่ยาว สะอาด และร่วมสมัยอย่างไม่มีที่สิ้นสุด — ซึ่งเป็นสิ่งที่โทเคนใหม่ ๆ ไม่มีพอดี

ในทางปฏิบัติ ให้จำกัด DCC โดยตรงไว้ที่ไม่กี่สิบสินทรัพย์เป็นอย่างมาก สำหรับจักรวาลขนาดใหญ่ DCC บนผลตอบแทนของปัจจัย (factor returns) บวกกับส่วนตกค้างเฉพาะตัว (idiosyncratic residuals) คือวิธีแก้ปัญหามาตรฐาน

Correlation targeting คือทางลัดที่มีค่าใช้จ่าย

การกำหนดเป้าหมาย Qˉ\bar{Q} ทำให้การประมาณจัดการได้ แต่ฝัง สหสัมพันธ์ไร้เงื่อนไขแบบ เต็มตัวอย่าง ไว้ใน RtR_t ทุกตัว ในการทดสอบย้อนหลังที่เข้มงวด นี่คือการรั่วไหลของการมองล่วงหน้า (look-ahead leak) เมทริกซ์สหสัมพันธ์ของวัน-tt ของคุณ "รู้" สหสัมพันธ์เฉลี่ยของตัวอย่างทั้งหมด รวมถึงอนาคตด้วย สำหรับการประเมินที่ตรงไปตรงมา คุณต้องประมาณ Qˉ\bar{Q} ใหม่บนหน้าต่างการฝึกเท่านั้นและตรึงมันไว้คงที่นอกตัวอย่าง หรือเลื่อนมันไปข้างหน้า นี่คือวินัยเดียวกันกับที่กรอบงาน walk-forward optimization ทั้งหมดบังคับใช้ และมันง่ายมากที่จะละเมิดโดยไม่ตั้งใจด้วย np.cov(Z) ที่สะดวกตลอดอาร์เรย์เต็ม — เหมือนที่โค้ดสอนของเราด้านบนทำ แก้ไขมันก่อนที่คุณจะเชื่อตัวเลข P&L ใด ๆ

ความถี่ในการปรับใหม่และวินัยเรื่องการมองล่วงหน้า

คุณไม่จำเป็นต้องหาค่าเหมาะสมที่สุดของ a,ba, b ใหม่ทุกวัน — มันเป็นพารามิเตอร์ที่เสถียร ความถี่การใช้งานจริงที่สมเหตุสมผล

  • ประมาณ a,ba, b และพารามิเตอร์ GARCH แบบตัวแปรเดี่ยวใหม่ ทุกสัปดาห์หรือทุกเดือน
  • รันตัวกรอง (filter) (อัปเดต QtQ_t, σi,t\sigma_{i,t}) ทุกช่วงเวลา ด้วยพารามิเตอร์ที่ตรึงไว้ เพื่อให้ได้ RtR_t และ HtH_t ใหม่ การกรองมีต้นทุนถูก การปรับ (fitting) ไม่ถูก
  • พยากรณ์เสมอ อย่าทำให้เรียบ (smooth) เด็ดขาด ใช้ RtR_t ที่สร้างจากข้อมูลผ่าน t1t-1 เพื่อเทรดที่ tt โครงสร้างสองรอบ (fit บนหน้าต่าง แล้วกรองไปข้างหน้า) คือสิ่งที่ทำให้คุณตรงไปตรงมา

ช่องว่างระหว่างการทดสอบย้อนหลัง DCC และประสิทธิภาพการเทรดสดมักเป็นการรั่วไหลของการมองล่วงหน้าเสมอ — Qˉ\bar{Q} แบบเต็มตัวอย่าง βt\beta_t ร่วมสมัย หรือการปรับใหม่บนข้อมูลที่รวมการเทรดที่คุณกำลังประเมิน วินัยของการจับคู่การทดสอบย้อนหลังกับสภาพการเทรดสดเป็นหัวข้อของตัวมันเองใน ความเท่าเทียมระหว่างการทดสอบย้อนหลังและการเทรดสด และ DCC เป็นแบบจำลองที่ลงโทษความหละหลวมตรงนี้มากกว่าส่วนใหญ่ ถ้าหลังจากการประเมิน walk-forward ที่สะอาดแล้ว สหสัมพันธ์แบบพลวัตไม่ได้เพิ่มอะไรเลยเหนือค่าประมาณ rolling ธรรมดาสำหรับกลยุทธ์ ของคุณ นั่นคือผลลัพธ์เชิงลบที่แท้จริงและตีพิมพ์ได้ — แนวคิดใน ผลลัพธ์เชิงลบที่ตรงไปตรงมา ใช้ได้โดยตรง

Asymmetric DCC (aDCC)

เช่นเดียวกับ leverage effect แบบตัวแปรเดี่ยว (ตอนที่ 2) ที่ข่าวร้ายเพิ่มความผันผวนมากกว่าข่าวดี สหสัมพันธ์เพิ่มขึ้นมากกว่าหลังช็อกทางลบร่วมกัน (joint negative) มากกว่าหลังช็อกทางบวกร่วมกัน Cappiello, Engle & Sheppard (2006) จับสิ่งนี้ด้วย asymmetric DCC เพิ่มเทอมที่ขับเคลื่อนโดย outer product ของส่วนตกค้างที่ถูกทำให้เป็นมาตรฐานส่วน ทางลบ zt=min(zt,0)z_t^- = \min(z_t, 0)

Qt=(QˉaQˉbQˉgNˉ)+azt1zt1+gzt1zt1+bQt1Q_t = (\bar{Q} - a\bar{Q} - b\bar{Q} - g\bar{N}) + a\, z_{t-1} z_{t-1}' + g\, z_{t-1}^- z_{t-1}^{-\prime} + b\, Q_{t-1}

โดยที่ Nˉ=1Ttztzt\bar{N} = \frac{1}{T}\sum_t z_t^- z_t^{-\prime} และ g0g \ge 0 วัดแรงกระตุ้นสหสัมพันธ์พิเศษจากการเคลื่อนไหวขาลงร่วมกัน สำหรับคริปโต ที่สหสัมพันธ์แบบล่ม (crash-correlation) เป็นความเสี่ยงหลัก เทอมความไม่สมมาตรมักมีนัยสำคัญและคุ้มค่ากับพารามิเตอร์เพิ่มเติมหนึ่งตัว rmgarch ปรับ aDCC ได้ทันที (model="aDCC") การเพิ่มเทอม ztz_t^- เข้าไปในตัวประมาณ NumPy ของเราเป็นแบบฝึกหัดที่ตรงไปตรงมา

การเปรียบเทียบ: DCC เทียบกับทางเลือกอื่น

DCC อยู่ตรงไหนในบรรดาวิธีต่าง ๆ ที่คุณอาจได้เมทริกซ์ความแปรปรวนร่วมสำหรับพอร์ตคริปโต สรุปแบบตรงไปตรงมา

แนวทาง พารามิเตอร์ ขยายไปถึง สหสัมพันธ์แปรผันตามเวลาไหม? รับประกัน PD ไหม? การพึ่งพากันของหางไหม?
Sample / rolling covariance 0 (ความยาวหน้าต่าง) dd ใดก็ได้ หยาบ (ล่าช้า มีสัญญาณรบกวน) ไม่ (ต้องแก้ไข) ไม่
EWMA (RiskMetrics) 1 (λ\lambda) dd ใดก็ได้ ใช่ (การสลายตัวเดียว) ใช่ ไม่
CCC-GARCH margins dd ตัว + Qˉ\bar{Q} หลายสิบ ไม่ (RR คงที่) ใช่ ไม่
DCC-GARCH margins dd ตัว + 2 หลายสิบ ใช่ ใช่ ไม่
aDCC-GARCH margins dd ตัว + 3 หลายสิบ ใช่ ไม่สมมาตร ใช่ บางส่วน
BEKK O(d2)O(d^2) 4\le 4 ใช่ (สมบูรณ์) ใช่ ไม่
VECH O(d4)O(d^4) 3\le 3 ใช่ (สมบูรณ์ที่สุด) ลำบาก ไม่
GARCH-copula margins dd ตัว + copula หลายสิบ (vines) copula คงที่ ใช่ ใช่

การอ่านตารางนี้ไม่กี่ประเด็น

  • EWMA เป็นเกณฑ์พื้นฐานราคาถูกที่ทุกคนควรเอาชนะให้ได้ก่อนอ้างว่า DCC ช่วย มันเป็นกรณีพิเศษแบบพารามิเตอร์เดียวในเชิงจิตวิญญาณ — การสลายตัวแบบเอ็กซ์โพเนนเชียลเดี่ยวที่ใช้กับความแปรปรวนร่วมโดยตรง — และสำหรับหลายพอร์ตมันยากอย่างน่าประหลาดใจที่จะปรับปรุงนอกตัวอย่าง ถ้า DCC ไม่เอาชนะ EWMA ใน walk-forward ที่สะอาด ให้ใช้ EWMA
  • CCC เทียบกับ DCC คือประเด็นทั้งหมดของบทความนี้ การแยกตัวประกอบเดียวกัน แต่ CCC ตรึง RR ไว้ และ DCC ปล่อยให้มันเคลื่อนไหว พารามิเตอร์เพิ่มเติมสองตัว (a,ba, b) คือความแตกต่างทั้งหมด และในคริปโตพวกมันคุ้มค่าที่จะมี
  • BEKK/VECH ซื้อพลวัตที่สมบูรณ์กว่า — ทุกความแปรปรวนร่วมสามารถตอบสนองต่อทุกช็อกในอดีตได้ — แต่ต้นทุนพารามิเตอร์จำกัดมันไว้ที่พอร์ตขนาดเล็กมาก สำหรับเกิน 4 สินทรัพย์มันไม่ใช่ทางเลือกที่แท้จริง
  • GARCH-copula เป็นแถวเดียวที่มี "ใช่" ภายใต้การพึ่งพากันของหาง นั่นคือความเสริมกันอีกครั้ง DCC สร้างแบบจำลอง ศูนย์กลาง แบบพลวัตของการแจกแจงร่วม copula สร้างแบบจำลอง หาง แบบคงที่ของมัน ถ้าคำถามความเสี่ยงของคุณคือ "จะเกิดอะไรขึ้นเมื่อทุกอย่างพังพร้อมกัน" ให้หยิบ ไปป์ไลน์ copula ถ้าคือ "อัตราส่วนป้องกันความเสี่ยง/ความแปรปรวนของพอร์ตของฉันตอนนี้คือเท่าไร" ให้หยิบ DCC

ค่าเริ่มต้นในทางปฏิบัติสำหรับเดสก์คริปโตเชิงระบบ DCC (หรือ aDCC) สำหรับอัตราส่วนป้องกันความเสี่ยงและความแปรปรวนร่วมแบบพลวัตในตัวหลัก ชั้นซ้อน copula สำหรับความเสี่ยงหางและ CVaR และ EWMA เป็นเกณฑ์พื้นฐานตรวจสอบความสมเหตุสมผลที่ทำให้คุณตรงไปตรงมาว่ากลไกเพิ่มเติมนั้นคุ้มค่ากับตัวมันเองหรือไม่

ข้อจำกัด

  • พลวัตแบบสเกลาร์ aa และ bb ตัวเดียวสำหรับทุกคู่เป็นข้อจำกัดที่แข็งแกร่ง BTC-ETH และอัลต์คอยน์ที่ไม่ค่อยมีคนรู้จักสองตัวใช้ความเร็วการปรับตัวเดียวกัน Generalized DCC ผ่อนคลายสิ่งนี้แต่นำการระเบิดของพารามิเตอร์ที่ DCC ถูกออกแบบมาเพื่อหลีกเลี่ยงกลับมา
  • การสูญเสียประสิทธิภาพแบบสองขั้นตอน ตัวประมาณ quasi-likelihood มีความสม่ำเสมอแต่ไม่มีประสิทธิภาพเต็มที่ และค่าความคลาดเคลื่อนมาตรฐานแบบไร้เดียงสาผิดพลาด ใช้การปรับแก้ของ Engle-Sheppard ถ้าคุณสนใจการอนุมานเชิงสถิติ สำหรับการสร้างสัญญาณ ค่าประมาณจุดก็เพียงพอ
  • หางแบบ Gaussian โดยค่าเริ่มต้น quasi-likelihood แบบ Gaussian ธรรมดาประเมินความเสี่ยงหางร่วมต่ำเกินไป Student-t innovations ช่วยได้ สำหรับ การพึ่งพากัน ของหางที่แท้จริง (ความน่าจะเป็นของการเคลื่อนไหวสุดขั้วพร้อมกัน) DCC เป็นเครื่องมือที่ผิด และ แบบจำลอง copula คือเครื่องมือที่ถูกต้อง DCC ให้ ตัวหลัก (body) แบบพลวัตของสหสัมพันธ์ copula ให้ หาง แบบคงที่ เดสก์ที่จริงจังใช้ทั้งสองอย่าง
  • สหสัมพันธ์ไม่ใช่เหตุปัจจัย และไม่ใช่ทิศทาง ρˉt\bar{\rho}_t ที่เพิ่มขึ้นเตือนว่าความหลากหลายกำลังล้มเหลว มันไม่ได้บอกอะไรเกี่ยวกับทิศทางตลาด อย่าใส่ความคาดหวังเชิงทิศทางลงในสัญญาณความเสี่ยงมากเกินไป
  • ความหิวกระหายข้อมูล ทุกอย่างข้างต้นสมมติประวัติที่ยาว สะอาด และตรงกันตามเวลา โทเคนคริปโตที่ใหม่และน่าสนใจที่สุดละเมิดทั้งสามข้อ

สรุป

  • สหสัมพันธ์แบบคงที่คือคำโกหกในคริปโต สหสัมพันธ์รวมกลุ่ม คงอยู่ และพุ่งเข้าใกล้ 1 ในตลาดร่วง — พอดีในช่วงที่ความหลากหลายควรจะช่วยได้ สหสัมพันธ์แบบตัวอย่างเดี่ยว ρ^\hat{\rho} เฉลี่ยกระบวนการที่เปลี่ยนระบอบเข้าเป็นค่ากลางที่ไม่มีความหมาย
  • GARCH แบบหลายตัวแปรเต็มรูปแบบ (VECH, BEKK) ไม่ขยายตามขนาด จำนวนพารามิเตอร์เพิ่มขึ้นเป็น O(d2)O(d^2) ทั้งสองแบบถูกจำกัดไว้ที่สินทรัพย์ไม่กี่ตัวในทางปฏิบัติ
  • DCC (Engle 2002) แยกตัวประกอบปัญหา Ht=DtRtDtH_t = D_t R_t D_t โดยที่ DtD_t มาจากการปรับ GARCH แบบตัวแปรเดี่ยวอิสระ (นำตอนที่ 1-2 กลับมาใช้) และ RtR_t มาจากการวนซ้ำแบบสองพารามิเตอร์ มันขยายไปถึงหลายสิบสินทรัพย์เพราะมีเพียง a,ba, b เท่านั้นที่ถูกหาค่าเหมาะสมที่สุด
  • การวนซ้ำ Qt=(1ab)Qˉ+azt1zt1+bQt1Q_t = (1-a-b)\bar{Q} + a\,z_{t-1}z_{t-1}' + b\,Q_{t-1} ที่ถูกทำให้เป็นมาตรฐานเป็น RtR_t ผลิตเมทริกซ์สหสัมพันธ์ positive-definite ที่ถูกต้องในทุกขั้นตอน โดยมี a,b>0a,b>0, a+b<1a+b<1
  • arch ไม่รองรับ DCC ปรับขอบเขต (margins) ด้วย arch แล้วทำใช้จริงตัวประมาณ NumPy/SciPy ~60 บรรทัดในที่นี้ หรือใช้ mgarch (Python) หรือ rmgarch (R เป็นตัวอ้างอิง)
  • ผลตอบแทนที่จับต้องได้สามอย่าง อัตราส่วนป้องกันความเสี่ยงแบบพลวัต βt=ρtσETH,t/σBTC,t\beta_t = \rho_t\,\sigma_{\text{ETH},t}/\sigma_{\text{BTC},t} สำหรับการเทรดคู่ ความแปรปรวนของพอร์ตที่แปรผันตามเวลาอย่างตรงไปตรงมา wHtww'H_t w สำหรับการจัดสรรตามความเสี่ยง และสหสัมพันธ์เฉลี่ยแบบคู่เป็นสัญญาณระบอบ risk-off
  • วินัยคือทุกสิ่ง Correlation targeting รั่วไหลค่าเฉลี่ยแบบเต็มตัวอย่าง ดังนั้นให้ประมาณ Qˉ\bar{Q} ใหม่บนข้อมูลฝึกเท่านั้น ล่าช้าอัตราส่วนป้องกันความเสี่ยงทุกตัว กรองไปข้างหน้า ไม่เคยทำให้เรียบ การประเมิน walk-forward ไม่สามารถต่อรองได้
  • aDCC เพิ่มเทอมความไม่สมมาตรขาลงและมักคุ้มค่าในคริปโต ที่สหสัมพันธ์แบบล่มครอบงำ
  • ตอนที่ 4 ใช้การพยากรณ์เหล่านี้เพื่อสร้างและทดสอบย้อนหลังกลยุทธ์ที่กำหนดเป้าหมายความผันผวน

เอกสารอ้างอิง:

  • Engle, R. (2002). Dynamic Conditional Correlation: A Simple Class of Multivariate Generalized Autoregressive Conditional Heteroskedasticity Models. Journal of Business & Economic Statistics, 20(3), 339-350. DOI
  • Engle, R. & Sheppard, K. (2001). Theoretical and Empirical Properties of Dynamic Conditional Correlation Multivariate GARCH. NBER Working Paper 8554. DOI
  • Bollerslev, T. (1990). Modelling the Coherence in Short-Run Nominal Exchange Rates: A Multivariate Generalized ARCH Model. Review of Economics and Statistics, 72(3), 498-505. DOI
  • Cappiello, L., Engle, R., & Sheppard, K. (2006). Asymmetric Dynamics in the Correlations of Global Equity and Bond Returns. Journal of Financial Econometrics, 4(4), 537-572. DOI
  • Engle, R. & Kroner, K. (1995). Multivariate Simultaneous Generalized ARCH. Econometric Theory, 11(1), 122-150. DOI
  • Bollerslev, T., Engle, R., & Wooldridge, J. (1988). A Capital Asset Pricing Model with Time-Varying Covariances. Journal of Political Economy, 96(1), 116-131. DOI
  • Galanos, A. (2022). rmgarch: Multivariate GARCH Models. R package. CRAN.
ข้อจำกัดความรับผิดชอบ: ข้อมูลที่ให้ไว้ในบทความนี้มีไว้เพื่อการศึกษาและให้ข้อมูลเท่านั้น และไม่ถือเป็นคำแนะนำทางการเงิน การลงทุน หรือการเทรด การเทรดสกุลเงินดิจิทัลมีความเสี่ยงสูงที่จะขาดทุน

MarketMaker.cc Team

การวิจัยและกลยุทธ์เชิงปริมาณ

พูดคุยใน Telegram
Newsletter

ก้าวนำหน้าตลาด

สมัครรับจดหมายข่าวของเราเพื่อรับข้อมูลเชิงลึกการเทรดด้วย AI เฉพาะ การวิเคราะห์ตลาด และการอัปเดตแพลตฟอร์ม

เราเคารพความเป็นส่วนตัวของคุณ ยกเลิกการสมัครได้ทุกเมื่อ