J-GATE への接続は API と OUCH の選択から始まる── 発注と相場情報を分けて設計する
インフラ

J-GATE への接続は API と OUCH の選択から始まる── 発注と相場情報を分けて設計する

FTL編集部

大阪取引所(OSE)のデリバティブ売買システムへ接続したいという相談は、たいてい「どこまで速くできるか」から始まります。ただ、構成を決めるうえで先に確定させるべきは速度ではありません。J-GATE は注文と相場情報でそれぞれ 2 通りの接続方式を用意しており、どれを組み合わせるかで実装量も運用体制も変わります。ここを決めないまま回線の話に進むと、後から接続方式を変えることになり、実装のやり直しが発生します。

本稿では、J-GATE が公表している接続方式の違いと選び分け、遅延が実際にどこで生まれるのか、そして接続開始までの手続きの順序を整理します。数値と仕様は日本取引所グループ(JPX)が公開している資料に基づいており、参照先は末尾に挙げています。

J-GATE が提供しているもの

J-GATE は "Global Access Trading Engine" の頭文字を取った名称で、2016 年 7 月 19 日に稼働し、2021 年 9 月 21 日にリプレイスされています。基盤は Nasdaq 社の Genium INET Trading で、リプレイス後も引き続き採用されています。対象商品は指数先物・国債証券先物・商品先物・オプション等です。

公表されている性能は、注文処理レイテンシが 50 パーセンタイルで 40 マイクロ秒、注文処理スループットが全体で約 100,000 件/秒です。ここで注意したいのは、この 40 マイクロ秒が取引所の内部処理時間である点です。JPX は「注文取引を受信してから板登録が完了しその応答を返すまでの内部処理時間」と定義しています。自社のアプリケーションが注文を組み立てる時間も、回線を往復する時間も、この数字には含まれていません。

もう一つ、設計に影響する前提があります。J-GATE は TradeGuard というプリ・トレード・リスク・チェック機能を持ち、全ての取引参加者による利用が必須とされています。取引所が注文を受け付ける前にリスクチェックにかけ、閾値を越えていれば発注を自動的に止める仕組みです。自社側でリスク制御を作り込む場合も、取引所側でこの層が入ることを前提に、二重に止まったときの挙動を決めておく必要があります。

J-GATE の接続方式を示した図。注文等は API または OUCH の 2 通り、相場情報は API または ITCH の 2 通りで、API は注文と相場情報の両方を扱えるのに対し、OUCH は発注に特化し、ITCH はマルチキャストによる相場情報の受信に特化していることを表している
注文と相場情報で接続方式が分かれており、API だけは両方をまたぐ

注文の接続方式は API か OUCH か

JPX は、取引参加者と J-GATE との間で注文等を行う接続方式として、API による接続と OUCH による接続の 2 種類を示しています。

API は、J-GATE との接続の共通処理がアプリケーションにより提供された標準的な接続方式です。新規注文、訂正・取消注文のほか、相場情報等も取得することができます。つまり、API を選べばこれ 1 本で発注と相場情報の両方をまかなえます。

OUCH は、J-GATE との通信仕様を定めたプロトコルで、新規注文・訂正注文・取消注文の送信等に特化した接続方式です。相場情報は扱いません。プロトコルとして定義されているということは、接続の共通処理はこちら側で実装するということでもあります。

選択の実質は、接続の共通処理を借りるか、自分で持つかです。API はセッション管理や再接続といった土台が提供される代わりに、その振る舞いは提供されたものに従います。OUCH は薄い分だけ自社で制御できる余地が広く、そのぶん実装と検証の範囲が広がります。「速いほうを選ぶ」という決め方ではなく、自社の開発体制でどこまで持てるかで決める性質のものです。

相場情報は API か ITCH か

相場情報の受信についても 2 通りあります。API による接続と、世界的に標準的な通信方式であるマルチキャストによる相場情報配信プロトコル、ITCH による接続です。

JPX は ITCH を「API との併用を前提とした、相場情報の受信に特化した接続方式」と説明しています。ITCH は単独では成り立ちません。相場情報を ITCH で受けるなら、注文側は API か OUCH のいずれかを別に用意することになります。

マルチキャストで受ける以上、実装上の論点はユニキャストとは変わります。まず受信側の参加処理です。Python であれば次のような形になります。

import socket
import struct

GROUP = "239.0.0.1"      # 実際のグループアドレスは接続仕様書に従う
PORT = 30001
LOCAL_IF = "10.0.0.5"    # 受信に使う NIC のアドレスを明示する

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 受信バッファは既定値のままにしない。バーストで取りこぼす原因になる。
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 16 * 1024 * 1024)
sock.bind(("", PORT))

# 受信する NIC を明示して参加する。複数 NIC の機器では既定の経路に載って
# しまい、意図した回線で受けられないことがある。
mreq = struct.pack("4s4s", socket.inet_aton(GROUP), socket.inet_aton(LOCAL_IF))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
    payload, _ = sock.recvfrom(65535)
    handle(payload)

