コンテンツにスキップ

ギャップ補填

概要

Mac再起動やAPI障害によるデータ欠損を検出し、自動的に補填する仕組みです。


ギャップ発生の原因

原因 頻度 影響
Mac再起動 週1-2回 数分〜数時間のギャップ
API障害 月1-2回 数分〜数時間のギャップ
ネットワーク切断 数分のギャップ
スクリプトエラー 数分〜数時間のギャップ

ギャップ検出

ArchiveState

_state.json で各データタイプの最終アーカイブ時刻を追跡。

{
  "uw_flow": {
    "last_archive": "2025-11-28T18:45:00Z",
    "last_date": "2025-11-28"
  },
  "stocks": {
    "last_archive": "2025-11-28T07:00:00Z",
    "last_date": "2025-11-28"
  }
}

検出ロジック

def detect_gaps(self, archive_type: ArchiveType) -> list[dict]:
    """ギャップを検出"""
    last_archive = self.get_last_archive(archive_type)
    now = datetime.now(timezone.utc)

    # 許容ギャップ時間(データタイプによる)
    max_gap = {
        ArchiveType.UW_FLOW: timedelta(minutes=5),
        ArchiveType.OPTIONS: timedelta(minutes=20),
        ArchiveType.STOCKS: timedelta(hours=2),
    }

    if now - last_archive > max_gap[archive_type]:
        return [{
            "start": last_archive,
            "end": now,
            "duration_hours": (now - last_archive).total_seconds() / 3600
        }]

    return []

補填プロセス

sequenceDiagram
    participant EOD as archive_eod_fill.py
    participant State as ArchiveState
    participant API as Polygon API
    participant PQ as Parquet Files

    Note over EOD: JST 07:00 実行

    EOD->>State: detect_gaps(STOCKS)
    State-->>EOD: gaps: [{start, end}]

    loop 各ギャップ
        EOD->>API: 1分足データ取得<br/>(gap.start - gap.end)
        API-->>EOD: OHLCV bars
        EOD->>PQ: 追記保存
    end

    EOD->>State: update_last_archive(STOCKS)

    Note over EOD: 完了

archive_eod_fill.py

機能

  1. ギャップ検出: 各データタイプのギャップを検出
  2. 1分足補填: Polygon APIから1分足データを取得
  3. IV Rank補填: Barchart CSVをParquet化
  4. 状態更新: 最終アーカイブ時刻を更新

使用方法

# 通常実行(自動ギャップ補填)
python scripts/archive_eod_fill.py

# ステータス確認のみ
python scripts/archive_eod_fill.py --status

# 特定日付の補填
python scripts/archive_eod_fill.py --date 2025-11-27

# ドライラン(実際には書き込まない)
python scripts/archive_eod_fill.py --dry-run

出力例

=== AEGIS EOD Gap Fill ===
Date: 2025-11-28 (ET)

Checking gaps...
  UW_FLOW: OK (last: 2025-11-28T21:30:00Z)
  OPTIONS: OK (last: 2025-11-28T21:00:00Z)
  STOCKS: GAP DETECTED
    - 2025-11-28T14:00:00Z to 2025-11-28T21:00:00Z (7.0 hours)

Filling gaps...
  STOCKS: Fetching 1m bars for 56 symbols...
    - AAPL: 390 bars
    - NVDA: 390 bars
    ...
  STOCKS: Total 21840 bars written

Archiving IV Rank...
  - 56 symbols processed

Updating state...
  - All archive types updated

=== Complete ===

手動補填

特定銘柄の補填

from core.archive import LiveDataArchive
from scripts.archive_market_data import get_polygon_1m_bars

archive = LiveDataArchive()

# 特定銘柄の1分足を取得・保存
bars = get_polygon_1m_bars("NVDA", date(2025, 11, 27))
for bar in bars:
    archive.write_stock_snapshot(bar)

日付範囲の補填

# 複数日を補填
for date in 2025-11-25 2025-11-26 2025-11-27; do
    python scripts/archive_eod_fill.py --date $date
done

監視とアラート

ギャップ検出時のSlack通知

def check_and_alert_gaps():
    """ギャップを検出してSlack通知"""
    state = ArchiveState()

    for archive_type in ArchiveType:
        gaps = state.detect_gaps(archive_type)
        if gaps:
            send_slack_alert(
                f"⚠️ Archive Gap: {archive_type.value}",
                f"Duration: {gaps[0]['duration_hours']:.1f} hours"
            )

ダッシュボード表示

ダッシュボードの「Archive Status」セクションでギャップ状況を確認可能。


ベストプラクティス

定期的な確認

毎朝、ダッシュボードでアーカイブ状況を確認する習慣をつけましょう。

長期ギャップ

24時間以上のギャップは、Polygon APIのレート制限に注意して補填してください。

バックアップ

週次で data/archive/ をバックアップすることを推奨します。