วิธีสร้างและอ่านค่า Bootstrapping Confidence Bands
เส้นกราฟผลตอบแทนเพียงหนึ่งเส้นถือเป็นกลุ่มตัวอย่างเดียว การทำ Bootstrapping ช่วยสร้างช่วงความเชื่อมั่นของค่า Sharpe ratio เพื่อประเมินความเสี่ยงและนัยสำคัญของกลยุทธ์อย่างแม่นยำ
ช่วงความเชื่อมั่นของการทดสอบย้อนหลัง (Backtest)
ช่วงความเชื่อมั่นของการทดสอบย้อนหลังตอบคำถามเพียงข้อเดียว คือเส้นกราฟผลตอบแทนของกลยุทธ์นั้นมาจากตัวกลยุทธ์เองเท่าใด และมาจากช่วงเวลาเฉพาะที่นำมาทดสอบเท่าใด การทำ Bootstrapping ในการทดสอบย้อนหลังจะสร้างช่วงความเชื่อมั่นดังกล่าวขึ้นมาโดยการสุ่มตัวอย่างชุดข้อมูลผลตอบแทนซ้ำหลายครั้ง คำนวณค่าสถิติใหม่ในแต่ละรอบของการสุ่ม และอ่านค่าเปอร์เซ็นไทล์จากผลลัพธ์ที่ได้ ค่า Sharpe ratio ที่ระดับ 1.4 ซึ่งวัดจากข้อมูลรายวันในช่วงเวลาหนึ่งปีนั้น มีช่วงความเชื่อมั่นที่ระดับ 95 เปอร์เซ็นต์กว้างพอที่จะครอบคลุมถึงศูนย์ และแผงข้อมูลด้านล่างนี้จะแสดงให้เห็นถึงสาเหตุของเรื่องดังกล่าว
เหตุใดเส้นกราฟผลตอบแทนหนึ่งเส้นจึงเป็นเพียงกลุ่มตัวอย่างเดียว
การทำ Backtest จะให้ตัวเลขสถิติออกมาเพียงค่าเดียว เช่น Sharpe ratio หนึ่งค่า, ผลตอบแทนต่อปีหนึ่งค่า, ค่า Drawdown สูงสุดหนึ่งค่า และอัตราความสำเร็จหนึ่งค่า ซึ่งค่าเหล่านี้ไม่ใช่ค่าที่แท้จริงของกลยุทธ์ แต่ละค่าเป็นเพียงการประมาณการที่สร้างขึ้นจากจำนวนวันซื้อขายที่มีจำกัด หากเปลี่ยนช่วงเวลาที่มีความยาวเท่ากัน ผลลัพธ์ที่ได้ก็จะแตกต่างออกไป
ตารางด้านล่างนี้ตัดปัจจัยเรื่องกลยุทธ์ออกไปโดยสิ้นเชิง โดยวัดจากสถานะที่ง่ายที่สุดคือการถือครอง SPY ทีละหนึ่งปีปฏิทิน โดยคำนวณจากราคาปิดถึงราคาปิด
SQL เบื้องหลังตัวเลขแต่ละตัว
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2011-12-01'
AND date < '2026-01-01'
)
SELECT
toString(toYear(date)) AS year,
count() AS obs_count,
round(avg(ret) * 252 * 100, 2) AS ann_return_pct,
round(stddevSamp(ret) * sqrt(252) * 100, 2) AS ann_vol_pct,
round(avg(ret) / stddevSamp(ret) * sqrt(252), 2) AS sharpe_ratio
FROM daily
WHERE date >= '2012-01-01'
AND ret IS NOT NULL
GROUP BY year
ORDER BY yearแต่ละแถวครอบคลุมช่วงเวลาประมาณ 250 วันทำการ ซึ่งใกล้เคียงกับปีมาตรฐานของการซื้อขาย โดยไม่มีการเปลี่ยนแปลงใด ๆ ในสถานะการถือครองตลอดช่วงเวลาดังกล่าว ในปี 2012 ค่า Sharpe ratio ต่อปีวัดได้ 1.06 ส่วนในปี 2025 วัดได้ 0.88 โดยมีจำนวนปีที่แสดงบนแผนภูมิเท่ากับ 14 ปี การถือครองดัชนีในวงกว้างเพียงหนึ่งปีทำให้ตัวเลขหลักเปลี่ยนแปลงไปมากกว่าที่ผู้อ่านส่วนใหญ่จะมองว่าเป็นเพียงสัญญาณรบกวน (noise) และการทำ Backtest กลยุทธ์ที่มีความยาวเท่ากันย่อมได้รับผลกระทบจากความผันผวนนี้เช่นกัน หลักการคำนวณต่อปีที่อยู่เบื้องหลังคอลัมน์นี้อธิบายไว้ใน คู่มือ Sharpe ratio และกลไกการคำนวณผลตอบแทนรายงวดอธิบายไว้ใน วิธีการวัดผลตอบแทนรายเดือน
ช่วงความกว้างของค่า Sharpe ในการทดสอบย้อนหลังเป็นอย่างไร
ค่าความคลาดเคลื่อนมาตรฐาน (standard error) ของการประมาณค่า Sharpe จะลดลงตามรากที่สองของจำนวนข้อมูลที่สังเกตได้ แทนที่จะพึ่งพาสูตรดังกล่าว ให้ใช้วิธีวัดค่าความแตกต่างโดยตรง โดยแบ่งข้อมูลย้อนหลังยี่สิบปีออกเป็นช่วงเวลาที่มีความยาวคงที่และไม่ซ้อนทับกัน จากนั้นคำนวณค่า Sharpe แบบปรับเป็นรายปีในแต่ละช่วง แล้วพิจารณาว่าค่าเหล่านั้นมีความห่างกันมากน้อยเพียงใด
SQL เบื้องหลังตัวเลขแต่ละตัว
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2005-12-01'
AND date < '2026-01-01'
),
indexed AS
(
SELECT
ret,
row_number() OVER (ORDER BY date) AS i
FROM daily
WHERE date >= '2006-01-01'
AND ret IS NOT NULL
),
blocks AS
(
SELECT
w,
intDiv(i, w) AS blk,
count() AS n,
avg(ret) / nullIf(stddevSamp(ret), 0) * sqrt(252) AS sharpe
FROM indexed
CROSS JOIN (SELECT arrayJoin([21, 63, 126, 252, 504]) AS w) AS ws
GROUP BY w, blk
HAVING n = w
)
SELECT
concat(toString(w), ' sessions') AS horizon,
count() AS block_count,
round(quantileDeterministic(0.05)(sharpe, blk), 2) AS sharpe_p05,
round(quantileDeterministic(0.50)(sharpe, blk), 2) AS sharpe_p50,
round(quantileDeterministic(0.95)(sharpe, blk), 2) AS sharpe_p95,
round(quantileDeterministic(0.95)(sharpe, blk)
- quantileDeterministic(0.05)(sharpe, blk), 2) AS sharpe_band_width
FROM blocks
WHERE sharpe IS NOT NULL
GROUP BY w
ORDER BY wที่ 21 sessions ต่อช่วง ค่า Sharpe ที่วัดได้ในช่วงเปอร์เซ็นไทล์ที่ 5 ถึง 95 จะอยู่ในช่วงตั้งแต่ -3.37 ถึง 6.97 ซึ่งเป็นส่วนต่างขนาด 10.34 Sharpe points จากจำนวน 238 ช่วง หากขยายแต่ละช่วงออกไปเป็น 504 sessions ส่วนต่างจะลดลงเหลือ 1.67 points โดยวัดจากจำนวนเพียง 8 ช่วงเท่านั้น มีสองสิ่งที่เกิดขึ้นพร้อมกัน คือค่าประมาณการจะมีความแม่นยำมากขึ้นตามขนาดของกลุ่มตัวอย่าง และจำนวนตัวอย่างที่เป็นอิสระต่อกันซึ่งข้อมูลในอดีตสามารถจัดหาให้ได้นั้นจะลดลง ความขัดแย้งนี้คือประเด็นสำคัญทั้งหมดของเรื่องนี้
วิธีการสร้างช่วงความเชื่อมั่นสำหรับการทำ Backtest ด้วยวิธี Bootstrap
ขั้นตอนการดำเนินการนั้นสั้นพอที่จะเขียนออกมาได้ครบถ้วนดังนี้
- เริ่มต้นด้วยชุดข้อมูลผลตอบแทนที่เกิดขึ้นจริงของกลยุทธ์ โดยมีหนึ่งค่าต่อหนึ่งช่วงเวลา รวมทั้งหมด N ช่วง
- สุ่มเลือกผลตอบแทน N ค่าจากรายการดังกล่าวโดยใช้วิธีสุ่มแบบแทนที่ (with replacement) ซึ่งอาจมีบางค่าที่ถูกเลือกซ้ำ หรือบางค่าที่ไม่ถูกเลือกเลย
- คำนวณค่าสถิติใหม่จากชุดข้อมูลที่สุ่มขึ้นมา
- ทำซ้ำหลายพันครั้งโดยเก็บทุกค่าที่คำนวณได้ไว้
- เรียงลำดับค่าที่เก็บไว้ทั้งหมด แล้วอ่านค่าที่เปอร์เซ็นไทล์ที่ 2.5 และ 97.5 เพื่อให้ได้ช่วงความเชื่อมั่นที่ 95 เปอร์เซ็นต์
ควรตั้งค่า Seed ให้กับตัวสร้างตัวเลขสุ่มก่อนเริ่มขั้นตอนที่ 2 และบันทึกค่า Seed นั้นไว้ข้างช่วงความเชื่อมั่นที่เผยแพร่ การทำ Bootstrap คือการประมาณการแบบ Monte Carlo ซึ่งการรันโปรแกรมสองครั้งโดยไม่ตั้งค่า Seed จะให้ผลลัพธ์ในหลักสุดท้ายที่ไม่ตรงกัน และผู้ตรวจสอบที่ไม่สามารถรันช่วงความเชื่อมั่นของคุณซ้ำได้ย่อมไม่มีทางตรวจสอบความถูกต้องได้ นี่คือระเบียบวินัยแบบเดียวกับที่อธิบายไว้ใน การตั้งค่า Backtest ที่ทำซ้ำได้
ค่าเฉลี่ยผลตอบแทนและ Sharpe ratio สามารถผ่านขั้นตอนที่ 2 ได้อย่างราบรื่น เนื่องจากทั้งสองค่าอ่านรายการผลตอบแทนในลักษณะที่เป็นชุดข้อมูล แต่ Maximum drawdown ไม่สามารถทำเช่นนั้นได้ เนื่องจาก Drawdown อ่านลำดับของเหตุการณ์ตามช่วงเวลา การสุ่มใหม่ที่เรียงลำดับผลตอบแทนใหม่จะทำให้ได้ค่า Drawdown ที่แย่ที่สุดซึ่งไม่มีลำดับใดในเหตุการณ์จริงที่เคยเกิดขึ้น อย่างไรก็ตาม การทำ Bootstrap สำหรับค่านี้ยังคงมีประโยชน์ หากระบุไว้อย่างชัดเจนว่าผลลัพธ์ที่ได้คืออะไร นั่นคือการกระจายตัวของ Drawdown จากประวัติการซื้อขายที่ถูกสลับลำดับ ไม่ใช่การคาดการณ์เหตุการณ์ที่จะเกิดขึ้นในอนาคต คำจำกัดความอยู่ใน maximum drawdown
เหตุใดการทำ IID bootstrap จึงไม่เหมาะสมสำหรับผลตอบแทนของตลาด
ขั้นตอนที่สองตั้งสมมติฐานว่าผลตอบแทนทุกค่ามีความเป็นอิสระและมีการแจกแจงเหมือนกัน ซึ่งก็คือสมมติฐาน IID ผลตอบแทนรายวันทำลายสมมติฐานนี้ในลักษณะที่ส่งผลต่อความกว้างของช่วง ผลตอบแทนแบบมีทิศทาง (signed returns) มีความทรงจำเพียงเล็กน้อยในระดับหนึ่งวัน แต่ขนาดของผลตอบแทนกลับมีการเกาะกลุ่มกัน กล่าวคือ การเคลื่อนไหวที่รุนแรงมักเกิดขึ้นต่อเนื่องกัน และวันที่มีความผันผวนต่ำมักเกิดขึ้นติดต่อกันเป็นช่วง
SQL เบื้องหลังตัวเลขแต่ละตัว
WITH daily AS
(
SELECT
ticker,
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('SPY', 'MSFT', 'KO', 'XOM', 'JNJ', 'PG')
AND date >= '2015-11-01'
AND date < '2026-01-01'
),
lagged AS
(
SELECT
ticker,
date,
ret,
lagInFrame(ret, 1) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS ret_prev
FROM daily
WHERE ret IS NOT NULL
AND abs(ret) < 0.35
)
SELECT
ticker,
count() AS obs_count,
round(corr(ret, ret_prev), 3) AS return_autocorr,
round(corr(abs(ret), abs(ret_prev)), 3) AS abs_return_autocorr
FROM lagged
WHERE date >= '2016-01-01'
AND ret_prev IS NOT NULL
GROUP BY ticker
ORDER BY abs_return_autocorr DESCสำหรับ SPY ค่าสหสัมพันธ์ในตัวเอง (autocorrelation) แบบแล็กหนึ่งของผลตอบแทนรายวันแบบสัมบูรณ์วัดได้ 0.366 ตลอดช่วง 2514 รอบการซื้อขาย เมื่อเทียบกับ -0.133 สำหรับผลตอบแทนแบบมีทิศทางในช่วงวันเดียวกัน ให้เปรียบเทียบแท่งกราฟทั้งสองแท่งของหุ้นแต่ละตัวในแผนภูมิ การสลับลำดับอนุกรมผลตอบแทนจะทำลายการเกาะกลุ่มดังกล่าว และการทำ IID bootstrap บนข้อมูลชุดนี้จะรายงานช่วงที่แคบกว่าที่ข้อมูลตัวอย่างรองรับ ความผิดพลาดนี้เกิดขึ้นในทิศทางที่ไม่เป็นประโยชน์ที่สุด เนื่องจากเป็นการทำให้กลยุทธ์ดูดีเกินความเป็นจริง
การทำ Moving block bootstrap และการเลือกความยาวของบล็อก
วิธีแก้ไขคือการสุ่มตัวอย่างแบบบล็อกที่ต่อเนื่องกันแทนการสุ่มผลตอบแทนรายตัว ให้เลือกความยาวบล็อกเป็น L แล้วสุ่มเลือกบล็อกที่มีผลตอบแทนต่อเนื่องกันจำนวน L บล็อกแบบใส่คืน จากนั้นนำมาต่อกันจนได้อนุกรมสังเคราะห์ที่มีความยาว N ความสัมพันธ์ภายในบล็อกจะยังคงอยู่ครบถ้วน เนื่องจากผลตอบแทนเหล่านั้นยังคงอยู่ในลำดับเดิม จะมีเพียงจุดเชื่อมต่อระหว่างบล็อกเท่านั้นที่เป็นการสร้างขึ้นใหม่
ความยาวของบล็อกเป็นการแลกเปลี่ยนระหว่างข้อผิดพลาดสองประการที่ไม่มีการตั้งค่าใดหลีกเลี่ยงได้ บล็อกที่สั้นเกินไปจะมีพฤติกรรมเหมือน IID bootstrap และประเมินช่วงความเชื่อมั่นต่ำกว่าความเป็นจริง ซึ่งถือเป็นอคติ (bias) ส่วนบล็อกที่ยาวเกินไปจะรักษาความสัมพันธ์ไว้ได้มากกว่า แต่เหลือจำนวนบล็อกที่แตกต่างกันให้เลือกน้อยลง ทำให้การสุ่มแต่ละครั้งซ้ำข้อมูลชุดเดิมขนาดใหญ่ และส่งผลให้ช่วงความเชื่อมั่นมีความผันผวน (variance) สูงขึ้น กฎเกณฑ์ทั่วไปที่เผยแพร่กันจะปรับขนาดความยาวตามค่า N ยกกำลังหนึ่งส่วนสาม ซึ่งควรใช้เป็นเพียงจุดเริ่มต้นเท่านั้น
วิธีการวินิจฉัยที่ประหยัดกว่าคือการตรวจสอบว่าความผันผวนปรับตัวตามกรอบเวลาอย่างไร ภายใต้สมมติฐานความเป็นอิสระต่อกัน ความผันผวนของผลตอบแทนรวมราย k วัน จะเท่ากับ k คูณด้วยความผันผวนรายหนึ่งวัน และอัตราส่วนของทั้งสองค่าควรอยู่ที่ 1
SQL เบื้องหลังตัวเลขแต่ละตัว
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2005-12-01'
AND date < '2026-01-01'
),
indexed AS
(
SELECT
ret,
row_number() OVER (ORDER BY date) AS i
FROM daily
WHERE date >= '2006-01-01'
AND ret IS NOT NULL
),
base AS
(
SELECT varSamp(ret) AS var_1d FROM indexed
),
blocks AS
(
SELECT
k,
intDiv(i, k) AS blk,
count() AS n,
sum(ret) AS block_ret
FROM indexed
CROSS JOIN (SELECT arrayJoin([2, 3, 5, 10, 21, 42, 63]) AS k) AS ks
GROUP BY k, blk
HAVING n = k
)
SELECT
concat(toString(k), ' sessions') AS block_length,
count() AS block_count,
round(varSamp(block_ret) / (k * any(var_1d)), 3) AS variance_ratio
FROM blocks
CROSS JOIN base
GROUP BY k
ORDER BY kที่ 2 sessions อัตราส่วนที่วัดได้คือ 0.844 ส่วนที่ 63 sessions วัดได้ 0.584 ซึ่งคำนวณจากบล็อกที่ไม่ซ้อนทับกันจำนวน 78 บล็อก ค่าที่ใกล้ 1 หมายความว่าผลรวมมีการปรับตัวในลักษณะเดียวกับการสุ่มแบบอิสระที่กรอบเวลานั้น ค่าที่ห่างจาก 1 จะบ่งชี้ถึงกรอบเวลาที่ความสัมพันธ์ยังคงมีผลอยู่ ซึ่งเป็นช่วงที่ความยาวของบล็อกต้องครอบคลุมถึง ให้เลือกบล็อกที่สั้นที่สุดที่ครอบคลุมช่วงดังกล่าวได้ จากนั้นพิจารณาว่าจำนวนบล็อกที่เหลืออยู่นั้นลดลงไปมากน้อยเพียงใด
การสุ่มตัวอย่างแบบแบ่งกลุ่ม (Bucketed resampling) และจำนวนนับข้างช่วงความเชื่อมั่น
การสุ่มตัวอย่างใหม่ภายในกลุ่ม (Resampling within buckets) ไม่ว่าจะแบ่งตามสภาวะความผันผวนหรือตามเดือนปฏิทิน ช่วยรักษาเงื่อนไขที่ทำให้ประเด็นการวิเคราะห์มีความน่าสนใจ หากข้อสมมติฐานระบุว่ากลยุทธ์หนึ่งสร้างค่า Sharpe ได้ดีในช่วงที่ตลาดมีความผันผวนสูง ช่วงความเชื่อมั่นที่สร้างขึ้นจากการสุ่มเฉพาะข้อมูลในวันที่ตลาดผันผวนสูงย่อมเป็นตัวทดสอบสมมติฐานดังกล่าวได้ดีที่สุด ต้นทุนที่ต้องแลกคือความแม่นยำทางสถิติ การแบ่งข้อมูลสองร้อยห้าสิบรายการออกเป็นสี่กลุ่มจะเหลือข้อมูลกลุ่มละประมาณหกสิบรายการ ซึ่งการทำ bootstrap ด้วยข้อมูลหกสิบรายการจะให้ช่วงความเชื่อมั่นที่กว้างกว่าการใช้กลุ่มตัวอย่างเต็มประมาณสองเท่า
ดังนั้น ควรรายงานจำนวนนับของกลุ่มกำกับไว้ข้างช่วงความเชื่อมั่นทุกครั้ง คอลัมน์ block_count ในตารางด้านบนคือตัวอย่างของการสร้างนิสัยนี้ให้เห็นเป็นรูปธรรม ค่าเปอร์เซ็นไทล์ที่ห้าที่อ่านได้จากหน้าต่างข้อมูลเก้าชุด ย่อมเป็นข้อมูลคนละประเภทกับที่อ่านได้จากสองร้อยชุด แม้ว่าทั้งสองค่าจะแสดงผลออกมาเป็นทศนิยมสองตำแหน่งเท่ากันก็ตาม
สิ่งที่ Bootstrap แก้ไขไม่ได้
Bootstrap เป็นเครื่องมือวัดปริมาณสิ่งเดียวเท่านั้น คือสัญญาณรบกวนจากการสุ่มตัวอย่าง (sampling noise) ในสถิติที่คำนวณจากข้อมูลที่คุณมี แต่มันไม่ได้บ่งบอกว่าข้อมูลนั้นเป็นสิ่งที่สามารถทำได้จริงหรือไม่
การทำ Backtest ที่ปนเปื้อนด้วย look-ahead bias จะสร้างชุดข้อมูลผลตอบแทนที่ไม่เคยสามารถซื้อขายได้จริง และการทำ Bootstrap บนข้อมูลนั้นก็เพียงแค่ให้ช่วงความเชื่อมั่นที่แคบและดูน่าเชื่อถือแก่เรื่องที่แต่งขึ้นมาเท่านั้น จักรวาลของหุ้นที่ประกอบขึ้นจากสมาชิกดัชนีในปัจจุบันย่อมมี survivorship bias ติดมาด้วย และการสุ่มตัวอย่างใหม่ (resample) ทุกครั้งจากจักรวาลนั้นก็จะได้รับอคติดังกล่าวสืบทอดมาด้วย ช่องโหว่ที่สามคือผลกระทบจากการคัดเลือก (selection effect) หากคุณทดสอบกลยุทธ์สองร้อยรูปแบบแล้วเลือกเก็บไว้เพียงรูปแบบที่ดีที่สุด ช่วงความเชื่อมั่นแบบ Bootstrap ของมันจะอธิบายเพียงสัญญาณรบกวนจากการสุ่มตัวอย่างของรูปแบบนั้นรูปแบบเดียว โดยละเลยการสุ่มอีกหนึ่งร้อยเก้าสิบเก้าครั้งที่เกิดขึ้นก่อนจะมาถึงการเลือกนี้ ช่วงความเชื่อมั่นที่ซื่อตรงนั้นมีประโยชน์ แต่ไม่สามารถใช้แทนข้อมูลนอกกลุ่มตัวอย่าง (out-of-sample data) ได้
หมายเหตุข้อมูลและระเบียบวิธี
- ผลตอบแทนคือผลตอบแทนจากราคาปิดถึงราคาปิดจากแท่งราคารายวัน ไม่รวมเงินปันผล ซึ่งทำให้ระดับของผลตอบแทนและค่า Sharpe ทุกตัวต่ำกว่าความเป็นจริงประมาณเท่ากับอัตราเงินปันผลตอบแทน การกระจายตัวที่เป็นหัวข้อของบทความนี้แทบไม่ได้รับผลกระทบ
- หน้าต่างเวลาและบล็อกข้อมูลไม่มีการซ้อนทับกัน ดังนั้นสถิติที่วัดได้แต่ละตัวจึงใช้ช่วงเวลาในอดีตที่ไม่ซ้ำซ้อนกัน หากใช้หน้าต่างเวลาที่ซ้อนทับกันจะทำให้จำนวนตัวอย่างที่ปรากฏดูสูงเกินจริง
- ค่า Quantile ใช้ตัวประมาณค่าแบบกำหนดผลลัพธ์แน่นอน (deterministic estimator) ดังนั้นการรันข้อมูลชุดเดิมซ้ำจะได้ค่าเปอร์เซ็นไทล์เดิม ไม่ใช่การประมาณค่าใหม่
- แผงข้อมูลสหสัมพันธ์ในตัวเอง (autocorrelation panel) ใช้หุ้นขนาดใหญ่หกตัวที่ไม่มีการแตกหุ้นภายในหน้าต่างเวลาที่กำหนด และตัดวันที่ราคาเคลื่อนไหวเกินร้อยละสามสิบห้าออก เพื่อป้องกันไม่ให้สิ่งแปลกปลอมจากการปรับราคาเข้ามามีผลต่อค่าสหสัมพันธ์
คำถามที่พบบ่อย
Bootstrap confidence interval บอกอะไรเกี่ยวกับผลการทดสอบย้อนหลัง (backtest)?
มันแสดงช่วงของค่าที่สถิตินั้นมีโอกาสเป็นไปได้ หากกระบวนการเดียวกันถูกสุ่มตัวอย่างใหม่อีกครั้งในช่วงเวลาจำนวนเท่าเดิม หากช่วงความเชื่อมั่นร้อยละเก้าสิบห้าครอบคลุมค่าศูนย์ หมายความว่ากลุ่มตัวอย่างนั้นสั้นเกินกว่าที่จะแยกแยะได้ว่ากลยุทธ์ดังกล่าวมีข้อได้เปรียบเหนือกว่าการไม่มีข้อได้เปรียบใด ๆ
ต้องใช้จำนวนการสุ่มตัวอย่างซ้ำ (resample) แบบ bootstrap มากเท่าใดจึงจะเพียงพอ?
สำหรับช่วงความเชื่อมั่นร้อยละเก้าสิบห้า การสุ่มตัวอย่างซ้ำจำนวนไม่กี่พันครั้งมักจะให้ผลที่เสถียร และหนึ่งหมื่นครั้งเป็นค่าเริ่มต้นทั่วไปที่มีต้นทุนต่ำ สำหรับการวิเคราะห์ส่วนหาง (tail quantiles) ที่ลึกกว่านั้นจำเป็นต้องใช้จำนวนที่มากขึ้น เนื่องจากเปอร์เซ็นไทล์ที่หนึ่งของการสุ่มหนึ่งพันครั้งจะถูกอ่านค่าจากข้อมูลเพียงประมาณสิบค่าเท่านั้น
ควรใช้ความยาวของบล็อก (block length) เท่าใดสำหรับการทำ moving block bootstrap?
ไม่มีความยาวที่ถูกต้องเป็นสากล กฎทั่วไปคือการปรับขนาดตามขนาดกลุ่มตัวอย่างยกกำลังหนึ่งในสาม และการตรวจสอบในทางปฏิบัติคือการดูช่วงเวลาที่ความแปรปรวนหยุดปรับตัวเป็นเส้นตรง ซึ่งแผง variance ratio ด้านบนได้วัดค่านี้ไว้แล้ว โปรดระบุความยาวที่คุณใช้ควบคู่ไปกับช่วงความเชื่อมั่นที่แสดง
สามารถทำ bootstrap กับค่า maximum drawdown ได้หรือไม่?
ได้ แต่มีข้อควรระวังเรื่องลำดับ ค่า drawdown ขึ้นอยู่กับลำดับของผลตอบแทน ดังนั้นการสุ่มตัวอย่างซ้ำที่สร้างขึ้นจากการสลับตำแหน่งจะรายงานค่า drawdown ของประวัติที่ถูกเรียงลำดับใหม่ การทำ block bootstrap จะช่วยรักษาช่วงเวลาที่ต่อเนื่องกันไว้ได้ และเป็นเครื่องมือที่ดีกว่าสำหรับสถิติที่ขึ้นอยู่กับเส้นทางของราคา (path statistics)
Bootstrap ช่วยแก้ไขปัญหาการทำ overfitting ได้หรือไม่?
ไม่ได้ มันทำหน้าที่วัดสัญญาณรบกวนจากการสุ่มตัวอย่างภายในชุดข้อมูลผลตอบแทนชุดเดียวเท่านั้น ส่วนความเอนเอียงจากการมองไปข้างหน้า (look-ahead bias) และผลกระทบจากการคัดเลือกจากการทดสอบตัวแปรจำนวนมากนั้นอยู่นอกเหนือสิ่งที่ bootstrap สามารถตรวจพบได้
ทุกแผงข้อมูลที่นี่ประกอบด้วย SQL ที่ใช้สร้างผลลัพธ์ดังกล่าว คุณสามารถเปลี่ยน ticker หรือความยาวของช่วงเวลาและรันคำสั่งด้วยตนเองได้บน Strasmore terminal