📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

← Terug naar artikelen
July 24, 2026
5 min leestijd

Binnen de slice: child-order tactieken tussen je scheduler en de exchange

Binnen de slice: child-order tactieken tussen je scheduler en de exchange
#execution
#child orders
#order tactics
#queue position
#maker-taker
#iceberg orders
#microstructure
#python

Een Almgren-Chriss traject geeft je een getal: verkoop 4,2 BTC in de komende vijf minuten. Een VWAP-schema geeft je hetzelfde soort getal met een andere onderbouwing. Geen van beide zegt iets over wat er daarna gebeurt — of die 4,2 BTC het orderboek raken als één marketable order, aan de touch blijven staan om maker fees te verzamelen, zich verschuilen achter een display van 0,3 BTC, of elf keer worden herprijsd om een wegdrijvende quote achterna te jagen. Die tweede beslissingslaag is de tactieklaag, en op fee-gedomineerde crypto-orderboeken verplaatst die routinematig meer PnL per slice dan de keuze van de scheduler erboven. De interval-budgetten van de scheduler verschillen tussen TWAP en een goed afgestelde Almgren-Chriss met een paar basispunten aan impact over de hele parent order; taker fees betalen op slices die je had kunnen maken, of queue position weglekken door slordig herprijzen, kost dat bedrag per uur. Dit artikel gaat over de laag die iedereen draait en die bijna niemand op papier zet: de state machine die bepaalt hoe elke child order het orderboek raakt.

Twee lagen, één smalle interface

Lehalle en Laruelle formaliseren in Market Microstructure in Practice (2e ed., 2018) wat elk executiedesk uiteindelijk vaststelt: een strategische laag (de scheduler) die hoeveelheid over tijd verdeelt, en een tactische laag (de microtrader) die elke allocatie tegen het live orderboek uitvoert. De scheiding is niet esthetisch — de twee lagen leven op verschillende klokken en verschillende data. De scheduler denkt in minuten, verwerkt volatiliteits- en volumeprognoses, en lost een variationeel probleem op. De tactieklaag denkt in milliseconden tot seconden, verwerkt L2-deltas en queue-schattingen, en lost een reeks kleine stopping problems op.

Twee-lagen executiearchitectuur: scheduler geeft slice-budget en urgentie door naar beneden, tactieklaag geeft fills en shortfall terug naar boven

De interface daartussen moet smal zijn. Naar beneden, per slice kk:

  • budget qkq_k — de hoeveelheid die dit interval wordt uitgevoerd (de nkn_k van Almgren-Chriss, of de volumecurve-increment van VWAP);
  • venster τk\tau_k — de sliceduur;
  • urgentie — voor Almgren-Chriss is de natuurlijke kandidaat κ=λσ2/η\kappa = \sqrt{\lambda\sigma^2/\eta}, die al risicoaversie, volatiliteit en liquiditeit comprimeert tot één rate; voor een VWAP-scheduler is het meestal een bandafstand ("we lopen 1,8% achter op de doelcurve").

Naar boven: fills met tijdstempels en fees, het onvervulde restant, en de implementation shortfall op sliceniveau gemeten tegen de interval arrival mid. Dat laatste is belangrijk: de impactparameter η\eta van de scheduler prijst al in wat het vragen van liquiditeit tegen rate qk/τkq_k/\tau_k zou moeten kosten. De hele taakomschrijving van de tactieklaag is één regel: realiseer fills tegen minder dan de door η\eta geïmpliceerde kosten, zonder het bestaan van de parent order te lekken. Als je gemeten slice-shortfall consequent beter presteert dan de modelkosten, kan je gekalibreerde η\eta omlaag, versnelt de scheduler, en verbetert de hele stack. Als je slice-shortfall niet los kunt meten van scheduling-kosten, kun je geen van beide lagen afstellen — je hebt één wazig getal en twee knoppen.

Het beleid voor het restant maakt ook deel uit van het contract. Als een slice eindigt met onvervulde hoeveelheid, voltooit de tactieklaag ofwel geforceerd (het restant crossen — de standaard bij deadline-urgentie), of geeft het terug aan de scheduler voor herverdeling over de resterende slices (acceptabel vroeg in een schema met lage κ\kappa, giftig vlak voor de deadline, waar herverdeling zich stilletjes opstapelt tot een enorme laatste slice).

De escalatieladder: eerst passief, agressief bij deadline

