クオンツ研究では、つい「未来の情報を参照していないか」を、はい・いいえで答えられる問題として扱いがちだ。コードは翌日の価格を読んでおらず、財務データにも開示日を付けている。検査結果が緑になれば、その実験は point-in-time だと説明される。

しかし、コードが何を見られるかと、過去の研究者が何を知り得たかは、別々に証明する必要がある。

今日取得した過去のレコードには、後日行われた訂正がすでに反映されているかもしれない。今日作成した銘柄リストからは、その後上場廃止になった企業が除かれているかもしれない。今日ダウンロードした価格系列は、数年後の株式分割を基準に調整されているかもしれない。各行に日付があっても、表全体が当時の情報の状態を再現しているとは限らない。

本記事でいう時点データ、すなわち point-in-time data とは、特定の過去の時点で取得できた情報に基づいて整理されたデータを指す。データベースに日付フィールドを追加するだけでは、この要件は満たせない。どの事実の、どのバージョンが、どの経路を通じ、どの条件の下で、どの意思決定に入ったのかを説明する必要がある。

タイムスタンプの検査を通過したことは、過去の各時点の情報を完全に再現していると証明されたデータを持つことと同じではない。

1. 過去のレコードには、未来になって初めて分かる事実が含まれ得る

ある企業の会計年度が 3 月 31 日に終了し、決算が 5 月 15 日 15:00、日本時間で開示されたと仮定する。決算に記載された売上高は 1,000 億円だ。

今日のデータテーブルでは、次のように整理されているかもしれない。

会計期間末     3 月 31 日
売上高         1,000 億円

研究プログラムが会計期間末を基準にこのデータを日々の市場データに結合すると、4 月初めの戦略がすでにこの売上高を使ってしまう可能性がある。未来の価格は読んでいなくても、未来の事実を知ってしまっている。

問題は、二つの時間を混同したことにある。会計期間末が答えるのは「この数値はどの経済期間を表すか」であり、開示時刻が答えるのは「外部の人がいつからこの数値を知る機会を得たか」だ。3 月に属する財務上の事実が、自動的に 3 月の取引に使える情報になるわけではない。

J-Quants Pro の財務データのドキュメントでは、CurrentPeriodEndDate と DisclosedDate、DisclosedTime が別々に記載されている。この区別には意味がある。データが属する期間と、データが開示された時刻は、もともと別のものだからだ。

ただし、開示時刻だけで研究システムが利用できる時刻のすべてを説明できるわけでもない。発表が公開されていても、研究者が使う経路でデータが届いているとは限らず、ローカルのプログラムがダウンロード、解析、検査を終えているとも限らない。J-Quants Pro には別途データ更新時点の説明があり、研究設計では、自分が使うデータ製品と取得方法を確認すべきだ。

ここでは少なくとも、次の四つの時間を区別する必要がある。

時間答える問い
経済的な帰属期間この数値はどの期間を表すか?
公開時刻この情報はいつ外部に開示されたか?
システムで利用可能になった時刻指定の経路とシステムで、いつ利用できるようになったか?
戦略の意思決定時刻戦略はいつ今回の判断を形成したか?

これらの時間をどう使うかは、研究の目的によって変わる。公開情報に対する市場の反応を研究するなら、当時の公開状況と処理の遅延を合理的に再構築する必要がある。自分がかつて動かしたプログラムを振り返るなら、ローカルで実際に受信した記録がとりわけ重要になる。今日ファイルをダウンロードした時刻を、そのまま 2 年前の公開時刻に置き換えることはできない。2 年前の発表時刻だけで、当時自分のシステムがすでに受信していたと証明することもできない。

保守的な遅延の仮定を置くことはできるが、仮定として明記しなければならない。人為的にさらに 1 日遅らせても、欠けている過去のバージョンや銘柄ユニバースが自動的に復元されるわけではない。

2. available_at が解決するのは、特定の問題である

研究システムでは、次のルールが非常に役立つ。

available_at ≤ decision_at

意味は明快だ。レコードは、申告された利用可能時刻が意思決定時刻以前である場合にのみ、その意思決定の情報集合に入ることができる。

