📝

Draft article

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

← 記事一覧に戻る
July 24, 2026
読了時間: 5分

スライスの内側:スケジューラと取引所の間にある子注文戦術

スライスの内側:スケジューラと取引所の間にある子注文戦術
#execution
#child orders
#order tactics
#queue position
#maker-taker
#iceberg orders
#microstructure
#python

Almgren-Chriss軌道が与えてくれるのは1つの数字だ。今後5分間で4.2 BTCを売れ、というように。VWAPスケジュールも同種の数字を、別の根拠に基づいて与えてくれる。しかしどちらも、その後に何が起きるかについては何も語らない。その4.2 BTCが1本のマーケッタブル注文として板に叩き込まれるのか、タッチに滞留してメイカー手数料を稼ぐのか、0.3 BTCの表示注文の裏に隠れるのか、あるいは動くクォートを追いかけて11回もリプライスされるのか——。この二段目の意思決定こそが戦術レイヤーであり、手数料が支配的な暗号資産の板においては、上位のスケジューラの選択よりもスライスあたりのPnLを日常的に大きく動かす。TWAPとよく調整されたAlmgren-Chrisiの間で、親注文全体を通じたインパクトのbps差はスケジューラの区間予算によって数bps程度しか変わらない。一方、本来メイクできたはずのスライスでテイカー手数料を払ったり、不用意なリプライスでキューポジションを失ったりすれば、1時間あたりでそれと同等かそれ以上のコストがかかる。本稿が扱うのは、誰もが実装していながらほとんど誰も文書化しない層——各子注文が板にどう触れるかを決める状態機械——についてである。

二つのレイヤー、一つの狭いインターフェース

LehalleとLaruelleのMarket Microstructure in Practice(第2版、2018年)は、あらゆる執行デスクが行き着く構造を定式化している。数量を時間軸に配分する戦略レイヤー(スケジューラ)と、その配分をライブの板に対して実際にワークさせる戦術レイヤー(マイクロトレーダー)だ。この分離は美学の問題ではない。両レイヤーは異なる時計と異なるデータの上で生きている。スケジューラは分単位で思考し、ボラティリティと出来高の予測を消費し、変分問題を解く。戦術レイヤーはミリ秒〜秒単位で思考し、L2の差分とキュー推定を消費し、小さな停止問題の連続を解く。

二層執行アーキテクチャ:スケジューラがスライス予算と緊急度を下位に渡し、戦術レイヤーが約定と乖離を上位に返す

両者の間のインターフェースは狭くあるべきだ。下向きには、スライス kk ごとに:

  • 予算 qkq_k — この区間で執行すべき数量(Almgren-Chrisiの nkn_k、あるいはVWAPの出来高カーブの増分);
  • ウィンドウ τk\tau_k — スライスの長さ;
  • 緊急度 — Almgren-Chrisiにおける自然な候補は κ=λσ2/η\kappa = \sqrt{\lambda\sigma^2/\eta} であり、これはリスク回避度、ボラティリティ、流動性を1つのレートに圧縮したものだ。VWAPスケジューラの場合は通常バンド距離(「目標カーブから1.8%遅れている」)になる。

上向きには、タイムスタンプと手数料付きの約定、未約定の残量、そして区間到着ミッドに対して測定されたスライス単位の実装ショートフォールが渡される。この最後の項目が重要だ。スケジューラのインパクトパラメータ η\eta は、レート qk/τkq_k/\tau_k で流動性を要求することが本来いくらのコストを伴うべきかをすでに価格付けしている。戦術レイヤーの職務記述は一行で済む。親注文の存在を漏らすことなく、η\etaが示唆するコストより良い水準で約定を実現すること。 測定したスライスショートフォールがモデルコストを一貫して上回るなら、キャリブレーションされた η\eta は下げられ、スケジューラは加速し、スタック全体が改善する。もしスケジュールコストからスライスショートフォールを分離して測定できないなら、どちらのレイヤーも調整できない——手元にあるのはぼやけた1つの数字と、2つのつまみだけになる。

残量の扱いもこの契約の一部だ。スライスが未約定数量を残して終了したとき、戦術レイヤーは強制的に完了させる(残量をクロスする——締切緊急度下でのデフォルト)か、スケジューラに返して残りのスライスに再配分させる(低κ\kappaスケジュールの序盤なら許容できるが、締切間際では再配分が静かに積み重なり巨大な最終スライスへと化けるため有害)かのいずれかを選ぶ。

