ภายในสไลซ์: กลยุทธ์ child order ระหว่างสเกดูลเลอร์กับตลาด
วิถีการเทรดแบบ Almgren-Chriss ให้ตัวเลขมาตัวหนึ่ง เช่น ขาย BTC 4.2 เหรียญในห้านาทีข้างหน้า ตารางเวลาแบบ VWAP ก็ให้ตัวเลขทำนองเดียวกันแต่ด้วยเหตุผลต่างออกไป ทั้งสองอย่างไม่ได้บอกอะไรเลยว่าจากนั้นจะเกิดอะไรขึ้น — BTC 4.2 เหรียญนั้นจะเข้าสู่ order book เป็นคำสั่งเดียวที่พร้อมจับคู่ทันที หรือจะตั้งรออยู่ที่ touch เพื่อเก็บค่าธรรมเนียม maker หรือจะซ่อนตัวอยู่หลัง display size 0.3 BTC หรือจะถูกรีไพรซ์สิบเอ็ดครั้งเพื่อไล่ตามราคาที่กำลังเคลื่อนตัว การตัดสินใจในชั้นที่สองนี้คือชั้นกลยุทธ์ (tactics layer) และในตลาดคริปโตที่ค่าธรรมเนียมมีน้ำหนักสูง มันมักจะขยับ PnL ต่อสไลซ์ได้มากกว่าการเลือกสเกดูลเลอร์ที่อยู่เหนือมันเสียอีก งบต่อช่วงเวลาของ TWAP กับ Almgren-Chriss ที่ปรับจูนมาอย่างดีต่างกันแค่ไม่กี่ bps ของ impact ตลอดทั้ง parent order แต่การจ่ายค่าธรรมเนียม taker สำหรับสไลซ์ที่คุณควรจะ make ได้ หรือการเสียตำแหน่งในคิวจากการรีไพรซ์อย่างไม่ระมัดระวัง สามารถสร้างความเสียหายมากขนาดนั้นได้ต่อชั่วโมง บทความนี้พูดถึงชั้นที่ทุกคนใช้งานอยู่จริงแต่แทบไม่มีใครเขียนบันทึกไว้ นั่นคือสเตทแมชชีนที่ตัดสินว่า child order แต่ละตัวจะสัมผัส order book อย่างไร
สองชั้น หนึ่งอินเทอร์เฟซที่แคบ
Lehalle และ Laruelle ใน Market Microstructure in Practice (พิมพ์ครั้งที่ 2, 2018) ได้จัดระบบสิ่งที่ทุกโต๊ะเอ็กซีคิวชันมาบรรจบกัน นั่นคือ ชั้นกลยุทธ์ระดับสูง (สเกดูลเลอร์) ที่จัดสรรปริมาณตามเวลา และ ชั้นกลยุทธ์เชิงปฏิบัติ (microtrader) ที่ทำงานกับแต่ละการจัดสรรบน order book จริง การแยกกันนี้ไม่ใช่เรื่องความสวยงาม — ทั้งสองชั้นอยู่บนนาฬิกาคนละเรือนและข้อมูลคนละชุด สเกดูลเลอร์คิดเป็นหน่วยนาที ใช้การพยากรณ์ความผันผวนและปริมาณการซื้อขาย และแก้ปัญหาเชิงแปรผัน ส่วนชั้นกลยุทธ์คิดเป็นหน่วยมิลลิวินาทีถึงวินาที ใช้ L2 delta และการประมาณตำแหน่งในคิว และแก้ลำดับของปัญหาการหยุด (stopping problem) ขนาดเล็กจำนวนมาก

