21 กันยายน 2026 · วิศวกรรม

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

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

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

ถ้าผลไม่ตรงกัน แสดงว่าคุณพบปัญหาการจัดการสถานะ กลยุทธ์พึ่งพาสิ่งที่คุณไม่ได้บันทึกไว้หรือสร้างกลับคืนไม่ได้ การพึ่งพานี้สำคัญทุกครั้งที่มีการรันงานวิจัยต่อ เปลี่ยน worker หรือ deploy โค้ดใหม่ให้บริการ paper trading

ฉันชอบการทดสอบนี้เพราะคำตอบที่คาดหวังชัดเจนเป็นพิเศษ ไม่มีข้อโต้แย้งว่าตลาดเปลี่ยนไปหรือไม่ ทั้งสองรันได้รับข้อมูลตลาดชุดเดียวกัน

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

1. โหลดแท่งราคาไม่กี่แท่งแล้วคิดว่าอินดิเคเตอร์พร้อมใช้งาน

สมมติว่ากลยุทธ์ใช้อินดิเคเตอร์ exponential moving average 100 คาบ สูตรอัปเดตคือ:

alpha = 2 / 101
ema_next = alpha * close + (1 - alpha) * ema_previous

โปรเซสที่รันต่อเนื่องจะส่งต่อค่า EMA ที่สะสมมาแล้ว ส่วนโปรเซสที่รีสตาร์ตจะดึงแท่งราคา 100 แท่ง ตั้งต้น EMA ด้วยราคาปิดแท่งแรก แล้วคิดว่าอินดิเคเตอร์ 100 คาบต้องใช้ข้อมูลสังเกตการณ์ 100 จุด

สมมตินี้ทำให้สับสนระหว่างพารามิเตอร์การปรับเรียบของอินดิเคเตอร์กับหน้าต่างความจำที่มีขนาดตายตัว EMA ยังคงมีผลจากสถานะเริ่มต้นที่ค่อย ๆ ลดลง หาก EMA สองชุดเริ่มต้นต่างกัน 10 หน่วยราคา ราคาถัดจากนั้นที่เหมือนกันจะทำให้ความต่างลดลงดังนี้:

จำนวนการอัปเดตตั้งแต่เริ่มต้นความต่างที่เหลืออยู่สัดส่วนของค่าคลาดเคลื่อนเริ่มต้น
1001.35313.53%
2500.06740.674%
5000.0004540.00454%

คำนวณได้จาก 10 * (99 / 101)^k การดึงแท่งราคา 100 แท่งจะทำให้ได้เพียง 99 รอบการอัปเดต หากใช้ข้อมูลจุดแรกเป็นค่าเริ่มต้น

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

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

และประวัติก็ไม่ได้มีแค่อินดิเคเตอร์ เปอร์เซ็นไทล์แบบ rolling ต้องใช้หน้าต่างข้อมูลของมัน โมเดลออนไลน์อาจต้องใช้สถานะ optimizer กฎที่รอ 3 แท่งหลังขาดทุนก็ต้องจำทั้งการขาดทุนและตัวนับไว้

2. บันทึกสถานะโพซิชัน แต่ลืมคำสั่งที่ยังดำเนินการอยู่

โพซิชันเป้าหมายของคุณคือ 10 หน่วย มีคำสั่งซื้อ 10 หน่วยที่ดำเนินการแล้ว 4 หน่วย จึงเหลือค้างอยู่อีก 6 หน่วย คุณบันทึกจุดตรวจสอบโดยระบุโพซิชันเป็น 4 รีสตาร์ต แล้วส่งคำสั่งซื้ออีก 6 หน่วยที่ขาดไป

ถ้าคำสั่งส่วนที่เหลือเดิมและคำสั่งใหม่ดำเนินการครบทั้งคู่ คุณจะถือครอง 16 หน่วย

บั๊กแบบนี้ในแบ็กเทสต์มักซ่อนอยู่ เพราะการรีสตาร์ตระบบจับคู่คำสั่งโดยไม่แจ้งจะลบคำสั่งที่ยังทำงานอยู่ แต่ในการ paper trading ตัวจำลองหรือบริการภายนอกอาจยังเก็บคำสั่งเหล่านั้นไว้ โค้ดกู้คืนเดียวกันจึงทำให้ระดับความเสี่ยงต่างกัน ขึ้นอยู่กับว่าส่วนประกอบใดยังทำงานอยู่

เมื่อรีสตาร์ตสถานะจริงสิ่งที่การกู้คืนจากสถานะโพซิชันอย่างเดียวมองเห็น
โพซิชันเป้าหมาย1010
โพซิชันที่ดำเนินการแล้ว44
ปริมาณคำสั่งซื้อที่ยังค้าง60
ปริมาณที่ต้องซื้อเพิ่ม06