Het oudste resultaat op dit gebied is Harris (1998), "Optimal dynamic order submission strategies in some stylized trading problems" (Financial Markets, Institutions & Instruments 7(2)): voor een liquiditeitstrader die een trade voor een deadline moet afronden, is de optimale strategie dynamisch — sta in het orderboek met limit orders zolang tijd goedkoop is, herprijs richting de markt naarmate de deadline nadert, en cross aan het einde. Elke productie-tactiekengine is een afstammeling van deze vorm: post op de touch, laat verouderen, escaleer, cross. Wat moderne fee-schema's en queue-dynamiek toevoegen is de rekenkunde van precies wanneer elke overgang afgaat.

De break-even voor crossen

Werk per eenheid, prijzen relatief aan de huidige mid, voor een koop. Nu crossen kost de halve spread plus de taker fee:

ctake=s2+ft.c_{\text{take}} = \frac{s}{2} + f_t.

Posten op de bid over een venster τ\tau vult met kans pp; een fill levert de halve spread op en betaalt de maker fee fmf_m (negatief bij een rebate). Geen fill betekent crossen aan het einde van het venster nadat de prijs gemiddeld tegen je in is bewogen met δ(τ)=E[ongunstige mid-beweginggeen fill]>0\delta(\tau) = E[\,\text{ongunstige mid-beweging} \mid \text{geen fill}\,] > 0 — strikt positief, omdat geen-fill en ongunstige drift hetzelfde event zijn: je bid wordt niet geraakt wanneer de markt ervan wegtrekt. Verwachte postkosten:

cpost=p(s2+fm)+(1p)(s2+ft+δ).c_{\text{post}} = p\left(-\frac{s}{2} + f_m\right) + (1-p)\left(\frac{s}{2} + f_t + \delta\right).

Posten verslaat crossen iff

  p  >  p\*=δΠ+δ,Π=s+ftfm  \boxed{\; p \;>\; p^\* = \frac{\delta}{\Pi + \delta}, \qquad \Pi = s + f_t - f_m \;}

waarbij Π\Pi de prijs is — de volledige round-trip die je binnenhaalt door te maken in plaats van te nemen: de spread plus het fee-verschil. Dit is dezelfde break-even die de hele maker-taker economie van executie bepaalt, samengevat tot één slice.

Cijfers, BTCUSDT perp: mid $100.000, spread één tick s = \0,10,VIP0achtigefeesmaker2bps/taker5bps,dus, VIP0-achtige fees maker 2 bps / taker 5 bps, dus f_m = $20,, f_t = $50perBTC.Deprijsper BTC. De prijs\Pi = 0,10 + 50 - 20 = $30,10 \approx 3bpsmerkopdatdespreadvrijwelnietsbijdraagt;opkrappecryptomajorsisdeprijshetfeeverschil.Neem3 bps — merk op dat de spread vrijwel niets bijdraagt; op krappe crypto majors *is* de prijs het fee-verschil. Neem 3% dagelijkse vol (\sigma_{\text{day}} = $3{.}000)en) en \delta(\tau) \approx 0,6,\sigma_{\text{day}}\sqrt{\tau/86400}$ (de 0,6 is een adverse-selection-korting die je moet kalibreren, niet blindelings vertrouwen):

  • τ=10\tau = 10 s: \delta \approx \19,dus, dus p^* = 19/49 \approx 0,39$. Post alleen als je minstens een fill-kans van 39% binnen 10 seconden verwacht.
  • τ=60\tau = 60 s: \delta \approx \47,dus, dus p^* = 47/77 \approx 0,61$.
  • Met een maker rebate van 1 bp in plaats van een fee van 2 bp (f_m = -\10):): \Pi = $60,10,endedrempelbij10sdaaltnaar, en de drempel bij 10 s daalt naar p^* \approx 0,24$.

Twee structurele feiten vallen hieruit op. Ten eerste groeit δ\delta als τ\sqrt{\tau} terwijl Π\Pi constant is, dus p\*(τ)1p^\*(\tau) \to 1: geduld heeft een harde vervaldatum, en de age-out timer is geen heuristiek maar het snijpunt van twee curves — je geschatte p(τ)p(\tau) (concaaf, verzadigend naarmate de queue voor je leegloopt) tegenover p\*(τ)p^\*(\tau) (stijgend). Ten tweede verplaatst de fee-tier waarop je handelt de ladder letterlijk. Een tier-upgrade die taker fees verlaagt maakt je optimale tactiek agressiever — een koppeling die de meeste mensen pas ontdekken wanneer hun fill-statistieken verschuiven na een VIP-hertiering.

