Skip to content

V2対応: ClientV1/ClientV2 別クラス方式による移行 #8

Description

@apokamo

概要

J-Quants API V2対応として、V2クライアントを実装しました。

from jquants import ClientV2  # V2対応

進捗状況

Phase 内容 ステータス
Phase 1 パッケージ再構築 ✅ 完了
Phase 2 ClientV2 認証 ✅ 完了
Phase 3 ClientV2 エンドポイント + テスト ✅ Phase A 完了(Standard 12件)
Phase 3.7 リファクタリング ✅ 完了
Phase 3.8 ドキュメント整備 ✅ 完了
Phase 4 レートリミット ✅ 完了 (Phase 3.1.5 で前倒し実装)
Phase 5 V1削除 + リリース準備 🔄 V1削除完了、リリース未着手
Phase B Premium エンドポイント(6件) 🔲 未着手

詳細な進捗・設計は #10 を参照

結合テストは各 Sub-Phase で作成・実行(Premium 対象はスキップ設定)

背景

前提

  • V1(jquantsapi)は完全削除済み
  • 下位互換は不要(V1互換API / jquantsapi互換 / カラム名変換は行わない)

主要変更点

1. パッケージ構造

jquants/
├── __init__.py
├── client_v2.py      # V2クライアント
├── constants_v2.py   # V2カラム定義
├── pacer.py          # Leaky Bucket レートリミッター
└── exceptions.py     # カスタム例外

tests/
├── test_client_v2.py     # V2単体テスト
└── test_integration/     # V2結合テスト

Note: V1(jquantsapi)は #34 で完全削除済み

2. 認証方式

項目 ClientV2
認証方式 APIキー
ヘッダー x-api-key: {api_key}
環境変数 JQUANTS_API_KEY

3. エンドポイント(Standard 12件実装済み)

カテゴリ エンドポイント メソッド ステータス
Equities /v2/equities/master get_listed_info()
Equities /v2/equities/bars/daily get_prices_daily_quotes()
Equities /v2/equities/earnings-calendar get_fins_announcement()
Markets /v2/markets/calendar get_markets_trading_calendar()
Markets /v2/markets/margin-interest get_markets_weekly_margin_interest()
Markets /v2/markets/short-ratio get_markets_short_selling()
Markets /v2/markets/short-sale-report get_markets_short_selling_positions()
Markets /v2/markets/margin-alert get_markets_daily_margin_interest()
Indices /v2/indices/bars/daily get_indices()
Indices /v2/indices/bars/daily/topix get_indices_topix()
Financials /v2/fins/summary get_fins_summary()
Derivatives /v2/derivatives/bars/daily/options/225 get_options_225_daily()

Premium エンドポイント(6件)は Phase B で実装予定。

4. レスポンス形式

  • キー統一: 全て d["data"]
  • カラム名: V2ネイティブをそのまま使用(変換なし)

カラム名対応表(参考)

V1 V2 説明
Open O 始値
High H 高値
Low L 安値
Close C 終値
Volume Vo 出来高
TurnoverValue Va 売買代金
CompanyName CoName 会社名
Sector17Code S17 17業種コード
Sector33Code S33 33業種コード

5. レートリミット ⚠️ 重要

V2 APIは厳格なレートリミットが適用される。

プラン 上限 実効レート
Free 5 req/min 0.08 req/sec (12秒に1回)
Light 60 req/min 1 req/sec
Standard 120 req/min 2 req/sec (0.5秒に1回)
Premium 500 req/min 8.3 req/sec

