FXシステムの中のおはなし – FIXプロトコル
2020年12月10日 木曜日
CONTENTS
【IIJ 2020 TECHアドベントカレンダー 12/10(木)の記事です】
はじめに
自分は現在Raptorサービス部という部署に所属しています。IIJ Raptorサービス
RaptorサービスではFXプラットフォームそのものをSaaSとして提供しており、様々な金融機関の提供するFXシステムを担っております。
私たちはプラットフォームを提供する中で、多くの金融機関と直接接続し取引を行っています。その中で為替レートやポジション情報などの情報を受信するほか、注文を出したりリコンサイルを行ったりと業務は様々です。
これらの業務は金融機関同士の取引には必要不可欠であり、かつ共通の業務です。そこで、金融機関同士のこういった業務的な取引を電子的に行うために標準化されたプロトコルがあります。Financial Information eXchange プロトコル、通称FIXプロトコルです。
本稿では、このFIXプロトコルについて紹介して私たちのシステムのことを少しでも知ってもらえたらと思います。
FIXプロトコル
FIXプロトコルとはTCP上で動作する通信プロトコルで、電子取引が活発になった1990年代前半に電子取引の標準化とエコシステム構築のために作られました。元々は株式取引用に作られましたが、為替や債券など多種多様な商品の取引に利用されるようになり、今ではFX(外国為替証拠金取引)の通信プロトコルとしてもスタンダードになりました。
金融機関同士の取引は極めてレイテンシにシビアで、かつ非常に高い頻度で通信が発生します。そこで、FIXプロトコルはTCPソケットの起動・破棄にかかるコストを減らすためにセッション確立後ソケットは起動したまま利用します。
またFIXプロトコルはインタフェースが静的であり、プロトコル自体に「マーケット情報要求」「注文発注」「約定の確認」などの一般的な金融機関の取引業務に必要な定義が一通り用意されています。また特定の金融機関に固有の業務がある場合、カスタムでプロトコルを拡張するための定義も用意されています。
さて、実際にFIXプロトコルがどのような通信を行うのか見てみましょう。FIXプロトコルの通信内容は下記のようになっています。(可読性のためSOH文字を” | “で表現してあります)
8=FIX.4.4 | 9=67 | 35=A | 34=5 | 49=client | 52=20201201-00:00:00.000 | 56=server | 98=0 | 108=30 | 10=028
……このままでは何を表しているかさっぱりわかりませんね。
FIXプロトコルはkey-value(=タグ)とセパレータ(SOH文字)によって構成されています。例えば上記の電文は以下の意味を持っています。
Tag | 意味 | 値 |
---|---|---|
8 | BeginString | FIX.4.4 (バージョン) |
9 | Content-Length | 67 |
35 | MsgType | A (=LogOn) |
34 | MsgSeqNum | 5 |
48 | SenderCompId | client (=ユーザの識別子) |
52 | SendingTime | 20201201-00:00:00.000 (送信時刻) |
56 | TargetCompId | server (=送信先の識別子) |
98 | EncryptMethod | 0 (=暗号化無し) |
108 | HeartBtInt | 30 (=ハートビートインターバル) |
10 | CheckSum | 028 |
FIXプロトコルの電文は大きく分けてHeader/Body/Trailerの3つに分かれています。HeaderとTrailerは共通のスキーマで定義されておりHeaderの値にあわせてBody部のスキーマが決定されます。上記の例では、上から8-56までのタグに該当する箇所はHeader、98/108のタグはBody、10のタグがTrailerにそれぞれ該当します。
FIXプロトコルとして標準化されているだけで、FIXのバージョンにも依りますが、MsgType(上記ではLogOnのMsgType)は約100程度、タグそのものの数は約1000程度用意されています。
FIXプロトコルの流れ
「注文発注」を例に、実際にFIXプロトコルで行われるやり取りの流れを見てみます。
FIXプロトコルを用いて注文発注を行う場合、認証を行いセッションを確立させた後に注文の発注を送信する必要があります。
まず、Initiator(=いわゆるクライアント, 接続しに行く側)がAcceptor(=いわゆるサーバ, 接続される側)に認証のためのLogOnの電文を送信します。Acceptorは受信した電文を精査して、問題がない場合は今度はAcceptorがInitiatorへLogOnの電文を送信します。
このフローをもってInitiatorとAcceptor間の認証と対話の準備が完了となり、セッションが確立されます。もしInitiatorの送信したLogOnの電文になんらかのミスマッチがある場合、Rejectの電文がAcceptorからInitiatorへ送信されることになります。
次にInitiatorからAcceptorへNewOrderSingle(=注文発注)の電文を送信してみます。AcceptorはNewOrderSingleの電文を受信後、内容をチェックし注文の処理を実行します。
そのときInitiatorが発注した注文が約定(=注文が成立すること)となった場合、ExecutionReport(=約定情報)の電文がAcceptorからInitiatorへ送信されます。 またAcceptorがInitiatorから受け取った注文を何らかの理由で処理できない場合、Rejectの電文が返却されることもあります。
上記の例では1つの電文送信に対して1つの電文受信が発生するやり取りをしましたが、マーケット情報の取得などでは1つの電文送信に対してNの電文受信が発生するようなやり取りを行うこともあります。
さいごに
実際には接続する金融機関毎に固有の業務や処理が必要になり、そのためのカスタムタグの実装をすることが多いです。しかしそれでもREST APIやWebSocketなどの高レイヤーな汎用プロトコルを利用するよりも、FIXプロトコルを利用する方が簡潔にかつ堅牢な高速処理を行うシステムを構築することができると考えています。
といったところで、以上FIXプロトコルの紹介でした。FIXプロトコルは汎用的なHTTPやgRPCのような通信プロトコルとは異なり、プロトコル自体に業務が定義されている珍しいプロトコルなのではないかと個人的には思います。
おまけ:FIXプロトコルのライブラリ
Initiator/Acceptorを実装するためのライブラリとしてOSSで開発されているものもあります。
そのひとつであるQuickFIXはC++やJava、PythonやRubyなど幅広いプログラミング言語に対応されています。 quickfix/quickfix