バックテストでは、出した100件の注文のうち91件が約定扱いでした。同じ戦略をペーパートレードで動かすと、約定したのは63件でした。シグナルから注文確認までの時間は中央値で84ミリ秒。ペーパーで約定しなかった注文のうち12件は指値注文で、バックテストでは価格に触れた時点で約定したと仮定していました。
この28ポイントの差は、注文を出す判断と約定の判断を分けて見るまでは、戦略そのものの問題に見えました。どちらの実行でも、戦略が選んだ売買方向、数量、価格はほぼ同じでした。違っていたのは執行の流れです。注文の到着が遅れたもの、未約定のまま残ったもの、相場がすでに動いた後に発注されたものがありました。
バックテストとペーパーの注文パリティとは?
パリティとは、同じ時点で利用できる情報からバックテストとペーパーシステムが比較可能な判断を行い、実行モデルの違いを明示的に考慮することです。シミュレーション上の約定がすべてペーパーでも再現される、という意味ではありません。過去のバーからはキュー内の順位を復元できませんし、ペーパーの取引所シミュレーターが実際の取引所とは異なるマッチングモデルを使う場合もあります。
確認すべきことは、もっと絞れます。戦略が出そうとした注文ごとに、その後何が起きたかを説明できるでしょうか。取引件数や最終リターンだけでは情報が足りません。シグナル、注文、確認、キャンセル、約定の各イベントを一貫して追えるよう、判断ごとに固定の戦略判断IDを付けて記録を結合しましょう。
| 比較項目 | 確認できること | 例 |
|---|---|---|
| 判断時刻と売買方向 | 入力情報やスケジュールの違い | ペーパーではシグナルが1本後のバーで発生 |
| 発注数量と価格 | 丸め、リスク管理、取引所ルール | バックテストは0.013 BTCを発注し、ペーパーでは0.01に丸める |
| 注文状態の遷移 | 発注、拒否、キャンセルの処理漏れ | バックテストではキャンセル要求を完了扱いにする |
| 約定数量と価格 | 楽観的な約定モデルや相場変動 | 価格が指値に触れるとバックテストでは全量約定するが、ペーパーでは約定しない |
なぜ指値に触れた注文が、これほど多く未約定になったのでしょうか?
バックテストには1-minuteバーを使っていました。指値がバーの高値と安値の範囲に入れば、注文は約定したと判定していました。このルールで分かるのは、その1分間のどこかで市場価格がその価格で取引されたかどうかです。その時点で注文が有効だったか、キューの先頭にいたか、注文到着後に十分な数量が取引されたかは分かりません。
ペーパーのログから、タイミングの問題が見えてきました。戦略は12:03:00.000にシグナルを計算しましたが、市場データのイベントが注文処理プロセスに届くまでに31ミリ秒かかりました。リスクチェックにさらに22ミリ秒、その後、取引所シミュレーターが注文を確認するまでに31ミリ秒かかりました。相場が急変すると、過去のバー上では到達可能に見える価格でも、指値注文が届いた時点では相場がすでに通り過ぎていることがあります。
さらに、バックテストが次に進んだ時点で、ペーパーの注文12件はまだ未約定でした。シミュレーターはキャンセル要求を、注文が即座に消えたかのように扱っていました。ペーパーシステムではキャンセル確認が届くまでに時間があり、その間に3件が約定しました。その結果、次のシグナルが参照するポジションも変わっていました。
誤解を招かずに差を測るには?
まず、注文の意図ごとにまとめた簡潔な照合レポートを作り、分母を明示しましょう。「約定率」は、発注件数に対する約定件数、発注数量に対する約定数量、あるいは取引所に到達した注文に対する約定注文の割合を指すことがあります。それぞれ答える問いが異なります。
- 後から推測したタイムスタンプではなく、判断IDまたはクライアント注文IDでイベントを結合する。
- まず判断内容を比較する。シグナル時刻、売買方向、発注数量、注文種別、指値価格を確認する。
- 判断が一致した注文について、確認までの遅延、拒否、注文が有効だった時間、キャンセル時刻、約定数量、出来高加重平均約定価格を比較する。
- 注文種別と市場状況ごとに率を報告する。全体の約定率が63%でも、成行注文は90%、指値注文は35%かもしれません。
分類が重複しないようにしましょう。拒否された注文は未約定注文ではありません。一部約定した注文は全量約定ではなく、一部約定後にキャンセルされた注文もポジションを変えています。少額注文が集中して結果を実態より良く見せないよう、注文件数と発注数量の両方を数えましょう。
バックテストの何を変えるべきでしょうか?
データの解像度と想定する注文の動きに合った約定ルールを使いましょう。バーの場合、指値に触れたことは約定の可能性を示す証拠であり、約定した証明ではありません。保守的に一部約定をモデル化する、価格が指値を通過することを条件にする、あるいはキューを推定できない指値注文を除外する、といった方法があります。選択肢ごとに答える問いは異なります。ルールを文書化し、妥当な複数のルールで結果を比較しましょう。
注文状態もモデル化しましょう。システムが終端イベントを受け取るまで注文は有効で、キャンセル要求を送ってもエクスポージャーは消えません。最初の注文が処理中に戦略が2件目を発注できるなら、バックテストでその競合状態を再現するか、設計上発生しないようにする必要があります。
約定モデルは、注文がどのように約定し得たかについての主張です。説明できるルールを設け、そのルールをペーパーのログと照らし合わせましょう。
28ポイントの差で意外だったのは、1分足のバックテストが指値注文の約定を過大評価したことではありません。キャンセルのタイミングを省いていたため、次の判断より前に戦略のポジションが食い違っていたことです。注文状態のモデルを修正し、指値に触れた注文をすべて約定扱いにするのをやめると、ペーパーとの比較は厳しい結果になりましたが、より役立つものになりました。
実務上のパリティとは、シミュレーションとペーパーの挙動にある重要な違いにすべて記録された原因があり、データから確かなことが分からない部分についてバックテストが断定しない状態です。
← 記事一覧