エスカレーションのはしご:まずパッシブに、締切に向けてアグレッシブに

この分野で最も古い結果はHarris(1998)の"Optimal dynamic order submission strategies in some stylized trading problems"(Financial Markets, Institutions & Instruments 7(2))である。締切までに取引を完了させなければならない流動性トレーダーにとって、最適な戦略は動的だ——時間が安いうちは指値注文で板に立ち、締切が近づくにつれて市場に向かってリプライスし、最後にクロスする。あらゆる本番の戦術エンジンはこの形の子孫である。タッチにポストし、時間切れで撤退し、エスカレートし、クロスする。 現代の手数料体系とキューダイナミクスが付け加えるのは、各遷移が正確にいつ発火すべきかという算術だ。

クロスの損益分岐点

単位あたりの作業を、現在のミッドを基準とした相対価格で考える(買いの場合)。今すぐクロスすると、スプレッドの半分とテイカー手数料がかかる。

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

ウィンドウ τ\tau にわたってビッドにポストすると確率 pp で約定し、約定すればハーフスプレッドを得てメイカー手数料 fmf_m(リベートなら負)を払う。約定しなければウィンドウ終了時にクロスすることになるが、そのときには価格が平均して δ(τ)=E[約定なし時の逆行するミッド変動]>0\delta(\tau) = E[\,\text{約定なし時の逆行するミッド変動}\,] > 0 だけ不利に動いている——これは厳密に正である。なぜなら約定しないことと不利な方向へのドリフトは同じ事象だからだ。市場があなたのビッドから離れて上昇するとき、あなたのビッドはヒットされない。期待ポスティングコストは次のようになる。

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).

ポストがクロスに勝つのは次の条件を満たすときだけだ。

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

ここで Π\Piプライズ——テイクではなくメイクすることで獲得する往復分の全体、すなわちスプレッドと手数料差分の合計——である。これは執行におけるメイカー・テイカー経済学全体を支配するのと同じ損益分岐点を、単一スライスに凝縮したものだ。

具体的な数値を、BTCUSDT無期限先物で見てみよう。ミッド10万ドル、スプレッド1ティック s = \0.10VIP0相当の手数料はメイカー2bp・テイカー5bpなので、VIP0相当の手数料はメイカー2bp・テイカー5bpなので f_m = $20f_t = $50(1BTCあたり)。プライズは(1BTCあたり)。プライズは \Pi = 0.10 + 50 - 20 = $30.10 \approx 3bpとなる——スプレッドの寄与がほぼゼロである点に注目してほしい。タイトな暗号資産のメジャー通貨ペアでは、プライズの正体は事実上手数料差分そのものだ。日次ボラティリティを3 bp となる——スプレッドの寄与がほぼゼロである点に注目してほしい。タイトな暗号資産のメジャー通貨ペアでは、プライズの正体は事実上手数料差分そのものだ。日次ボラティリティを3%(\sigma_{\text{day}} = $3{,}000)とし、)とし、\delta(\tau) \approx 0.6,\sigma_{\text{day}}\sqrt{\tau/86400}$ とする(この0.6は逆選択のヘアカットであり、鵜呑みにせず自分でキャリブレーションすべき係数だ)。

  • τ=10\tau = 10 秒: \delta \approx \19、よって、よって p^* = 19/49 \approx 0.39$。10秒以内に少なくとも39%の約定確率が見込めるときだけポストする。
  • τ=60\tau = 60 秒: \delta \approx \47、よって、よって p^* = 47/77 \approx 0.61$。
  • 2bpの手数料の代わりに1bpのメイカーリベートがある場合(f_m = -\10):): \Pi = $60.10となり、10秒の閾値はとなり、10秒の閾値はp^* \approx 0.24$ まで下がる。

