> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# マッチング

> 板の構造、価格時間優先がどう表現されるのか、有効期間とセルフトレード防止がそこでどう解決されるのかです。

マッチングは[カーネル実行](/ja/protocol/architecture/kernel)の内部にあるステージであって、チェーンが呼び出すサービスではありません。ブロックの注文をコミットされた順序で受け取り、板に突き合わせ、約定を生み出します。誰の残高も動かしません。それは[クリアリングハウス](/ja/protocol/architecture/clearinghouse)の仕事で、マッチングが完了したあとに行われます。

この二つを分けておくことが、エンジンをテスト可能にしています。マッチングが答えるのは*何が何と約定したか*です。クリアリングハウスが答えるのは*それにいくらかかり、誰が誰にいくら支払うことになったのか*です。

<h2 id="the-book">
  板の構造
</h2>

銘柄ごとに専用の板があり、協調する三つの構造としてメモリ上に保持されます。

<div className="dg" data-dg="matching-book">
  <div className="dg-c" style={{aspectRatio:"720 / 302"}}>
    <svg className="dg-w" viewBox="0 0 720 302" aria-hidden="true">
      <path className="dg-wire dg-soft" d="M 348.60 82.00 L 352.60 82.00" />

      <path className="dg-wire dg-soft" d="M 438.20 82.00 L 442.20 82.00" />

      <path className="dg-wire dg-soft" d="M 527.80 82.00 L 531.80 82.00" />

      <path className="dg-wire dg-soft" d="M 617.40 82.00 L 621.40 82.00" />

      <path className="dg-wire dg--blue" d="M 205.00 68.00 L 238.60 68.00" />

      <path className="dg-head dg--blue" d="M 245.00 68.00 L 238.60 72.40 L 238.60 63.60 Z" />

      <path className="dg-wire dg--sky" d="M 205.00 162.00 L 238.60 162.00" />

      <path className="dg-head dg--sky" d="M 245.00 162.00 L 238.60 166.40 L 238.60 157.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"34.7222%",top:"9.9338%",width:"65.2778%",height:"56.2914%"}}><span className="dg-cap">slab arena：注文スロットの事前確保領域</span></div>
    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"9.9338%",width:"27.7778%",height:"25.1656%"}}><span className="dg-t">価格レベル</span><span className="dg-s">順序付きマップ、価格 → レベル</span><span className="dg-n">最良気配は端まで辿って得る、走査ではない</span></div>
    <div className="dg-b dg--sky" style={{left:"0.0000%",top:"41.0596%",width:"27.7778%",height:"25.1656%"}}><span className="dg-t">注文インデックス</span><span className="dg-s">注文ID → スロット</span><span className="dg-n">取り消しと変更は定数時間</span></div>
    <div className="dg-b dg--yellow" style={{left:"36.9444%",top:"19.5364%",width:"11.0556%",height:"15.2318%"}}><span className="dg-t">注文</span></div>
    <div className="dg-b dg--yellow" style={{left:"49.3889%",top:"19.5364%",width:"11.0556%",height:"15.2318%"}}><span className="dg-t">注文</span></div>
    <div className="dg-b dg--yellow" style={{left:"61.8333%",top:"19.5364%",width:"11.0556%",height:"15.2318%"}}><span className="dg-t">注文</span></div>
    <div className="dg-b dg--yellow" style={{left:"74.2778%",top:"19.5364%",width:"11.0556%",height:"15.2318%"}}><span className="dg-t">注文</span></div>
    <div className="dg-b dg--yellow" style={{left:"86.7222%",top:"19.5364%",width:"11.0556%",height:"15.2318%"}}><span className="dg-t">注文</span></div>
    <div className="dg-b dg-plain dg-left" style={{left:"36.9444%",top:"41.3907%",width:"60.8333%",height:"15.2318%"}}><span className="dg-s">到着順の双方向リンクで連なるため、レベル内の優先順位は計算ではなく位置で決まります。</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"74.8344%",width:"100.0000%",height:"20.5298%"}}><span className="dg-t">再利用の順序が固定である理由</span><span className="dg-s">解放スロットは決まった順序で再利用し、インデックスのシードも固定です。性能上の選択ではありません。再利用の順序が違う二つのバリデータは、フォークします。</span></div>
    <div className="dg-lbl" style={{left:"31.2500%",top:"17.8808%",width:"15.2778%",whiteSpace:"normal"}}>各レベルの先頭</div>
    <div className="dg-lbl" style={{left:"31.2500%",top:"62.9139%",width:"15.2778%",whiteSpace:"normal"}}>直接参照</div>
  </div>