Cont en Kukanov maken dit rigoureus in "Optimal order placement in limit order markets" (Quantitative Finance 17(1), 2017; arXiv 2012) voor één periode: minimaliseer de verwachte kosten van het uitvoeren van SS eenheden verdeeld over market en limit orders (op één of meerdere venues), met een boete voor shortfall. De single-venue-oplossing is expliciet en heeft een newsvendor-structuur: de optimale limit-ordergrootte wordt bepaald door de verdeling van queue outflow — post agressief wanneer de queue ervoor klein is ten opzichte van de verwachte outflow, en dek het staartrisico af met market orders. Hun multi-venue-uitbreiding wordt opgelost via stochastische approximatie en vormt de intellectuele kern van de passive-allocatielogica van elke smart order router. De praktische les voor een tactiekengine: pp in de break-even hierboven is geen constante — het is een functie van queue position en drainagerate, wat de reden is dat de tactieklaag de queue-position estimator als eersteklas input moet verwerken.

Slice-tijdlijn die de escalatie toont van passief posten aan de touch, via herprijzen, tot het crossen van het restant bij de deadline

De urgentieparameter comprimeert deze hele ladder. Hoge κ\kappa van de scheduler betekent dat de karakteristieke tijd θ=1/κ\theta = 1/\kappa kort is: vensters krimpen, p\*p^\* stijgt, en de engine springt direct naar crossen — terecht, want de scheduler heeft al vastgesteld dat inventarisrisico zwaarder weegt dan fee-besparingen. Lage κ\kappa rekt de passieve fase op. De tactieklaag mag urgentie nooit opnieuw afleiden uit zijn eigen kijk op de markt; dat is de taak van de scheduler, en het dupliceren ervan creëert twee elkaar tegensprekende controllers.

Herprijzen zonder je queue position te verbranden

Eenmaal geplaatst, drijft de quote weg. Er naïef achteraan jagen — annuleren, herposten op de nieuwe touch, herhalen — is hoe tactiekengines stilletjes precies de fill-kans vernietigen die het posten rechtvaardigde. Queue position is een asset met meetbare dollarwaarde (Moallemi en Yuan, 2016, zetten er een prijs op: posities vooraan in de queue in liquide FIFO-orderboeken zijn een betekenisvol deel van de spread waard), en elke herprijs-beslissing is een trade: verkoop je huidige queue position, koop er een achteraan een ander prijsniveau. De trade is alleen de moeite waard wanneer de waarde van het nieuwe niveau die van het oude plus messaging-kosten overtreft. Dat vereist te weten wat de amend van elke venue daadwerkelijk doet met je plek in de rij — en het antwoord is wild niet-uniform.

CME Globex documenteert de schoonste semantiek: het verlagen van orderhoeveelheid behoudt tijdprioriteit; het verhogen van hoeveelheid of het wijzigen van prijs stuurt je naar achteraan de queue. Dit is het referentiemodel — hoeveelheid-omlaag is gratis, al het overige is een re-queue.

Binance spot bood historisch alleen POST /api/v3/order/cancelReplace — een atomisch ogende, expliciet niet-transactionele cancel-plus-new. Twee modi: STOP_ON_FAILURE (standaard — als de cancel faalt, komt er geen nieuwe order) en ALLOW_FAILURE (plaats de nieuwe order zelfs als de cancel faalt — hallo, per ongeluk dubbele exposure). De operatie kan gedeeltelijk slagen, gesignaleerd door HTTP 409, dus je OMS moet beide poten onafhankelijk reconciliëren; en de nieuwe order start altijd een verse queue-levensduur. Toen bracht Binance in 2025 Order Amend Keep Priority uit (PUT /api/v3/order/amend/keepPriority): verlaag hoeveelheid ter plekke, behoud tijdprioriteit, tegen nul kosten aan het aantal onvervulde orders. CME-semantiek, vijftien jaar later — en alleen de helft voor hoeveelheid-omlaag.