ここから構造的な事実が2つ見えてくる。第一に、δ\deltaτ\sqrt{\tau} のように増大する一方 Π\Pi は一定なので、p\*(τ)1p^\*(\tau) \to 1 となる。つまり忍耐には明確な期限があり、タイムアウトタイマーはヒューリスティックではなく、2本の曲線の交点そのものだ——推定された p(τ)p(\tau)(前方のキューが捌けるにつれ飽和していく凹関数)と、p\*(τ)p^\*(\tau)(上昇する関数)の交点である。第二に、取引する手数料ティアが物理的にこのはしごを動かす。テイカー手数料を引き下げるティアアップグレードは最適な戦術をよりアグレッシブにする——多くの人がVIPティアの再判定後に約定統計が変化して初めて気づく連関だ。

Contと Kukanov, "Optimal order placement in limit order markets"(Quantitative Finance 17(1)、2017年;arXiv 2012年)は、これを1期間モデルで厳密化している。ショートフォールへのペナルティ付きで、SS単位を成行注文と指値注文(1つまたは複数の取引所にまたがる)に分割して執行する期待コストを最小化する問題だ。単一取引所の解は明示的であり、newsvendor構造を持つ。最適な指値注文サイズはキューアウトフローの分布によって決まる——前方のキューが期待アウトフローに対して小さいときは積極的にサイズをポストし、テールリスクは成行注文でカバーする。彼らのマルチ取引所への拡張は確率近似法で解かれ、あらゆるスマートオーダールーターのパッシブ配分ロジックの知的な核心を成している。戦術エンジンにとっての実践的な読み方はこうだ。上の損益分岐点における pp は定数ではなく、キューポジションとドレインレートの関数である。だからこそ戦術レイヤーはキューポジション推定器をファーストクラスの入力として消費しなければならない。

タッチでのパッシブなポストからリプライスを経て締切での残量クロスに至るエスカレーションを示すスライスタイムライン

緊急度パラメータはこのはしご全体を圧縮する。スケジューラから渡される κ\kappa が高いということは、特性時間 θ=1/κ\theta = 1/\kappa が短いということだ。ウィンドウは縮み、p\*p^\* は上昇し、エンジンはただちにクロスへと進む——これは正しい振る舞いだ。なぜならスケジューラはすでに、在庫リスクが手数料の節約を上回ると宣言しているからだ。低い κ\kappa はパッシブフェーズを引き伸ばす。戦術レイヤーは自らの市場観から緊急度を再導出すべきではない。それはスケジューラの仕事であり、これを重複させると互いに矛盾する2つのコントローラが生まれてしまう。

キューポジションを焼かずにリプライスする

一度ポストすると、クォートはドリフトしていく。これを愚直に追いかける——キャンセルして新しいタッチに出し直し、それを繰り返す——というやり方は、まさにポストを正当化していたはずのその約定確率を、戦術エンジン自身が静かに破壊してしまう典型例だ。キューポジションは測定可能なドル価値を持つ資産であり(Moallemi and Yuan、2016年は実際にこれに値をつけている——流動性の高いFIFOの板における列の先頭ポジションは、スプレッドの相当な割合に値する)、リプライスの判断はすべて1つのトレードである。今のキューポジションを売り、別の価格レベルの列の最後尾を買う。このトレードは、新しいレベルの価値がメッセージングコストを差し引いてもなお元のポジションの価値を上回るときにのみ実行する価値がある。そのためには、各取引所のamendが実際に自分の列内順位に何をするのかを知る必要がある——そしてその答えは驚くほど取引所ごとにばらばらだ。

CME Globexは最もクリーンなセマンティクスを文書化している。注文数量を減らすと時間優先権は保持される。数量を増やす、または価格を変更すると列の最後尾に送られる。これが参照モデルだ——数量減少は無料、それ以外はすべて再キューイングとなる。

Binance現物は歴史的にPOST /api/v3/order/cancelReplaceしか提供していなかった——アトミックに見えるが実際には明示的にノントランザクショナルな、キャンセルと新規注文の組み合わせだ。モードは2種類。STOP_ON_FAILURE(デフォルト——キャンセルが失敗すると新規注文も出されない)とALLOW_FAILURE(キャンセルが失敗しても新規注文を出す——うっかり二重エクスポージャーの温床)。この操作は部分的に成功することがあり、それはHTTP 409で通知される。そのためOMS側は両方のレグを独立して整合させなければならない。しかも新しい注文は常にゼロからキューの人生をスタートする。その後2025年、BinanceはOrder Amend Keep Priority(PUT /api/v3/order/amend/keepPriority)を実装した。数量をその場で減らし、時間優先権を保持し、未約定注文数へのコストはゼロ。CMEのセマンティクスが15年遅れでやってきた——ただし数量減少の側面だけだが。

