注文の状態は好きな値にはなれない
一言でいうと
注文の報告は、自由な記録ではなく状態機械の出力であり、その中の数量には、崩れてはならない等式があります。障害調査での「何が間違っていたのか」の大部分は、この2つを機械で検査すれば出てきます。
なぜ必要なのか
注文1つに付く報告は、少なければ3–4行、多ければ数十行です。その行を人が目で読んで異常を探せるのは、最初の数件までです。1日分を受け取ると数万行になり、その中で問題になるのは5–6件です。そのため、FDEが顧客のデータを受け取って最初にすることは、読むことではなく、ふるいにかけることです。
ふるいを作れる理由は、このドメインに規則があるからです。FIXプロトコルは、注文の状態をOrdStatusというフィールドで表現し、New・PartiallyFilled・Filled・Canceledのような名前を定めています。フィールドの意味はFiximateで確認できます。どの状態からどの状態へ行けるかは、市場やブローカーごとに少しずつ異なるので(このラボでは遷移表をデータとして与え、それをこのラボの前提とします)、重要なのは、表を暗記することではなく、表があることと、その表をコードに読ませることです。
どう動くのか
検査は5つに分かれます。
第一に、禁止された遷移。前の報告の状態から後ろの報告の状態へ行く道が表になければ、問題です。ここで最も重要な部類が終端状態です。約定完了・取消・拒否・失効のように、これ以上行く先がない状態から、再び何かが出てくれば、それは遅れて届いた報告か、本当の欠陥です。ところが、表自体が間違っている場合もあります。終端だと宣言しておきながら、出ていく遷移が1行残っていれば、検査器はその遷移を正常として通過させます。そのため、表を読んだらすぐに、表自身の矛盾を探します。
第二に、数量の等式。生きている注文では、CumQty + LeavesQty == OrderQtyです。累計約定と残数量を足すと、注文数量になるという意味です。注意すべき点は、注文が終わるとこの等式が成り立たないことです。半分だけ約定した注文を取り消すと、残りの半分は消えて、残数量は0になります。等式を無条件に適用する検査器は、正常な取消をすべて誤検知として上げます。
第三に、累計の単調性。CumQtyは減りません。減ったように見えるなら、報告が入れ替わって届いたか、巻き戻しが起きたのです。
第四に、過約定。約定数量の合計が注文数量を超えれば、それはお金のかかった事故です。ただし、同じ報告が2回入ってくると、合計が膨らんで過約定のように見えます。そのため、この判定は、重複を除外したあとで、もう一度行う必要があります。
第五に、平均約定価格。AvgPxは、そこまでの約定を数量で加重した平均でなければなりません。ここで浮動小数点数を使うと、最後の桁が揺らいで、問題のないデータがずれたように出ます。金額の計算はdecimalで行い、丸め方式を決めておきます。
そして、最後の質問が残ります。ふるいにかけたものの中で、何が本当の欠陥なのか。同じ報告が2回入ってきたものなら、重複を除外すれば異常が消えます。到着順が入れ替わったものなら、取引所時刻で並べ替え直せば消えます。両方やっても残るものが、本物です。この3つの方向を分けずに「異常30件」と報告すると、相手は何もできません。
現場での姿
ある時、過約定の警報が1日に20件ずつ上がってきたことがあります。すべて同じ原因で、再送された約定報告が、重複除外なしに合算されていました。実際の過約定は、その20件の中にはなく、本当に危険な1件は、数週間後に別の経路で見つかりました。ふるいがノイズでいっぱいになると、誰もその警報を見なくなります。
もう1つは、等式の検査でした。取消された注文をすべて異常として上げる検査器のせいで、1日に数千件が警報として出ていき、結局、その検査がまるごと止められました。状態を見ずに、数量だけを見た結果です。
3つ目は、遷移表そのものでした。顧客が渡した文書には、約定完了が終端状態として書かれていたのに、コードが読む表には、その状態から出ていく行が1つ残っていました。文書とコードがずれている箇所では、検査器が見るほうが勝ちます。そのため、新しい顧客のデータを受け取ったら、遷移表をまず自分自身と突き合わせます。終端と宣言した状態に出ていく道があるか、どの状態からも到達できない状態があるか、開始状態から終端まで行く道が本当にあるか。この3つは、データだけを見て数行で確認でき、ここで引っかかるものがあれば、あとのすべての判定が信頼できなくなります。
最後に、実務で1つ付け加えます。これらの検査は、顧客に渡せる形で作っておくほうがよいです。調査のときに1回使って捨てると、同じ問題が3か月後にまた上がってきて、そのときまた最初から作ることになります。規則がデータにあり、コードがそのデータを読むようにしておけば、市場やブローカーが変わっても、同じツールがそのまま動きます。
次のラボですること
遷移表と12個の注文の約定報告を作り、表自身の矛盾から探します。そのあと、禁止遷移・数量の等式・累計の逆行・過約定・平均約定価格を順に検査し、最後に、重複報告と順序の入れ替わりで説明できるものと、そうでないものを分けて、原因別の要約を出します。取消で終わった注文と拒否で終わった注文が混ざっているので、等式を無条件に適用すると、その場で行き詰まります。