TT Lab
はじめる
学ぶ 学習パス コース

資本市場と決済

取消通知が二度届き、ポジションが反対に振れた

TT Labで続きを見る

目標

すでに出ていった約定に対する取消・訂正の通知を、元の約定につなげ、元の帳簿を消す代わりに、反対仕訳を加えて新しい帳簿を作ります。ポジションを再計算して、すでに出た報告と突き合わせ、同じ通知を2回受け取っても帳簿が同じかを確認したうえで、再報告の対象と訂正レポートを出します。

なぜ重要なのか

約定元帳は、すでに複数の場所に流れ出たデータです。その1行を黙って書き換えると、昨日出た報告と今日見る元帳がずれ、ずれた理由はどこにも残りません。そのため、金融の帳簿はあとに書きます。取消は、符号が反対の反対仕訳を加えることで、訂正は、相殺したあと、直した値でもう一度書くことです。難しいのは、この規則自体ではなく、端の部分です。通知が存在しない約定を指すこともあり、同じ通知が再送で2回来ることもあり、すでに取り消された約定に訂正が来ることもあります。1つでも見逃すと、ポジションが反対に傾き、その事実は、たいてい翌日の報告が間違ってから、ようやく表に出ます。

ステップ

  1. python3で/root/bust/dataに、fills.jsonl・notices.jsonl・position_report.csv・rules.jsonを作成してください。
  2. 通知を到着順に読んで、判定を/root/bust/notice_match.csvに書いてください。
  3. 適用する取消を、反対仕訳として加えて、/root/bust/ledger_bust.jsonlを作ってください。
  4. 訂正を、相殺と再記帳として加えて/root/bust/ledger_final.jsonlを作り、注文別の平均約定価格を/root/bust/order_avg.csvに出してください。
  5. ポジションを再計算して、ずれた銘柄だけを/root/bust/position_diff.csvに書いてください。
  6. 同じ通知ストリームを2回流し込んで、/root/bust/ledger_twice.jsonlと/root/bust/idem.jsonを作ってください。
  7. 報告時刻のあとに届いた通知を集めて、/root/bust/rereport.csvを作ってください。
  8. 変更1つ1つの出どころを/root/bust/trace.csvに、全体の要約を/root/bust/report.jsonに書いてください。

参考

約定元帳と取消・訂正の通知、ポジション報告を作る

python3で/root/bust/dataに、fills.jsonl・notices.jsonl・position_report.csv・rules.jsonを作成してください。乱数を使わない生成スクリプトを、そのまま使ってください。

顧客の約定元帳をそのまま持ってこられないので、同じ形の合成データを作ります。乱数を使わなければ、誰が何回回しても同じデータが出て、お互いの判定を突き合わせられます。採点ツールは、データを標準形に変換してフィンガープリントを突き合わせるので、手で直すと、あとのステップがすべて行き詰まります。

通知と元の約定をつなげて判定する

/root/bust/notice_match.csvに、1行目にseq,notice_id,type,target_fill_id,verdictを置いて、通知を到着順に読み、적용・대상없음・이미취소됨・중복통지のうち1つを書いてください(韓国語の4つの語は、順に「適用」「対象なし」「取消済み」「重複通知」を意味します)。すべての通知を1行ずつ書きます。

4つをこの順序で見ます。同じ通知IDを前ですでに見たか、指す約定が元帳にあるか、その約定が前ですでに取り消されているか、そして残りが適用です。取消を適用するたびに、その約定IDを記憶しておく必要があり、そうして初めて3つ目の検査ができます。通知IDは、判定と無関係に、すべて記憶します。

取消を反対仕訳として加えて新しい帳簿を作る

/root/bust/ledger_bust.jsonlに、元の約定18行を、kindがfillの記録としてそのまま移し、適用する取消ごとに、数量と金額の符号が反対のreversal記録を加えてください。元の記録は直しません。

