バックテストでは、シグナルがそのままポジションに変わったかのように取引を数えることがよくあります。ペーパートレードでは、その間に注文が入ります。注文は板に残り、部分約定したり、キャンセルされたり、拒否されたり、シグナルが変わった後も有効なままだったりします。シミュレーションでこのライフサイクルを省くと、取引回数やエクスポージャーがペーパー口座の記録とかけ離れることがあります。
実務的な解決策は、注文を状態とタイムスタンプを持つ永続的なオブジェクトとして扱うことです。シグナルは取引を試みる指示であって、取引が成立した証拠ではありません。
ペーパー戦略の取引回数がバックテストより少ないのはなぜ?
まず、1度も約定しなかった注文を考えてみましょう。バックテストでは、市場価格が指値に触れれば必ず約定したと仮定することがあります。しかし実市場では、価格が触れただけでは、自分の注文がキューの先頭にあったか、十分な出来高があったか、注文が取引所に届いた時点で気配値がまだ残っていたかは分かりません。
たとえば、ある戦略が$100に買い指値を出し、30秒後にキャンセルするとします。市場では$100.00が付いていますが、その価格での取引量は少なく、ほかの注文が優先されています。注文は一部だけ約定するか、まったく約定しないかもしれません。価格接触だけで判定するバックテストでは、ポジション全体が約定したと記録されます。キューに関する仮定を反映するペーパー口座では、約定なしと記録されることもあります。
成行注文では、別の食い違いが起きます。バックテストでは次のバーの始値で全数量が約定したとみなす一方、ペーパートレードでは取引所のフィルターに抵触する数量が拒否されたり、板が動くにつれて注文が分割して約定したりすることがあります。バーは取引の要約であり、注文全体が1つの価格で約定できたことを保証するものではありません。
注文が約定する前にシグナルが変わったら、バックテストではどう扱うべき?
シミュレーターがキャンセルを受信して処理するまでは、古い注文を有効なままにしておきます。買い注文が板に残っている間にシグナルが反転したら、戦略はその注文をキャンセルして売り注文を出そうとするかもしれません。しかし、その意図がすぐに買い注文を消すわけではありません。キャンセル処理中に約定し、新しいシグナルがショートを示しているのに口座がロングになることもあります。
これを次のような流れとしてモデル化します。シグナルが変わり、戦略がキャンセル要求を送り、取引所がキャンセルを確認するか約定を通知し、その後になって初めて戦略は最終的な注文状態を把握します。単純な固定遅延を入れるだけでも、キャンセルを即時扱いするバックテストでは見えない競合状態が明らかになります。
単純なモデルから始めるなら、キャンセルに1秒の遅延を設けて次のイベントで処理するほうが、キャンセルが瞬時に完了すると仮定するより有益です。適切な遅延は取引所やシステムによって異なりますが、遅延を何らかの形で表すことが大切です。キャンセル猶予のない成行注文でも、部分約定や遅れて届く報告について同じ問題が生じます。
ペーパートレードのシミュレーターには、どの注文状態を記録すべき?
小さな状態遷移モデルを使い、各遷移とその時刻を記録します。取引所によって用語は異なりますが、基本的な区別は共通しています。
- 新規または保留中: 発注済みだが、まだ受理確認されていない。
- 有効: 受理され、約定可能な状態。
- 部分約定: 一部の数量が約定し、残りは引き続き有効な場合がある。
- 約定済み: 未約定の数量が残っていない。
- キャンセル保留中: キャンセル要求の処理中で、注文はまだ約定する可能性がある。
- キャンセル済み、拒否、または期限切れ: この注文でこれ以上約定することはない。
約定数量は注文数量と分けて記録し、約定価格と手数料も残します。部分約定した注文は、取引が成立していると同時に、残りの数量について有効な義務も残っています。単に「有効」または「完了」とだけ扱うと、戦略が次のアクションの数量を決めるために必要な情報が失われます。
| 注文イベント | 戦略が把握すべきこと | よくあるバックテスト上の簡略化 |
|---|---|---|
| 部分約定 | 約定数量、残数量、平均価格 | 注文全体が1つの価格で約定したとする |
| キャンセル要求 | 要求時刻と、最終的なキャンセルまたは約定の確認 | 注文を即座に削除する |
| 拒否 | 理由と、再試行が妥当かどうか | 要求した取引が成立したと仮定する |
| 期限切れ | 注文が約定可能でなくなった時刻 | 後で価格が触れるまで有効なままにする |
バックテストの取引とペーパートレードを公平に比較するには?
まず注文イベントを比較し、次にポジション、最後にP&Lを比較します。バックテストでは約定したのにペーパー口座では約定しなかった注文があれば、その後のP&Lの差は結果であり、問題を突き止める場所ではありません。
意図した注文ごとに、安定した戦略判断IDまたは注文IDを使って2つの実行結果を照合します。そのうえで、発注時刻、要求価格と数量、有効期限条件、約定、キャンセル、拒否、手数料、最終ポジションを確認します。シミュレーションで約定しなかった理由も記録しましょう。指値に届かなかった、想定した前方キューが解消されなかった、あるいは注文が期限切れになった、といった理由です。
小さな例で流れを見てみましょう。シグナルは10単位の注文を要求します。両方のシステムが10:00:00に発注します。バックテストでは10:00:01に全数量が約定したと仮定します。ペーパートレードでは10:00:01に4単位が約定し、10:00:02にキャンセル要求を受信した後、キャンセルが10:00:03に確認される前に、さらに2単位の約定が報告されます。正確に比較すると、約定数量は6単位対10単位で、4単位がキャンセルされています。どちらも1つの「取引」にまとめて平均すると、戦略が実際に抱えていたエクスポージャーが見えなくなります。
正しくモデル化するには、取引所全体のシミュレーターが必要?
いいえ。バックテストでは、いくつかの明確な仮定から始められます。指値への価格接触だけで十分か、想定した前方キューを解消するには価格を超えてどれだけの出来高が必要か、注文をどれだけ有効にするか、キャンセル遅延をどう扱うか、といった点です。もっともらしい設定を複数用意して戦略を実行します。指値注文がすべて完全約定するという前提に性能が依存するなら、それ自体がモデルについての有益な発見です。
ペーパートレードも、執行品質を測る絶対的な基準ではありません。約定はシミュレーションの場合があり、実際のキューを再現できないこともあります。ここでの価値はもっと限定的です。イベントが時間とともに届く中で、戦略と注文管理システムが、未約定数量、キャンセル、ポジション、再試行の挙動について正しく連携しているかを確かめられます。
この作業には、ちょっとした楽しみもあります。優れた注文ログがあれば、不可解だった食い違いが拍子抜けするほど単純に説明できることがあります。「キャンセル要求の後に2つ目の子注文が約定した」なら、「ペーパートレードの挙動がおかしい」よりずっと役立ちます。バックテストとペーパー口座に食い違いがあったら、シグナルを編集する前に注文のライフサイクルを追いましょう。
← 記事一覧