</div>

| 構造           | 役割                                                 |
| ------------ | -------------------------------------------------- |
| **価格レベル**    | 価格からレベルへの順序付きマップ。最良買い気配と最良売り気配は、走査ではなく端まで辿るだけで見つかる |
| **注文チェーン**   | 到着順に注文をつなぐ双方向連結リスト。レベル内の優先順位は計算されるのではなく位置で決まる      |
| **注文インデックス** | 注文IDからスロットへの直接マップ。取り消しと変更は探索ではなく定数時間になる            |

注文は**slab arena**に置かれます。確保と解放が定数時間の、事前確保された領域です。そのため板の操作はホットパスでメモリを確保せず、解放されたスロットは、アロケータが置いた場所任せではなく決まった順序で再利用されます。この最後の点は性能上の選択ではありません。二つのバリデータがスロットを異なる順序で再利用したら、スロット配置を観測するものはすべて食い違うからです。

同じ規律が注文インデックスにも当てはまります。シードはランダムではなく固定です。プロセスごとにシードを変えるハッシュマップは衝突攻撃に対する標準的な防御ですが、コンセンサスの実行経路上では、それはフォークです。

価格は全面的に整数で、小数ではなくサブティック単位です。それが実際に送信する値とどう対応するかは[精度](/ja/trading/precision)を参照してください。

<h2 id="priority">
  優先順位
</h2>

優先順位はまず価格、次にその価格でのチェーン内の位置です。「時間」とは、ノードに到着した時刻ではなく、コミットされたブロック内での注文の正規の位置を指します。

これがブロック内のレイテンシ競争を取り除きます。同じブロック内の二つの注文には、どのバリデータも同一に計算する明確な優劣があり、特定のノードにどれだけ近くてもそれは変わりません。ブロックとブロックの間では到着順は依然として意味を持ちますが、競争の単位はマイクロ秒ではなくブロックです。

カーネルのステージ順序がこれを補強します。ブロック内では取り消しがテイカー注文の発注より先に実行されるため、取り消しと同じブロックに届いた注文が板の気配を奪うことはできません。

<h2 id="matching-an-order">
  注文のマッチング
</h2>

<div className="dg" data-dg="matching-walk">
  <div className="dg-c" style={{aspectRatio:"720 / 334"}}>
    <svg className="dg-w" viewBox="0 0 720 334" aria-hidden="true">
      <path className="dg-wire dg--blue" d="M 134.00 144.00 L 155.60 144.00" />

      <path className="dg-head dg--blue" d="M 162.00 144.00 L 155.60 148.40 L 155.60 139.60 Z" />

      <path className="dg-wire dg--sky" d="M 320.00 144.00 L 345.60 144.00" />

      <path className="dg-head dg--sky" d="M 352.00 144.00 L 345.60 148.40 L 345.60 139.60 Z" />

      <path className="dg-wire dg--green" d="M 510.00 144.00 L 535.60 144.00" />

      <path className="dg-head dg--green" d="M 542.00 144.00 L 535.60 148.40 L 535.60 139.60 Z" />

      <path className="dg-wire dg--sky" d="M 633.00 114.00 L 633.00 80.00 L 241.00 80.00 L 241.00 103.60" />

      <path className="dg-head dg--sky" d="M 241.00 110.00 L 236.60 103.60 L 245.40 103.60 Z" />

      <path className="dg-wire dg--green" d="M 633.00 174.00 L 633.00 213.60" />

      <path className="dg-head dg--green" d="M 633.00 220.00 L 628.60 213.60 L 637.40 213.60 Z" />

      <path className="dg-wire dg--sky" d="M 241.00 178.00 L 241.00 213.60" />

      <path className="dg-head dg--sky" d="M 241.00 220.00 L 236.60 213.60 L 245.40 213.60 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"35.3293%",width:"18.0556%",height:"15.5689%"}}><span className="dg-t">到来した注文</span></div>
    <div className="dg-b dg--yellow dg-round" style={{left:"23.0556%",top:"34.1317%",width:"20.8333%",height:"17.9641%"}}><span className="dg-t">板と交差するか</span></div>
    <div className="dg-b dg--sky" style={{left:"49.4444%",top:"35.3293%",width:"20.8333%",height:"15.5689%"}}><span className="dg-t">反対側の最良レベルを消費</span></div>
    <div className="dg-b dg--green" style={{left:"75.8333%",top:"35.3293%",width:"24.1667%",height:"15.5689%"}}><span className="dg-t">約定を出力</span></div>
    <div className="dg-b dg--green" style={{left:"75.8333%",top:"67.0659%",width:"24.1667%",height:"25.7485%"}}><span className="dg-t">完了</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"10.5556%",top:"67.0659%",width:"45.8333%",height:"25.7485%"}}><span className="dg-t">有効期間に応じて残数量を板に置くか拒否</span><span className="dg-s">GTCは板に残す · IOCは取り消す · FOKは全量約定しなければ何も執行しない · ポストオンリーは交差させずに拒否</span></div>
    <div className="dg-lbl" style={{left:"60.6944%",top:"23.9521%",width:"27.7778%",whiteSpace:"normal"}}>残数量、次のレベルへ</div>
    <div className="dg-lbl" style={{left:"87.9167%",top:"58.9820%"}}>残りなし</div>
  </div>