先ほどの仮定で available_at が 5 月 15 日 15:00 なら、5 月 15 日 14:00 の意思決定からはそのレコードを参照できない。すべてのファクターの作成者が決算の遅延を手作業で処理し忘れないことに期待する代わりに、システムが明示的に遮断できる。

このルールは実装し、テストする価値がある。ただし、証明するのは条件付きの命題だ。システムに与えられた時間メタデータによれば、この入力の利用可能時刻は意思決定時刻より後ではなかった。

時間メタデータそのものが正しいことを、これだけで証明するわけではない。訂正後のレコードに元の開示時刻が付いたままなら、比較は通過し得る。ベンダーの配信遅延を無視した場合も、通過し得る。タイムスタンプがないときに会計期間末で補完しても、不明な事実を、一見埋まっているフィールドに変えるだけだ。

等号にさえ説明が必要になる。開示と意思決定の両方が 15:00 と記されていれば、後者は前者を利用してよいのか。それは時刻の精度、イベントの順序、処理の遅延による。分単位の時刻だけでは、同じ 1 分の中の因果的な順序は証明できない。タイムスタンプによる制御には、明確なイベントと遅延のルールを組み合わせる必要がある。

したがって、レビューでは次のような別々の問いをさらに確かめるべきだ。

証拠の観点証明すべき内容
意思決定時点での可視性指定の情報経路から、意思決定前にこの入力を取得できたか?
過去のバージョン入力された値は、当時参照可能だったバージョンか?
過去の銘柄ユニバースその証券は、当時戦略が研究対象として認めていた範囲に含まれていたか?
コーポレートアクションの処理価格、株数、リターンに整合する定義を使っているか?
出所と変換原資料から戦略の特徴量に至る過程を説明できるか?

これらの問いは互いに代替できない。適切なタイムスタンプがあっても、バージョン履歴は補えない。完全なバージョンの記録があっても、証券の適格性を代わりに再構築してくれるわけではない。

「時点データは真偽値ではない」とは、時点の要件を検証できないという意味ではない。個々の具体的な検査には、合格・不合格という結果を出せる。問題は、一つの検査の真偽値を、過去の情報集合全体の証拠に置き換えてはいけないことだ。

3. 訂正は日付を残したまま、過去を書き換え得る

同じ架空の企業を引き続き考えよう。5 月 15 日の初回開示では、売上高は 1,000 億円だった。6 月 10 日に企業が訂正を公表し、920 億円に変更した。

この会計年度の最新の財務状況を表すなら、使うべき数値は 920 億円かもしれない。しかし、5 月 20 日の意思決定を再構築するなら、当時参照できたのは依然として 1,000 億円だ。

データベースが最新値だけを保持していると、今日返されるレコードは次のようになり得る。

会計期間末     3 月 31 日
売上高         920 億円

この行に 5 月 15 日の元の開示時刻を追加しても、問題は解決しない。後の数値に古いタイムスタンプを借用させ、その数値がまだ存在しなかった日付に戻してしまうからだ。

過去の再構築を支えるには、異なるバージョンを同時に保持する必要がある。

対象期間バージョンの公開時刻売上高バージョン
3 月 31 日に終了する会計年度5 月 15 日 15:00 JST1,000 億円初回開示
3 月 31 日に終了する会計年度6 月 10 日 15:00 JST920 億円後日の訂正

こうすれば、5 月 20 日と 6 月 11 日に異なる答えを返しながら、それぞれの情報時点に忠実でいられる。

ここでいう vintage は、ある時点で取得できたデータのバージョンを指す。最終的に正しいバージョンとは限らない。過去の投資家は、誤り、不完全さ、後になって初めて訂正される情報に向き合っていた。その意思決定の条件を再構築するには、こうした不完全さを残す必要がある。

バージョンの問題は派生特徴量にも及ぶ。累計値の差分から、ある四半期単独の指標を計算するとしよう。片方の累計値が後日修正されれば、今日計算し直した四半期の値は当時の値と異なるかもしれない。そのため、結果にタイムスタンプを付けるだけでなく、計算に使った元の入力とそのバージョンも追跡可能である必要がある。

すべての個人研究者が、まず複雑なデータベースを構築しなければならないわけではない。元のファイル、開示識別子、取得時刻、変換スクリプトを保存するところから始められる。ただし、過去のバージョンを取得できないなら、その制約を研究の結論に残すべきだ。