次に、取りこぼしの検知です。マルチキャストは再送を持たないため、抜けたことに気づく仕組みを受信側に持たないと、板が静かに壊れます。配信されるメッセージには連番が振られるので、期待値との差を監視します。

class SequenceGuard:
    """連番の抜けを検知する。抜けたら復旧手段に切り替える判断材料にする。"""

    def __init__(self) -> None:
        self.expected: int | None = None
        self.gaps = 0

    def check(self, seq: int) -> str:
        if self.expected is None:
            self.expected = seq + 1
            return "ok"
        if seq == self.expected:
            self.expected += 1
            return "ok"
        if seq < self.expected:
            return "duplicate"      # 冗長経路からの重複。捨ててよい
        self.gaps += 1
        self.expected = seq + 1
        return "gap"                # スナップショットの取り直しへ

ギャップを検知したときに何をするかは、設計で決めておく事項です。差分だけを積み上げる実装は、1 度でも抜けた時点で状態が実際とずれます。抜けを検知したらスナップショットから作り直すという復旧経路を、最初から持たせておきます。

組み合わせをどう決めるか

注文 2 通り、相場情報 2 通りなので、組み合わせは 4 つです。実務で候補になるのは次の 3 つに絞られます。

  • API のみ — 発注も相場情報も API で完結する。接続が 1 系統で済み、運用の対象が最も少ない
  • API + ITCH — 発注は API、相場情報はマルチキャストで受ける。板の取り込みを自社で作り込みたい場合の構成
  • OUCH + ITCH — 発注も受信も専用プロトコルで組む。制御できる範囲が最も広く、実装と検証の負担も最も大きい

判断の軸は 3 つあります。1 つ目は遅延の許容値で、これは秒でもマイクロ秒でもよいので数値で決めます。2 つ目は開発体制で、プロトコル実装と接続検証を継続して保守できる人員がいるかどうかです。3 つ目は運用で、障害時に切り分けられる人が何人いるかを見ます。3 つのうち 1 つでも「決まっていない」なら、まず API のみで始めるほうが安全です。後から相場情報だけを ITCH へ移すことはできますが、逆に、走り出してから接続方式を減らす判断は簡単ではありません。

遅延はネットワークで決まる

取引参加者およびユーザは、J-GATE 等の売買システムへアクセスするために arrownet へ接続する必要があります。JPX が公表している arrownet の実測値は、アクセスポイント経由で片道 60 マイクロ秒程度、コロケーション経由で片道 3 マイクロ秒程度です。前者はアクセスポイントからプライマリセンタの売買系システムまで、後者はセンタ内のコロケーションエリアから売買系システムまでの値です。

先ほどの取引所内部処理 40 マイクロ秒と並べると、どこを削ると効くのかが見えます。アクセスポイント経由の往復は 120 マイクロ秒程度、コロケーション経由なら 6 マイクロ秒程度で、この差は 100 マイクロ秒を超えます。取引所内部の処理時間より大きい差が、置き場所だけで生まれます。逆に言えば、コロケーションを使わない構成でマイクロ秒を詰める作業には、費用に見合う効果がありません。

回線側の仕様も押さえておきます。arrownet はアクセスポイントとセンタの間を WDM による 10Gbps の光ファイバーリング網で結び、可用性は 99.999% を確保しています。利用者側の接続回線は 5 キャリアを採用し、広域 Ethernet と専用線、512kbps から 10Gbps までの帯域から選べます。またネットワーク仮想化により、発注のユニキャスト通信と相場情報のマルチキャスト通信、本番環境とテスト環境を 1 つの回線で扱えます。接続方式ごとに回線を引き直す必要はありません。

手続きは 3 段階で進む

JPX は、取引参加者として取引を開始するまでの手続きを、取引資格の取得・ネットワーク接続・取引システム接続の 3 段階として示しています。ISV や相場報道ユーザなど、取引参加者としての接続以外の場合は、この流れの 2 ヶ月目から手続きを開始する形になります。

実装計画を引くときは、この順序が制約になります。取引システムへの接続テストは、ネットワークが通ってからでなければ始められません。接続方式の決定は、ネットワークの申し込みより前に済ませておく必要があります。「実装しながら決める」進め方は、この手続きの構造と噛み合いません。

まとめ

J-GATE への接続で最初に決めるのは、回線でも遅延でもなく接続方式の組み合わせです。注文は API か OUCH、相場情報は API か ITCH で、API だけが両方をまたぎます。ITCH は API との併用が前提で単独では成り立ちません。遅延は取引所内部の 40 マイクロ秒より、アクセスポイント経由 60 マイクロ秒とコロケーション経由 3 マイクロ秒の差のほうが大きく、置き場所の判断が支配的です。そして手続きは資格・ネットワーク・システムの順に進むため、接続方式は最初に確定させておく必要があります。

金融テクノロジー総合研究所では、J-GATE 接続の構成設計から実装、接続検証までを受託しています。既存構成の見直しや、現物と併せた基盤の設計からご相談いただけます。J-GATE 接続開発の詳細もあわせてご覧ください。ご相談はお問い合わせよりご連絡ください。

参考資料

記事一覧に戻る