</div>

マッチャーは反対側の先頭を繰り返し消費し、取ったメイカーごとに約定を出力します。これを、到来した注文を使い切るか板が交差しなくなるまで続けます。残数量がどうなるかは有効期間が決めます。

* **GTC** — 残数量を板に置きます。
* **IOC** — 残数量を取り消します。
* **FOK** — 全数量を約定できない場合、何も執行されません。
* **ALO** — ポストオンリー。流動性を取りにいく注文は、交差させずに拒否されます。

約定は生成される時点で帰属情報を持ちます。各約定は、その銘柄の約定列の中で自分がどこに位置するかを記録し、銘柄ごとのその位置は、出力を組み立てる際にブロック全体でのひとつの順序へ解決されます。これによって、あとからイベントを、それを引き起こした正確なトランザクションと、ブロック内の正確な地点まで辿れます。

<h2 id="self-trade-prevention">
  セルフトレード防止
</h2>

到来した注文が、同一の保有者が板に置いている流動性と約定しそうになった場合、その約定は執行されずに抑止されます。どちらの側が譲るかは設定できます。

| モード                         | 動作                            |
| --------------------------- | ----------------------------- |
| **Expire taker**（テイカーを取り消し） | 到来した注文が取り消される                 |
| **Expire maker**（メイカーを取り消し） | 板に置かれていた注文が取り消され、到来した注文は続行される |
| **Expire both**（両方を取り消し）    | 両方が取り消される                     |

この方法で取り消されたメイカー注文はマッチング中に集められ、同じブロックの一部として除去されます。そのため板が、すでに抑止された注文を抱え続けることはありません。

このチェックにおける保有者の同一性は、板が追跡しているアカウントの単位で判定されます。取引側から見た説明は[セルフトレード防止](/ja/trading/self-trade-prevention)を参照してください。

<h2 id="what-matching-does-not-do">
  マッチングがやらないこと
</h2>

手数料の計算も、損益の実現も、ポジションの調整も、証拠金のチェックもしません。それらはマッチングのあと、マッチングが生んだ約定を起点として[クリアリングハウス](/ja/protocol/architecture/clearinghouse)で行われます。

そもそもその注文が許されるものだったのかも判断しません。証拠金の十分性、未約定注文数の上限、リデュースオンリーの制約、成行から指値への変換は、注文が板に到達する前に解決されます。マッチャーが注文を見る時点で残っている問いは、それが板のどこに属するかだけです。

<h2 id="where-to-go-next">
  次に読む
</h2>

<CardGroup cols={2}>
  <Card title="クリアリングハウス" href="/ja/protocol/architecture/clearinghouse">
    約定が生まれたあと、残高とポジションに何が起きるのかです。
  </Card>

  <Card title="注文タイプ" href="/ja/trading/order-types">
    取引側から見た説明です。送信できる注文の種類と、それぞれの振る舞いです。
  </Card>

  <Card title="板" href="/ja/trading/order-book">
    板の厚み、価格レベル、トレーダーとしての板の読み方です。
  </Card>

  <Card title="IntentionKernel" href="/ja/protocol/architecture/kernel">
    ブロック実行の中で、マッチングはここに位置します。
  </Card>
</CardGroup>