計算を繰り返せば、処理の一貫性は証明できる。しかし、入力が正しい過去の状態を表していることは証明できない。2 回とも同じ訂正済みデータを使えば、完全に一致する結果を得られると同時に、後になって知り得た事実を、まったく同じように過去へ持ち込んでしまうこともある。

4. 銘柄ユニバースも未来の情報を漏らす

未来の情報は、財務数値だけでなく、証券コードのリストにも隠れ得る。

今日ある指数の現在の構成銘柄を取得し、それらの過去 10 年分の市場データをダウンロードしてバックテストすると仮定する。価格はすべて実際の取引記録に由来し、シグナルは意思決定日以前のデータだけを読む。一見、時間の扱いには問題がない。

しかし、そのリスト自体が今日初めて分かるものだ。

過去 10 年の間には、上場廃止、倒産、買収、指数からの除外を経験した企業があるかもしれない。現在の構成銘柄リストは通常、こうした過去の構成銘柄を完全には示さない。現在のリストを過去に持ち込むことは、どの証券が研究サンプルに残る資格を持つかを、先回りして決めることになる。

この種の問題は通常、生存者バイアスと呼ばれる。ただし、対象は「生き残った」企業だけではない。指数への追加・除外、上場時期、証券の種類の変更、コードの変更、戦略の選別ルールが依存する情報も関係する。

実際の過去の価格があることと、実際の過去の銘柄ユニバースがあることは同じではない。

過去の銘柄ユニバースは、各意思決定時点で再構築する必要がある。いつ上場したか、いつ対象指数に入ったか、いつ外れたか、いつ社名やコードが変わったかは、いずれも証券の同一性を構成する。流動性の選別も、その時点までの取引情報を使うべきだ。バックテスト期間全体の平均売買代金から、後に最も活発に取引された企業を先に選んではいけない。

リストの発表と、構成銘柄としての適用開始も区別する必要がある。指数の入れ替えは、事前に発表され、その後適用されることがある。戦略が発表後の予想される変化を研究するのか、それとも当時すでに適用されていた構成銘柄だけを取引対象とするのかを、ルールで明示すべきだ。

現段階で現在のリストしか取得できなくても、「今日のこの企業群が過去にどう推移したか」は研究できる。これは価値のある問いだが、その答えを「当時の指数構成銘柄に従って投資したらどうなったか」と書くことはできない。入力の範囲が変われば、研究の問いも変わる。

銘柄ユニバースを修正した後も、上場廃止銘柄のリターン、最後に取引できた価格、退出時の処理を安易に捨ててはいけない。銘柄名だけをサンプルに戻し、最も扱いにくい価格の期間を削除したままでは、過去の投資条件を完全には再構築できていない。

5. コーポレートアクションによって、過去の価格はモデル上の選択になる

過去の価格にも説明が必要だ。

ある株式が 1 株を 2 株に分割したと仮定する。価格系列を比較しやすくするため、データサービスは分割前の価格を 2 で割るかもしれない。その結果、今日見る調整済みの過去の価格は、当時画面に表示された名目上の株価とは異なる。

この変換自体が誤りというわけではない。未調整の価格だけを見ると、分割当日に、経済的な損失ではない価格の飛びが生じることがある。一部のリターンやモメンタムの計算では、一貫した調整済み系列を使うことで、単位の変化を市場の変動と取り違えるのを防げる。

ただし、「調整済み価格を使う」という説明だけでは研究手法を十分に表せない。

まず、どのイベントを調整に含めるかを説明する必要がある。株式分割だけを処理した価格系列と、現金配当を含めたトータルリターン系列は、異なる問いに答える。現金配当を再投資するか、いつ現金口座に入るかも、リターンの計算に影響する。

次に、価格をどの段階に入力するのかを説明する必要がある。シグナルに使う正規化された価格が、売買シミュレーションの約定価格と同じとは限らない。バックテストの台帳では、約定価格、保有株数、キャッシュフロー、コーポレートアクションの整合を保つ必要がある。調整済み価格を、対応する調整をしていない株数に直接掛けると、定義が食い違う可能性がある。

