ตัวเลข 4 ค่า วัดจากระบบ paper trading ของเราเองทั้งหมด กลยุทธ์เดียว สัญญาณ perpetual BTCUSDT ระดับ 1-minute เป็นเวลา 31 วัน กับคำสั่ง 1,418 รายการ เวลามัธยฐานตั้งแต่แท่งปิดจนตลาดแลกเปลี่ยนตอบรับคำสั่ง: 195 ms. เปอร์เซ็นไทล์ที่ 99: 2,970 ms. ค่ามัธยฐานใน 1% ของนาทีที่มีความผันผวนจริงสูงสุด: 840 ms. ส่วนค่าความหน่วงที่ตั้งไว้ในคอนฟิกแบ็กเทสต์ตลอดช่วงเกือบ 1 ปีก่อนหน้านั้น: 0.
ตัวเลข 3 ค่าแรกน่าเบื่อ ทุกคนรู้ว่าค่า 0 นั้นผิด และสุดท้ายก็เปลี่ยนเป็นค่าอื่น ซึ่งแทบทุกครั้งก็เป็นค่าคงที่ที่ใครสักคนเลือกเอาตามความรู้สึก 100 ms, 250 ms หรือ “เอาแบบเผื่อไว้ก่อน 500” ตัวเลขที่สำคัญจริง ๆ คือ 840 เพราะมันบอกว่าความหน่วงขึ้นอยู่กับสภาวะตลาด และช่วงตลาดที่ทำให้ความหน่วงพุ่งก็คือช่วงเดียวกับที่สัญญาณของคุณคิดว่าตัวเองเจอจังหวะทำกำไรแล้ว
195 มิลลิวินาทีใช้ไปกับอะไรบ้าง
นี่คืองบความหน่วงทั้งหมด วัดทีละขั้นด้วยเวลา monotonic clock ที่บันทึกไว้ทุกจุดที่ส่งต่อ เซิร์ฟเวอร์เป็นอินสแตนซ์ AWS ใน ap-northeast-1 ซึ่งเป็นรีเจียนเดียวกับ endpoint ของตลาด นับว่าใกล้เคียงที่สุดแล้วสำหรับการตั้งค่าของรายย่อยที่ไม่ได้วางเครื่องไว้ร่วมที่เดียวกับตลาด
| ขั้นตอน | p50 | p95 | p99 |
|---|---|---|---|
| แท่งปิด → ได้รับเหตุการณ์ WS kline-closed | 128 ms | 402 ms | 1,940 ms |
| แยกวิเคราะห์ + อัปเดตสถานะฟีเจอร์ | 3 ms | 9 ms | 28 ms |
| ตัดสินใจ: ประเมินโมเดล + ตรวจสอบความเสี่ยง | 11 ms | 22 ms | 60 ms |
| ส่งคำสั่ง → ตลาดตอบรับ | 47 ms | 180 ms | 1,100 ms |
| ตั้งแต่ต้นจนจบ (วัดจริง ไม่ใช่บวกตัวเลข) | 195 ms | 690 ms | 2,970 ms |
ก่อนถึงประเด็นสำคัญ มี 2 เรื่องที่ควรสังเกต ข้อแรก ค่ามัธยฐานบวกกันไม่ลงตัว: 128 + 3 + 11 + 47 = 189 แต่ค่ามัธยฐานที่วัดได้ตั้งแต่ต้นจนจบคือ 195 เปอร์เซ็นไทล์บวกกันไม่ได้ และถ้าคุณประเมินความหน่วงด้วยการบวกค่า p99 ของแต่ละขั้น ก็จะได้ 3,128 ms ทั้งที่ p99 จริงคือ 2,970 ใกล้เคียงพอใช้ในกรณีนี้ แต่อาจคลาดเคลื่อนมากเมื่อขั้นตอนต่าง ๆ มีความสัมพันธ์กันไปอีกทาง วัดเส้นทางทั้งหมด
ข้อสอง ดูแถวบนสุด สองในสามของงบความหน่วงมัธยฐานหมดไปกับการรอให้ตลาดแจ้งว่าแท่งปิดแล้ว ไม่ใช่เครือข่าย ไม่ใช่โค้ดของคุณ ไม่ใช่การส่งคำสั่ง ตลาดรวบรวมธุรกรรมเป็น kline ตัดสินใจว่าครบ 1 นาทีแล้ว แล้วจึงส่งข้อมูลออกมา ก่อนข้อมูลนั้นจะถูกส่งยังมีคิวรออยู่ และคิวนั้นใช้ร่วมกับผู้ติดตามรายอื่นทั้งหมดในสตรีมนั้น
ค่า 840
แบ่งคำสั่งทั้ง 1,418 รายการตามความผันผวนจริงของนาทีที่สร้างสัญญาณ แล้วการกระจายตัวก็เปลี่ยนไปอย่างชัดเจน
| กลุ่มความผันผวนของแท่งสัญญาณ | คำสั่ง | p50 ตั้งแต่ต้นจนจบ | p99 ตั้งแต่ต้นจนจบ |
|---|---|---|---|
| ควอร์ไทล์ล่างสุด | 201 | 141 ms | 488 ms |
| 2 ควอร์ไทล์ตรงกลาง | 796 | 183 ms | 1,210 ms |
| ควอร์ไทล์บนสุด | 407 | 312 ms | 2,880 ms |
| 1% ของนาทีทั้งหมดที่มีความผันผวนสูงสุด | 14 | 840 ms | 4,100 ms |
ทุกขั้นตอนช้าลงพร้อมกัน จึงทบกันหนักขึ้น คิวรวบรวมและกระจายข้อมูลของตลาดได้รับผลจากโหลดของ matching engine ดังนั้นนาทีที่มีธุรกรรม 11,000 รายการจะส่งข้อมูลช้ากว่านาทีที่มี 600 รายการ โปรเซสของคุณเองก็ต้องจัดการ depth update และ trade print มากขึ้นในช่วงเวลาเดียวกัน การอัปเดตฟีเจอร์ที่ปกติใช้ 3 ms จึงกลายเป็น 28 ส่วนเส้นทางคำสั่ง REST ต้องแย่งทรัพยากรกับคำสั่งตื่นตระหนกของคนอื่น ๆ และบางครั้งก็เจอ 503 แล้วลองใหม่ ซึ่งทำให้เสียเวลาไปเต็ม ๆ 1 วินาที ค่าสัมประสิทธิ์สหสัมพันธ์ระหว่างจำนวนธุรกรรมในแท่งสัญญาณกับความหน่วงตั้งแต่ต้นจนจบในชุดข้อมูลของเราอยู่ที่ 0.41 ไม่ได้สูงมาก แต่ก็พอทำให้ค่าคงที่ใช้ไม่ได้
กลยุทธ์ที่ผ่านการคัดกรองรอบแรกมักเป็นกลยุทธ์ที่เทรดเมื่อเกิด breakout, reversal, dislocation หรือ liquidation cascade กลยุทธ์เหล่านี้ส่งสัญญาณพอดีในกลุ่มที่ความหน่วงแย่ที่สุด สัญญาณโมเมนตัมที่ทำงานเฉพาะเมื่อนาทีหนึ่งเคลื่อนไหว 40 bps คือสัญญาณที่ถูกกำหนดโครงสร้างมาให้ใช้ระบบในจังหวะที่ช้าที่สุดเสมอ
ครั้งหนึ่งเราใช้เวลาทั้งวันตามหาสาเหตุของค่าผิดปกติ 3.6 วินาทีที่เกิดขึ้นเวลาใกล้เคียงกันทุกคืน สุดท้ายพบว่าเป็น logrotate ที่คัดลอกแล้วตัดไฟล์ขนาด 2 GB บน EBS volume เดียวกับที่โปรเซสกำลังเขียนข้อมูลอยู่ จน event loop หยุดชะงัก ตลาดไม่ได้ทำอะไรผิด วัดก่อนแล้วค่อยโทษ microstructure
ผลต่อการจับคู่คำสั่ง
ราคาระหว่างที่คุณรอมีการขยับ ในนาทีทั่วไป การเคลื่อนไหวของราคาที่สวนทางกับสัญญาณโดยเฉลี่ยตลอดช่วงค่ามัธยฐาน 195 ms อยู่ที่ประมาณ 1.1 bps ส่วนนาทีในควอร์ไทล์บนสุดที่ 312 ms อยู่ที่ 5.8 bps และนาทีในกลุ่มบนสุด 1% ที่ 840 ms ราคาขยับสวนทางไปราว 14 bps ก่อนที่คำสั่งจะถึง order book ด้วยซ้ำ
สำหรับ BTC perps สเปรดแทบไม่มีผลในเรื่องนี้: 1 tick บนราคา 84,000 คิดเป็น 0.012 bps ดังนั้นความเสียหายจึงมาจากราคาที่ขยับสวนทาง ไม่ใช่ต้นทุนจากการข้ามสเปรด แต่ถ้าย้ายกลยุทธ์เดียวกันไปใช้กับ perp ของเหรียญมิดแคป ปัจจัยที่สองก็เริ่มมีผล สเปรด top-of-book ในชุดข้อมูลของเราเพิ่มจาก 1.4 bps ในนาทีที่ตลาดสงบเป็น 6.2 bps ในควอร์ไทล์บนสุด และความลึกที่ระดับราคานั้นลดลงมากกว่าครึ่ง คุณเสียทั้งจากราคาที่ขยับสวนทาง สเปรดที่กว้างขึ้น และความลึกที่ลดลงพร้อมกัน เพราะทั้งหมดมีสาเหตุร่วมกัน
เมื่อเราจำลองย้อนหลัง 31 วันเดียวกันโดยใช้ความหน่วงแบบมีเงื่อนไขแยกตามแท่ง แทนค่าคงที่ 200 ms ราคาเข้าเฉลี่ยในแบ็กเทสต์แย่ลง 3.1 bps โดยแทบทั้งหมดกระจุกอยู่ใน 9% ของการเทรด ความคลาดเคลื่อนของราคาเข้าระหว่างแบ็กเทสต์กับ paper trading ลดจาก 4.2 bps เหลือ 0.9 bps ค่า Sharpe ใน IS ของกลยุทธ์นั้นลดจาก 1.7 เหลือ 1.1 ซึ่งเป็นตัวเลขตามจริง และเป็นเช่นนั้นมาตลอด
แล้วควรใส่อะไรไว้ในคอนฟิก
ไม่ใช่ค่าตัวเลขเดี่ยว ๆ สิ่งที่เราใช้อยู่ตอนนี้คือ:
- สุ่มตัวอย่าง อย่ากำหนดค่า. สุ่มค่าความหน่วงของแต่ละคำสั่งจำลองจากการกระจายเชิงประจักษ์ โดยกำหนดเงื่อนไขตามกิจกรรมของแท่งนั้นเอง แค่จำนวนธุรกรรมกับผลตอบแทนสัมบูรณ์ก็เพียงพอ และทั้งคู่มีอยู่แล้วใน kline มาตรฐาน ปรับแบบจำลองครั้งละ 1 ตลาดต่อ 1 ประเภทคำสั่ง แล้วปรับใหม่ทุกเดือน
- เก็บส่วนหางของการกระจายไว้. อย่าฟิต lognormal แล้วคิดว่าจบ เพราะค่า p99 มาจากเหตุการณ์ retry storm และ GC pause ซึ่งการกระจายแบบเรียบไม่สามารถจำลองได้ เราใช้ควอนไทล์เชิงประจักษ์ พร้อมสุ่มตัวอย่างใหม่จากส่วนหางที่เกิน p95
- ความหน่วงมีผลกับการยกเลิกคำสั่งด้วย. การเปลี่ยน stop หรือการยกเลิก hedge ก็เจอความล่าช้าแบบเดียวกัน และในตลาดที่เคลื่อนไหวเร็ว คำสั่งยกเลิกของคุณกำลังแข่งกับการจับคู่ หากตัวจำลองยกเลิกได้ทันที แบบจำลองความเสี่ยงของคุณก็ไม่ตรงกับความจริง
- เพิ่มเงื่อนไขตรวจสอบความล้าสมัยแล้วจำลองตามจริง. เราทิ้งทุกสัญญาณที่แท่งมีอายุเกิน 1.5 วินาทีเมื่อมาถึง นี่คือพฤติกรรมจริงที่มีต้นทุนจริง เพราะมันตัดการเทรดออกไปโดยไม่แจ้งให้เห็น และแบ็กเทสต์ก็ต้องตัดรายการเดียวกันออกด้วย
- ปรับเทียบกับ paper trading. paper trading คือที่ที่คุณได้ข้อมูลจริง บันทึกเวลา 4 จุดที่ส่งต่อในทุกคำสั่ง แล้วเปรียบเทียบการกระจายกับสมมติฐานของตัวจำลองทุกสัปดาห์
สินทรัพย์ประเภทอื่นก็มีปัญหาเดียวกัน. หุ้นสหรัฐฯ: consolidated tape เพิ่มความล่าช้าจากการรวบรวมข้อมูลเข้ามาอีกชั้น นอกเหนือจากโบรกเกอร์ และความล่าช้าจะเพิ่มขึ้นเมื่ออัตราข้อความกดดันระบบ ด้วยเหตุผลเชิงโครงสร้างแบบเดียวกัน ตลาดพยากรณ์: ตลาดส่วนใหญ่รับคำสั่งผ่าน REST เท่านั้น และเราวัดค่ามัธยฐานได้ต่ำกว่า 100 ms แต่เพิ่มเป็นหลายวินาทีเมื่อเกิดเหตุการณ์ตัดสินผลและทุกคนส่งคำสั่งเข้ามาพร้อมกัน ออปชันคริปโท: ราคาอ้างอิงที่คุณใช้ตั้งราคาอาจล้าหลังไป 2 วินาที ในจังหวะที่สินทรัพย์อ้างอิงเพิ่งเคลื่อนไหวพอดี
แก่นของความผิดพลาดคือการมองพารามิเตอร์ด้านการส่งคำสั่งเป็นค่าคงที่อิสระ ทั้งที่จริงแล้วมันขึ้นอยู่กับตัวแปรสภาวะเดียวกับที่ขับเคลื่อนสัญญาณของคุณ ค่าธรรมเนียมมีพฤติกรรมค่อนข้างคงที่ funding ก็เช่นกัน แต่ความหน่วงไม่ใช่ หากจะจำตัวเลขเดียวจากทั้งหมดนี้ ให้จำอัตราส่วน: p99 ของเราสูงกว่าค่ามัธยฐาน 15 เท่า และสัญญาณของเรามักมาถึงในช่วงใกล้ p99 มากเป็นพิเศษ
ไปใส่เครื่องมือวัดเวลาให้ครบทั้ง 4 จุด ใช้เวลาทำแค่ครึ่งวัน แต่จะบอกอะไรเกี่ยวกับกลยุทธ์ของคุณได้มากกว่าการค้นหาพารามิเตอร์อีก 1 สัปดาห์
← บทความทั้งหมด


