Fill simulyatsiyasi: yopilish narxi fantaziyasidan navbat holatini hisobga oluvchi haqiqatgacha bo'lgan zinapoya
Sizning backtestingiz ikkita modeldan iborat: alfa modeli va fill modeli. Ko'pchilik o'z kuchining 95 foizini birinchisiga sarflaydi, ikkinchisini esa qaysi freymvork ishlatilayotgan bo'lsa, o'shanidan meros qilib oladi. Bu teskari yondashuv. Halol fill modeli bilan o'rtacha signal o'rtacha, lekin haqiqiy PnL bahosini beradi. fill_price = candle.close bilan ajoyib signal esa hech narsaning bahosi bo'lmagan raqamni beradi — bu siz hech qachon tekshirmagan taxminning natijasidir.
Likvid instrumentlardagi teyker strategiyalar uchun fill modeli — tuzatish hadidir. Kutilayotgan limit orderlarni o'z ichiga olgan har qanday narsa uchun — market making, passiv kirishlar, post-only rebate yig'ish — fill modeli strategiyaning o'zidir. Siz fill olasizmi, qachon, qancha miqdorda va keyingi narx harakatiga bog'liq holda — bu PnLning nafaqat kattaligini, balki ishorasini ham belgilaydi.
Backtest-live parity maqolasida biz backtest va jonli savdo orasidagi farqlarning to'liq taksonomiyasini xaritaladik va ijro farqini 5/5 og'irlik darajasi bilan baholadik — bu eng yomon toifa. O'sha maqola fill simulyatsiyasiga uchta yirik aniqlik darajasini berdi va davom etdi. Bu maqola esa chuqurlik hamrohi: to'liq zinapoya, pog'ona-pog'ona, order hayot tsikli holat mashinasi sifatida, siz haqiqatan hisoblay oladigan fill-ehtimollik chegaralari va "foydali" market-making strategiyasi zinapoyaning aynan qaysi joyida o'ladi — buni ko'rsatuvchi o'lchangan tajriba bilan.
Zinapoya

