หกสัปดาห์หลังจากที่เรารันการทดสอบย้อนหลัง เรารันอีกครั้งด้วยโค้ด การตั้งค่า และช่วงวันที่เดิม มูลค่าพอร์ตตอนสิ้นสุดไม่เท่ากัน ความต่างไม่ได้มากมาย แต่ก็มากพอที่จะทำให้ Sharpe เปลี่ยนจาก 1.31 เป็น 1.08 และทำให้ชุดพารามิเตอร์ที่ดูดีที่สุดเปลี่ยนไปด้วย
กลยุทธ์ไม่ได้เปลี่ยน แต่ข้อมูลย้อนหลังเปลี่ยน ผู้ให้บริการปรับแก้ข้อมูลการซื้อขายและแท่งราคาหลายวัน ส่วนการรันครั้งแรกของเราไม่ได้เก็บสแนปช็อตอินพุตที่ตรงกันทุกประการไว้ เราใช้เวลาสองสามวันถัดมาหาคำตอบว่าผลลัพธ์ใหม่เกิดจากการแก้ข้อมูล บั๊กในไปป์ไลน์ หรือกระบวนการวิจัยที่เราไม่สามารถทำซ้ำได้
วันจันทร์: ผลรันซ้ำไม่ตรงกัน
เบาะแสแรกคือช่องว่างเล็กน้อยในคู่สปอตที่มีสภาพคล่องสูง แท่งราคาเดิมของเรามีราคาสูงสุดที่ 62,418 แต่ผลรันซ้ำแสดง 62,431 ความต่างนี้ดูเหมือนไม่มีนัยสำคัญ จนกระทั่งเราตามรอยจุดเข้าออเดอร์ของกลยุทธ์ พบว่าระดับเกณฑ์อยู่ระหว่างราคาทั้งสอง แท่งราคาที่เปลี่ยนไปเพียงไม่กี่แท่งทำให้สัญญาณเปลี่ยน แล้วตำแหน่งการลงทุนในอีกหลายวันต่อมาก็เปลี่ยนตาม
เราเปรียบเทียบจำนวนรายการซื้อขายรายวัน แล้วพบว่าความไม่ตรงกันเริ่มขึ้นในวันเดียว จากนั้นเราเทียบแถวข้อมูลดิบที่ใช้สร้างข้อมูลของวันนั้น คำตอบปัจจุบันจากผู้ให้บริการมีรายการซื้อขายที่แก้ไขแล้วอยู่จำนวนหนึ่ง และมีแท่งราคารวมที่ปรับแก้ใหม่ ไม่มีบันทึกการเปลี่ยนแปลงแนบมากับคำตอบที่เราเคยใช้
ข้อมูลเปลี่ยนแปลงเช่นนี้เป็นเรื่องปกติ ตลาดซื้อขายแก้ไขระเบียน ผู้ให้บริการเติมข้อมูลที่ขาด แก้รายการราคาที่ผิดพลาด และปรับวิธีรวมข้อมูล คำขอ “ข้อมูลเดือนมกราคม” อาจให้ผลลัพธ์ต่างกันในเดือนมีนาคม
วันอังคาร: เราพบหลักฐานที่ขาดหาย
เราเก็บชื่อผู้ให้บริการ สัญลักษณ์ และช่วงวันที่ไว้ในระเบียนการรัน แต่ไม่ได้เก็บคำตอบที่ได้รับหรือแฮชเนื้อหาของแต่ละพาร์ทิชันอินพุตไว้ นั่นหมายความว่าเราพิสูจน์ได้ว่าเราขออะไรไป แต่พิสูจน์ไม่ได้ว่าผู้ให้บริการส่งไบต์ใดกลับมา
เราดึงไฟล์แคชเก่าที่สุดเท่าที่หาได้มาเปรียบเทียบกับคำตอบปัจจุบัน ความต่างไม่ได้เกิดจากการปรับตามการแตกพาร์หรือการแปลงเขตเวลา แต่เป็นชุดระเบียนการซื้อขายที่แก้ไขแล้วจำนวนเล็กน้อย ซึ่งส่งผลต่อข้อมูลที่ตัวสร้างแท่งราคาสร้างขึ้น สิ่งนี้ตัดข้อสันนิษฐานหนึ่งข้อออกไป แต่แคชไม่ครบถ้วน เราจึงยังสร้างแท่งราคาที่ได้รับผลกระทบทั้งหมดกลับมาให้ตรงกันทุกประการไม่ได้
| สิ่งที่เราบันทึก | คำถามที่ข้อมูลนั้นช่วยตอบได้ | สิ่งที่ขาดหาย |
|---|---|---|
| ผู้ให้บริการ, สัญลักษณ์, ช่วงวันที่ | คำขอที่การรันส่งไป | เนื้อหาคำตอบ |
| เวอร์ชันไปป์ไลน์ | โค้ดชุดใดสร้างแท่งราคา | แถวอินพุตที่แน่นอน |
| เวลาที่รัน | เรารันงานเมื่อใด | มีการแก้ข้อมูลของผู้ให้บริการเวอร์ชันใดอยู่ในขณะนั้น |
เราคิดว่า “คำขอเดิม” หมายถึง “ข้อมูลเดิม” สมมติฐานนั้นทำให้การทดลองดูเหมือนทำซ้ำได้มากกว่าความเป็นจริง
วันพุธ: การแก้ข้อมูลเปลี่ยนข้อสรุป
เรารันข้อมูลของวันที่ได้รับผลกระทบใหม่ โดยใช้ข้อมูลที่มีอยู่ทั้งสองเวอร์ชัน แท่งราคาที่ปรับแก้ใหม่ทำให้จุดเข้าหายไป 2 จุด และเลื่อนจุดออก 1 แท่ง การซื้อขายทั้ง 3 รายการนี้อธิบายความเปลี่ยนแปลงของ Sharpe ได้เกือบทั้งหมด กลยุทธ์อ่อนไหวต่อข้อมูลบางจุดที่อยู่ใกล้ระดับกระตุ้น แม้เมื่อดูบนกราฟแล้ว อนุกรมราคาภาพรวมแทบไม่ต่างกัน
ไม่ได้หมายความว่าผลลัพธ์เดิมเป็นการฉ้อฉล หรือผลลัพธ์ที่แก้แล้วดีกว่าโดยอัตโนมัติ แต่หมายความว่าเราต้องระบุขอบเขตของข้อสรุปให้ชัดเจน: ผลรันเดิมอธิบายสแนปช็อตข้อมูลที่เรามีในขณะนั้น ส่วนผลรันซ้ำอธิบายข้อมูลย้อนหลังฉบับปัจจุบันของผู้ให้บริการ เราไม่อาจเรียกผลหนึ่งว่าเป็นการทำซ้ำอีกผลหนึ่งได้อย่างตรงไปตรงมา
วันพฤหัสบดี: เราปรับปรุงบันทึกการวิจัย
เราเพิ่มสแนปช็อตอินพุตที่แก้ไขไม่ได้ให้กับการรันงานวิจัยครั้งใหม่ แต่ละพาร์ทิชันจะมีแฮชเนื้อหา และรายการกำกับการรันจะบันทึกแหล่งที่มา เวลาดึงข้อมูล เวอร์ชันสคีมา นโยบายการปรับแก้ และเวอร์ชันโค้ดแปลงข้อมูล สำหรับชุดข้อมูลขนาดใหญ่ เราเก็บไฟล์จริงไว้ในพื้นที่จัดเก็บที่อ้างอิงด้วยเนื้อหา ทำให้ใช้พาร์ทิชันที่เหมือนกันร่วมกันได้โดยไม่เขียนทับเวอร์ชันก่อนหน้า
เมื่อข้อกำหนดด้านพื้นที่จัดเก็บหรือใบอนุญาตห้ามเราเก็บข้อมูลดิบไว้ เราจะเก็บหลักฐานที่ครบถ้วนที่สุดเท่าที่เงื่อนไขอนุญาต ได้แก่ แฮช พารามิเตอร์คำขอ ตัวระบุเวอร์ชันของแหล่งข้อมูล และตัวอย่างแถวที่แยกวิเคราะห์แล้วจำนวนเล็กน้อยเพื่อใช้วินิจฉัย แฮชกู้ข้อมูลกลับมาไม่ได้ แต่บอกเราได้ว่าการรันสองครั้งใช้ไบต์ชุดเดียวกันหรือไม่
การทดสอบย้อนหลังที่ทำซ้ำได้ต้องมีตัวระบุอินพุต ไม่ใช่แค่ URL ของข้อมูล ให้บันทึกสิ่งที่ได้รับ เวลาที่ได้รับ และวิธีที่ข้อมูลกลายเป็นแถวที่กลยุทธ์ของคุณนำไปใช้
วันศุกร์: สิ่งที่เราจะข้ามไปในครั้งหน้า
เราจะไม่ดูแค่ตัวชี้วัดสรุปผล Sharpe ที่เปลี่ยนไปบอกว่ามีบางอย่างเปลี่ยน แต่ไม่ได้ระบุสาเหตุ ให้เริ่มจากจำนวนแถวและแฮชของพาร์ทิชัน แล้วหาวันแรกที่อินพุตต่างกัน จากนั้นจึงเปรียบเทียบแถวหลังการแปลง สัญญาณ คำสั่งซื้อขาย และรายการจับคู่คำสั่ง ตามลำดับ
เราจะไม่แทนที่ข้อมูลเก่าด้วยข้อมูลย้อนหลังที่แก้ไขแล้วโดยไม่แจ้งให้ทราบ การแก้ข้อมูลมีประโยชน์ แต่ผลรันเก่าควรยังคงผูกกับอินพุตเดิม ชุดข้อมูลใหม่ควรสร้างผลรันใหม่ พร้อมระบุความเชื่อมโยงกับผลรันก่อนหน้าให้เห็นชัดเจน
ตอนนี้กฎที่เราใช้จริงเรียบง่าย: หากการรันซ้ำมีเป้าหมายเพื่อทำซ้ำการทดลอง ให้ตรึงสแนปช็อตข้อมูลไว้ หากต้องการใช้ประโยชน์จากข้อมูลย้อนหลังที่แก้ไขแล้ว ให้ระบุว่าเป็นการทดลองใหม่ เราใช้เวลาสองสามวันกว่าจะเข้าใจความแตกต่างนี้ แต่บันทึกไว้ในรายการกำกับการรันเพียงบรรทัดเดียว
← บทความทั้งหมด


