exchange-session-detector について
時系列データで取引時間と休場日を正確に判定するスキルです。単純な時間帯チェックを置き換える開発者向けで、夏時間、昼休み、短縮取引にも対応します。
主な機能
- 0110取引所のMICレジストリ
- 02夏時間対応の取引時間判定
- 03休場日と昼休みの処理
- 04分単位の事前計算検索
- 05ClickHouseの取引時間SQLパターン
活用シーン
- 01DataFrameへの取引時間フラグ追加
- 02取引所の休場日判定
- 03ClickHouseでの取引時間分類
- 04固定時間チェックの置き換え
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill exchange-session-detectorインストール後、Claude Code で/exchange-session-detectorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/clickhouse-session-sql.mdexchange-registry.mdsession-detector-pattern.md詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
取引所セッション検出器
DST、祝日、昼休みに完全対応した、本番環境向けの取引所セッション検出パターンです。世界の10取引所で、exness-data-preprocess を通じて検証済みです。
継続的に進化するスキル:このスキルは使用を通じて改善されます。指示が誤っている、パラメーターが変化している、または回避策が必要だった場合は、先延ばしにせず、すぐにこのファイルを修正してください。実際に再現可能な問題がある場合にのみ更新してください。
使用する場面
- 時系列 DataFrame にセッションフラグ(is_nyse_session、is_lse_session など)を追加するとき
- タイムスタンプが主要な取引所の取引時間内にあるかを検出するとき
- 祝日を確認するとき(NYSE、LSE、または両方が休場の場合の「主要」)
- アジアの取引所(東京、香港、シンガポール)の昼休みを処理するとき
- 簡易的な時間範囲チェックから、本番環境に適した精度へアップグレードするとき
- セッション分類用の ClickHouse マテリアライズドカラムを構築するとき
アーキテクチャの概要
ExchangeConfig registry (exchanges.py) SessionDetector (session_detector.py)
┌──────────────────────────────────┐ ┌──────────────────────────────────────┐
│ 10 frozen dataclasses │ │ Wraps exchange_calendars library │
│ ISO 10383 MIC codes │─────▶│ Pre-computes trading minutes (sets) │
│ IANA timezones for DST │ │ Vectorized .isin() lookup (2.2x) │
│ Local open/close hours │ │ Holiday detection (NYSE + LSE) │
└──────────────────────────────────┘ └──────────────────────────────────────┘
クイックスタート
import exchange_calendars as xcals
import pandas as pd
# Single-exchange check
cal = xcals.get_calendar("XNYS") # NYSE via ISO 10383 MIC
cal.is_open_on_minute(pd.Timestamp("2024-07-04 14:30", tz="UTC")) # False (July 4th)
cal.is_open_on_minute(pd.Timestamp("2024-07-05 14:30", tz="UTC")) # True
# Full session detection across 10 exchanges
from session_detector import SessionDetector
detector = SessionDetector()
df = detector.detect_sessions_and_holidays(dates_df)
# Adds: is_us_holiday, is_uk_holiday, is_major_holiday, is_{exchange}_session
セッション検出の2つの段階
段階1:単純な時間範囲(多くのプロジェクトが最初に採用する方法)
# Pattern from opendeviationbar-py/ouroboros.py
EXCHANGE_SESSION_HOURS = {
"sydney": {"tz": "Australia/Sydney", "start": 10, "end": 16},
"tokyo": {"tz": "Asia/Tokyo", "start": 9, "end": 15},
"london": {"tz": "Europe/London", "start": 8, "end": 17},
"newyork": {"tz": "America/New_York", "start": 10, "end": 16},
}
def is_in_session(session_name, timestamp_utc):
info = EXCHANGE_SESSION_HOURS[session_name]
tz = zoneinfo.ZoneInfo(info["tz"])
local_time = timestamp_utc.astimezone(tz)
if local_time.weekday() >= 5:
return False
return info["start"] <= local_time.hour < info["end"]
正しく処理できること:zoneinfo による DST 変換、週末の除外。
処理できないこと:
- 祝日(クリスマス、感謝祭、銀行休業日)
- 昼休み(東京 11:30~12:30、HK 12:00~13:00、SGX 12:00~13:00)
- 半日取引/早引けセッション
- 1時間未満の精度(NYSE の開始時刻は 10:00 ではなく 9:30、LSE の終了時刻は 17:00 ではなく 16:30)
- 取引所のスケジュール変更(東京は 2024 年 11 月 5 日に 15:30 まで延長)
段階2:exchange_calendars(本番環境向け)
exchange_calendars ライブラリ(保守されており、pip でインストール可能、50 以上の取引所に対応)は、is_open_on_minute() を使用して上記のすべてを自動的に処理します。このライブラリは内部で IANA タイムゾーンデータを使用するため、手動のロジックを使わなくても DST の切り替えが正しく処理されます。
MIC コード、タイムゾーン、開始・終了時刻を含む10取引所の完全なレジストリについては、references/exchange-registry.md を参照してください。
事前計算済みの取引分とベクトル化ルックアップを使用した、SessionDetector の完全な実装パターンについては、references/session-detector-pattern.md を参照してください。
取引所レジストリ
ISO 10383 MIC コードを使用して、10取引所に対応しています。
| 取引所 | MIC コード | タイムゾーン | 取引時間(現地時間) | 昼休み |
|---|---|---|---|---|
| NYSE | XNYS | America/New_York | 09:30 - 16:00 | - |
| LSE | XLON | Europe/London | 08:00 - 16:30 | - |
| SIX | XSWX | Europe/Zurich | 09:00 - 17:30 | - |
| FWB | XFRA | Europe/Berlin | 09:00 - 17:30 | - |
| TSX | XTSE | America/Toronto | 09:30 - 16:00 | - |
| NZX | XNZE | Pacific/Auckland | 10:00 - 16:45 | - |
| JPX | XTKS | Asia/Tokyo | 09:00 - 15:00 | 11:30 - 12:30 JST |
| ASX | XASX | Australia/Sydney | 10:00 - 16:00 | - |
| HKEX | XHKG | Asia/Hong_Kong | 09:30 - 16:00 | 12:00 - 13:00 HKT |
| SGX | XSES | Asia/Singapore | 09:00 - 17:00 | 12:00 - 13:00 SGT |
取引所を追加するには、レジストリの辞書に ExchangeConfig エントリを1つ追加するだけです。SessionDetector、スキーマ生成、カラム名はすべて自動的に反映されます。
パフォーマンス:事前計算済みの取引分
単純な方法では、タイムスタンプごと、取引所ごとに calendar.is_open_on_minute() を呼び出すため、定数係数が大きい O(N * E) になります。検証済みのパターンでは、すべての取引分を事前にセットへ計算しておき、O(1) でルックアップします。
# Pre-compute once (startup cost, amortized over millions of lookups)
trading_minutes = detector._precompute_trading_minutes(start_date, end_date)
# Returns: {"nyse": {ts1, ts2, ...}, "lse": {ts1, ts2, ...}, ...}
# Vectorized lookup via pandas .isin() — 2.2x faster than per-row .apply()
df["is_nyse_session"] = df["ts"].isin(trading_minutes["nyse"]).astype(int)
事前計算では内部的に is_open_on_minute() を使用するため、昼休み、祝日、スケジュール変更がすべて反映されます。
祝日検出
# NYSE holidays (excludes weekends — only official closures)
nyse_holidays = {
pd.to_datetime(h).date()
for h in calendar.regular_holidays.holidays(start=start, end=end, return_name=False)
}
# Major holiday = both NYSE AND LSE closed
df["is_major_holiday"] = ((df["is_us_holiday"] == 1) & (df["is_uk_holiday"] == 1)).astype(int)
ClickHouse 連携
サーバー側でセッションを検出する場合(マテリアライズドカラムなど)、IANA タイムゾーン名を指定すると、ClickHouse の toTimezone() が DST を自動的に処理します。
-- DST-aware hour extraction (matches Python zoneinfo behavior)
ALTER TABLE my_table
UPDATE is_nyse_session = if(
toHour(toTimezone(toDateTime(intDiv(close_time_ms, 1000)), 'America/New_York')) >= 9
AND toHour(toTimezone(toDateTime(intDiv(close_time_ms, 1000)), 'America/New_York')) < 16
AND toDayOfWeek(toTimezone(toDateTime(intDiv(close_time_ms, 1000)), 'America/New_York')) <= 5,
1, 0
) WHERE 1 = 1
制限事項:ClickHouse の toTimezone() は DST を処理しますが、祝日や昼休みには対応していません。これらは Python で計算してフラグを書き戻すか、ClickHouse で祝日カレンダーテーブルを管理してください。
アップグレード手順:時間範囲から exchange_calendars へ
pip install exchange_calendars(またはpyproject.tomlに追加します)- 固定時間の辞書を
ExchangeConfigレジストリに置き換えます(references/exchange-registry.mdを参照) zoneinfoによる時間チェックをSessionDetector.detect_sessions_and_holidays()に置き換えます- テストを更新し、祝日、昼休み、DST の切り替わり、早じまいを網羅します
exchange_calendars ライブラリのインストールサイズは約 10MB で、pandas と numpy 以外に大きな依存関係はありません。カレンダーデータは同梱されているため、実行時のネットワーク呼び出しはありません。
参考資料
| ファイル | 内容 |
|---|---|
| exchange-registry.md | frozen dataclass パターンを使用した ExchangeConfig レジストリ全体 |
| session-detector-pattern.md | 分を事前計算する SessionDetector クラス全体 |
| clickhouse-session-sql.md | サーバー側でセッションを検出する ClickHouse SQL パターン |
ソース
検証済みの実装:~/eon/exness-data-preprocess/src/exness_data_preprocess/session_detector.py + exchanges.py
簡略化された旧バージョン:~/eon/opendeviationbar-py/python/opendeviationbar/ouroboros.py(Tier 1 のみ)
実行後の振り返り
このスキルの実行後、完了する前に以下を確認してください。
- コマンドは成功しましたか? — 成功しなかった場合は、失敗の原因となった指示またはエラーテーブルを修正してください。
- パラメーターや出力に変更はありましたか? — 基盤となるツールのインターフェースに変更があった場合は、使用例とパラメーターテーブルを更新して一致させてください。
- 回避策が必要でしたか? — 別のフラグや追加手順などの工夫が必要だった場合は、次回同じ回避策が不要になるよう、この SKILL.md を更新してください。
問題が実際に発生し、再現可能な場合にのみ更新してください。推測に基づく更新は行わないでください。