---
title: "7 · Backtesting: ขั้นตอน การทดสอบ และสัญญาณไฟจราจร"
description: ตรรกะของ backtest, ขั้นตอนตาม Excel/Python ของคอร์ส, การแจกแจง Binomial, traffic light ของ Basel, Kupiec และ Christoffersen
inline_math: true
---

# 7 · Backtesting: ขั้นตอน การทดสอบ และสัญญาณไฟจราจร

<p class="lead">Backtest ทดสอบคุณสมบัติสองข้อของแบบจำลอง VaR: ความถี่ของ breach ถูกต้องไหม และ breach เกิดอย่างอิสระไหม บทนี้ไล่ตั้งแต่การนับไปจนถึงการทดสอบทางสถิติและเขตสัญญาณไฟจราจร</p>

<p class="source-note">อ้างอิงต้นฉบับ: หน้า 18–19 · <a href="downloads/market-risk-handbook.pdf#page=19">เปิด PDF หน้า 18</a></p>

## 7.1 ตรรกะของ backtest

ลองนึกภาพ: ทุกเช้าคุณคำนวณ VaR 99%/10 วันโดยใช้ **เฉพาะข้อมูลที่มี ณ ตอนนั้น** แล้ว “ปิดผนึก” ไว้ สิบวันทำการต่อมาเทียบกับผลตอบแทนที่เกิดจริงในช่วงนั้น และตรวจว่าคำทำนายผลขาดทุนแย่สุดถูกเกิน (breach) หรือไม่ ถ้าแบบจำลองถูก breach จะเกิดราว 1% ของเวลาและ **เป็นอิสระต่อกัน** [Backtest](glossary.md#backtesting) ทดสอบสองคุณสมบัตินี้พอดี: **ความถี่** (unconditional coverage) และ **ความเป็นอิสระ** (independence)

## 7.2 ทีละขั้น (ตัวอย่าง Excel / Python ของคอร์ส)

$$
\operatorname{VaR}_t=\Phi^{-1}(0.01)\times\sigma_t\sqrt{10}\ (+10\mu),
\qquad
r_{10D,t}=\ln(S_{t+10}/S_t),
\qquad
\text{breach}_t=\mathbb 1\{r_{10D,t}<\operatorname{VaR}_t\}
$$

1. **ผลตอบแทน**: ราคาวันแรกใช้คำนวณ log-return ตัวแรกเท่านั้น
2. **σ แบบหน้าต่างเลื่อน**: ต้องใช้ผลตอบแทน 21 ค่าสำหรับส่วนเบี่ยงเบนมาตรฐาน (รายวัน) ตัวแรก หน้าต่างเลื่อนไปทีละหนึ่งค่า (ผลตอบแทน 1–21, 2–22, …)
3. **VaR**: ตั้งแต่วันของผลตอบแทนที่ 21 คำนวณ $\operatorname{VaR}_t$ ทุกวัน
4. **ผลตอบแทนไปข้างหน้า**: $r_{10D,t}$ ใช้ราคา 10 วันหลัง $t$; 10 วันสุดท้ายจึงไม่มีค่า
5. **การเปรียบเทียบที่ใช้ได้**: $T=N_{\text{prices}}-21-10$ ข้อมูลของคอร์ส: ราคา 1,250 ค่า → **1,219** การเปรียบเทียบ
6. **สถิติ**: (a) จำนวนและสัดส่วนของ breach; (b) ความน่าจะเป็นแบบมีเงื่อนไข $\Pr(\text{breach}_t\mid\text{breach}_{t-1})$; (c) เทียบกับ binomial
7. **กราฟ**: $\operatorname{VaR}_t$ และ $r_{10D,t}$ พร้อมกัน และทำเครื่องหมาย breach สังเกตการกระจุกตัว

<div class="box box-pitfall">
<p class="box-label">ข้อควรระวัง · ผลตอบแทน 10 วันที่ซ้อนกัน</p>

ผลตอบแทนไปข้างหน้า 10 วันที่ติดกันใช้ข้อมูลร่วมกัน 9 วัน breach จึงกระจุกตัวโดยกลไก: การตกแรงครั้งเดียวทำให้เกิด breach ในการเปรียบเทียบหลายครั้งติดกัน ข้อสมมติ “breach อิสระ” ของ binomial ล้มเหลว และการทดสอบความเป็นอิสระจะปฏิเสธโดยโครงสร้าง backtest ตามกฎเกณฑ์จึงเปรียบเทียบ VaR **1 วัน** กับ P&L **1 วัน** (MAR32) ถ้าจะ backtest VaR 10 วัน ให้ใช้ช่วงที่ไม่ซ้อนกัน (เหลือหนึ่งในสิบของตัวอย่าง) หรือการทดสอบที่ปรับสำหรับการซ้อน

</div>

## 7.3 การแจกแจง Binomial และสัญญาณไฟจราจรของ Basel

$$
X\sim\operatorname{Binomial}(T,\ p=1-c),
\qquad
\mathbb E[X]=Tp,
\qquad
\Pr(X\le k)=\sum_{j=0}^{k}\binom{T}{j}p^j(1-p)^{T-j}
\quad(\text{Excel: }\texttt{BINOM.DIST(k,T,p,TRUE)})
$$

<figure class="source-figure"><img src="assets/images/source-figures/figure-05.png" alt="กราฟแท่งการแจกแจงจำนวน exception ใน 250 วันสำหรับ VaR 99%: 0 ถึง 4 สีเขียว 5 ถึง 9 สีเหลือง ตัวเลขบนแท่งเป็นความน่าจะเป็นสะสม 0.0811, 0.2858, 0.5432, 0.7581, 0.8922, 0.9588, 0.9863, 0.9960, 0.9989, 0.9997, 0.9999" width="1072" height="523" loading="lazy"><figcaption>ภาพที่ 5 (ต้นฉบับ Figure 5) การแจกแจงจำนวน breach เมื่อ T = 250, p = 1% ตัวเลขบนแท่งเป็นความน่าจะเป็นสะสม</figcaption></figure>

กฎของ Basel (1996): เมื่อมี breach $k$ ครั้ง แบบจำลองอยู่เขต **เขียว** ถ้า $\Pr(X\le k)<95\%$ เขต **เหลือง** ถ้า $95\%\le\Pr(X\le k)<99.99\%$ และเขต **แดง** ถ้า $\ge 99.99\%$ สำหรับ $T=250$: เขียว 0–4, เหลือง 5–9, แดง ≥10

เขตจะกำหนดตัวคูณเงินกองทุนที่ใช้กับเงินกองทุนตาม VaR (Basel 2.5: 3 + plus factor; FRTB MAR32 ระดับทั้งธนาคาร: 1.5 เพิ่มถึง 2.0) ในเขตแดง ผู้กำกับดูแลอาจถอนการอนุมัติแบบจำลองด้วย

| จำนวน breach | เขต | Basel 2.5 | FRTB |
|---|---|--:|--:|
| 0–4 | เขียว | 3.00 | 1.50 |
| 5 | เหลือง | 3.40 | 1.70 |
| 6 | เหลือง | 3.50 | 1.76 |
| 7 | เหลือง | 3.65 | 1.83 |
| 8 | เหลือง | 3.75 | 1.88 |
| 9 | เหลือง | 3.85 | 1.92 |
| ≥10 | แดง | 4.00 | 2.00 |

<div class="box box-pitfall">
<p class="box-label">ข้อควรระวัง · ขอบเขตของเขตคลาดไปหนึ่ง (off-by-one)</p>

ใช้ `scipy.stats.binom.ppf(0.95, 250, 0.01)` = 5 แล้วเขียนว่า “เขียว ≤5” คลาดไปหนึ่ง: ppf คืนค่า $k$ ที่เล็กที่สุดที่ความน่าจะเป็นสะสม **ถึง** 95% และ $k$ นั้นอยู่ในเขตเหลืองแล้ว ที่ถูกต้องคือ เขียวถ้า $k<$ ppf(0.95), แดงถ้า $k\ge$ ppf(0.9999) นอกจากนี้สไลด์หนึ่งของคอร์สให้เกณฑ์เหลืองเป็น 0.9599 ที่ถูกคือ **0.9999** ตารางความน่าจะเป็นของ breach ในสไลด์นั้นแท้จริงเป็น **probability mass** สำหรับ T=252, p=5% (BINOMDIST(…, FALSE)) ไม่ใช่ความน่าจะเป็นสะสมของ VaR 99%

</div>

## 7.4 Kupiec proportion-of-failures test

$$
\mathrm{LR}_{\mathrm{POF}}=-2\ln\frac{(1-p)^{T-x}p^{x}}{(1-\hat p)^{T-x}\hat p^{x}},
\qquad
\hat p=\frac{x}{T},
\qquad
\mathrm{LR}_{\mathrm{POF}}\sim\chi^2_1\ \ (\text{ค่าวิกฤตที่ 5\% คือ }3.841)
$$

สมมติฐานหลัก: ความน่าจะเป็นของ breach ที่แท้จริงเท่ากับ $p$ อัตราส่วน likelihood เปรียบเทียบว่า breach ที่สังเกตได้มีความเป็นไปได้แค่ไหนภายใต้ $p$ ทางทฤษฎี เทียบกับความถี่ที่สังเกตได้ $\hat p$ การทดสอบเป็นแบบ **สองทาง**: breach มากเกินไป (แบบจำลองก้าวร้าว) และน้อยเกินไป (ระมัดระวังเกิน สิ้นเปลืองทุน) ถูกปฏิเสธทั้งคู่

**ตัวอย่าง**: $T=249$, $x=11$, $\hat p=4.42\%$, $\mathrm{LR}=15.96$, p-value $6.5\times10^{-5}$: ปฏิเสธอย่างแรง

## 7.5 Christoffersen independence และ conditional coverage

$$
\pi_0=\frac{n_{01}}{n_{00}+n_{01}},\quad
\pi_1=\frac{n_{11}}{n_{10}+n_{11}},\quad
\mathrm{LR}_{\mathrm{ind}}=-2\ln\frac{(1-\pi)^{n_{00}+n_{10}}\pi^{n_{01}+n_{11}}}{(1-\pi_0)^{n_{00}}\pi_0^{n_{01}}(1-\pi_1)^{n_{10}}\pi_1^{n_{11}}}\sim\chi^2_1,\quad
\mathrm{LR}_{\mathrm{cc}}=\mathrm{LR}_{\mathrm{POF}}+\mathrm{LR}_{\mathrm{ind}}\sim\chi^2_2
$$

$n_{ij}$ นับวันที่สถานะเมื่อวานเป็น $i$ และวันนี้เป็น $j$ (1 = breach) “ความน่าจะเป็นของ breach เมื่อช่วงก่อนหน้ามี breach” ของคอร์สคือ $\pi_1$ สำหรับแบบจำลองที่ดี $\pi_1\approx\pi_0\approx p$; ถ้า $\pi_1\gg p$ แสดงว่า breach กระจุกตัวและแบบจำลองตอบสนองต่อการเปลี่ยนความผันผวนช้าเกินไป การทดสอบ conditional coverage $\mathrm{LR}_{\mathrm{cc}}$ (ค่าวิกฤตที่ 5% คือ 5.991) ทดสอบความถี่และความเป็นอิสระพร้อมกัน

<div class="box box-practice">
<p class="box-label">ในทางปฏิบัติ · กำลังของการทดสอบและขนาดตัวอย่าง</p>

ด้วยข้อมูล 250 ค่าต่อปีและ breach ที่คาดไว้ 2.5 ครั้ง ทุกการทดสอบมีกำลังต่ำ: แบบจำลองที่อัตรา breach แท้จริงเป็น 2% มีโอกาสสูงที่จะยังอยู่ในเขตเขียว เมื่อมี breach น้อย สถิติของ Christoffersen ก็ไม่เสถียร ($n_{11}$ มักเป็น 0 หรือ 1) ดังนั้น (1) ใช้ประวัติให้ยาวที่สุด (หลายปี หลายพอร์ต) (2) backtest หลายระดับ (97.5% และ 99%) (3) ใช้ร่วมกับ P&L attribution, การวินิจฉัย residual และการทบทวนเชิงคุณภาพ แทนการพึ่ง p-value เพียงตัวเดียว

</div>

## 7.6 สามทางในการปรับปรุง VaR

1. **ค่าเฉลี่ย**: ตัด μ ออกแล้วหรือยัง? μ ที่เป็นบวกทำให้ VaR เอียงไปทางมองโลกในแง่ดี
2. **ความผันผวน**: ไวพอไหม? procyclical เกินไปไหม? GARCH เพิ่มพารามิเตอร์และดึงการพยากรณ์เข้าหาค่าเฉลี่ยระยะยาว ผู้ปฏิบัติงานใช้ EWMA แต่ต้องบริหาร procyclicality
3. **ตัวคูณ**: เปอร์เซ็นไทล์ Normal “ดีพอ” แต่ไม่เพียงพอสำหรับ P&L เชิงประจักษ์ ตัวคูณ Cornish–Fisher หรือ t ช่วยได้

<div class="box box-regulatory">
<p class="box-label">เทียบกฎเกณฑ์ · Backtesting</p>

| กรอบ | ข้อกำหนด |
|---|---|
| UCITS | backtest รายเดือนของ VaR 1 วันเป็นอย่างน้อย; overshooting เกิน 4 ครั้งที่ 99% ใน 250 วันต้องรายงานต่อผู้บริหารระดับสูงและผู้กำกับดูแล พร้อมทบทวนแบบจำลอง (สอดคล้องกับเขตเขียว 0–4 ของ Basel) |
| AIFMD | Level 2 Art. 45 กำหนดให้ backtest เป็นระยะ “ตามความเหมาะสม” โดยไม่มีเกณฑ์ตัวเลข; ในทางปฏิบัติมักยืมเกณฑ์ 4 overshooting ของ UCITS |
| MiFID II | บริษัทหลักทรัพย์ที่ใช้ internal model ตาม CRR ปฏิบัติตามกฎ backtest ของธนาคาร (VaR 1 วัน 99% เทียบ P&L จริงและสมมุติ, ตัวคูณตามสัญญาณไฟ) |

</div>

## ห้องทดลอง: Binomial, Kupiec และสัญญาณไฟ

เลือกจำนวนการเปรียบเทียบ ระดับความเชื่อมั่น และจำนวน breach ที่สังเกตได้ เพื่อดูเขตตามกฎความน่าจะเป็นสะสม 95% / 99.99% และผล Kupiec ตัวเลขทั้งหมดคำนวณจากการแจกแจง Binomial ไม่ใช่ผล backtest ของพอร์ตจริง

<div class="interactive-mount" id="traffic-light-lab"><noscript><p class="noscript-note">เปิด JavaScript เพื่อใช้ห้องทดลอง</p></noscript></div>