消さずに加えます。反対仕訳の数量は、元の約定の数量にマイナスを付けた値で、単価は元の約定のままです。そうすれば、金額も自然に反対の符号になります。entry_idは通知IDに-rvを付け、source_noticeにその通知を残しておけば、あとで出どころをたどれます。元の約定の記録のsource_noticeは、空文字列です。

訂正を反映して平均約定価格を出し直す

/root/bust/ledger_final.jsonlは、ステップ3の帳簿に、訂正ごとにreversalとrebookの2行を加えたものです。/root/bust/order_avg.csvに、1行目にorder_id,net_qty,net_notional,avg_pxを置いて、注文ごとに1行ずつ書いてください。

訂正は、元の記録を相殺したあと、直した値でもう1行書きます。通知にない値は、元の約定の値をそのまま使ってください。価格だけが変わる訂正は、数量が同じで、金額だけが変わります。平均約定価格は、帳簿の金額の合計を数量の合計で割った値で、全部取り消された注文は、数量の合計が0なので、0にします。割る前に、0かどうかを先に見てください。

ポジションを再計算して既存の報告と突き合わせる

/root/bust/position_diff.csvに、1行目にsymbol,reported_qty,recomputed_qty,diffを置いて、最終的な帳簿で再計算したポジションが、position_report.csvと異なる銘柄だけを書いてください。

ポジションは、買いを足して売りを引いて数えます。反対仕訳は数量が負の数なので、符号が自然に反転し、別に分岐する必要はありません。diffは、再計算した値から、報告された値を引いたものです。値が同じ銘柄は書きません。差のすべてが遅れて来た通知で説明されるわけではないので、説明されない銘柄があっても、そのままにしてください。

同じ通知を2回受け取っても帳簿が同じかをテストする

通知ストリームのあとに、同じ通知をもう一度つなげて(2番目のまとまりは、seqに1000を足します)/root/bust/ledger_twice.jsonlを作り、/root/bust/idem.jsonにentries・same_as_final・ignored_duplicatesを書いてください。

再送は正常なことです。通知IDを記憶しなければ、一度取り消された約定が2回相殺され、ポジションが反対に傾きます。2番目のまとまりは、IDがすべて前に見たものなので、1つも適用されてはならず、そうすれば、帳簿はステップ4のものとまったく同じになります。ignored_duplicatesは、つなげたストリーム全体で、重複通知と判定された通知の数で、same_as_finalは、真か偽です。

報告のあとに届いた通知を再報告の対象として集める

/root/bust/rereport.csvに、1行目にnotice_id,type,target_fill_id,symbol,position_deltaを置いて、適用された通知のうち、通知時刻がrules.jsonのポジション報告時刻より後のものを書いてください。

ポジション報告が出たあとに届いた通知は、帳簿だけを直して終わりではなく、すでに出た報告を間違いにします。基準時刻はrules.jsonにあるので、今日の日付を使わないでください。position_deltaは、その通知がポジションをどれだけ動かすかで、売りは符号が反対です。価格だけが変わる訂正は、数量に触れないので0になりますが、再報告の対象から外さないでください。

訂正レポートと変更追跡表を書く

/root/bust/trace.csvに、1行目にentry_id,kind,fill_id,source_notice,reason,qty,px,notionalを置いて、最終的な帳簿でkindがfillでない記録をすべて書き、/root/bust/report.jsonに全体の要約を書いてください。

受け取った人が次に何をするかを決められて初めて、報告が役に立ちます。変更ごとに、どの通知から来たかと、その通知の理由を付ければ、数か月後にもたどれます。reasonは通知データから持ってきますが、実際に適用された通知のものでなければなりません。同じIDで再送されたコピーは、理由が違うので、ここで分かれます。要約に入れるキーは、fills・notices・적용・대상없음・이미취소됨・중복통지・bust_applied・adjust_applied・entries_before・entries_after・position_mismatch・rereportです(韓国語の4つの語は、順に「適用」「対象なし」「取消済み」「重複通知」を意味します)。