ผลเสียคือคำสั่งซื้อขายจำนวนมากที่อธิบายไม่ได้เกิดขึ้นทันทีหลังการกู้คืน บางครั้งทำให้ความเสี่ยงเพิ่มเป็นสองเท่า บางครั้งก็ปิดโพซิชันทั้งที่คำสั่งป้องกันความเสี่ยงยังทำงานอยู่ ทำให้คำสั่งนั้นเปิดโพซิชันใหม่ได้ในภายหลัง

จุดตรวจสอบต้องบันทึกข้อมูลระบุตัวตนและสถานะวงจรของคำสั่งควบคู่กับโพซิชัน ก่อนสร้างการดำเนินการใหม่ การกู้คืนต้องกระทบยอดระเบียนเหล่านั้นกับระบบดำเนินการซื้อขาย คำสั่งที่ยังไม่ทราบผลต้องตรวจสอบ การถือว่า “ไม่มีบันทึกการตอบรับ” แปลว่า “ไม่เคยส่งคำสั่ง” คือสาเหตุที่ทำให้เกิดคำสั่งซ้ำ

รหัสคำสั่งซื้อขายฝั่งไคลเอนต์ที่คงที่ช่วยให้ค้นหาได้ว่าเกิดอะไรขึ้น โดยจะป้องกันคำสั่งซ้ำได้ก็ต่อเมื่อระบบปลายทางบังคับใช้กฎความไม่ซ้ำหรือ idempotency ตามที่ต้องการจริง ๆ ด้วย บันทึกรหัสการดำเนินการซื้อขายที่ประมวลผลแล้วด้วย เพื่อไม่ให้การเล่นซ้ำของรายการจับคู่คำสั่งเพิ่มโพซิชันซ้ำสองครั้ง

ฉันชอบหน้าจอสถานะคำสั่งซื้อขายที่ดูธรรมดา ๆ เป็นพิเศษ พอถึงวันที่ต้องรีสตาร์ต แถวเล็ก ๆ เหล่านั้นกลับกลายเป็นอินเทอร์เฟซที่น่าสนใจที่สุดในอาคารขึ้นมาทันที

3. กู้คืนโพซิชัน แล้วเริ่มบัญชี P&L ใหม่

ลองดูตัวอย่างการซื้อขาย spot ที่ไม่ใช้เลเวอเรจและไม่มีค่าธรรมเนียม เริ่มด้วยเงินสด $10,000 ซื้อ 10 หน่วยที่ราคา $100 และบันทึกจุดตรวจสอบเมื่อราคาประเมินอยู่ที่ $110

สถานะที่ถูกต้องคือเงินสด $9,000 บวกกับโพซิชันมูลค่า $1,100 รวมเป็นมูลค่าพอร์ต $10,100 หากการกู้คืนคืนค่า 10 หน่วย แต่รีเซ็ตเงินสดกลับเป็น $10,000 เดิม ระบบจะแสดง $11,100 คุณสร้างเงิน $1,000 ขึ้นมาได้ด้วยการรีสตาร์ตโปรเซส

กรณีอื่นอาจไม่ชัดเจนเท่านี้ การกู้คืนรักษามูลค่าพอร์ตไว้ได้ แต่รีเซ็ตราคาเข้าซื้อเป็น $110 มูลค่าพอร์ตโดยรวมอาจยังถูกต้อง ขณะที่การแยกกำไรขาดทุนที่รับรู้แล้วกับที่ยังไม่รับรู้เปลี่ยนไป หากเงื่อนไข stop หรือ exit อ้างอิงราคาเข้าซื้อ ทางลัดด้านบัญชีนี้ก็เปลี่ยนพฤติกรรมการซื้อขายไปด้วย

หรือระบบอาจลืมจุดสูงสุดเดิมของมูลค่าพอร์ต สมมติว่ามูลค่าพอร์ตเคยขึ้นถึง $10,600 ก่อนลดลงมาเหลือ $10,100 ค่า drawdown อยู่ที่ประมาณ 4.72% หากรีเซ็ตจุดสูงสุดระหว่างการกู้คืน กลยุทธ์ก็จะคิดว่า drawdown เป็นศูนย์ทันที การควบคุมความเสี่ยงที่อิง drawdown จึงถูกรีเซ็ตโดยไม่ได้รับอนุญาต

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

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

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

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

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

สถานะกลยุทธ์แบ็กเทสต์การกู้คืนจากจุดตรวจสอบpaper trading
แชร์XLinkedInFacebookRedditHacker NewsWhatsAppTelegramEmail
← บทความทั้งหมด