はじめに|定量開発でよくあるデータトラブル
定量バックテストやファクター分析を行う方なら、一度は経験する悩みがあります。相場 API から分割で取得した 1 分足をそのまま連結して DB に保存すると、短期間は画面上の価格表示に違和感がないのに、長期間戦略検証を回すと出来高が不自然に膨らんだり、テクニカル指標の波形が実盤と大きくズレる現象です。
私自身、ファンド向けの相場収集ツールを自作した時にこの問題に苦労しました。最初は K 線の計算ロジックを何度も見直しましたが原因が見つからず、全ての生データを出力して検証したところ、ページング時の時間区間重複やリアルタイム配信と過去データの衝突が根本的な問題だと判明しました。
ここで大切なポイントをお伝えします。画面の価格更新が正常に見えても、全ての 1 分足が漏れなく正しく保存できているとは限りません。株式は取引が活発なため、少しのデータ不具合はすぐに気づきにくいですが、長期の回測やモデル作成に使うと無視できない誤差が生まれます。今回は実務で活用している検証フローと、動作する Python コードを合わせて解説します。
1. 1 分足の重複・欠損が発生する 3 つのシチュエーション
① ページ分割で過去データを取得する時の時間境界重複
多くの株式相場 API は時間範囲を指定し、ページごとにデータを返す仕様になっています。例えば 1 ページ目が 09:30~10:30、2 ページ目が 10:30~11:30 のように設定すると、境界の 10:30 の 1 分足が両方のページに含まれてしまいます。
単純に配列を連結するだけだと同一時刻のデータが二重に登録され、何日も運用を続けると出来高や売買代金の集計値が大きく歪んでしまいます。
② リアルタイム Tick と過去 1 分足を統合する時の衝突
WebSocket でリアルタイム Tick を受信すると、逐次最新の 1 分足を生成し続けます。一方、過去データ取得 API の取得期間が現在進行中の分足にかかる場合、同じタイムスタンプのデータが 2 つ作成され、時系列の一意性が崩れるのです。
③ 通信障害と取引ルールによる時系列空白
API リクエストのタイムアウトやアクセス制限で一部区間のデータが届かないケースがあります。また昼休みの取引停止、個別銘柄の売買停止など、仕様上の空白も存在するため、単純に 1 分間隔が空いただけで「データ欠損」と判断すると誤判定につながります。
こうした不具合は目視で発見しにくいのが特徴で、定量モデルやバックテストの結果全体に影響を与えてしまいます。
2. 検証の核心:銘柄コード+タイムスタンプを一意の識別子に
API から返却されるデータの順番は状況によって入れ替わるため、配列の並びだけで重複を判断する方法は安定性に欠けます。実務では「銘柄コード+1 分足のタイムスタンプ」を 1 本の足の固有キーとして判定する手法を統一しています。
処理の流れはシンプルです。新しい相場データを受け取ったら、DB 内に同じ銘柄・同じ時刻のレコードが存在するか検索します。存在する場合は最新の価格と出来高で上書き更新、存在しない場合のみ新規登録することで、ロジック上の重複を遮断できます。
3. ページ別過去データの標準クリーニング手順
長期の過去 1 分足を一括取得する際は、下記 4 ステップのクリーニングを必ず実装し、ページ境界の重複を除去しましょう。
- API から 1 ページ分の 1 分足データを受信
- 銘柄コード、タイムスタンプを基準に昇順でソート
- 複合一意キーをもとに同一時刻の重複レコードを削除
- 時系列を走査し、隣り合う足の時間間隔が取引ルールに適合するか確認
時間間隔が 1 分以上空いていた場合は、昼休みや売買停止といった正常な空白なのか、通信障害による真の欠損なのか分類し、安易に架空の相場データを補完しないよう注意してください。
4. リアルタイムと過去データ統合の実装例
24 時間稼働する相場収集システムでは、過去の蓄積データと WebSocket のリアルタイム配信を統合する必要があり、ここが重複データの発生ポイントになります。Tick から 1 分足を作成後、事前に DB 内の同時間レコードを確認し、更新または新規作成に分岐させます。
開発検証時は AllTick API の WebSocket 配信を活用してリアル Tick を取得しており、下記は最小限の動作サンプルコードです。タイムスタンプによる重複チェックロジックを追加するだけで、過去データとの衝突を回避できます。
5. 二重の防御:コードロジック+DB 複合一意インデックス
プログラム側の判定だけでは見落としが発生するリスクが残るため、実運用環境では 2 層の防御体制を構築します。
- コード層:データ受信から登録まで全工程にタイムスタンプの重複チェック、時系列欠損の定期検知処理を組み込む
- ストレージ層:「銘柄コード+timestamp」の複合一意インデックスを作成し、DB 側で重複登録を自動的に弾くフェイルセーフとする
1 分足テーブルに必要なフィールドは銘柄コード、タイムスタンプ、始値、終値、出来高です。 また定時巡回タスクを作成し、1 営業日あたりの理論上の 1 分足総数と DB の実保存件数を比較することで、欠損区間を素早く特定でき、調査の手間を大きく削減できます。
まとめ
相場 API から 1 分足を取得する作業は定量開発の基礎的な工程に過ぎません。時系列データに重複や欠損がない状態を保つことこそ、信頼できるバックテストやファクター分析を実現する核心的なポイントです。
ページデータのクリーニング、リアルタイムと過去データの統合処理、タイムスタンプによる検証、DB インデックスによる防御の 4 つの仕組みを組み合わせることで、長期間安定して稼働する相場収集ツールのデータ品質を維持できます。
ネットワークの瞬間的な揺れを完全になくすことは不可能なため、事前のデータ整合性検証フローを標準実装に定めることで、上位の定量戦略や分析ツールの出力結果に実務的な価値を持たせることができます。