Binance USDT-M futures heeft een echt modify-endpoint (PUT /fapi/v1/order), maar lees de kleine lettertjes: alleen LIMIT orders, zowel price als quantity moeten worden meegestuurd, en "modified orders will be reordered in the match queue" — de documentatie belooft geen prioriteitsbehoud, zelfs niet bij pure hoeveelheidsverlagingen. Behandel elke futures-modify als een queue-reset die toevallig één bericht bespaart en de order-ID behoudt. Eén scherpe rand die het weten waard is: het wijzigen van een GTX (post-only) order naar een prijs die zou crossen resulteert in het annuleren van de order, niet in afwijzen-en-behouden — een peg-implementatie die dit niet controleert zal zichzelf af en toe uit het bestaan wegwijzigen.

OKX biedt POST /api/v5/trade/amend-order (newPx, newSz, met cxlOnFail om automatisch te annuleren bij een mislukte amend). Het is één bericht, behoudt de order-ID, en bevestigt asynchroon — sCode = 0 betekent "verzoek geaccepteerd", en de daadwerkelijke uitkomst arriveert op het orders-kanaal als amendResult. Wat de publieke documentatie opvallend niet specificeert is queue-prioriteitsgedrag. Vul dat documentatiegat niet met optimisme. Meet het: post twee markerorders op een rustig niveau, verlaag de size van één via amend, en observeer welke over enkele honderden trials het eerst vult. Tot je die data hebt is de conservatieve aanname — elke prijswijziging re-queuet je overal, hoeveelheid-omlaag behoudt prioriteit alleen waar expliciet gedocumenteerd — de enige verdedigbare.

Matrix van amend-operaties versus venues die toont welke operaties queue-prioriteit behouden en welke die resetten

De beleidsconsequenties:

  1. Hysterese, geen pegging. Herprijs alleen wanneer de touch meer dan een band bb ticks van je resterende prijs is weggedreven. Binnen de band is drift ruis en is je queue position meer waard dan één tick prijsverbetering. Een verstandige startband is 1–3 ticks geschaald naar korte-horizon vol; de juiste band maakt de marginale herprijs EV-neutraal: VnewVcur=cmsgV_{\text{new}} - V_{\text{cur}} = c_{\text{msg}}, met VV de Moallemi-Yuan-achtige queue-waarde en cmsgc_{\text{msg}} je schaduwprijs voor het rate-limit. Amend/cancel-replace-operaties verbruiken order-rate-budget op beide Binance-venues; een tactiekengine die elke tick pegt zal de rest van je systeem uithongeren van berichtcapaciteit.
  2. Amend omlaag, nooit cancel-repost omlaag. Wanneer de scheduler een slice-budget halverwege verlaagt (een POV-scheduler die volume ziet opdrogen, een Almgren-Chriss-herberekening na gedeeltelijke fills), gebruik het prioriteitsbehoudende pad waar het bestaat. Dit is de enige gratis lunch in de hele laag.
  3. Asymmetrische urgentie bij het herprijzen. Herprijzen richting de markt (achtervolgen) reset je queue tegen een slechtere prijs — dat zou alleen mogen afgaan vanuit de escalatielogica, op zijn timer. Herprijzen weg (de markt kwam naar jou toe) is een cadeau, neem het alleen via de passieve band, want je huidige niveau staat toch al op het punt te vullen.

Icebergs, displaygrootte, en wat je intentie lekt

Displaygrootte is de derde beslissing, en het is een echte tweezijdige trade, geen gratis stealth-knop. Het empirische bewijs:

  • Frey en Sandås ("The Impact of Iceberg Orders in Limit Order Books", 2009 working paper; Quarterly Journal of Finance, 2017), op Xetra-data: iceberg orders droegen 9,3% van het ingediende en 15,9% van het uitgevoerde volume, waren 12–20x zo groot als gewone limit orders, en — de clou — wanneer andere deelnemers een iceberg detecteren, reageren ze met bijpassende market orders. Verborgen omvang trekt, eenmaal afgeleid, flow aan: het zoeken naar latente liquiditeit werkt in beide richtingen.
  • Bessembinder, Panayides en Venkataraman ("Hidden liquidity: an analysis of order exposure strategies in electronic stock markets", JFE 94(3), 2009), op Euronext Paris, waar verborgen orders 44% van het steekproefvolume vormden: verbergen verlaagt de implementation shortfall maar verlaagt ook de kans op volledige uitvoering en verlengt de tijd tot voltooiing. Blootstelling koopt fills en betaalt daarvoor in impact; de optie wordt precies gebruikt zoals de theorie voorspelt — agressieve orders stellen zich bloot om tegenpartijen aan te trekken, geduldige omvang verbergt zich.
  • Esser en Mönch ("The navigation of an iceberg", Finance Research Letters 4(2), 2007) behandelen de peak size als een optimalisatie: grotere display vult sneller, kleinere display lekt minder, en het optimum ligt ertussenin.

