arrowhead は切断すると注文が消える── 異常切断・流量制限・自己対当の設計
インフラ

arrowhead は切断すると注文が消える── 異常切断・流量制限・自己対当の設計

FTL編集部

取引システムの再接続処理を設計するとき、多くの実装は「切れたら繋ぎ直して、続きから再開する」という形を取ります。FIX でもマルチキャストでも、その考え方でおおむね間違いありません。ところが東証の arrowhead は違います。接続が異常切断された時点で、取引所側が板の注文を取り消し、以後の注文を抑止します。

この前提を知らずに再接続を実装すると、繋ぎ直した後の状態が想定とずれます。本稿では arrowhead4.0 が持つリスク管理の仕組みを起点に、異常切断・流量制限・自己対当防止の 3 つを設計にどう織り込むかを整理します。仕様は日本取引所グループ(JPX)が公開している資料に基づいており、参照先は末尾に挙げています。

arrowhead4.0 で何が変わったか

arrowhead は 2010 年 1 月 4 日に稼働した現物商品の売買システムです。2015 年、2019 年の更新を経て、2024 年 11 月 5 日に四世代目となる arrowhead4.0 が稼働しました。立会時間の延伸とクロージング・オークションの導入が、この世代の大きな変更です。

公表されている処理能力は、注文応答時間が約 0.2 ミリ秒、情報配信時間が約 0.5 ミリ秒です。取引情報は三重化されたサーバ上で処理されます。ここで注意したいのは、0.2 ミリ秒が取引所内部の応答時間である点です。デリバティブ側の J-GATE と同様、自社の処理時間と回線の往復はこの数字に含まれていません。

クロージング・オークションは、後場のザラバ終了(15 時 25 分)から 5 分間の注文受付時間(プレ・クロージング)を設け、15 時 30 分に板寄せを行う仕組みです。従来の板寄せの条件で約定しない場合でも、売買成立可能値幅の上下限で約定処理を行う特別約定があります。大引けの時刻と挙動を定数で埋め込んだ実装は、この変更で作り直しになりました。制度変更で動く値は設定として外に出しておきます。

arrowhead のリスク管理機能を示した図。取引参加者と取引所の間で接続が異常切断されると、取引所側が板登録済みの注文を即時に取り消し、以後の注文を抑止すること、および注文抑止・取消、ユーザ設定型ハードリミット、自己対当取引防止という 3 つの機能が取引所側に用意されていることを表している
切断の後始末は取引所側で行われる。再接続の設計はその前提から始まる

異常切断で注文は取り消される

arrowhead にはコネクション異常切断時注文取消という機能があります。JPX の説明は「取引参加者と取引所システムとの接続の異常切断時に、即時に注文を取消し、以後の注文を抑止する機能」です。

これは安全側に倒した設計です。接続が切れたということは、参加者側がその後の相場変動に対して注文を管理できない状態になったということで、板に注文を残しておくのは危険だからです。取引所がその判断を代行してくれます。

実装側から見ると、意味するところは 2 つあります。1 つは、再接続した後の板は空になっている前提で組むことです。切断前に出していた注文が生きているつもりで残高や建玉を計算すると、実際とずれます。もう 1 つは、再接続の直後に「以後の注文を抑止」された状態が解除されているかを確認する手順が要ることです。繋がった=発注できる、ではありません。

したがって、再接続後の処理は次の順序になります。

  • 接続の確立 — 通信路が復旧しただけの状態。まだ何も送らない
  • 状態の照会 — 注文状況を問合せ参照機能で取り直し、自社の記録と突き合わせる
  • 抑止の解除確認 — 発注可能な状態に戻っているかを確かめる
  • 発注の再開 — 必要な注文を出し直す。切断前の注文を「そのまま復元」しない

最後の点は運用の判断が要ります。切断していた間に相場は動いています。切断前と同じ値段で機械的に出し直す実装は、状況が変わった後の価格で発注することになります。

状態として書き下すと、次のような形になります。接続の確立と発注可能を別の状態にしておくのが要点です。

from enum import Enum, auto


class LinkState(Enum):
    """接続の状態。CONNECTED と TRADABLE を分けて持つ。"""

    DISCONNECTED = auto()   # 切れている
    CONNECTED = auto()      # 通信路は復旧したが、まだ発注してはいけない
    RECONCILING = auto()    # 注文状況を照会し、自社の記録と突き合わせている
    TRADABLE = auto()       # 抑止の解除を確認した。発注してよい


