สัญญาณเข้าอาจเป็นสิ่งที่ส่งผลต่อแบ็กเทสต์ของคุณน้อยที่สุดก็ได้ ผมเอากฎโมเมนตัมธรรมดา ๆ กฎหนึ่งมาใช้ โดยไม่แตะเวลาเข้าออกเลยสักจุด เปลี่ยนแค่ฟังก์ชันที่กำหนดว่าจะถือกี่สัญญา แล้วขยับ net Sharpe จาก 0.41 เป็น 0.71 และ max drawdown จาก 31% เหลือ 13% เทรดชุดเดิม การจับคู่คำสั่งชุดเดิม แต่เป็นกลยุทธ์คนละแบบ
ข้ออ้างนี้ทำให้หลายคนหงุดหงิด ซึ่งก็สมควรแล้ว เพราะมันชวนให้คิดว่าเวลาส่วนใหญ่ที่ใช้ปรับ lookback และเกณฑ์ตัวกรองนั้นไปลงกับปัจจัยเล็กน้อย งั้นผมจะแสดงผลรันจริง แล้วค่อยให้เหตุผลกับฝ่ายวิจารณ์อย่างเป็นธรรม เพราะข้อโต้แย้งแบบนี้มีรูปแบบหนึ่งที่ผิด และควรรู้ว่าผมกำลังเสนอแบบไหน
สัญญาณเดียว วิธีถือ 6 แบบ
สัญญาณ: สัญญา perpetual ETHUSDT บน Binance USDⓈ-M แท่งราคา 1 ชั่วโมง เปิด long เมื่อ EMA 12 ชั่วโมงอยู่เหนือ EMA 96 ชั่วโมง และไม่ถือสถานะในกรณีอื่น ไม่มี short ตั้งแต่กรกฎาคม 2022 ถึงมิถุนายน 2026 ปิดรอบเทรด 431 รอบ ค่าธรรมเนียม taker ทั้งขาเข้าและขาออกที่ 5.0 bps จ่ายหรือรับ funding ทุก 8 ชั่วโมงตามสถานะจริง และจำลอง slippage จากความลึกของสมุดคำสั่งระดับบนสุด สัญญาณนี้จงใจทำให้เรียบง่ายน่าเบื่อ ผมเลือกมันเพราะไม่มีใครอยากออกหน้าปกป้อง จึงเป็นพื้นทดสอบที่ชัดเจน
ทุกรายการด้านล่างใช้เวลาเข้าและออกของแท่งเดียวกันทั้งหมด ต่างกันเพียงฟังก์ชันกำหนดขนาด
| กฎกำหนดขนาด | Net Sharpe | Max DD | มูลค่าซื้อขายต่อปี (× ขนาดสถานะเฉลี่ย) | ต้นทุนคิดเป็น % ของ PnL ขั้นต้น | เลเวอเรจสูงสุด |
|---|---|---|---|---|---|
| มูลค่าสถานะคงที่ $10k | 0.41 | 18.2% | 246× | 14% | 1.0× |
| สัดส่วนคงที่ 100% ของ equity | 0.44 | 30.8% | 251× | 15% | 1.0× |
| ผกผันกับ realized vol 20 วัน | 0.68 | 14.1% | 690× | 29% | 4.4× |
| ตั้งเป้า vol รายปี 20% ปรับสมดุลทุกชั่วโมง ไม่จำกัดเพดาน | 0.71 | 12.9% | 1,180× | 41% | 6.3× |
| ตั้งเป้า vol 20% ช่วงไม่เทรด 20% จำกัดเลเวอเรจที่ 3× | 0.66 | 15.3% | 402× | 19% | 3.0× |
| Half-Kelly จากค่าเฉลี่ย/ความแปรปรวนย้อนหลัง 60 วัน | 0.52 | 24.6% | 830× | 33% | 8.1× |
ดูช่วงห่างระหว่างผลลัพธ์สิ แถวที่แย่ที่สุดกับดีที่สุดต่างกัน 73% เมื่อเทียบกันโดยสัมพัทธ์ในค่า Sharpe และ drawdown ต่างกัน 2.4 เท่า ทีนี้ลองหาพารามิเตอร์ของสัญญาณเข้าบนชุดข้อมูลนี้ที่ขยับ Sharpe ได้ 0.30 โดยไม่ดูเหมือน overfit ชัด ๆ ดูสิ ผมลองหาแล้ว ความยาวคู่ EMA ขยับค่าได้ประมาณ 0.12 ตลอดกริดค่าที่เป็นไปได้ และส่วนใหญ่เป็นความผันผวนที่คงอยู่เมื่อนำไปทดสอบนอกตัวอย่างไม่ได้
ทำไม inverse-vol ถึงดูดี และส่วนไหนเป็นผลจริง
กลไกนี้ไม่ซับซ้อน เมื่อใช้มูลค่าสถานะคงที่ ขนาดสถานะของคุณไม่สัมพันธ์กับ realized volatility นั่นหมายความว่าความเสี่ยงเป็นเงินดอลลาร์ต่อเทรดขึ้นอยู่กับว่า vol ในสัปดาห์นั้นเป็นเท่าไร สำหรับ ETH ในช่วงนี้ realized vol 20 วันอยู่ระหว่าง 31% ถึง 118% ต่อปี รอบที่ใช้มูลค่าสถานะคงที่รับความเสี่ยงเป็นเงินดอลลาร์ในมีนาคม 2024 มากกว่ากรอบกรกฎาคม 2023 ถึง 3.8× ไม่ใช่เพราะสัญญาณมั่นใจขึ้น แต่เพราะตลาดเหวี่ยงแรงขึ้น เกือบทั้งหมดของ drawdown กระจุกตัวอยู่ในกลุ่ม vol สูงสุด 20% การกำหนดขนาดแบบ inverse-vol ตัดความเชื่อมโยงนี้ออก และนั่นช่วยปรับรูปแบบของกระแสผลตอบแทนได้จริง
แต่ค่า Sharpe ที่เพิ่มขึ้นส่วนหนึ่งเป็นผลจากวิธีวัด และถ้าคุณไม่แยกสองส่วนนี้ออกจากกัน คุณจะตัดสินใจผิดในขั้นต่อไป Sharpe หารด้วยส่วนเบี่ยงเบนมาตรฐานของผลตอบแทน ส่วน vol targeting ก็คือการทำให้ส่วนเบี่ยงเบนมาตรฐานของผลตอบแทนคงที่ตามนิยาม เท่ากับคุณกำลังปรับตัวหารโดยตรง กฎที่ปรับขนาดสถานะให้ได้ vol ล่วงหน้าคงที่ จะทำให้ Sharpe ดีขึ้นในกระแสผลตอบแทนแทบทุกรูปแบบที่มีการจับกลุ่มของ vol รวมถึงกระแสที่ไม่มี edge เลย ผมตรวจสอบเรื่องนี้กับสัญญาณที่สับเปลี่ยนแล้ว: สุ่มเวลาเข้า คงการปรับ vol target ไว้ แล้ว Sharpe ก็ยังดีขึ้นราว 0.06 เมื่อเทียบกับมูลค่าสถานะคงที่ ทั้งที่ฐานมีค่าเฉลี่ยเป็นศูนย์ ผลไม่มาก แต่ไม่ใช่ศูนย์ และเกิดจากกลไกล้วน ๆ
ดังนั้นเวลาเปรียบเทียบกฎกำหนดขนาดภายในทีม ผมไม่เคยดู Sharpe เป็นตัวเลขเดียว ผมอยากดู Calmar, net PnL ต่อหน่วยมูลค่าสถานะเฉลี่ยที่นำไปใช้ และลำดับจาก gross ไป net เพราะเมื่อดูทั้ง 3 อย่างพร้อมกันแล้ว จะเล่นกลด้วยตัวหารได้ยากกว่ามาก
ค่าประมาณ vol เป็นโมเดล และข้อมูลรั่วไหลได้เหมือนโมเดลอื่น
วิธีที่พบบ่อยที่สุดที่ทำให้ผลการกำหนดขนาดที่ดูดีกลายเป็นของปลอมคือ ค่าประมาณความผันผวนใช้ข้อมูลจากแท่งที่กำลังใช้กำหนดขนาด หากอนุกรม vol ของคุณคำนวณจากหน้าต่างแบบมีจุดกึ่งกลาง หรือใช้ `rolling().std()` ค่าเริ่มต้นของ pandas หลัง resample ที่รวมแท่งปัจจุบันซึ่งยังไม่ปิด หรือคำนวณจากการปรับมาตรฐานด้วยข้อมูลทั้งชุด นั่นคือข้อมูลรั่วไหล เรื่องนี้สังเกตยากเพราะ vol มีความต่อเนื่อง ข้อมูลที่รั่วในแต่ละแถวจึงน้อย และเส้น equity ยังดูสมเหตุสมผล แค่มันเรียบเกินจริงนิดหน่อยในสัปดาห์ที่สำคัญพอดี
เอเจนต์ของเราตรวจ 4 เรื่องในกฎกำหนดขนาดทุกรูปแบบ ก่อนเลื่อนผลเข้าแถวรอ paper trading:
- ข้อมูลต้องพร้อมใช้ ณ เวลาตัดสินใจ ขนาดสถานะที่ใช้กับแท่งซึ่งเปิดตอน 14:00 ต้องคำนวณได้จากข้อมูลที่มีเวลาปิดไม่เกิน 13:59:59.999 เราตรวจโดยคำนวณอนุกรมขนาดสถานะใหม่จากเฟรมข้อมูลที่ตัดไว้ ณ จุดตัดสินใจสุ่ม 200 จุด แล้วเปรียบเทียบความต่าง
- ช่วงย้อนหลังของตัวประมาณเป็นพารามิเตอร์จริง หน้าต่าง vol 20 วันกับ 60 วันคือกลยุทธ์คนละแบบ เราใส่ช่วงย้อนหลังนี้ในกริด walk-forward รวมกับพารามิเตอร์อื่นทั้งหมด และถ้าผลใช้ได้แค่ความยาวหน้าต่างเดียว นั่นก็เป็นข้อค้นพบเรื่องความเปราะบาง
- เส้นทางเลเวอเรจ ไม่ใช่แค่จุดสูงสุด แสดงการกระจายของ gross leverage ทั้งหมด รอบ vol target แบบไม่จำกัดเพดานข้างต้นใช้เวลา 4% ของชั่วโมงทั้งหมดที่เลเวอเรจเกิน 5× ซึ่งเป็นรายละเอียดที่ไม่เคยปรากฏในตารางสรุป แต่เป็นตัวกำหนดโดยตรงว่ากลยุทธ์นำไปใช้จริงได้หรือไม่
- ทดสอบความทนทานด้วยการปรับขนาด ถ้า Sharpe พังเมื่อเปลี่ยน vol target จาก 20% เป็น 25% แสดงว่ากลยุทธ์ไม่ได้แค่กำหนดเป้าหมาย vol แต่กำลังจูนเลเวอเรจ และคุณเจอ edge เพราะเลือกตัวเลขตัวหนึ่ง
เพดานเลเวอเรจไม่ใช่ของตกแต่งด้านบริหารความเสี่ยง แต่เป็นส่วนหนึ่งของนิยามกลยุทธ์ Binance ปรับลดเลเวอเรจสูงสุดตามระดับของ ETHUSDT เมื่อมูลค่าสถานะเพิ่มขึ้น และอัตรา maintenance margin ก็ปรับสูงขึ้นตามไปด้วย แบ็กเทสต์ที่ปล่อยให้กฎ vol target ไปถึง 6.3× ที่มูลค่าสถานะ $400k กำลังอธิบายสถานะที่แพลตฟอร์มไม่อนุญาตให้คุณถือภายใต้ margin ระดับนั้น แถวที่มีเพดานในตารางเสีย Sharpe ไป 0.05 และเป็นแถวเดียวในสองแถวที่อธิบายสิ่งที่เกิดขึ้นได้จริง
เงินหายไปตรงการปรับสมดุล
สังเกตคอลัมน์ต้นทุน การปรับสมดุลทุกชั่วโมงเพื่อให้ได้ vol target ให้ค่า Sharpe พาดหัวดีที่สุด และส่ง PnL ขั้นต้น 41% ให้แพลตฟอร์ม นั่นคือมูลค่าซื้อขาย 1,180× ของมูลค่าสถานะเฉลี่ยต่อปี ที่ 5 bps ต่อข้าง ยังไม่รวม spread และ market impact วิธีแก้แบบง่าย ๆ คือปรับสมดุลให้น้อยลงตามตารางเวลา วิธีที่ดีกว่าคือกำหนดช่วงไม่เทรด: ปรับขนาดเฉพาะเมื่อสถานะปัจจุบันเบี่ยงจากเป้าหมายเกินเกณฑ์ที่กำหนด
ช่วง 20% ลดมูลค่าซื้อขายต่อปีจาก 1,180× เหลือ 402× ลดลง 66% โดยเสีย Sharpe ไป 0.05 ผมลองกับสัญญาณ 8 ตัวแล้ว และรูปแบบก็เหมือนกัน: ช่วงระหว่าง 15% ถึง 25% รักษาประโยชน์ด้านควบคุมความเสี่ยงไว้ได้เกือบหมด โดยมี turnover เพียง 1 ใน 3 ส่วนช่วงที่ต่ำกว่า 10% ก็แค่จ่ายค่าธรรมเนียมเพื่อความแม่นยำที่ดูดีในปริมาณซึ่งคุณก็ประมาณจากหน้าต่าง 20 วันอยู่แล้ว คุณจะปรับสมดุลถึงทศนิยม 3 ตำแหน่งไม่ได้ เมื่อค่าที่ใช้อ้างอิงมี standard error 15%
เดือนกุมภาพันธ์ เราเจอรอบหนึ่งที่รายงานซึ่งเอเจนต์เขียนอ้างว่าค่า Sharpe ดีขึ้น 0.22 เพราะ "ตัวกรองสัญญาณเข้าที่ปรับปรุงแล้ว" แต่ diff มีแค่บรรทัดเดียวในโมดูลกำหนดขนาด ตัวกรองไม่ได้เปลี่ยน ผมเลยให้รายงานพิมพ์ hash ของ config กำหนดขนาดไว้ด้านบน เพราะการระบุที่มาของผลลัพธ์ต้องทำอย่างมีวินัย และโมเดลก็ชอบเล่าเรื่องให้เรียบร้อยไม่แพ้ใคร
กฎกำหนดขนาดของคุณเปลี่ยนไปอย่างไรเมื่อ paper trading เริ่มทำงาน
ช่องว่างระหว่างแบ็กเทสต์กับ paper trading เปิดกว้างที่สุดตรงนี้ และส่วนใหญ่เป็นเรื่องคณิตศาสตร์ การกำหนดขนาดที่ตอบสนองต่อ vol ทำให้ขนาดสถานะแกว่งได้ 4 ถึง 8 เท่าตลอดชุดข้อมูล ทั้งค่าต่ำสุดและสูงสุดของช่วงนี้ชนข้อจำกัดของแพลตฟอร์มที่แบ็กเทสต์ไม่เคยจำลองไว้
กรณีขนาดเล็ก: ขั้นปริมาณและมูลค่าขั้นต่ำ สัญญา perpetual ETHUSDT มีขั้นปริมาณ 0.001 และขั้นต่ำ $5 หากขนาดในช่วง vol ต่ำของคุณคือ 0.0004 ETH แบ็กเทสต์จะถือสถานะ แต่ paper trading จะไม่ถืออะไรเลย ฟังดูเหมือนกรณีสุดโต่ง จนกว่าจะนึกได้ว่ากฎ vol target ทำให้ขนาดเล็กที่สุดเกิดขึ้นในตลาดที่สงบที่สุด ซึ่งสำหรับสัญญาณตามแนวโน้ม มักเป็นช่วงที่มีจังหวะเข้าดี ๆ อยู่ด้วย กรณีขนาดใหญ่: ขีดจำกัดสถานะ ระดับ margin และสถานะ 6× ที่ต้องมีวินัยเรื่อง isolated margin ซึ่งคุณไม่ได้ทดสอบด้วยโมเดล liquidation
เราจับได้กรณีหนึ่งที่เส้น equity ของ paper trading ตามแบ็กเทสต์คลาดกันไม่เกิน 3% อยู่ 6 สัปดาห์ ก่อนจะแยกจากกันอย่างชัดเจน สาเหตุคือการปัดเศษ: ใช้ `int()` ตัดทิ้งแทนการปัดตามขั้นปริมาณในตัวจัดขนาดคำสั่ง กับสถานะที่เฉลี่ยเพียง 1.4 ขั้น แบ็กเทสต์กำหนดขนาดในพื้นที่ต่อเนื่อง แต่ตัวกำหนดขนาดที่ใช้งานจริงทำให้สถานะเล็ก ๆ ทุกครั้งเสียไป 20-30% จากขนาดที่ตั้งใจ ไม่มีอะไรพิสดารเรื่อง fill model ไม่มีเรื่อง latency แค่ตัดเศษทิ้ง
ข้อวิจารณ์ข้อไหนที่มีเหตุผล
มีข้อโต้แย้ง 3 ข้อที่ฟังขึ้น และผมไม่อยากขายเกินจริงจนกลบข้อเหล่านี้
ข้อแรกและสำคัญที่สุด: การกำหนดขนาดเป็นการจัดสรร edge ไม่ใช่การสร้าง edge ถ้า gross expectancy ของสัญญาณคุณไม่เป็นบวกหลังหักค่าธรรมเนียมและ funding ตามจริง กฎทุกข้อในตารางนั้นก็ขาดทุน กฎที่ดูหรูแค่ขาดทุนโดยมีรูปแบบความแปรปรวนสวยกว่า ผมเลือกสัญญาณที่มี net edge บวกเล็กน้อยในช่วงนี้ ลองใช้กฎทั้ง 6 แบบเดิมกับสัญญาณที่ได้ −1.2 bps ต่อเทรดหลังหักต้นทุน อันดับยังเหมือนเดิม แต่ equity ณ สิ้นสุดต่ำกว่าจุดเริ่มต้นทั้งหมด การกำหนดขนาดเป็นตัวคูณของบางสิ่ง คุณยังต้องมีสิ่งนั้นก่อน
ข้อสอง vol targeting มีจุดอ่อนที่เกิดขึ้นจริงและมีการบันทึกไว้อย่างดี: ลดเลเวอเรจตอนใกล้จุดต่ำสุดของการเทขายอย่างรวดเร็ว แล้วเพิ่มเลเวอเรจอีกครั้งหลังราคาดีดกลับ ในช่วงฟื้นตัวแบบ V อย่างรวดเร็ว มูลค่าสถานะคงที่ชนะ บางครั้งก็ชนะมาก ตลาดหุ้นในมีนาคม 2020 และการร่วงลงของคริปโตในสิงหาคม 2024 ต่างลงโทษการกำหนดขนาดที่ตอบสนองต่อ vol ในช่วงฟื้นตัว หน้าต่าง ETH 4 ปีของผมบังเอิญมีช่วงแกว่งตัวโดย vol จับกลุ่มมากกว่าการเหวี่ยงกลับรูป V จึงทำให้แถว inverse-vol ดูดีขึ้น หากใช้ช่วงเวลาอื่น ลำดับบางส่วนก็จะกลับกัน และถ้าผมเริ่มต้นด้วยตารางจากปี 2020 ข้อโต้แย้งนี้คงมีน้ำหนักน้อยลง
ข้อสาม กฎกำหนดขนาดก็ overfit ได้ไม่ต่างจากอย่างอื่น Half-Kelly ที่อิงค่าประมาณย้อนหลังในตารางของผมเป็นตัวอย่างชัดเจน: ดูซับซ้อน มีหลักการทางทฤษฎีรองรับ แต่กลับทำให้ drawdown แย่เป็นอันดับ 2 เพราะค่าประมาณค่าเฉลี่ยย้อนหลังของอนุกรมผลตอบแทนที่เต็มไปด้วย noise ใช้ไม่ได้ และ Kelly ก็อ่อนไหวต่อค่านี้อย่างรุนแรง กฎกำหนดขนาดใดก็ตามที่ใช้ค่าประมาณผลตอบแทนคาดหวังเป็นอินพุต จะรับความคลาดเคลื่อนของค่านั้นไปขยายต่อ กฎที่ใช้เพียงค่าประมาณความแปรปรวนทำงานได้เสถียรกว่ามาก เพราะความแปรปรวนเป็นโมเมนต์เดียวที่คุณประมาณจากข้อมูลรายชั่วโมงตลอด 4 ปีได้จริง
สิ่งที่ผมอยากให้จำจากทั้งหมดนี้คือ เมื่อผลแบ็กเทสต์ทำให้คุณแปลกใจ ให้ตรวจโมดูลกำหนดขนาดก่อนมองหาความชาญฉลาดในสัญญาณ และเมื่อรายงาน Sharpe ให้แสดงเส้นทางเลเวอเรจกับลำดับต้นทุนประกอบด้วย เพราะตัวเลขที่ขึ้นอยู่กับการตัดสินใจกำหนดขนาดมากขนาดนี้ ไม่ใช่คุณสมบัติของสัญญาณเลย
← บทความทั้งหมด