最後に、将来の調整が戦略の判断を変えるかを検査する必要がある。比率に基づく一部の指標では、同じ過去のウィンドウ内の価格をすべて同じ係数で掛けても、結果が変わらないことがある。しかし、名目価格の閾値、1 株当たりの指標、異なるフィールド間の比較では、この不変性が成り立つとは限らない。一つのリターン計算が影響を受けなかったからといって、すべての特徴量が影響を受けないと推論してはいけない。

JPX のコーポレートアクション情報サービスでは、現金配当、株式分割、合併、公開買付け、証券マスタの変更を独立したイベント区分として扱い、公表日、基準日、効力発生日などの検索日付を区別している。これは、コーポレートアクションを、時間と意味を持つイベントとして扱うべきことを示唆している。

研究で説明すべき具体的な選択には、シグナルに未調整価格と調整済み価格のどちらを使うか、株式分割で数量をどう変えるか、配当をリターンにどう反映するか、調整係数がいつ利用可能になるか、1 株当たりのデータと価格が同じ単位に基づいているかが含まれる。

したがって、「今日の調整済みの過去の価格はすべてバックテストに使えない」と一括して断定することも、ベンダーの adjusted close を説明不要な過去の事実として扱うこともできない。確認すべきなのは、採用した表現が後の情報を意思決定に持ち込んでいないか、そして執行と記帳の定義に整合しているかだ。

6. KabuForge の検査は、どの主張を支えるのか

これらの区別は、私が研究基盤の中に残しておきたい境界でもある。

以前の KabuForge の研究フレームワークに関する記事では、データ、ファクター、戦略、目標ポートフォリオ、リスク、注文計画の関係を紹介した。ここでは、その中の一つの問いに注目する。システムの検査結果に基づいて、どこまで主張してよいのか。

本記事は KabuForge v0.1.1 を事例とし、引用するソースコードを対応するリリースのコミットに固定している。その検査結果を、後続のバージョンへ自動的に一般化すべきではない。このバージョンの研究方法ドキュメントは、時間による制御と完全な認証を明確に区別している。研究入力には意思決定時刻とスナップショット識別子の宣言が必要であり、check_point_in_time と check_lookahead は available_at を使って可視性を検査する。同時に、これがデータの出所、ベンダーの時刻、過去の訂正、生存者バイアス、コーポレートアクション、銘柄ユニバースの構築に関する完全な科学的認証ではないとも説明している。

時間による制御の役割は、現在の情報集合に入るべきでない行を識別し、制限できるようにすることだ。入力のメタデータを、自動的に信頼できる過去の記録へ変えるわけではない。

入力の同一性と実行記録が解決するのは、別の問題だ。ファイルのハッシュ、スナップショット識別子、マニフェストを残せば、「この実験は何を読んだのか」に答えやすくなり、その後ファイルが変わったかも検出できる。しかし、ハッシュが証明するのは保存した対象の同一性であり、その内容を過去に知り得たかどうかではない。今日固定したファイルは、その後一切変更されなくても、後日訂正されたデータを含んでいる可能性がある。

ここでは、リリースパッケージのソースコード一覧と研究入力のマニフェストも区別すべきだ。ソフトウェアのバージョンを固定しても、データのバージョンを固定したことにはならない。データのバージョンを固定しても、その過去の可視性を検証したことにはならない。どちらも検証に役立つが、担う証拠上の責任は異なる。

公開実装の実際の過去の価格を使う研究経路には、次の状態宣言が残されている。

readiness: RESEARCH-ONLY
pit_guarantee: false

この宣言は該当する研究経路に属するもので、すべてのデータとすべての実行の状態を逆に要約することはできない。これは利用者に、実際の過去のデータは教育、ソフトウェアの処理フローの検証、探索を支えられる一方、「実際の」という言葉だけでは過去の情報の完全性を証明できないことを伝える。このバージョンの価格研究の実装では、現在ダウンロードしたバージョンを使うこと、過去の可視性を検証していないことなどの仮定も宣言し、株式分割の調整を含む区間を拒否している。これらの制約は、結果とともに残すべきだ。