class Link:
    def __init__(self, gateway, book) -> None:
        self.state = LinkState.DISCONNECTED
        self.gateway = gateway
        self.book = book          # 自社が把握している注文の記録

    def on_disconnected(self) -> None:
        """異常切断。取引所側で板の注文は取り消され、以後の注文は抑止される。

        自社の記録を「板に注文が残っている」ままにしない。生きているつもりの
        注文を前提に建玉を計算すると、実際とずれる。
        """
        self.state = LinkState.DISCONNECTED
        self.book.mark_all_unknown()

    def on_connected(self) -> None:
        self.state = LinkState.CONNECTED

    def reconcile(self) -> None:
        """注文状況を取引所へ問い合わせ、記録を実際に合わせる。"""
        self.state = LinkState.RECONCILING
        live = self.gateway.query_orders()      # 問合せ参照機能
        self.book.replace_with(live)            # 差分ではなく置き換える

        # 繋がった=発注できる、ではない。抑止が解けているかを確かめる。
        if self.gateway.is_order_entry_enabled():
            self.state = LinkState.TRADABLE

    def can_send(self) -> bool:
        return self.state is LinkState.TRADABLE

止める手段は取引所側にも用意されている

異常切断以外にも、arrowhead には注文を止める機能が用意されています。設計の際は、自社で作る制御と取引所側の機能の役割分担を決めておきます。

注文抑止・取消は、取引参加者からの指示により、仮想サーバまたは仮想サーバグループという単位で注文の抑止と板登録済み注文の自動取消を行う機能です。障害時に「まず止める」という操作を、アプリケーションの外側から実行できます。

ユーザ設定型ハードリミットは、参加者が個別に閾値を設定できるリミッター機能です。設定できるのは、一注文あたりの注文代金と、単位時間あたりの注文・約定代金の上限です。単位時間あたりの上限があるという点は、自社側の流量制御を設計するうえで重要です。自社の送信ペースを取引所の閾値と独立に決めると、想定外の場面で取引所側に止められます。

2024 年 11 月にはマスキャンセルも導入されました。arrowhead にアカウントを持つユーザの注文を一括で取り消す機能で、機関投資家等の利用が想定されています。

これらを踏まえた設計指針は 1 つです。止める手段を自社の実装だけに頼らない。アプリケーションが暴走したとき、そのアプリケーション自身に止めさせる設計は成り立ちません。取引所側の手段と、その実行手順を運用ドキュメントに書いておきます。

自己対当は事前登録が要る

同一投資家の注文同士が約定してしまう自己対当は、機関投資家にとって避けたい事象です。arrowhead には自己対当取引防止(STP; Self-Trade Prevention)機能があり、サーバに設定された STP アカウントを参照して、同一投資家の注文が対当した場合に発動します。

方式は 2 つあります。STP-O は既に板登録されていた注文側を失効させ、STP-N は新規に発注された注文側を失効させます。どちらを選ぶかで、失効する注文が変わります。板に置いた指値を守りたいのか、新規の発注を優先したいのかという運用方針の問題です。

実装上の注意は 3 点あります。1 つ目は、STP の対象がザラバ約定方式による付合せに限られ、同時呼値注文は除かれることです。板寄せでは効きません。2 つ目は、利用に STP アカウントの事前登録が必要なことで、これは開発の日程に影響します。3 つ目は、注文が失効する経路が 1 つ増えるという点です。自分が出した注文が、自分の別の注文のせいで消えます。失効の理由を記録に残していないと、後から原因を追えません。

相場情報は 2 系統から選ぶ

相場情報の配信は 2 つのサービスがあります。FLEX Standard は 10 本気配までの気配数量を値段ごとに配信し、四本値(場単位)・売買高・売買代金・指数や統計情報も配信します。FLEX Market by Order は 2024 年 11 月に導入されたもので、相場情報を注文ごとに、すべての気配情報をより詳細な情報として配信します。

選択は用途で決まります。10 本気配で足りる用途に Market by Order を引くと、扱うデータ量と実装の複雑さだけが増えます。逆に、板の厚みや注文の挙動を分析するなら Standard では情報が足りません。

Market by Order を選んだ場合、板は自分で組み立てることになります。注文単位の更新から板を再構成する処理と、欠損を検知したときにスナップショットから作り直す経路が必要です。この設計は J-GATE の ITCH を扱う場合と同じ考え方になります。

まとめ

arrowhead への接続では、異常切断の後始末が取引所側で行われます。切れた時点で板の注文は取り消され、以後の注文は抑止される。したがって再接続の実装は「続きから再開する」ではなく、状態を照会し直して、抑止の解除を確認してから発注を再開する形になります。止める手段は注文抑止・取消とマスキャンセルが取引所側に用意されており、自社の制御だけに頼らない設計にします。ユーザ設定型ハードリミットには単位時間あたりの上限があるため、自社の流量制御はその閾値と揃えます。自己対当防止は STP-O と STP-N のどちらを使うかを運用方針として決め、事前登録の期間を日程に織り込みます。

金融テクノロジー総合研究所では、arrowhead 接続の設計・実装と、障害時の挙動を含めた検証を受託しています。既存接続の点検や、現物とデリバティブを併せた基盤の設計からご相談いただけます。arrowhead 接続開発の詳細もあわせてご覧ください。ご相談はお問い合わせよりご連絡ください。

参考資料

記事一覧に戻る