BinanceのUSDT-M先物には真のmodifyエンドポイント(PUT /fapi/v1/order)があるが、注意書きを読む必要がある。対象はLIMIT注文のみで、pricequantityの両方を送らなければならず、そして*「修正された注文はマッチングキュー内で再順序付けされる」*——ドキュメントは、たとえ純粋な数量減少であっても優先権保持を約束していない。先物のmodifyはすべて、1回のメッセージ数と注文IDの維持だけを節約してくれるキューリセットだと考えるべきだ。知っておくべき鋭い注意点が1つある。GTX(post-only)注文をクロスしてしまうような価格へと修正すると、その注文はキャンセルされるのであって、拒否されて元のまま残るわけではない——これを確認しないペッグ実装は、時折自分自身を消滅させてしまうことになる。

OKXPOST /api/v5/trade/amend-order(newPxnewSz、amend失敗時に自動キャンセルするcxlOnFail)を公開している。これは単一メッセージで注文IDを保持し、非同期に結果を確認する——sCode = 0は「リクエストが受理された」ことを意味するだけで、実際の結果はordersチャネル上でamendResultとして届く。公開ドキュメントが際立って明記していないのがキュー優先権の挙動だ。この文書化の欠落を楽観で埋めてはいけない。実際に測定すべきだ。閑散としたレベルに2本のマーカー注文をポストし、片方のサイズを下方向にamendして、数百試行にわたってどちらが先に約定するかを観察する。そのデータが手元にあるまでは、保守的な仮定——価格変更はどこでも再キューを引き起こし、数量減少は明示的に文書化された取引所でのみ優先権を保持する——だけが正当化できる立場だ。

amend操作を取引所別にまとめ、どの操作がキュー優先権を保持しどれがリセットするかを示すマトリクス

この政策上の帰結は次のとおりだ。

  1. ペッグではなくヒステリシス。 タッチが自分の指値からバンド bb ティック以上ドリフトしたときだけリプライスする。バンドの内側では、ドリフトはノイズであり、自分のキューポジションは1ティックの価格改善よりも価値がある。妥当な初期バンドは短時間ボラティリティでスケールした1〜3ティックだ。正しいバンドは限界的なリプライスをEVニュートラルにする。VnewVcur=cmsgV_{\text{new}} - V_{\text{cur}} = c_{\text{msg}}、ここで VV はMoallemi-Yuan流のキュー価値、cmsgc_{\text{msg}} はレート制限のシャドープライスだ。amend/cancel-replace操作は両方のBinance取引所で注文レート予算を消費する。すべてのティックでペッグする戦術エンジンは、システムの残りの部分からメッセージ容量を奪ってしまう。
  2. 下方向はamend、下方向にcancel-repostは絶対にしない。 スケジューラが飛行中にスライス予算を削減したとき(出来高が枯渇しているのを見たPOVスケジューラ、部分約定後のAlmgren-Chrisiの再ソルブなど)、優先権保持パスが存在する場合はそれを使う。これはこの層全体の中で唯一のフリーランチだ。
  3. リプライスにおける非対称な緊急度。 市場に向かってリプライスする(追いかける)と、より悪い価格でキューがリセットされる——これはエスカレーションロジックからそのタイマーによってのみ発火すべきだ。逆方向へのリプライス(市場が自分の方に来た)は贈り物だ。パッシブバンド経由でのみそれを受け取る。なぜなら現在のレベルはどのみちすぐに約定するからだ。

アイスバーグ、表示サイズ、そして何が意図を漏らすか