実装済み機能:

  1. Leaky Bucket (Pacer) 方式 - 常に一定間隔を守る「整流化」
  2. 429エラー時5分10秒待ってリトライ - 遮断解除を待つ
  3. 並列化は設定可能 - デフォルトは直列(max_workers=1

設計方針

V2ネイティブ採用の理由

  1. 新規クラス - V1互換性を引きずる必要なし
  2. シンプルさ - 変換レイヤー不要、コードがクリーン
  3. 将来性 - V1廃止後はV2カラム名が標準

TDD方針

各機能は Red → Green → Refactor サイクルで実装。

カバレッジ方針

  • V2のみ計測(V1は完全削除済み)
  • 現在カバレッジ: 98%

実装計画(TDD)

Phase 1: パッケージ再構築 ✅ 完了

  • jquants パッケージ作成
  • make test && make lint パス

Phase 2: ClientV2 認証 ✅ 完了

Phase 3: ClientV2 エンドポイント + テスト

詳細な Sub-Phase 設計・進捗は #10 を参照

Sub-Phase 3.1: 基本インフラ ✅ 完了 (PR #14)

  • exceptions.py 作成(カスタム例外クラス)
  • constants_v2.py 作成(V2カラム定義)
  • _request() 拡張(エラーハンドリング強化)

Sub-Phase 3.1.5: レートリミッター基盤 ✅ 完了 (PR #16)

  • pacer.py 作成(Leaky Bucket方式)
  • 429エラー時の5分10秒リトライ実装

Sub-Phase 3.2: Equities-Standard ✅ 完了 (PR #18, #22)

  • get_listed_info(), get_prices_daily_quotes(), get_fins_announcement()
  • get_price_range() 並列取得

Sub-Phase 3.3: Markets ✅ 完了 (PR #23)

  • 6エンドポイント実装(5 Standard + 1 Premium)

Sub-Phase 3.4: Indices ✅ 完了 (PR #27)

  • get_indices(), get_indices_topix()

Sub-Phase 3.5: Financials-Standard ✅ 完了 (PR #26)

  • get_fins_summary(), get_summary_range()

Sub-Phase 3.6: Derivatives-Standard ✅ 完了 (PR #28)

  • get_options_225_daily(), get_options_225_daily_range()

Phase 3.7: リファクタリング ✅ 完了

Issue 内容 PR ステータス
#37 パラメータ排他チェック共通化 #42 ✅ 完了
#40 日付範囲取得ロジック共通化 #46 ✅ 完了
#44 429リトライ制御の分離と高度化 #47 ✅ 完了
#45 型ヒントとDocstringの整備 #48 ✅ 完了
#33 リクエストパイプライン共通化 #49 ✅ 完了

Phase 3.8: ドキュメント整備 ✅ 完了 (PR #38, #39)

  • ドキュメント構造のリファクタリング(Progressive Disclosure)
  • V2ユーザーガイド追加
  • README更新

Phase 4: レートリミット ✅ 完了 (Phase 3.1.5 で前倒し実装)

Phase 5: V1削除 + リリース準備 🔄 進行中

Phase B: Premium エンドポイント 🔲 未着手

Sub-Phase 3.7-P: Equities-Premium (2件)

  • /v2/equities/bars/daily/amget_prices_prices_am()
  • /v2/equities/investor-typesget_markets_trades_spec()

Sub-Phase 3.8-P: Financials-Premium (2件)

  • /v2/fins/detailsget_fins_fs_details()
  • /v2/fins/dividendget_fins_dividend()

Sub-Phase 3.9-P: Derivatives-Premium (2件)

  • /v2/derivatives/bars/daily/futuresget_derivatives_futures()
  • /v2/derivatives/bars/daily/optionsget_derivatives_options()

ClientV2 インターフェース

class ClientV2:
    def __init__(
        self,
        api_key: Optional[str] = None,
        rate_limit: Optional[int] = None,  # req/min (None=Free 5 req/min)
        max_workers: int = 1,              # 並列取得ワーカー数(デフォルト直列)
        retry_on_429: bool = True,         # 429時リトライするか
        retry_wait_429: int = 310,         # 429時待機秒数(デフォルト5分10秒)
        retry_max_429: int = 3,            # 429時最大リトライ回数
    ) -> None:
        ...

使用例

from jquants import ClientV2

# デフォルト(Free プラン、直列取得)
client = ClientV2(api_key="xxx")
df = client.get_prices_daily_quotes(code="7203")
print(df["O"])  # V2ネイティブカラム名

# Standard プラン、並列取得
client = ClientV2(
    api_key="xxx",
    rate_limit=120,    # Standard: 120 req/min
    max_workers=3,     # 並列取得(Pacer制御付き)
)
df = client.get_price_range(start_dt="2024-01-01", end_dt="2024-12-31")

完了条件

  • from jquants import ClientV2 が動作
  • Phase 1 完了: パッケージ再構築
  • Phase 2 完了: ClientV2 認証
  • Phase 3 Phase A 完了: Standard 12エンドポイント
  • Phase 3.7 完了: リファクタリング
  • Phase 3.8 完了: ドキュメント整備
  • Phase 4 完了: レートリミット
  • V1完全削除 (V1(jquantsapi)削除: コード/ドキュメント/テストの整理 #34)
  • make lint パス
  • カバレッジ 98%
  • Phase B: Premium 6エンドポイント
  • v2.0.0 リリース

関連Issue

参考


🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions