コンテンツにスキップ

データ形式

概要

すべてのアーカイブデータはApache Parquet形式で保存されます。

なぜParquetか?

  • 列指向: 特定カラムのみの読み込みが高速
  • 圧縮効率: zstd圧縮で70-80%のサイズ削減
  • スキーマ強制: データ型の一貫性を保証
  • エコシステム: pandas, PyArrow, DuckDBなど多くのツールで読み込み可能

UW Flow (Unusual Whales フロー)

スキーマ

フィールド 説明
timestamp timestamp[us, tz=UTC] 取得時刻 2025-11-28T14:30:00Z
symbol string ティッカー NVDA
strike float64 ストライク価格 140.0
expiration date32 満期日 2025-12-20
option_type string オプションタイプ CALL / PUT
sentiment string センチメント BULLISH / BEARISH / NEUTRAL
premium float64 プレミアム総額 ($) 125000.0
volume int64 出来高 500
size int64 取引サイズ 100
iv float64 IV (%) 0.45
delta float64 デルタ 0.65
is_unusual bool 異常フラグ true
et_offset int8 ETオフセット (時間) -5

サンプルデータ

import pandas as pd

df = pd.read_parquet("data/archive/uw_flow/date=2025-11-28/uw_flow_20251128.parquet")
print(df.head())
                          timestamp symbol  strike  expiration option_type sentiment   premium  volume  size    iv  delta  is_unusual  et_offset
0 2025-11-28 14:30:00+00:00   NVDA   140.0  2025-12-20        CALL   BULLISH  125000.0     500   100  0.45   0.65        True         -5
1 2025-11-28 14:32:15+00:00   AAPL   185.0  2025-12-06         PUT   BEARISH   85000.0     300    50  0.32  -0.40       False         -5

Options (オプションチェーン)

スキーマ

フィールド 説明
timestamp timestamp[us, tz=UTC] スナップショット時刻 2025-11-28T14:30:00Z
symbol string 原資産ティッカー NVDA
underlying_price float64 原資産価格 142.50
strike float64 ストライク価格 140.0
expiration date32 満期日 2025-12-20
option_type string オプションタイプ CALL / PUT
bid float64 ビッド価格 5.20
ask float64 アスク価格 5.40
last float64 直近約定価格 5.30
volume int64 当日出来高 1500
open_interest int64 建玉 25000
iv float64 IV (%) 0.42
delta float64 デルタ 0.55
gamma float64 ガンマ 0.025
theta float64 セータ -0.08
vega float64 ベガ 0.15
et_offset int8 ETオフセット (時間) -5

読み込み例

# 特定銘柄のオプションチェーンを取得
df = pd.read_parquet(
    "data/archive/options/",
    filters=[
        ("symbol", "==", "NVDA"),
        ("expiration", ">=", "2025-12-01"),
    ]
)

# ATMオプションを抽出
atm = df[abs(df["strike"] - df["underlying_price"]) < 5]

GEX Profile (Gamma Exposure)

スキーマ

フィールド 説明
timestamp timestamp[us, tz=UTC] 計算時刻 2025-11-28T14:30:00Z
symbol string ティッカー NVDA
gex_value float64 GEX値 ($ billions) 2.5
flip_point float64 フリップポイント価格 138.0
call_wall float64 コールウォール価格 150.0
put_wall float64 プットウォール価格 130.0
regime string GEXレジーム POS_GAMMA_SAFE / NEG_GAMMA_RISKY
ratio float64 GEXレシオ (当日) 1.25
ratio_98d float64 98D GEXレシオ 1.15
et_offset int8 ETオフセット (時間) -5

GEXレジーム判定

def classify_regime(gex_value: float, ratio_98d: float) -> str:
    """GEXレジームを判定"""
    if gex_value > 0:
        if ratio_98d > 1.2:
            return "POS_GAMMA_SAFE"
        else:
            return "POS_GAMMA_NEUTRAL"
    else:
        if ratio_98d < 0.8:
            return "NEG_GAMMA_RISKY"
        else:
            return "NEG_GAMMA_NEUTRAL"

Stocks 1m (1分足株価)

スキーマ

フィールド 説明
timestamp timestamp[us, tz=UTC] バー開始時刻 2025-11-28T14:30:00Z
symbol string ティッカー NVDA
open float64 始値 142.50
high float64 高値 142.80
low float64 安値 142.30
close float64 終値 142.65
volume int64 出来高 125000
vwap float64 VWAP 142.55
et_offset int8 ETオフセット (時間) -5

取得元

  • リアルタイム: Polygon WebSocket (場中)
  • EOD補填: Polygon REST API /v2/aggs/ticker/{symbol}/range/1/minute/{from}/{to}

使用例

# 1日分の1分足データを読み込み
df = pd.read_parquet("data/archive/stocks/date=2025-11-28/stocks_1m_20251128.parquet")

# VWAPを使った分析
df["vwap_deviation"] = (df["close"] - df["vwap"]) / df["vwap"] * 100

IV Rank

スキーマ

フィールド 説明
timestamp timestamp[us, tz=UTC] 取得時刻 2025-11-28T14:00:00Z
symbol string ティッカー NVDA
iv_rank float64 IV Rank (0-100) 45.2
iv_percentile float64 IV Percentile (0-100) 52.1
current_iv float64 現在のIV (%) 0.42
iv_high_52w float64 52週高値IV 0.85
iv_low_52w float64 52週安値IV 0.25
et_offset int8 ETオフセット (時間) -5

取得元

Barchart.com からスクレイピング(1日2回: JST 09:00, 21:00)


Trades (トレード履歴)

スキーマ

フィールド 説明
trade_id string トレードID TR-20251128-001
entry_time timestamp[us, tz=UTC] エントリー時刻 2025-11-28T14:30:00Z
exit_time timestamp[us, tz=UTC] イグジット時刻 2025-11-28T18:45:00Z
symbol string ティッカー NVDA
strategy string 戦略名 SUNACCHAN_SPEAR
direction string 方向 LONG / SHORT
quantity int32 数量 1
entry_price float64 エントリー価格 2.50
exit_price float64 イグジット価格 4.50
pnl float64 損益 ($) 200.0
pnl_percent float64 損益率 (%) 80.0
hold_days int32 保有日数 0
exit_reason string イグジット理由 PROFIT_TARGET
et_offset int8 ETオフセット (時間) -5

データ読み込みユーティリティ

日付範囲でのデータ取得

from pathlib import Path
import pandas as pd

def load_archive_data(
    archive_type: str,
    start_date: str,
    end_date: str,
    symbols: list[str] = None
) -> pd.DataFrame:
    """
    アーカイブデータを日付範囲で読み込み

    Args:
        archive_type: "uw_flow", "options", "gex", "stocks", "iv_rank", "trades"
        start_date: 開始日 (YYYY-MM-DD)
        end_date: 終了日 (YYYY-MM-DD)
        symbols: フィルタする銘柄リスト (Noneで全銘柄)

    Returns:
        pd.DataFrame: 結合されたデータ
    """
    base_path = Path("data/archive") / archive_type

    filters = []
    if symbols:
        filters.append(("symbol", "in", symbols))

    df = pd.read_parquet(
        base_path,
        filters=filters
    )

    # 日付でフィルタ
    df = df[
        (df["timestamp"].dt.date >= pd.to_datetime(start_date).date()) &
        (df["timestamp"].dt.date <= pd.to_datetime(end_date).date())
    ]

    return df.sort_values("timestamp")

DuckDBでのクエリ

import duckdb

# 高速なSQLクエリ
result = duckdb.query("""
    SELECT 
        symbol,
        DATE_TRUNC('hour', timestamp) as hour,
        AVG(premium) as avg_premium,
        SUM(volume) as total_volume
    FROM 'data/archive/uw_flow/**/*.parquet'
    WHERE symbol = 'NVDA'
      AND sentiment = 'BULLISH'
    GROUP BY symbol, hour
    ORDER BY hour
""").df()