表示サイズは3つ目の意思決定であり、これは正真正銘の両刃のトレードであって、無料のステルスボタンではない。実証結果を見てみよう。

  • FreyとSandås("The Impact of Iceberg Orders in Limit Order Books"、2009年ワーキングペーパー;Quarterly Journal of Finance、2017年)は、Xetraのデータでアイスバーグ注文が提出出来高の9.3%、執行出来高の15.9%を占め、通常の指値注文の12〜20倍のサイズで、そして——ここが肝心な点だが——他の参加者がアイスバーグを検知すると、対応する成行注文で応じてくることを示した。隠れたサイズは、一度推測されると、フローを引き寄せる。潜在流動性の探索は双方向に働く。
  • Bessembinder、Panayides、Venkataraman("Hidden liquidity: an analysis of order exposure strategies in electronic stock markets"、JFE 94(3)、2009年)は、隠れた注文がサンプル出来高の44%を占めたユーロネクスト・パリのデータで、隠すことは実装ショートフォールを下げる一方、完全執行の確率を下げ、完了までの時間を伸ばすことを示した。露出は約定を買い、それをインパクトで支払う。オプションは理論が予測するとおりに使われる——アグレッシブな注文は取引相手を引き寄せるために露出し、忍耐強いサイズは隠れる。
  • EsserとMönch("The navigation of an iceberg"、Finance Research Letters 4(2)、2007年)は、ピークサイズを最適化問題として扱う。表示を大きくすれば約定は速くなり、表示を小さくすれば漏れる情報は減り、最適点は内点解となる。

まずメカニクスを押さえておく必要がある。これが最適化を縛るからだ。ネイティブのアイスバーグをサポートするほぼすべての取引所(Binance現物はicebergQty経由、OKXはアイスバーグアルゴ注文経由)で、表示中のピークがリフィルされるたびに、そのリフィルはその価格の列の最後尾に入る。つまりアイスバーグは「隠れたサイズを持つ1本の注文」ではなく、それぞれがフルにキューウェイトを払う小さな注文の連続であり、それが自動的に発射され続ける。上の手数料損益分岐点の議論において、これは重要な意味を持つ。ピークあたりの実効的な pp は元のポジションのそれではなく、列の最後尾からの約定確率になる。深いキューは小さなピークを二重に罰する——約定が遅くなり、リフィルのたびに逆選択のコストが積み増しされる。

次にシグナリング問題がある。FreyとSandås自身の検知手法が教訓的だ。彼らの頻度主義的な検知器は、最もありがちな実装上の手抜きパターン2つに着目する。一定のピークサイズと、実行された取引のタイムスタンプと一致するリフィルのタイムスタンプだ。この検知器を走らせている参加者は誰でも(そして暗号資産の取引所では、それを行う参加者は多い——取引所自身のマッチングメタデータのおかげで、コロケーションされたフローにとってはさらに容易だ)、わずか数回のリフィルであなたの隠れたサイズを再構築してしまう。漏洩の経路を、私が実際によく見かける頻度順に並べると次のようになる。

  1. 一定または丸い表示サイズ(毎回0.5 BTC、など)。
  2. フルピークの執行直後の、瞬時かつ決定論的なリフィル——同一タイムスタンプという署名。
  3. 決定論的なエスカレーションタイマー:すべてのスライスでちょうど30秒後にクロスすれば、テープはメトロノームのように見える。
  4. 固定されたリプライスのレイテンシとバンド——amendのケイデンスは、注文サイズと同じくらい識別力の高い指紋になる。これはデジタルフィンガープリントとトレーダー識別で扱っているテーマだ。

検知されることのコストは仮説上の話ではない。Van KervelとMenkveld("High-frequency trading around large institutional orders"、Journal of Finance 74(3)、2019年)は、HFTが最初は機関投資家のメタ注文に逆張りする(あなたのパッシブな戦術が消費する流動性を提供する)が、その持続性が情報を明かした時点で、注文と同じ方向に切り替わり、残量をバックランして親注文のコストを大幅に押し上げることを示している。彼らが調査した機関投資家は、投機的な利益と検知リスクをトレードオフさせることで対応した。あなたの戦術レイヤーは、まさにそのトレードオフが実装される場所だ。表示サイズをランダム化する(ボラティリティでスケールしたベースの30〜70%を一様分布で選ぶのがよく機能する)、すべてのタイマーを±20〜30%ジッターさせる、時にはリフィルを待たせる、そして2つの子注文がサイズ・タイマー位相・レイテンシプロファイルを共有することのないようにする。これらは測定可能な約定品質を犠牲にしない。それでいて、あなたのフローに検知器をフィッティングしようとする者にとってのノイズフロアを引き上げる。

最小構成の戦術エンジン