Eerst de mechanica, want die begrenst de optimalisatie: op vrijwel elke venue die native icebergs ondersteunt (Binance spot via icebergQty, OKX via zijn iceberg-algo-orders), komt elke refill van de zichtbare peak achteraan de queue op dat prijsniveau te staan. Een iceberg is dus niet "één order met verborgen omvang" — het is een reeks kleine orders, elk met de volledige queue-wachttijd, automatisch afgevuurd. Bij de fee-break-even hierboven is dit belangrijk: de effectieve pp per peak is de fill-kans achteraan de queue, niet die van je oorspronkelijke positie. Diepe queues straffen kleine peaks dubbel — langzamere fills en meer refills' waarde aan adverse selection.

Dan het signaleringsprobleem. De eigen detectiemethode van Frey en Sandås is het waarschuwende verhaal: hun frequentistische detector richt zich op de twee meest voorkomende luiheidspatronen in implementatie — constante peak-grootte en refill-tijdstempels identiek aan het tijdstempel van de uitvoerende trade. Elke deelnemer die die detector draait (en op crypto-venues doen velen dat — de eigen matching-metadata van de exchange maakt het voor gecolokeerde flow nog makkelijker) reconstrueert je verborgen omvang in een handvol refills. De lekvectoren, gerangschikt naar hoe vaak ik ze in het wild tegenkom:

  1. Constante of ronde displaygroottes (0,5 BTC, elke keer).
  2. Onmiddellijke, deterministische refill na een volledige peak-uitvoering — de identieke-tijdstempel-handtekening.
  3. Deterministische escalatietimers: cross precies 30 s in elke slice en de tape toont een metronoom.
  4. Vaste herprijs-latentie en -band — je amend-cadans is een vingerafdruk net zo identificerend als je ordergroottes, wat het onderwerp is van digitale vingerafdrukken en trader-identificatie.

De kosten van gedetecteerd worden zijn niet hypothetisch. Van Kervel en Menkveld ("High-frequency trading around large institutional orders", Journal of Finance 74(3), 2019) tonen aan dat HFT's aanvankelijk tegen institutionele metaorders in leunen — ze leveren de liquiditeit die je passieve tactiek consumeert — om vervolgens om te slaan naar handelen met de order zodra de aanhoudendheid ervan informatie onthult, waarbij ze het restant back-runnen en de kosten van de parent aanzienlijk verhogen. Hun instituten reageerden door speculatieve winst af te wegen tegen detectierisico. Je tactieklaag is precies waar die afweging wordt geïmplementeerd: randomiseer displaygrootte (uniform 30–70% van een vol-geschaalde basis werkt prima), jitter elke timer met ±20–30%, laat een refill af en toe wachten, en laat nooit twee child orders een grootte, een timerfase, en een latentieprofiel delen. Niets hiervan kost meetbare fill-kwaliteit; het verhoogt allemaal de ruisvloer voor iedereen die een detector op je flow probeert te fitten.

Een minimale tactiekengine

De hele laag hierboven comprimeert tot een kleine state machine per slice: IDLE → POSTED → (reprice loop) → CROSSING → DONE, met de break-even-poort bij binnenkomst, een hysteresisband tijdens het posten, en deadline-escalatie. De versie hieronder is bewust minimaal — geen venue-adapters, geen iceberg-beheer — maar is event-driven en side-effect-vrij, dus past hij direct in de rung-4 queue-aware simulator uit de fill-simulatieladder: de simulator roept on_tick/on_fill aan, en interpreteert acties als post → GTX/post-only, cross → IOC, cancel_replace/amend_down → de venue-semantiek uit de matrix hierboven.

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",)]