Har bir pog'ona ko'proq ma'lumot va ko'proq kod talab qiladi, va har bir pog'ona ma'lum bir tizimli noto'g'rilikni yo'q qiladi. Pog'onalar nima xato qilishlariga ko'ra tartiblangan, shunchaki narxga ko'ra emas.
0-pog'ona: yopilish narxidagi fill
fill_price = bar.close
Order darhol, to'liq, signal hosil qilingan barning yopilish narxida to'ladi. Signal aynan shu yopilish narxidan hisoblangan, demak siz narx bosilganda mavjud bo'lmagan ma'lumotlar bilan savdo qilyapsiz: ijro kostyumini kiygan look-ahead noto'g'riligi. Aylanmasi bo'lgan har qanday strategiya bu yerda yaxshi ko'rinadi.
1-pog'ona: keyingi bar ochilishi
fill_price = next_bar.open
Barlardagi teyker mantiqi uchun minimal halol model. Signal barida hisoblanadi, fill esa barining birinchi kuzatiladigan narxida sodir bo'ladi. Bu look-ahead noto'g'riligini yo'qotadi, lekin baribir nol spred, nol ta'sir, ochilish narxida cheksiz likvidlik va 100% fill kafolatini taxmin qiladi. Limit orderlar uchun bu touch-fill mantiqiga aylanadi (buning nega zaharli ekani quyida tushuntiriladi).
2-pog'ona: spred + belgilangan slippage
half_spread = mid * spread_bps / 2e4
slip = mid * slippage_bps / 1e4
fill_price = mid + side * (half_spread + slip) # side: +1 sotib olish, -1 sotish
Endi har bir teyker savdosi yarim spred plyus kalibrlangan konstantani to'laydi. Bu — yuqori aylanmali strategiya backtestda o'lishi mumkin bo'lgan birinchi pog'ona, va bu aynan maqsaddir. Qolgan xato: slippage doimiy emas. U ko'rsatilgan chuqurlikka nisbatan order hajmiga qarab o'zgaradi va aynan sizning strategiyangiz eng ko'p savdo qilishni xohlagan paytda portlaydi. Belgilangan 5 bps — bu rejimlar bo'yicha o'rtacha; sizning strategiyangiz o'rtacha rejimda savdo qilmaydi.
3-pog'ona: market orderlar uchun L2 chuqurlik-yurishi (depth-walk)
Order kitobi snapshotlari bilan siz slippage haqida taxmin qilishni to'xtatib, uni hisoblaysiz. hajmdagi market sotib olish ask tomonini daraja-daraja bosib o'tadi; fill narxi iste'mol qilingan darajalar bo'yicha hajm-vaznli o'rtachadir:
def depth_walk(levels: list[tuple[float, float]], qty: float) -> tuple[float, float]:
"""levels: [(price, size), ...] eng yaxshisidan boshlab saralangan. Qaytaradi: (vwap, filled_qty)."""
remaining, cost = qty, 0.0
for price, size in levels:
take = min(size, remaining)
cost += take * price
remaining -= take
if remaining <= 0:
break
filled = qty - remaining
return (cost / filled if filled > 0 else float("nan"), filled)
Ikkita tuzatish buni sezilarli darajada halolroq qiladi. Birinchidan, latensiya: kitobni qaror qabul qilish vaqtingizdan keyin turgan holatda bosib o'ting, bu yerda — sizning o'lchangan signaldan birjagacha bo'lgan latensiyangiz — siz ko'rgan kitob siz urgan kitob emas. Ikkinchidan, qisman market fillar: agar sizning limit-orqali narxingiz ichidagi ko'rsatilgan chuqurlik dan kam bo'lsa, model qisman fillni qaytarishi va kutayotgan qoldiqni qoldirishi kerak, bu esa muammoni quyidagi holat mashinasiga topshiradi.
3-pog'onadagi qolgan xato — ta'sir va to'ldirish (refill): siz kitobni statik ob'ekt sifatida iste'mol qilasiz, lekin haqiqiy kitoblar qisman to'ldiriladi (va haqiqiy kontragentlar reaksiya bildiradi). Top-of-book chuqurligining bir necha foizidan kam klip hajmlari uchun bu xato kichik; kattaroq kliplar uchun ustiga ta'sir modeli (Almgren-Chriss 2001) qo'yish kerak.
4-pog'ona: limit orderlar uchun ehtimollik asosidagi navbat-pozitsiyasi fillari
0-3 pog'onalar "mening agressiv orderim qaysi narxda to'ladi" degan savolga javob beradi. 4-pog'ona qiyinroq savolga javob beradi: mening passiv orderim umuman to'ladimi — va bu market-making strategiyasini baholay oladigan yagona pog'ona. narxida kutayotgan limit order, agar dagi jami savdo qilingan hajm undan oldingi navbat hajmidan oshsa, to'ladi. Bu sizning to'g'ridan-to'g'ri kuzata olmaydigan FIFO navbatdagi pozitsiyangizni kuzatishni talab qiladi.
Navbat-pozitsiyasini baholash mexanizmi — boshlang'ich pozitsiya, savdolar va bekor qilishlar bo'yicha yangilash qoidalari, kuzatilmagan bekor qilishlarni taqsimlash uchun ehtimollik oilasi — biz Devor ichidagi navbat maqolasida qurgan primitivdir. Men buni bu yerda qaytadan chiqarmayman; simulyator uni iste'mol qiladi. 4-pog'ona qo'shadigan narsa — quyidagi fill-ehtimollik bo'limida yoritilgan fill qarori qoidasi.
Bu pog'onaning nima uchun muhimligi adabiyotda miqdoriy jihatdan ko'rsatilgan: Moallemi va Yuan (2016), "A Model for Queue Position Valuation in a Limit Order Book", katta-tikli instrumentlar uchun navbatning old qismidagi pozitsiya qiymati orqa qismidagi pozitsiyaga nisbatan yarim spredga taqqoslanadigan darajada ekanini ko'rsatadi — bu market-making strategiyasining butun nazariy ustunligi bilan bir xil kattalik tartibida. Navbat pozitsiyasini e'tiborsiz qoldiruvchi fill modeli market-makerning PnL sini noto'g'ri baholamaydi; u boshqa strategiyaning PnL sini baholaydi.
5-pog'ona ham bor — bu to'liq agent-asoslangan simulyatsiya bo'lib, unda bozor sizning orderlaringizga reaksiya bildiradi (Huang, Lehalle va Rosenbaum 2015 ma'nosidagi navbat-reaktiv modellar; ABIDES kabi multi-agent freymvorklar, Byrd va boshq. 2020). Tarixiy takrorlash, hatto navbatni hisobga olgan holda ham, sizning orderingiz boshqalarning xatti-harakatida hech narsani o'zgartirmaydi deb taxmin qiladi. Bu taxmin chakana savdo hajmida to'g'ri va sizning kvotalaringiz darajaning ko'rinadigan qismiga aylangani sari borgan sari noto'g'ri bo'lib boradi. 5-pog'ona bu yerda ko'rib chiqilmaydi; shuni bilingki, zinapoya 4-pog'onada tugamaydi.
Holat mashinasi sifatida qisman fillar
0-2 pog'onalar orderni funksiya chaqiruvi sifatida ko'rsatishga harakat qilishi mumkin: yuborish, narxni olish, tugadi. 3-pog'onadan boshlab, order — hayot tsikliga ega jarayondir, va simulyator uni holat mashinasi sifatida modellashi kerak, aks holda u eng muhim holatlarni jimgina noto'g'ri ishlaydi.