上述のレイヤー全体は、スライスごとの小さな状態機械に圧縮できる。IDLE → POSTED → (リプライスループ) → CROSSING → DONE、エントリー時に損益分岐点ゲートを、ポスト中はヒステリシスバンドを、そして締切エスカレーションを備えたものだ。以下のバージョンは意図的に最小構成にしてある——取引所アダプタもアイスバーグ管理もない——が、イベント駆動かつ副作用フリーであるため、fill-simulationのラダーにあるランク4のキュー対応シミュレータにそのまま組み込める。シミュレータがon_tick/on_fillを呼び出し、アクションを解釈する。post → GTX/post-only、cross → IOC、cancel_replace/amend_down → 上のマトリクスにある各取引所のセマンティクスへ、というように。

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

正直に言うべき注意点が3つある。ここでのp_fillはプレースホルダーの比率にすぎない。本番ではfill-simulation記事にあるようなバケット化されライブでキャリブレーションされたモデルであるべきだ。なぜならpost/crossゲート全体の質は、その推定値の質を超えられないからだ。adverse_fracはこの記事の中で最も難しい量を隠している(δ\deltaはレジーム依存であり、まさにポストが最も魅力的に見えるときにスパイクする)。自分自身のno-fill(未約定)の結果から、ボラティリティレジーム別にバケット化して推定すべきだ。そして上のエンジンは無条件にcancel-replace経由でリプライスしている——取引所を意識したバージョンでは、数量減少の変更を優先権保持パスに通し、すべてのアクションをメッセージ予算に対して課金すべきだ。

このパラメータを信じる前に、リプレイテープに対してシミュレータ内で実際に走らせてみてほしい。重要な実験はこうだ。スケジューラを固定し、escalate_fracreprice_bandを掃引しながら、スライスショートフォールを η\eta が示唆するモデルコストに対してプロットする。その曲面には台地(近似最適なパラメータの広い領域)と、2つの崖がある。エスカレートが遅すぎる崖(未約定の残量がモメンタムに突っ込んでクロスする)と、リプライスが早すぎる崖(キュー価値がすべて焼かれる)だ。自分の崖がどこにあるかは、本番がそれを教えてくれる前に知っておきたい。

まとめ

  1. 二つのレイヤー、一つの契約。 スケジューラはどれだけ・いつまでにを決め、戦術はどうやってを決める。インターフェースは下向きに予算・ウィンドウ・緊急度、上向きに約定と区間到着ミッドに対するスライスショートフォールだ。ショートフォールをどちらのレイヤーに帰属させるべきか分からなければ、どちらも調整できない。
  2. post/crossゲートは勘ではなく算術だ。 Π=s+ftfm\Pi = s + f_t - f_m として、p>δ/(Π+δ)p > \delta/(\Pi + \delta) のときのみポストする。タイトな暗号資産の板では、プライズの正体は手数料差分そのものであり、あなたの手数料ティアがあなたの戦術を決める——ティアが再判定されるたびにはしごを調整し直すこと。
  3. タイムアウトタイマーは2本の曲線の交点である——飽和していく約定確率と、τ\sqrt{\tau}で成長する逆選択の交点であり、経験則の定数ではない。
  4. キューポジションは資産であり、それを費やす前に各取引所のamendセマンティクスを知っておくこと。 CME:数量減少は優先権を保持する。Binance現物:cancelReplaceは常に再キューを引き起こすが、2025年のamend-keepPriorityは数量削減について優先権を保持する。Binance先物:すべてのmodifyが再キューを引き起こす。OKX:未文書化——測定せよ、それまでは最悪を仮定せよ。
  5. アイスバーグは列の最後尾に並ぶ注文の連続であり、手抜きな実装は読み取られる。 一定のピークと同一タイムスタンプのリフィルは、既に論文で発表された検知シグネチャだ。サイズとタイマーをランダム化するか、バックランされることを受け入れるかのどちらかだ。
  6. 状態機械はまずfillシミュレータに組み込むこと。 戦術レイヤーはバックテストと本番が最も乖離しやすい部分であり、だからこそ後付けではなく、シミュレータの内側に最初から組み込まれるべきなのだ。

Useful 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.}
}
blog.disclaimer

Authors

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

市場の先を行く

ニュースレターを購読して、独占的なAI取引の洞察、市場分析、プラットフォームの更新情報を受け取りましょう。

プライバシーを尊重します。いつでも配信停止可能です。