Drie eerlijke kanttekeningen. p_fill is hier een placeholder-ratio — in productie zou het het gebucketede, live-gekalibreerde model uit het fill-simulatie-artikel moeten zijn, want de hele post/cross-poort is slechts zo goed als die schatting. adverse_frac verbergt de moeilijkste grootheid in het artikel (δ\delta is regime-afhankelijk en piekt precies wanneer posten het meest verleidelijk is); schat het uit je eigen no-fill-uitkomsten, gebucketed naar vol-regime. En de engine hierboven herprijst onvoorwaardelijk via cancel-replace — een venue-bewuste versie zou hoeveelheid-omlaag-wijzigingen via het prioriteitsbehoudende pad moeten routeren en elke actie tegen een messagebudget moeten aanrekenen.

Draai hem in de simulator tegen een replay-tape voordat je de parameters gelooft. Het experiment dat ertoe doet: fixeer de scheduler, veeg escalate_frac en reprice_band, en plot slice-shortfall tegen de door η\eta geïmpliceerde modelkosten. Het oppervlak heeft een plateau — brede banden van bijna-optimale parameters — en twee kliffen: te laat escaleren (onvervulde restanten die in momentum crossen) en te gretig herprijzen (alle queue-waarde verbrand). Je wilt weten waar je kliffen liggen voordat productie ze voor je vindt.

Wat je moet onthouden

  1. Twee lagen, één contract. De scheduler bepaalt hoeveel en tegen wanneer; de tactiek bepaalt hoe. De interface is budget, venster, urgentie naar beneden; fills en slice-shortfall versus interval arrival naar boven. Als je shortfall niet aan een laag kunt toeschrijven, kun je geen van beide afstellen.
  2. De post/cross-poort is rekenkunde, geen onderbuikgevoel. Post iff p>δ/(Π+δ)p > \delta/(\Pi + \delta) met Π=s+ftfm\Pi = s + f_t - f_m. Op krappe crypto-orderboeken is de prijs het fee-verschil, dus je fee-tier bepaalt je tactiek — stel de ladder na elke hertiering opnieuw af.
  3. Age-out timers zijn het snijpunt van twee curves — verzadigende fill-kans tegenover τ\sqrt{\tau}-groeiende adverse selection — geen folklore-constanten.
  4. Queue position is een asset; ken de amend-semantiek van elke venue voordat je hem uitgeeft. CME: hoeveelheid-omlaag behoudt prioriteit. Binance spot: cancelReplace re-queuet altijd, de amend-keepPriority van 2025 behoudt hem voor hoeveelheidsverlagingen. Binance futures: elke modify re-queuet. OKX: ongedocumenteerd — meet het, en ga intussen uit van het slechtste geval.
  5. Icebergs zijn een reeks orders achteraan de queue, en luie zijn herkenbaar. Constante peaks en refills met hetzelfde tijdstempel zijn een gepubliceerde detectiehandtekening; randomiseer groottes en timers of accepteer back-running.
  6. Verscheep de state machine eerst naar je fill-simulator. De tactieklaag is het deel van de stack waar backtest en productie het hardst uiteenlopen — precies daarom hoort hij thuis in de simulator, niet er achteraf aan vastgeschroefd.

Nuttige links

  1. Harris, L. — Optimal Dynamic Order Submission Strategies in Some Stylized Trading Problems, Financial Markets, Institutions & Instruments 7(2), 1-76 (1998)
  2. Cont, R., Kukanov, A. — Optimal Order Placement in Limit Order Markets, Quantitative Finance 17(1), 21-39 (2017)
  3. Frey, S., Sandås, P. — The Impact of Iceberg Orders in Limit Order Books (2009)
  4. 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)
  5. van Kervel, V., Menkveld, A. — High-Frequency Trading around Large Institutional Orders, Journal of Finance 74(3), 1091-1137 (2019)
  6. Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
  7. Lehalle, C.-A. — Market Microstructure Knowledge Needed for Controlling an Intra-Day Trading Process (2011)
  8. Binance Spot API — Order Amend Keep Priority
  9. Binance Spot API — Trading endpoints (cancelReplace semantics)
  10. Binance USDT-M Futures API — Modify Order
  11. OKX API v5 — Amend order
  12. 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.}
}
Disclaimer: De informatie in dit artikel is uitsluitend bedoeld voor educatieve en informatieve doeleinden en vormt geen financieel, beleggings- of handelsadvies. Het handelen in cryptovaluta brengt een aanzienlijk risico op verlies met zich mee.

Auteurs

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Blijf de markt voor

Abonneer je op onze nieuwsbrief voor exclusieve AI-handelsinzichten, marktanalyses en platformupdates.

We respecteren je privacy. Je kunt je op elk moment afmelden.