enum OrderState {
PendingNew, // yuborilgan, hali tasdiqlanmagan (latensiya oynasi)
Resting { remaining: f64, q_ahead: f64 }, // kitobda, navbat pozitsiyasi baholangan
PartialFill { remaining: f64, q_ahead: f64 }, // qisman bajarilgan, qolgani hali navbatda
PendingAmend, // o'zgartirish jarayonda
PendingCancel, // bekor qilish jarayonda
Filled,
Canceled { filled_qty: f64 }, // bekor qilish vaqtida qisman to'lgan bo'lishi mumkin
Rejected,
}
O'tishlar iqtisodiyotni o'zida tashiydi:
PendingNew→Resting: order navbatga tasdiqlash vaqtida mavjud bo'lgan hamma narsadan keyin, qaror qabul qilish vaqtida emas, qo'shiladi. Sizning navbat pozitsiyangiz dagi daraja hajmi bilan urug'lanadi. Qaror qabul qilish vaqtida urug'lantiruvchi simulyatorlar navbat ustuvorligini tizimli ravishda oshirib baholaydi — aynan latensiya oynangiz davomida kelgan hajm miqdorida, bu esa portlashlar paytida eng ko'p hajmdir.Resting→PartialFill: sizning darajangizdagi undan oldingi navbatdan katta savdo sizni qisman to'ldiradi. Qoldiq o'zining (endi navbat oldida bo'lgan) pozitsiyasini saqlaydi. Qisman fillar shovqin emas — ular ma'lumot: 1.0 dan 0.3 qismini olish va narxning uzoqlashib ketishini kuzatish to'liq filldan farqli PnL hodisasidir, va market-makerning inventar jarayoni aynan shu bo'laklardan quriladi.Resting→PendingAmend→Resting: tuzoq. Deyarli har bir kripto platformada, o'zgartirish — bu cancel/replace: Binance ningcancelReplacefunksiyasi ikki marta bajarilishga qarshi atomik, lekin navbat oxirida yangi order ID qaytaradi. Native modify semantikasiga ega platformalar (CME Globex) ham vaqt ustuvorligini faqat miqdorni kamaytirishda saqlaydi; narx o'zgarishi yoki miqdor oshishi ustuvorlikni yo'qotadi. Shuning uchun simulyatorda: har qanday narx o'zgartirishiq_aheadni joriy daraja hajmining to'liq qiymatiga qaytaradi. Har 500ms da qayta joylashadigan kvota mexanizmi "kvotani saqlab turgani" yo'q — u doimiy ravishda navbat oxiriga qaytadan kirmoqda, va uning realistik fill profili deyarli sof teskari tanlovdir (adverse selection). Moallemi-Yuan natijasi bilan birgalikda: qayta kvota qo'yishning narxi bor, va bu narx sizning navbat pozitsiyangizdir.PendingCancel→PartialFill→Canceled: bekor qilishlar ham latensiya oladi. Kvotani olib tashlashga qaror qilish va bekor qilishning matching engine ga yetib borishi oralig'ida siz hali ham fill olishingiz mumkin — va bu fillar siz olishingiz mumkin bo'lgan eng yomon fillardir, chunki siz kvotani olib tashlayotganingizning sababi — bozor sizni bosib o'tishga tayyor turgani edi. Bekor qilish latensiyasi bo'lmagan simulyator sizning tarixingizdan aynan eng zararli fillarni o'chirib tashlaydi.
Holat mashinasi shuningdek simulyatorning hisobini halol qiladi: to'lovlar har bir fill hodisasi bo'yicha to'planadi, inventar har bir fill hodisasi bo'yicha yangilanadi, va holatda o'tkazilgan vaqt statistikasi (orderlar to'lgunga yoki bekor qilingunga qadar qancha vaqt kutadi) jonli loglar bilan bevosita solishtiriladigan bo'ladi — bu esa oxirida keladigan kalibrlash tsiklining ozig'idir.
Limit-fill ehtimolligi: uchta model va bir qamrov
narxida kutayotgan order berilgan (aytaylik, bid), simulyator qachon fillni e'lon qiladi? Halollik darajasi ortib boruvchi uchta qaror qoidasi:
1. Touch-fill (soddalashtirilgan). Agar narx sizning darajangizga tegsa, fill: . Bu birinchi-o'tish-vaqti (first-passage-time) qoidasi, va uning muvaffaqiyatsizligi chorak asr oldin o'lchangan: Lo, MacKinlay va Zhang (2002), "Econometric Models of Limit-Order Executions" (Journal of Financial Economics 65), haqiqiy limit order ma'lumotlariga survival modellarini moslashtiradi va birinchi-o'tish vaqtlaridan tuzilgan gipotetik ijrolar "haqiqiy limit-order ijrolari uchun juda yomon proksi ekanini" xulosa qiladi. Muvaffaqiyatsizlik rejimi tuzilmaviy: narx sizning darajangizga tegib qaytganda, teginish navbatning old qismini — sizdan oldin kvota qo'ygan treyderlarni — iste'mol qilgan bo'ladi. Touch-fill sizga ularning fillarini beradi. Yanada yomoni, bu aynan yaxshi fillarni beradi (teginish-va-qaytish market-maker uchun foydali stsenariy), sizning haqiqiy fill to'plamingiz esa teginish-va-o'tib-ketish — teskari tanlangan fillarga qarab qiyshaygan bo'ladi.
2. Trade-through (konservativ chegara). Faqat narx sizning darajangizdan qat'iy o'tib ketsa fill: , yoki tick ma'lumotlarida, dagi jami savdo qilingan hajm butun darajadan oshsa. Agar narx o'tib ketgan bo'lsa, dagi butun navbat iste'mol qilingan, demak siz pozitsiyangizdan qat'i nazar to'lgansiz. Bu hech qachon siz olmagan bo'lardingiz deb bo'lmaydigan fillni bermaydi. Uning noto'g'riligi touch-fill ning ko'zgu aksidir: u navbat sizning pozitsiyangizgacha to'liq penetratsiyasiz kamayib ketgan har bir fillni sizdan mahrum qiladi, va u beradigan fillar nomutanosib ravishda o'tib-ketuvchi (teskari tanlangan) fillardir. Trade-through ostidagi market-maker backtesti — baho emas, stress-testdir.
3. Navbat-kamayishi bahosi. Savdo lentasidan sizning narxingizdagi jami savdo qilingan hajm ni va L2 deltalaridan chiqarilgan bekor qilingan hajm ni kuzating. Sizning baholangan oldingi navbatingiz:
bu yerda — order kirish vaqtidagi (tasdiqlash vaqtidagi) daraja hajmi, esa sizdan oldin sodir bo'ladi deb taxmin qilingan bekor qilishlar ulushi — bu tugma, uning tamoyilli shakli ( oilasi) navbat-pozitsiyasi maqolasida chiqarilgan. Fill bo'lganda boshlanadi; sizning to'lgan miqdoringiz undan ortiqcha savdo qilingan hajm bo'lib, bu tabiiy ravishda qisman fillarni beradi:
ni o'rnatish (barcha bekor qilishlar sizdan oldin) bu modelning optimistik chetini beradi; — pessimistik chetini. Sizda faqat siyrak L2 snapshotlari va darajada savdo lentasi yo'q bo'lganda — 100ms bilan cheklangan kripto feedlarida odatiy holat — model-asoslangan priorga tayanishingiz mumkin: Cont, Stoikov va Talreja (2010), "A Stochastic Model for Order Book Dynamics" (Operations Research 58), har bir narx darajasini tug'ilish-o'lim navbati sifatida modellashtiradi va Laplas transformatsiyalari orqali bid dagi orderning mid harakatlanishidan oldin bajarilish ehtimolini, joriy navbat hajmlariga bog'liq holda hisoblab chiqadi. Bu — analitik fill-ehtimollik orakuli: lenta takrorlashiga nisbatan sodda, touch-fill dan ancha yaxshi, va issiq backtest tsikli ichida baholash uchun yetarlicha arzon.
Qamrov intizomi
Uchta qoida raqobatchi emas — ular tartib:
bu esa PnL qamrovini keltirib chiqaradi. Har bir market-maker backtestini uch marta ishga tushiring va oraliqni bering:
(yuqori tengsizlik taxminiy — touch-fill nafaqat oshirib ko'rsatishi, balki strategiyalarni noto'g'ri tartiblashi ham mumkin, chunki u sizga kontrfaktik yaxshi fillarni beradi). Bundan kelib chiqadigan qaror qoidasi: market-maker strategiyasi faqat qamrovning konservativ chetida omon qolgandagina joriy etilishga loyiq, va qamrov nuqta bahosi biror narsani anglatadigan darajada tor bo'lishi kerak. +3k trade-through ko'rsatgan strategiya 2.1k / +$0.4k ko'rsatgan strategiya esa sizga haqiqiy narsani aytmoqda.
Tajriba: bitta market-maker strategiyasini zinapoya bo'ylab pastga tushirish

Ataylab sodda market-maker olaylik — eng yaxshi bid/ask da simmetrik kvotalar, belgilangan 0.05 BTC kliplar, ±0.5 BTC da inventar chegaralangan va chegarada teyker bilan tekislash. Bir oylik BTCUSDT perpetual ma'lumotlari: past pog'onalar uchun 1m barlar, yuqori pog'onalar uchun 100ms L2 farqlar plyus savdo lentasi; market-maker to'lovi 1.0 bps, teyker 4.0 bps. Har bir pog'onada bir xil signal kodi (umumiy yadro, shunday qilib yagona o'zgaruvchi — fill modeli). Quyidagi raqamlar bizning bitta vakillik namunali ishlashimizdir — sizning ko'rsatkichlaringiz platforma, oy va hajmga qarab farq qiladi; shakl esa farq qilmaydi:
| Pog'ona | Fill modeli | Kvota fill darajasi | Fillar | Oylik PnL | Xulosa |
|---|---|---|---|---|---|
| 0 | close-fill | 98% | 41,200 | +$14,800 | fantaziya |
| 1 | next-bar-open / 1m barlarda touch | 89% | 37,400 | +$9,600 | latensiyali fantaziya |
| 2 | teyker tekislashda touch + spred va belgilangan slippage | 89% | 37,400 | +$7,100 | xarajatlar modellangan, fillar hali ham fiktiv |
| 3 | + teyker tekislashda L2 chuqurlik-yurishi | 89% | 37,400 | +$6,400 | chiqishlar halol, kirishlar hali ham fiktiv |
| 4a | trade-through (konservativ) | 21% | 8,900 | -$3,900 | stress chegarasi |
| 4b | navbat-kamayishi, kalibrlangan | 37% | 15,600 | -$700 | eng yaxshi baho |
| 4c | navbat-kamayishi, (optimistik) | 44% | 18,700 | +$1,900 | yuqori chegara |
| — | jonli soya yugurish, xuddi shu oy | 35% | 14,100 | -$1,150 | haqiqat |
Jadvalni yuqoridan pastga o'qing va strategiya qayerda o'lishini kuzating. Bu 2-pog'ona emas — to'lovlar va slippage 26% ni kesib tashlaydi, strategiya esa hali ham mustahkam foydali ko'rinadi. U 3 va 4-pog'ona orasida o'ladi, va hech qanday xarajat modeli qamrab ololmaydigan sabab bilan o'ladi: fill tanlovi. Touch-fill 37,400 fill berdi, ularning ko'pchiligi teginish-va-qaytish edi — sof spred yig'ish. Navbatni hisobga oluvchi model bu fillarning 58% ini o'chirdi, va o'chirilgan fillar nomutanosib ravishda foydali fillar edi: daraja yengil ta'sirlanganda, qayta kvota qo'yuvchi chakana-latensiyali market-maker oldidagi navbat hamma narsani yutib yuboradi. 4-pog'onaga omon qolgan fillar darajani tozalovchi supurishlarga qarab qiyshaygan — narx sizni allaqachon bosib o'tayotgan fillarga. Fill darajasi 2.4 marta pasaydi; PnL ishorasi teskarisiga o'tdi. Bu assimetriya — yaxshi fillarni yo'qotish, yomonlarini saqlab qolish — mexanik ravishda aniq ko'rsatilgan teskari tanlovdir (adverse selection), va u 4-pog'onadan pastdagi har bir pog'onada ko'rinmasdir.
Shuningdek, qamrov nima qilganiga e'tibor bering: [-1,900] nolni qamrab oladi, kalibrlangan baho -1,150 da. Simulyator jonli PnL ni dollargacha aniq topmadi — u ishorani, kattalikni va fill darajasini 2 ball ichida to'g'ri topdi. Fill modelining vazifasi aynan shu. 1-pog'ona backtesti jonli PnL dan $10,750 ga adashdi — bu strategiyaning butun oylik yalpi ustunligi bir necha ming dollar bo'lgan holda: fill-model xatosi alfa hajmidan taxminan 3 marta katta edi. Shu sababli tezis: sizning fill modelingiz alfangizdan kattaroq taxmindir.
Past pog'onalar uchun bitta ogohlantirish: agar sizga bar ma'lumotlarida yashashga to'g'ri kelsa (0-2 pog'onalar), hech bo'lmaganda moslashuvchan drill-down yordamida bar ichidagi noaniqlikni hal qiling — SL, TP yoki kvota darajalari bar diapazoni ichiga tushganda 1m dan 1s/100ms/savdolarga o'tib. Drill-down ketma-ketlik xatolarini tuzatadi (qaysi daraja birinchi bosilgan) lekin navbat xatolarini tuzata olmaydi; u shu maqolaning ma'lumot-aniqligi hamrohi, 4-pog'onaning o'rnini bosuvchi emas.
Kalibrlash tsikli: jonli fillarga qarshi yopish
4-pog'ona simulyatori erkin parametrlarga ega — , latensiya , bekor qilish latensiyasi, daraja-to'ldirish taxmini. Kalibrlanmagan holda u faqat boshqacha shaklda taxmindir. Uni asbobga aylantiruvchi tsikl:
1. Hamma narsani jonli holda logga yozing. Birja vaqt belgilari bilan har bir order hodisasi: yuborish, tasdiqlash, har bir qisman fill, o'zgartirish tasdiqlari, bekor qilish tasdiqlari. Plyus yuborish vaqtidagi L2 holati. Bu backtest-live parity o'zining DivergenceMonitor i uchun talab qiladigan xuddi shu logging intizomi — fill-model kalibrlashi o'sha monitorning eng chuqur qatlamidir.
2. Bir xil orderlarni simulyator orqali qayta o'tkazing. Yozib olingan bozor ma'lumotlarini va yozib olingan order ko'rsatmalarini (fillarni emas) simulyatorga bering. Endi sizda juftlashgan natijalar bor: har bir jonli order uchun simulyatsiya qilingan taqdir.
3. O'rtachalarni emas, taqsimotlarni bucketlar bo'yicha solishtiring. Yagona global fill-darajasi mosligi kompensatsiyalanuvchi xatolarni yashirishi mumkin (tinch rejimlarda juda optimistik, portlashlarda juda pessimistik — "kalibrlangan" holatga netto bo'lib). Drayverlar bo'yicha bucketlarga bo'ling:
import numpy as np
from scipy.stats import ks_2samp
def calibration_report(pairs, bucket_key):
"""pairs: [{'bucket':…, 'live_filled':bool, 'sim_filled':bool,
'live_ttf':float|None, 'sim_ttf':float|None}, …]"""
out = {}
for b in sorted({p['bucket'] for p in pairs}):
grp = [p for p in pairs if p['bucket'] == b]
live_fr = np.mean([p['live_filled'] for p in grp])
sim_fr = np.mean([p['sim_filled'] for p in grp])
live_ttf = [p['live_ttf'] for p in grp if p['live_ttf'] is not None]
sim_ttf = [p['sim_ttf'] for p in grp if p['sim_ttf'] is not None]
ks = ks_2samp(live_ttf, sim_ttf) if len(live_ttf) > 20 and len(sim_ttf) > 20 else None
out[b] = {
'n': len(grp),
'fill_rate_live': live_fr,
'fill_rate_sim': sim_fr,
'fill_rate_gap': sim_fr - live_fr, # ishoraga ega: + optimistik simulyator demakdir
'ttf_ks_pvalue': ks.pvalue if ks else None,
}
return out
Har bir bucket uchun ikkita statistika: ishoraga ega fill-darajasi farqi (simulyator minus jonli) va to'lgan orderlar orasida vaqt-fillgacha taqsimotlari bo'yicha KS testi. Vaqt-fillgacha solishtirish o'tkir bo'lgan narsa — simulyator fill darajalarini mos kelishi mumkin, lekin tizimli ravishda noto'g'ri vaqtlarda to'ldirishi mumkin, bu esa keyingi har qanday inventar va teskari-tanlov statistikasini buzadi. Bu aynan Lo-MacKinlay-Zhang ning survival-tahlil talqinining darsi: ijro — vaqt-hodisa muammosi, shuning uchun uni shunday tekshiring.
4. Tugmalarni identifikatsiya qilinishi tartibida moslang. Avval latensiya (bevosita tasdiqlash vaqt belgilaridan o'lchangan — moslashtirilmagan). Keyin navbat-chuqurligi bucketlari bo'yicha fill-darajasi farqini minimallashtirish orqali . Keyin volatillik-rejimi bucketlarini tekshiring: portlash bucketlarida to'plangan doimiy optimistik farq odatda sizning simulyatoringiz bekor-qilish-latensiyasi zaharli fillarini yoki daraja to'ldirilishini yetarli modellamayotganini bildiradi, ni emas.
5. Qamrovni qayta ishga tushiring. Kalibrlashdan so'ng, navbat-kamayishi bahosi jonliga yaqin qamrov ichida joylashishi kerak, va — haqiqiy qabul testi — simulyator ostidagi strategiya variantlarining tartiblanishi soya rejimidagi tartiblanishiga mos kelishi kerak. Keyin parametrlarni muzlatib qo'ying va jadval bo'yicha qayta kalibrlang; fill dinamikasi platformaning to'lov darajalari, tick-hajm o'zgarishlari va HFT populyatsiyasi bilan siljib boradi, martda kalibrlangan esa iyulga kelib gipotezaga aylanadi.
Bizning yugurishlarimizdan konvergensiya kutilmalari: kalibrlanmagan 4-pog'ona simulyatori odatda jonli fill darajasidan ±10-15 ball ichida joylashadi; bitta kalibrlash o'tishidan keyin — ±3-5 ball, vaqt-fillgacha KS p-qiymatlari endi bir xilda rad etilmaydi. Tarixiy takrorlash bilan bundan yaxshiroqqa erisha olmaysiz — qoldiq bozorning sizga bergan reaksiyasidir, bu esa 5-pog'onaning muammosi.
Nimani olib qolish kerak
- Pog'onangizni nomlang. Har bir backtest shu zinapoyada turadi, siz pog'onani tanladingizmi yoki freymvorkingiz sizning o'rningizga tanladimi, farqi yo'q. Agar siz fill modelingizning pog'onasini va uning ma'lum noto'g'riliklarini nomlay olmasangiz, PnL raqamingizda siz ko'rmagan xato chegaralari bor.
- Teykerlar 3-pog'onada to'xtashi mumkin. Chuqurlik-yurishi plyus o'lchangan latensiya chakana hajmda agressiv ijroni halol baholaydi. Tejalgan kuchni ma'lumot sifatiga sarflang.
- Market-makerlar 4-pog'onadan boshlanadi. Undan pastda, limit-order fill mantig'i taxminiy emas — u teskari-tanlov qiyshiyligi qarama-qarshi bo'lgan kontrfaktik fillar to'plamini tanlaydi. Market-maker strategiyalarining touch-fill backtestlari ishlab chiqarish bilan aloqa qilganda o'ladigan strategiyalarni yaratishning eng ishonchli manbaidir.
- Fillni emas, hayot tsiklini modellang. Qisman fillar, o'zgartirish-navbatni-qayta-tiklaydi, bekor qilish latensiyasi — holat mashinasi zaharli fillar yashaydigan joy, zaharli fillar esa market-maker PnL i o'ladigan joy.
- Qamrovni bering. Konservativ va optimistik chegaralar ikkita qo'shimcha backtest yugurishiga tushadi va "mening backtestim +3.9k, +$1.9k] oralig'ida" degan gapga aylantiradi — bu boshqacha va yaxshiroq qarordir.
- Jonli fillarga qarshi bucketlarda kalibrlang. Faqat agregatda tasdiqlangan fill modeli — yashirin kompensatsiyalanuvchi xatolarga ega fill modelidir. Bucketlangan fill-darajasi farqlari plyus vaqt-fillgacha KS testlari, choraklik qayta kalibrlangan.
Zinapoyaning pog'onalari akademik gradatsiyalar emas — har biri backtestingiz endi aytmaydigan aniq bir yolg'ondir. Yolg'onlar sizning ustunligingizdan kichikroq bo'lguncha ko'tariling.
Foydali havolalar
- Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
- Cont, R., Stoikov, S., Talreja, R. — A Stochastic Model for Order Book Dynamics, Operations Research 58(3), 549-563 (2010)
- Lo, A., MacKinlay, C., Zhang, J. — Econometric Models of Limit-Order Executions, Journal of Financial Economics 65(1), 31-71 (2002)
- Huang, W., Lehalle, C.-A., Rosenbaum, M. — Simulating and Analyzing Order Book Data: The Queue-Reactive Model, JASA 110(509), 107-122 (2015)
- Almgren, R., Chriss, N. — Optimal Execution of Portfolio Transactions (2001)
- Byrd, D., Hybinette, M., Balch, T. — ABIDES: Towards High-Fidelity Multi-Agent Market Simulation (2020)
- Binance API — Cancel-Replace order semantics
- CME Globex — Order modification and time priority rules
Citation
@article{soloviov2026fillsimulation,
author = {Soloviov, Eugen},
title = {Fill simulation: the ladder from close-price fantasy to queue-aware reality},
year = {2026},
url = {https://marketmaker.cc/blog/fill-simulation-partial-fills-backtest},
description = {Five rungs of fill simulation fidelity — from close-price fills to probabilistic queue-position models. Partial fills as a state machine, limit-fill probability bounds as a PnL bracket, and a calibration loop against live fills.}
}
Authors
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.