私が重視するシステムの能力は、完了した検査と、まだ裏付けられていない主張の両方を見えるようにすることだ。ある経路が時間による制御を通過したなら、その検査について報告できる。過去のバージョンをまだ確認していないなら、検査結果を「データに完全な PIT 保証がある」という主張へ広げてはいけない。

これは AI を使った研究にも関係する。AI は、データの読み込み、フィールドの結合、ファクターの計算を行うコードを素早く生成できる。しかし、コードの実行に成功したからといって、欠けているバージョン履歴を補うことはできない。研究記録に入力の同一性、時間に関する仮定、未検証の境界を残しておけば、次の変更で参照すべき基準が明確になる。

現在のプロジェクトの状態は、KabuForge のプロジェクトページでさらに確認できる。ここで扱っているのは、ある戦略の有効性でも、シミュレーションの結果が実運用の利益に変わるかでもない。研究システムが、自ら支えられる結論をどう正確に述べるかだ。

7. PIT は、証拠に支えられた主張の連鎖として捉えるべきだ

バックテストを説明するとき、「過去のデータを使った」は出発点にすぎない。

より強い主張は、意思決定時刻より後の入力が計算に入るのを防いだ、というものだ。さらに進むと、公開開示と指定のデータ経路から、利用可能時刻をどう導いたかを説明できる。そのうえで、過去のバージョン、証券の適格性、コーポレートアクション、変換過程も説明する必要がある。

これらの主張は、段階的に展開する証拠の連鎖として書ける。

過去のデータを使った
        ↓
明らかに意思決定時刻より後の入力を制限した
        ↓
指定の経路での過去の利用可能時刻を再構築した
        ↓
当時参照できたデータのバージョンを保持または再構築した
        ↓
各時点でルールに適合する証券の範囲を再構築した
        ↓
価格、株数、コーポレートアクションを一貫して処理した
        ↓
各意思決定を、対応する入力と変換の証拠まで追跡できる

これは汎用的な認証の等級でも、すべての研究が従うべき実装の順序でもない。各責任は完全に直線的な関係にはない。ある研究では財務データの全バージョンを保存していても、過去の指数構成銘柄リストが欠けているかもしれない。別の研究では、証券の履歴は信頼できても、データ経路の遅延には近似的な仮定しかないかもしれない。

証拠の連鎖の役割は、一枚のラベルでこうした違いを覆い隠す代わりに、主張の構成要素を読者に見せることにある。

「このバックテストは未来の情報を参照していない」よりも、次のような説明のほうが検証しやすい。

本実験は、開示時刻と明示的な遅延の仮定に従って財務入力を制限し、固定したデータスナップショットと変換ルールを使用する。財務データの過去の訂正はまだ完全に再構築できていない。証券サンプルには現在のリストを使っているため、結果はこの証券群の過去のパフォーマンスだけを表し、過去の指数投資の効果の推定としては使えない。

この結論は見栄えがよくないかもしれないが、結果が何を支え、次にどの証拠を補うべきかを読者に伝えられる。

こうした情報集合の問題をすべて解決しても、多数の試行の中から、偶然最もよい成績を示した戦略を選んでしまう可能性は残る。Bailey と López de Prado はバックテストの過剰適合に関する論文で、多重の試行がもたらすこの選択バイアスを論じている。過去に知り得た情報であることと、統計的な妥当性の両方を検証する必要があり、前者は後者を代替できない。

個人研究者にとって、この区別は時間をどこに使うかも左右する。バージョンの記録が欠けているなら、タイムスタンプの検査をさらに改善しても、主な誤差が減るとは限らない。銘柄ユニバースに後知恵による選択があるなら、ファクターを増やしても、サンプルが過去の状態に近づくわけではない。不確実性がどこにあるかを先に説明すれば、次の実装作業に取り組む価値があるか判断しやすくなる。

「ArcaViso という名に込めたもの:不確実性の中で、理性を道しるべに」では、観察、判断、自らの誤りを見つける自律について述べた。バックテストにおいて、この自律は、一つの実装上の検査に、その検査が担えない証明責任を負わせないことを意味する。

研究基盤の目的は、不確実性を緑のチェックマークに変えることではない。どの不確実性が減り、どれがまだ残っているかを、明確に把握できるようにすることだ。