อินเทอร์เฟซระหว่างสองชั้นนี้ควรจะแคบ ในทิศทางลง สำหรับแต่ละสไลซ์ :
- งบ (budget) — ปริมาณที่ต้องเอ็กซีคิวต์ในช่วงเวลานี้ (คือ ของ Almgren-Chriss หรือส่วนเพิ่มของ volume curve ใน VWAP);
- หน้าต่างเวลา (window) — ความยาวของสไลซ์;
- ความเร่งด่วน (urgency) — สำหรับ Almgren-Chriss ตัวเลือกตามธรรมชาติคือ ซึ่งได้บีบอัดความเกลียดชังความเสี่ยง ความผันผวน และสภาพคล่องไว้ในอัตราเดียว ส่วนสเกดูลเลอร์แบบ VWAP มักใช้ระยะห่างจากแบนด์ ("เราตามหลังเส้นเป้าหมายอยู่ 1.8%")
ในทิศทางขึ้น: ฟิลล์พร้อมไทม์สแตมป์และค่าธรรมเนียม ส่วนที่ยังไม่ฟิลล์ และ implementation shortfall ระดับสไลซ์ที่วัดเทียบกับ mid ณ จุดเริ่มต้นของช่วงเวลานั้น ข้อสุดท้ายนี้สำคัญมาก เพราะพารามิเตอร์ impact ของสเกดูลเลอร์ได้ตั้งราคาไว้แล้วว่าการเรียกร้องสภาพคล่องที่อัตรา ควร มีต้นทุนเท่าไหร่ หน้าที่ทั้งหมดของชั้นกลยุทธ์สรุปได้บรรทัดเดียว ทำให้ฟิลล์ได้ต้นทุนดีกว่าที่โมเดล บอกไว้ โดยไม่รั่วไหลการมีอยู่ของ parent order ถ้า shortfall ระดับสไลซ์ที่วัดได้เอาชนะต้นทุนตามโมเดลได้อย่างสม่ำเสมอ ค่า ที่ปรับเทียบไว้ก็ลดลงได้ สเกดูลเลอร์จะเร็วขึ้น และทั้งระบบก็ดีขึ้น แต่ถ้าคุณวัด shortfall ของสไลซ์แยกจากต้นทุนของตารางเวลาไม่ได้ คุณก็จูนทั้งสองชั้นไม่ได้เลย — คุณมีตัวเลขเบลอๆ ตัวเดียวกับปุ่มปรับสองปุ่ม
นโยบายจัดการส่วนที่เหลือก็เป็นส่วนหนึ่งของสัญญานี้เช่นกัน เมื่อสไลซ์จบลงโดยยังมีปริมาณที่ไม่ฟิลล์ ชั้นกลยุทธ์จะต้องเลือกอย่างใดอย่างหนึ่ง คือบังคับให้เสร็จสิ้น (cross ส่วนที่เหลือ — ค่าเริ่มต้นภายใต้ความเร่งด่วนของ deadline) หรือส่งคืนให้สเกดูลเลอร์เพื่อกระจายใหม่ในสไลซ์ที่เหลือ (ยอมรับได้ในช่วงต้นของตารางเวลาที่มี ต่ำ แต่เป็นพิษเมื่อใกล้ deadline ที่การกระจายใหม่จะสะสมเงียบๆ จนกลายเป็นสไลซ์สุดท้ายขนาดมหึมา)
บันไดไต่ระดับความเร่งด่วน: passive ก่อน แล้วค่อยรุกเมื่อใกล้ deadline
ผลลัพธ์เก่าแก่ที่สุดในสาขานี้คือ Harris (1998), "Optimal dynamic order submission strategies in some stylized trading problems" (Financial Markets, Institutions & Instruments 7(2)): สำหรับเทรดเดอร์ที่ต้องการสภาพคล่องและต้องทำการเทรดให้เสร็จภายใน deadline กลยุทธ์ที่เหมาะสมคือแบบไดนามิก — ตั้ง limit order ค้างไว้ใน book ตราบใดที่เวลายังมีราคาถูก แล้วรีไพรซ์เข้าใกล้ตลาดมากขึ้นเมื่อ deadline ใกล้เข้ามา และ cross ในตอนท้าย ทุกเอนจินกลยุทธ์ที่ใช้งานจริงล้วนสืบทอดรูปแบบนี้ ตั้งที่ touch แล้วปล่อยให้อายุมากขึ้น ไต่ระดับ แล้วค่อย cross สิ่งที่ตารางค่าธรรมเนียมสมัยใหม่และพลวัตของคิวเพิ่มเข้ามาคือเลขคณิตที่บอกว่าแต่ละการเปลี่ยนผ่านนี้ควรเกิดขึ้น เมื่อไหร่ กันแน่
จุดคุ้มทุนของการ cross
พิจารณาต่อหน่วย ราคาสัมพัทธ์กับ mid ปัจจุบัน สำหรับการซื้อ การ cross ทันทีมีต้นทุนเท่ากับครึ่งหนึ่งของสเปรดบวกค่าธรรมเนียม taker:
การตั้งที่ bid ในหน้าต่างเวลา จะฟิลล์ด้วยความน่าจะเป็น หากฟิลล์ คุณจะได้ครึ่งสเปรดและจ่ายค่าธรรมเนียม maker (ติดลบหากเป็น rebate) หากไม่ฟิลล์ คุณต้อง cross เมื่อจบหน้าต่างเวลา หลังจากราคาเคลื่อนตัวสวนทางคุณโดยเฉลี่ยไปแล้ว — ค่านี้เป็นบวกเสมอ เพราะการไม่ฟิลล์กับการเคลื่อนไหวที่สวนทางคือเหตุการณ์เดียวกัน bid ของคุณไม่โดนกินเมื่อตลาดยกตัวหนีไปจากมัน ต้นทุนคาดหวังของการตั้ง post:
การ post จะดีกว่าการ cross ก็ต่อเมื่อ
โดยที่ คือ รางวัล (prize) — ผลตอบแทนแบบ round-trip เต็มรูปแบบที่คุณจะได้จากการ make แทนที่จะ take ได้แก่สเปรดบวกส่วนต่างของค่าธรรมเนียม นี่คือจุดคุ้มทุนเดียวกับที่ควบคุมเศรษฐศาสตร์ของ maker-taker ในการเอ็กซีคิวชันทั้งหมด เพียงแต่ถูกบีบให้เหลือเฉพาะสไลซ์เดียว
ตัวเลขตัวอย่าง สำหรับ BTCUSDT perp: mid $100,000 สเปรดหนึ่งติ๊ก s = \0.10f_m = $20f_t = $50\Pi = 0.10 + 50 - 20 = $30.10 \approx 3\sigma_{\text{day}} = $3{,}000\delta(\tau) \approx 0.6,\sigma_{\text{day}}\sqrt{\tau/86400}$ (ค่า 0.6 คือส่วนลดจาก adverse selection ที่คุณควรปรับเทียบเอง ไม่ใช่เชื่อตามนี้เลย):
- วินาที: \delta \approx \19p^* = 19/49 \approx 0.39$ ควร post ก็ต่อเมื่อคุณคาดว่าจะฟิลล์อย่างน้อย 39% ภายใน 10 วินาที
- วินาที: \delta \approx \47p^* = 47/77 \approx 0.61$
- หากมี maker rebate 1 bp แทนที่จะเป็นค่าธรรมเนียม 2 bp (f_m = -\10\Pi = $60.10p^* \approx 0.24$
มีข้อเท็จจริงเชิงโครงสร้างสองข้อที่ตามมา ข้อแรก โตแบบ ในขณะที่ คงที่ ดังนั้น — ความอดทนมีวันหมดอายุที่แน่นอน และตัวจับเวลา age-out ไม่ใช่ heuristic แต่คือจุดตัดของสองเส้นโค้ง คือ ที่คุณประมาณไว้ (เว้าและอิ่มตัวเมื่อคิวข้างหน้าคุณระบายออก) เทียบกับ (ที่เพิ่มขึ้นเรื่อยๆ) ข้อที่สอง ระดับค่าธรรมเนียมที่คุณเทรดด้วยส่งผลกระทบต่อบันไดนี้โดยตรง การอัปเกรดระดับที่ลดค่าธรรมเนียม taker จะทำให้กลยุทธ์ที่เหมาะสมของคุณ รุกมากขึ้น — เป็นความเชื่อมโยงที่คนส่วนใหญ่ค้นพบก็ต่อเมื่อสถิติการฟิลล์ของพวกเขาเปลี่ยนไปหลังจากได้ re-tier VIP
Cont และ Kukanov, "Optimal order placement in limit order markets" (Quantitative Finance 17(1), 2017; arXiv 2012), ได้พิสูจน์เรื่องนี้อย่างเข้มงวดในช่วงเวลาเดียว โดยลดต้นทุนคาดหวังของการเอ็กซีคิวต์ หน่วยที่แบ่งระหว่าง market order และ limit order (ในหนึ่งหรือหลาย venue) พร้อมบทลงโทษสำหรับ shortfall คำตอบสำหรับ venue เดียวเป็นแบบชัดเจนและมีโครงสร้างแบบ newsvendor คือขนาด limit order ที่เหมาะสมถูกกำหนดโดยการกระจายตัวของ queue outflow — ตั้งขนาดใหญ่อย่างรุกเมื่อคิวข้างหน้ามีขนาดเล็กเทียบกับอัตราการระบายที่คาดไว้ และคุ้มครองความเสี่ยง tail ด้วย market order ส่วนขยายแบบหลาย venue ของพวกเขาแก้ด้วย stochastic approximation และเป็นแกนกลางทางความคิดของตรรกะการจัดสรร passive ในทุก smart order router การอ่านในเชิงปฏิบัติสำหรับเอนจินกลยุทธ์คือ ค่า ในสมการจุดคุ้มทุนข้างต้นไม่ใช่ค่าคงที่ แต่เป็นฟังก์ชันของตำแหน่งในคิวและอัตราการระบาย ซึ่งเป็นเหตุผลว่าทำไมชั้นกลยุทธ์ต้องรับตัวประมาณตำแหน่งในคิวเป็นอินพุตระดับหนึ่ง

พารามิเตอร์ความเร่งด่วนบีบอัดบันไดทั้งหมดนี้เข้าด้วยกัน ค่า สูงจากสเกดูลเลอร์หมายความว่าเวลาลักษณะเฉพาะ สั้น หน้าต่างเวลาหดตัว สูงขึ้น และเอนจินจะข้ามไป cross ทันที — ซึ่งถูกต้อง เพราะสเกดูลเลอร์ได้ประกาศไว้แล้วว่าความเสี่ยงจาก inventory มีน้ำหนักเหนือกว่าการประหยัดค่าธรรมเนียม ค่า ต่ำจะยืดช่วง passive ออกไป ชั้นกลยุทธ์ไม่ควรคำนวณความเร่งด่วนขึ้นใหม่จากมุมมองของตัวเองต่อตลาด นั่นเป็นหน้าที่ของสเกดูลเลอร์ และการทำซ้ำจะสร้างตัวควบคุมสองตัวที่ขัดแย้งกัน
รีไพรซ์โดยไม่เผาตำแหน่งในคิวทิ้ง
เมื่อตั้งไว้แล้ว ราคาก็จะเคลื่อนตัว การไล่ตามแบบไม่คิดหน้าคิดหลัง — cancel, ตั้งใหม่ที่ touch ใหม่, ทำซ้ำ — คือวิธีที่เอนจินกลยุทธ์ทำลายความน่าจะเป็นในการฟิลล์ที่เป็นเหตุผลของการ post ตั้งแต่แรกไปอย่างเงียบๆ ตำแหน่งในคิวเป็นสินทรัพย์ที่มีมูลค่าเป็นเงินซึ่งวัดได้ (Moallemi และ Yuan, 2016 ได้ตั้งราคาให้กับมัน ตำแหน่งหน้าคิวใน FIFO book ที่มีสภาพคล่องสูงมีมูลค่าเป็นสัดส่วนที่มีนัยสำคัญของสเปรด) และการตัดสินใจรีไพรซ์ทุกครั้งคือการเทรดครั้งหนึ่ง คือขายตำแหน่งในคิวปัจจุบันของคุณ แล้วซื้อตำแหน่งท้ายคิวที่ระดับราคาอื่น การเทรดนี้คุ้มค่าก็ต่อเมื่อมูลค่าของระดับใหม่มากกว่ามูลค่าของระดับเดิมบวกต้นทุนการส่งข้อความ ซึ่งต้องรู้ว่าการ amend ของแต่ละ venue ส่งผลต่อตำแหน่งของคุณในคิวจริงๆ อย่างไร — และคำตอบนั้นแตกต่างกันอย่างมาก
CME Globex มีเอกสารกำหนดความหมายที่ชัดเจนที่สุด การลดปริมาณคำสั่งยังคงรักษาความสำคัญตามเวลา (time priority) ไว้ ส่วนการเพิ่มปริมาณหรือเปลี่ยนราคาจะส่งคุณไปท้ายคิว นี่คือโมเดลอ้างอิง — การลดปริมาณคือฟรี ส่วนอย่างอื่นทั้งหมดคือการเข้าคิวใหม่
Binance spot ในอดีตมีเพียง POST /api/v3/order/cancelReplace — การ cancel-บวก-new ที่ดูเหมือนเป็น atomic แต่จริงๆ ไม่ใช่ transactional มีสองโหมด คือ STOP_ON_FAILURE (ค่าเริ่มต้น — หาก cancel ล้มเหลว จะไม่มี order ใหม่) และ ALLOW_FAILURE (วาง order ใหม่แม้ cancel จะล้มเหลว — สวัสดี exposure ซ้ำซ้อนโดยไม่ตั้งใจ) การดำเนินการนี้อาจสำเร็จบางส่วน ซึ่งบ่งชี้ด้วย HTTP 409 ดังนั้น OMS ของคุณต้องกระทบยอดทั้งสองขาแยกกัน และ order ใหม่จะเริ่มชีวิตในคิวใหม่เสมอ จากนั้นในปี 2025 Binance ได้เปิดตัว Order Amend Keep Priority (PUT /api/v3/order/amend/keepPriority) ลดปริมาณในที่เดิม รักษา time priority ไว้ โดยไม่มีต้นทุนต่อจำนวน order ที่ยังไม่ฟิลล์ เป็นความหมายแบบ CME ที่มาช้าไปสิบห้าปี — และเป็นแค่ครึ่งหนึ่งของฝั่งลดปริมาณเท่านั้น
Binance USDT-M futures มี endpoint สำหรับ modify จริง (PUT /fapi/v1/order) แต่ต้องอ่านตัวอักษรเล็กๆ ให้ดี ใช้ได้เฉพาะ LIMIT order ต้องส่งทั้ง price และ quantity และ "modified orders will be reordered in the match queue" — เอกสารระบุว่าไม่มีการรักษา priority แม้แต่การลดปริมาณล้วนๆ ก็ตาม ควรถือว่าทุกการ modify futures คือการรีเซ็ตคิวที่บังเอิญช่วยประหยัดข้อความหนึ่งข้อความและรักษา order ID ไว้ได้เท่านั้น มีจุดคมที่ควรรู้ไว้ คือการ modify order แบบ GTX (post-only) ให้ไปอยู่ที่ราคาที่จะ cross จะทำให้ order ถูก ยกเลิก ไม่ใช่ถูกปฏิเสธและคงเดิมไว้ — การ implement peg ที่ไม่ได้เช็คเรื่องนี้จะ amend ตัวเองจนหายไปเป็นครั้งคราว
OKX เปิด POST /api/v5/trade/amend-order (newPx, newSz พร้อม cxlOnFail เพื่อ auto-cancel เมื่อ amend ล้มเหลว) เป็นข้อความเดียว รักษา order ID ไว้ และยืนยันแบบ asynchronous — sCode = 0 หมายถึง "คำขอได้รับการยอมรับแล้ว" ส่วนผลลัพธ์จริงจะมาถึงบน orders channel ในชื่อ amendResult สิ่งที่เอกสารสาธารณะไม่ได้ระบุไว้อย่างชัดเจนคือพฤติกรรม queue-priority อย่าเติมช่องว่างในเอกสารนี้ด้วยความคิดในแง่ดี ต้องวัดเอง ตั้ง marker order สองตัวที่ระดับราคาเงียบๆ amend ขนาดของตัวหนึ่งให้ลดลง แล้วดูว่าตัวไหนฟิลล์ก่อนในหลายร้อยครั้งทดลอง จนกว่าคุณจะมีข้อมูลนั้น สมมติฐานแบบระมัดระวัง — การเปลี่ยนราคาใดๆ จะทำให้เข้าคิวใหม่ทุกที่ การลดปริมาณรักษา priority ไว้เฉพาะที่ระบุไว้อย่างชัดเจนเท่านั้น — คือสมมติฐานเดียวที่ป้องกันได้

ผลที่ตามมาในเชิงนโยบาย:
- Hysteresis ไม่ใช่การ peg รีไพรซ์เฉพาะเมื่อ touch เคลื่อนตัวเกินแบนด์ ติ๊กจากราคาที่คุณตั้งค้างไว้ ภายในแบนด์ การเคลื่อนไหวคือ noise และตำแหน่งในคิวของคุณมีค่ามากกว่าการปรับปรุงราคาหนึ่งติ๊ก แบนด์เริ่มต้นที่สมเหตุสมผลคือ 1-3 ติ๊ก ปรับตามความผันผวนระยะสั้น แบนด์ที่ถูกต้องทำให้การรีไพรซ์ ที่ขอบ เป็นกลางต่อ EV คือ โดย คือมูลค่าของคิวแบบ Moallemi-Yuan และ คือราคาเงาของ rate-limit ของคุณ การดำเนินการ amend/cancel-replace กินงบ order-rate บนทั้งสอง venue ของ Binance เอนจินกลยุทธ์ที่ peg ทุกติ๊กจะทำให้ระบบส่วนที่เหลือของคุณขาดแคลนความจุของข้อความ
- Amend ลง อย่า cancel-repost ลง เมื่อสเกดูลเลอร์ตัดงบสไลซ์ระหว่างทาง (สเกดูลเลอร์แบบ POV เห็นปริมาณแห้งลง หรือ Almgren-Chriss re-solve หลังฟิลล์บางส่วน) ใช้เส้นทางที่รักษา priority ไว้เมื่อมีให้ใช้ นี่คือมื้อฟรีมื้อเดียวในชั้นนี้ทั้งหมด
- ความเร่งด่วนที่ไม่สมมาตรในการรีไพรซ์ การรีไพรซ์ เข้าหา ตลาด (การไล่ตาม) จะรีเซ็ตคิวของคุณที่ราคาที่แย่กว่า — ควรเกิดขึ้นเฉพาะจากตรรกะการไต่ระดับ ตามตัวจับเวลาของมันเท่านั้น การรีไพรซ์ ออกจาก ตลาด (ตลาดวิ่งเข้าหาคุณ) คือของขวัญ รับมันผ่านแบนด์ passive เท่านั้น เพราะระดับปัจจุบันของคุณกำลังจะฟิลล์อยู่แล้ว
Iceberg display size และสิ่งที่รั่วไหลความตั้งใจของคุณ
Display size คือการตัดสินใจที่สาม และมันเป็นการเทรดสองด้านอย่างแท้จริง ไม่ใช่ปุ่มซ่อนตัวฟรี บันทึกเชิงประจักษ์แสดงว่า:
- Frey และ Sandås ("The Impact of Iceberg Orders in Limit Order Books", working paper 2009; Quarterly Journal of Finance, 2017) จากข้อมูล Xetra: iceberg order ครองปริมาณ 9.3% ของที่ส่งเข้าไปและ 15.9% ของที่ถูกเอ็กซีคิวต์ มีขนาดใหญ่กว่า limit order ธรรมดา 12-20 เท่า และประเด็นสำคัญคือ เมื่อผู้เข้าร่วมตลาดคนอื่น ตรวจจับ iceberg ได้ พวกเขาตอบสนองด้วย market order ที่จับคู่มา สภาพคล่องที่ซ่อนอยู่ เมื่อถูกอนุมานได้แล้ว จะดึงดูดกระแสคำสั่งเข้ามา การค้นหาสภาพคล่องแฝงทำงานได้ทั้งสองทิศทาง
- Bessembinder, Panayides และ Venkataraman ("Hidden liquidity: an analysis of order exposure strategies in electronic stock markets", JFE 94(3), 2009) จาก Euronext Paris ซึ่ง hidden order คิดเป็น 44% ของปริมาณตัวอย่าง: การซ่อนลด implementation shortfall แต่ก็ลดความน่าจะเป็นในการฟิลล์เต็มจำนวนและยืดเวลาที่ใช้ในการทำเสร็จออกไป การเปิดเผยซื้อฟิลล์และจ่ายด้วย impact ตัวเลือกนี้ถูกใช้ตรงตามที่ทฤษฎีทำนายไว้เป๊ะ — order ที่รุกเปิดเผยเพื่อดึงคู่ค้า ส่วนขนาดที่อดทนซ่อนตัว
- Esser และ Mönch ("The navigation of an iceberg", Finance Research Letters 4(2), 2007) มองขนาด peak เป็นปัญหา optimization การแสดงขนาดใหญ่ฟิลล์เร็วกว่า การแสดงขนาดเล็กรั่วไหลน้อยกว่า และค่าที่เหมาะสมอยู่ตรงกลาง
กลไกมาก่อน เพราะมันกำหนดขอบเขตของ optimization ในแทบทุก venue ที่รองรับ iceberg แบบเนทีฟ (Binance spot ผ่าน icebergQty, OKX ผ่าน iceberg algo order ของมัน) การเติม peak ที่มองเห็นแต่ละครั้งจะเข้าไปท้ายคิวที่ราคานั้น ดังนั้น iceberg จึงไม่ใช่ "order เดียวที่มีขนาดซ่อนอยู่" แต่เป็น ลำดับ ของ order ขนาดเล็ก แต่ละตัวต้องจ่ายเวลารอในคิวเต็มรูปแบบ ยิงออกไปโดยอัตโนมัติ ในสมการจุดคุ้มทุนของค่าธรรมเนียมข้างต้น เรื่องนี้สำคัญมาก ค่า ที่แท้จริงต่อ peak คือความน่าจะเป็นในการฟิลล์แบบท้ายคิว ไม่ใช่ของตำแหน่งเดิมของคุณ คิวที่ลึกลงโทษ peak เล็กๆ สองต่อ คือฟิลล์ช้ากว่าและมี adverse selection มากขึ้นจากการเติมซ้ำหลายรอบ
จากนั้นคือปัญหาการรั่วไหลสัญญาณ วิธีตรวจจับของ Frey และ Sandås เองคือกรณีตัวอย่างเตือนใจ ตัวตรวจจับแบบ frequentist ของพวกเขาจับที่รูปแบบความขี้เกียจในการ implement ที่พบบ่อยที่สุดสองแบบ คือ ขนาด peak คงที่ และ ไทม์สแตมป์การเติมซ้ำที่เหมือนกับไทม์สแตมป์ของ trade ที่ทำให้ฟิลล์ ผู้เข้าร่วมตลาดที่รันตัวตรวจจับแบบนั้น (และในตลาดคริปโต มีไม่น้อยเลยที่ทำ — metadata การจับคู่ของ exchange เองยิ่งทำให้ง่ายขึ้นสำหรับกระแสคำสั่งที่ colocated) จะสร้างขนาดที่ซ่อนอยู่ของคุณขึ้นมาใหม่ได้ในไม่กี่ครั้งของการเติมซ้ำ เวกเตอร์การรั่วไหล เรียงตามความถี่ที่พบในสนามจริง:
- Display size คงที่หรือเป็นตัวเลขกลม (0.5 BTC ทุกครั้ง)
- การเติมซ้ำแบบทันทีและกำหนดแน่นอนหลังจาก peak เต็มถูกเอ็กซีคิวต์ — ลายเซ็นไทม์สแตมป์เดียวกัน
- ตัวจับเวลาไต่ระดับที่กำหนดแน่นอน — cross ที่ 30 วินาทีพอดีทุกสไลซ์ และ tape ก็แสดงเป็นจังหวะเมโทรนอม
- เวลา latency และแบนด์การรีไพรซ์ที่ตายตัว — จังหวะ amend ของคุณเป็นลายนิ้วมือที่บ่งชี้ตัวตนได้พอๆ กับขนาด order ของคุณ ซึ่งเป็นหัวข้อของลายนิ้วมือดิจิทัลและการระบุตัวตนเทรดเดอร์
ต้นทุนของการถูกตรวจจับไม่ใช่เรื่องสมมติ Van Kervel และ Menkveld ("High-frequency trading around large institutional orders", Journal of Finance 74(3), 2019) แสดงว่า HFT ในตอนแรกจะเอียง ต่อต้าน metaorder ของสถาบัน — โดยให้สภาพคล่องที่กลยุทธ์ passive ของคุณบริโภคอยู่ — จากนั้นพลิกมาเทรด ไปในทิศทางเดียวกับ order เมื่อความต่อเนื่องของมันเผยข้อมูลออกมา แล้ว back-run ส่วนที่เหลือ ทำให้ต้นทุนของ parent เพิ่มขึ้นอย่างมีนัยสำคัญ สถาบันเหล่านั้นตอบสนองด้วยการชั่งน้ำหนักระหว่างกำไรเชิงเก็งกำไรกับความเสี่ยงในการถูกตรวจจับ ชั้นกลยุทธ์ของคุณคือจุดที่การแลกเปลี่ยนนั้นถูก implement โดยตรง สุ่มขนาด display (uniform 30-70% ของ base ที่ปรับตามความผันผวนใช้ได้ดี) jitter ตัวจับเวลาทุกตัว ±20-30% บางครั้งปล่อยให้การเติมซ้ำรอ และอย่าให้ child order สองตัวมีขนาด เฟสของตัวจับเวลา และโปรไฟล์ latency ร่วมกันเลย ทั้งหมดนี้ไม่มีต้นทุนต่อคุณภาพการฟิลล์ที่วัดได้เลย และทั้งหมดนี้ยกระดับพื้นเสียงรบกวนสำหรับใครก็ตามที่กำลัง fit ตัวตรวจจับเข้ากับกระแสคำสั่งของคุณ
เอนจินกลยุทธ์แบบขั้นต่ำ
ชั้นทั้งหมดข้างต้นบีบอัดเป็นสเตทแมชชีนเล็กๆ ต่อสไลซ์ คือ IDLE → POSTED → (reprice loop) → CROSSING → DONE พร้อมประตูจุดคุ้มทุนที่ทางเข้า แบนด์ hysteresis ระหว่างที่ตั้งค้าง และการไต่ระดับตาม deadline เวอร์ชันด้านล่างจงใจทำให้ขั้นต่ำ — ไม่มี venue adapter ไม่มีการจัดการ iceberg — แต่มันเป็นแบบ event-driven และไม่มี side effect จึงเสียบเข้ากับ rung-4 queue-aware simulator จากบันไดการจำลองฟิลล์ได้ทันที ตัว simulator เรียก on_tick/on_fill และตีความ action เป็น post → GTX/post-only, cross → IOC, cancel_replace/amend_down → ความหมายของ venue นั้นจากตารางเมทริกซ์ข้างต้น
import math
from dataclasses import dataclass
from enum import Enum, auto
class State(Enum):
IDLE = auto(); POSTED = auto(); CROSSING = auto(); DONE = auto()
@dataclass
class Fees:
maker: float # $ per unit; negative = rebate
taker: float # $ per unit
@dataclass
class Cfg:
tick: float
sigma_1s: float # $ per sqrt(second), from your live vol estimator
adverse_frac: float = 0.6 # E[adverse move | no fill] ~ 0.6 * sigma; calibrate
reprice_band: float = 2.0 # ticks of touch drift tolerated before repricing
escalate_frac: float = 0.7 # cross the remainder at this fraction of the window
class SliceTactic:
"""One instance per scheduler slice. Drive it from a fill simulator or OMS."""
def __init__(self, side: str, qty: float, window: float, fees: Fees, cfg: Cfg):
self.side, self.qty, self.window = side, qty, window
self.fees, self.cfg = fees, cfg
self.filled, self.state, self.px, self.t0 = 0.0, State.IDLE, None, None
def p_star(self, spread: float, tau: float) -> float:
"""Break-even fill probability for posting over a window tau."""
delta = self.cfg.adverse_frac * self.cfg.sigma_1s * math.sqrt(tau)
prize = spread + self.fees.taker - self.fees.maker
return delta / (prize + delta)
def p_fill(self, queue_ahead: float, drain: float, tau: float) -> float:
"""Crude queue-drain estimate; swap in your calibrated fill model."""
if drain <= 0: return 0.0
return min(1.0, drain * tau / max(queue_ahead + self.qty, 1e-9))
def on_tick(self, t, bid, ask, queue_ahead, drain):
if self.state == State.DONE: return []
if self.t0 is None: self.t0 = t
left = self.qty - self.filled
elapsed, remain = t - self.t0, self.window - (t - self.t0)
touch = bid if self.side == "buy" else ask
if elapsed >= self.cfg.escalate_frac * self.window and left > 0:
self.state = State.CROSSING # deadline: pay up, finish
return [("cross", left)]
if self.state == State.IDLE:
if self.p_fill(queue_ahead, drain, remain) >= self.p_star(ask - bid, remain):
self.state, self.px = State.POSTED, touch
return [("post", touch, left)] # GTX / post-only
self.state = State.CROSSING # posting is -EV here
return [("cross", left)]
if self.state == State.POSTED:
if abs(touch - self.px) / self.cfg.tick > self.cfg.reprice_band:
self.px = touch # hysteresis breached:
return [("cancel_replace", touch)] # accept the queue reset
return []
def on_fill(self, t, fill_qty):
self.filled += fill_qty
if self.filled >= self.qty - 1e-9:
self.state = State.DONE
return [("slice_done", self.filled)]
return []
def on_budget_cut(self, new_qty):
"""Scheduler revised the slice down: amend-down keeps queue priority
where documented (CME, Binance spot amend/keepPriority)."""
self.qty = new_qty
left = new_qty - self.filled
return [("amend_down", left)] if left > 0 else [("cancel",)]
ข้อควรระวังสามข้อที่ต้องยอมรับตรงไปตรงมา p_fill ในที่นี้เป็นแค่อัตราส่วน placeholder — ในระบบจริงควรเป็นโมเดลที่ปรับเทียบแบบสดและแบ่งเป็น bucket จากบทความเรื่องการจำลองฟิลล์ เพราะทั้งประตู post/cross ดีได้เท่ากับคุณภาพของค่าประมาณนี้เท่านั้น adverse_frac ซ่อนปริมาณที่ยากที่สุดในบทความนี้ไว้ ( ขึ้นกับ regime และพุ่งขึ้นสูงสุดพอดีตอนที่การ post ล่อใจที่สุด) ให้ประมาณค่านี้จากผลลัพธ์ no-fill ของคุณเอง แบ่งเป็น bucket ตาม regime ความผันผวน และเอนจินข้างต้นรีไพรซ์ผ่าน cancel-replace แบบไม่มีเงื่อนไข เวอร์ชันที่ตระหนักถึง venue ควรส่งการเปลี่ยนแปลงแบบลดปริมาณผ่านเส้นทางที่รักษา priority ไว้ และคิดค่าใช้จ่ายทุก action กับงบข้อความ
รันมันภายใน simulator กับ replay tape ก่อนที่จะเชื่อพารามิเตอร์ใดๆ การทดลองที่สำคัญคือ ตรึงสเกดูลเลอร์ไว้ กวาดค่า escalate_frac และ reprice_band แล้ว plot slice shortfall เทียบกับต้นทุนตามโมเดลที่ บ่งบอก พื้นผิวนี้มีที่ราบ (แบนด์กว้างของพารามิเตอร์ที่เกือบเหมาะสมที่สุด) และหน้าผาสองแห่ง คือไต่ระดับช้าเกินไป (ส่วนที่เหลือไม่ฟิลล์ cross เข้าไปในโมเมนตัม) และรีไพรซ์กระตือรือร้นเกินไป (มูลค่าคิวทั้งหมดถูกเผาทิ้ง) คุณต้องรู้ว่าหน้าผาของคุณอยู่ตรงไหนก่อนที่ระบบจริงจะไปเจอมันเข้าให้แทนคุณ
สิ่งที่ควรจดจำ
- สองชั้น หนึ่งสัญญา สเกดูลเลอร์ตัดสินใจว่าเท่าไหร่และเมื่อไหร่ ชั้นกลยุทธ์ตัดสินใจว่าอย่างไร อินเทอร์เฟซคืองบ หน้าต่างเวลา ความเร่งด่วนที่ส่งลงมา และฟิลล์กับ slice shortfall เทียบกับ mid ตอนเริ่มช่วงเวลาที่ส่งขึ้นไป ถ้าคุณระบุที่มาของ shortfall ไปยังชั้นใดชั้นหนึ่งไม่ได้ คุณก็จูนทั้งสองชั้นไม่ได้
- ประตู post/cross คือเลขคณิต ไม่ใช่สัญชาตญาณ ควร post ก็ต่อเมื่อ โดย ในตลาดคริปโตที่สเปรดแคบ รางวัลคือส่วนต่างของค่าธรรมเนียม ดังนั้นระดับค่าธรรมเนียมของคุณกำหนดกลยุทธ์ของคุณ — ปรับจูนบันไดใหม่ทุกครั้งหลังจาก re-tier
- ตัวจับเวลา age-out คือจุดตัดของสองเส้นโค้ง — ความน่าจะเป็นในการฟิลล์ที่อิ่มตัวเทียบกับ adverse selection ที่โตแบบ — ไม่ใช่ค่าคงที่ตามความเชื่อพื้นบ้าน
- ตำแหน่งในคิวคือสินทรัพย์ ต้องรู้ความหมายของ amend ของแต่ละ venue ก่อนใช้จ่ายมัน CME คือลดปริมาณรักษา priority Binance spot คือ cancelReplace เข้าคิวใหม่เสมอ ส่วน amend-keepPriority ของปี 2025 รักษาไว้สำหรับการลดปริมาณ Binance futures คือทุก modify เข้าคิวใหม่ OKX คือไม่มีเอกสารระบุ — ต้องวัดเอง และในระหว่างนี้ให้สมมติกรณีที่แย่ที่สุดไว้ก่อน
- Iceberg คือลำดับของ order ท้ายคิว และตัวที่ขี้เกียจก็อ่านออกได้ Peak คงที่และการเติมซ้ำแบบไทม์สแตมป์เดียวกันคือลายเซ็นการตรวจจับที่เผยแพร่แล้ว สุ่มขนาดและตัวจับเวลา หรือไม่ก็ยอมรับว่าจะถูก back-run
- ส่งสเตทแมชชีนเข้า fill simulator ของคุณก่อน ชั้นกลยุทธ์คือส่วนของระบบที่ backtest กับ production แตกต่างกันมากที่สุด — ซึ่งเป็นเหตุผลว่าทำไมมันควรอยู่ภายใน simulator ไม่ใช่ต่อเติมเข้ามาทีหลัง
ลิงก์ที่เป็นประโยชน์
- Harris, L. — Optimal Dynamic Order Submission Strategies in Some Stylized Trading Problems, Financial Markets, Institutions & Instruments 7(2), 1-76 (1998)
- Cont, R., Kukanov, A. — Optimal Order Placement in Limit Order Markets, Quantitative Finance 17(1), 21-39 (2017)
- Frey, S., Sandås, P. — The Impact of Iceberg Orders in Limit Order Books (2009)
- Bessembinder, H., Panayides, M., Venkataraman, K. — Hidden Liquidity: An Analysis of Order Exposure Strategies in Electronic Stock Markets, Journal of Financial Economics 94(3), 361-383 (2009)
- van Kervel, V., Menkveld, A. — High-Frequency Trading around Large Institutional Orders, Journal of Finance 74(3), 1091-1137 (2019)
- Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
- Lehalle, C.-A. — Market Microstructure Knowledge Needed for Controlling an Intra-Day Trading Process (2011)
- Binance Spot API — Order Amend Keep Priority
- Binance Spot API — Trading endpoints (cancelReplace semantics)
- Binance USDT-M Futures API — Modify Order
- OKX API v5 — Amend order
- CME Group — Order Functionalities (modification and time priority)
Citation
@article{soloviov2026childordertactics,
author = {Soloviov, Eugen},
title = {Inside the slice: child-order tactics between your scheduler and the exchange},
year = {2026},
url = {https://marketmaker.cc/blog/child-order-execution-tactics},
description = {The tactics layer between execution schedulers and the exchange: passive-then-aggressive escalation with maker-taker break-even math, amend vs cancel-replace queue semantics across venues, iceberg anti-signaling, and a per-slice Python state machine for fill simulators.}
}
ผู้เขียน
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.