【代替手段】pandas-datareaderでyfinance以外のデータ源を確保する

準備・環境構築

※本記事のコードや情報は執筆時点の仕様に基づいています。投資は自己責任であり、必ずデモ環境や少額資金でテストした上で運用してください。

yfinanceで株価データを取得する環境はすでに構築できている段階でしょう。しかし、ある日突然データが取れなくなった経験はないでしょうか。

yfinanceはYahoo Finance の非公式APIに依存しており、仕様変更やアクセス制限で突然動かなくなるリスクがあります。データ取得手段を1つに依存することは、分析パイプライン全体の停止を意味します。

pandas-datareaderは、Stooq・FRED・Tiingo など複数のデータソース(Data Source)に対応したライブラリです。yfinanceが使えない状況でもデータ取得を継続でき、バックアップ手段として非常に有効です。

しかし、pandas-datareaderは公式ドキュメントが分散しており、どのデータソースが現在も動作するのか判断しにくい状態です。過去に動いていたGoogle FinanceやMorningstarのリーダーはすでに廃止されています。

本記事では、2025年時点で実際に動作するデータソースに絞り、pandas-datareaderのインストールから実践的なデータ取得コード、yfinanceとの自動フォールバック(Fallback:代替切り替え)機構の構築までを解説します。

コードはすべてコピペで動く構成です。自分の分析パイプラインにそのまま組み込み、データ取得の冗長性を確保してください。

pandas-datareaderの概要と対応データソース

pandas-datareaderとは何か

pandas-datareaderは、外部のWebAPIやデータベースから金融・経済データを取得し、pandasのDataFrame形式で返すライブラリです。pandas本体から分離された経緯を持ち、独立パッケージとして開発が続いています。

最大の特徴は、データソースごとに専用のリーダー(Reader)クラスが用意されている点です。リーダーを切り替えるだけで、同じインターフェースで異なるソースからデータを取得できます。

現在も動作するデータソース一覧

すべてのリーダーが動作するわけではありません。以下の表は動作確認済みのデータソースです。

データソース 取得対象 APIキー 主な用途
Stooq 株価(日本株・米国株) 不要 yfinanceの代替として最有力
FRED 米国経済指標(GDP・CPI・金利等) 不要 マクロ分析・ファンダメンタルズ
Tiingo 米国株価・暗号資産 必要(無料枠あり) 高品質な米国株データ
Alpha Vantage 株価・為替・暗号資産 必要(無料枠あり) グローバル対応

Google Finance・Morningstar・Yahoo Finance(datareader経由)のリーダーは廃止済みです。これらを使おうとしてもImmediateDeprecationErrorが発生するので注意してください。

yfinanceとの使い分け方針

yfinanceをメイン、pandas-datareader(Stooq等)をバックアップとする二重構成を推奨します。日本株のデータ取得にはStooqリーダーが最も手軽です。

米国の経済指標(金利・インフレ率等)を取得する場合はFREDリーダー一択です。yfinanceではカバーできない領域なので、補完関係として併用してください。

【コピペOK】pandas-datareaderによるデータ取得コード

まず必要なライブラリをインストールしてください。


pip install pandas-datareader pandas numpy matplotlib yfinance

以下がメインコードです。


import datetime
import numpy as np
import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import matplotlib.pyplot as plt
from typing import Optional

# ==============================
# 設定エリア
# ==============================
TICKER_JP: str = "7203.JP"            # Stooq用 日本株コード(トヨタ自動車)
TICKER_US: str = "AAPL"              # Stooq/Tiingo用 米国株コード
TICKER_YF: str = "7203.T"            # yfinance用 日本株コード
FRED_SERIES: str = "DFF"             # FRED系列ID(FF金利)
START_DATE: str = "2023-01-01"       # データ取得開始日
END_DATE: str = "2024-12-31"         # データ取得終了日
TIINGO_API_KEY: str = '             # Tiingo APIキー(使用時に設定)

# ==============================
# Stooqからの取得(APIキー不要)
# ==============================
def fetch_from_stooq(ticker: str, start: str, end: str) -> Optional[pd.DataFrame]:
    'Stooqから株価データを取得する'
    try:
        df: pd.DataFrame = web.DataReader(
            ticker,
            "stooq",
            start=start,
            end=end,
        )
        df = df.sort_index()
        df.columns = [c.lower() for c in df.columns]
        print(f"[Stooq] {ticker} : {len(df)}行 取得成功")
        return df
    except Exception as e:
        print(f"[Stooq] {ticker} : 取得失敗 - {e}")
        return None

# ==============================
# FREDからの取得(APIキー不要)
# ==============================
def fetch_from_fred(series_id: str, start: str, end: str) -> Optional[pd.DataFrame]:
    'FREDから経済指標データを取得する'
    try:
        df: pd.DataFrame = web.DataReader(
            series_id,
            "fred",
            start=start,
            end=end,
        )
        print(f"[FRED] {series_id} : {len(df)}行 取得成功")
        return df
    except Exception as e:
        print(f"[FRED] {series_id} : 取得失敗 - {e}")
        return None

# ==============================
# Tiingoからの取得(APIキー必要)
# ==============================
def fetch_from_tiingo(
    ticker: str, start: str, end: str, api_key: str,
) -> Optional[pd.DataFrame]:
    'Tiingoから米国株データを取得する'
    if not api_key:
        print("[Tiingo] APIキーが未設定です。スキップします。")
        return None
    try:
        df: pd.DataFrame = web.DataReader(
            ticker,
            "tiingo",
            start=start,
            end=end,
            api_key=api_key,
        )
        df.index = df.index.droplevel("symbol") if isinstance(df.index, pd.MultiIndex) else df.index
        df.columns = [c.lower() for c in df.columns]
        print(f"[Tiingo] {ticker} : {len(df)}行 取得成功")
        return df
    except Exception as e:
        print(f"[Tiingo] {ticker} : 取得失敗 - {e}")
        return None

# ==============================
# yfinanceからの取得(フォールバック用)
# ==============================
def fetch_from_yfinance(ticker: str, start: str, end: str) -> Optional[pd.DataFrame]:
    'yfinanceから株価データを取得する'
    try:
        df: pd.DataFrame = yf.download(
            ticker, start=start, end=end, auto_adjust=True,
        )
        df = df.droplevel("Ticker", axis=1) if isinstance(df.columns, pd.MultiIndex) else df
        df.columns = [c.lower() for c in df.columns]
        if len(df) == 0:
            raise ValueError("データが0行です")
        print(f"[yfinance] {ticker} : {len(df)}行 取得成功")
        return df
    except Exception as e:
        print(f"[yfinance] {ticker} : 取得失敗 - {e}")
        return None

# ==============================
# フォールバック付き統合取得関数
# ==============================
def fetch_with_fallback(
    ticker_stooq: str,
    ticker_yf: str,
    start: str,
    end: str,
) -> Optional[pd.DataFrame]:
    'Stooq → yfinance の順にフォールバックしてデータを取得する'
    print("n--- フォールバック取得開始 ---")

    # 第1候補: Stooq
    df: Optional[pd.DataFrame] = fetch_from_stooq(ticker_stooq, start, end)
    if df is not None and len(df) > 0:
        print("→ Stooq をデータソースとして採用")
        return df

    # 第2候補: yfinance
    df = fetch_from_yfinance(ticker_yf, start, end)
    if df is not None and len(df) > 0:
        print("→ yfinance をデータソースとして採用")
        return df

    print("→ すべてのデータソースで取得に失敗しました")
    return None

# ==============================
# データ比較(Stooq vs yfinance)
# ==============================
def compare_sources(
    df_a: pd.DataFrame,
    df_b: pd.DataFrame,
    label_a: str,
    label_b: str,
) -> None:
    '2つのデータソースの終値を比較してグラフ表示する'
    merged: pd.DataFrame = pd.DataFrame({
        label_a: df_a["close"],
        label_b: df_b["close"],
    }).dropna()

    if len(merged) == 0:
        print("共通する日付がありません。比較をスキップします。")
        return

    diff: pd.Series = (merged[label_a] - merged[label_b]).abs()
    print(f"n--- 終値の差分統計 ({label_a} vs {label_b}) ---")
    print(f"  平均差分 : {diff.mean():>10.2f}")
    print(f"  最大差分 : {diff.max():>10.2f}")
    print(f"  一致率   : {(diff < 0.01).mean() * 100:>10.2f} %")

    fig, axes = plt.subplots(2, 1, figsize=(14, 8))

    axes[0].plot(merged.index, merged[label_a], label=label_a, linewidth=1.2)
    axes[0].plot(merged.index, merged[label_b], label=label_b, linewidth=1.2, linestyle="--")
    axes[0].set_title("Close Price Comparison")
    axes[0].set_ylabel("Price")
    axes[0].legend()
    axes[0].grid(alpha=0.3)

    axes[1].bar(merged.index, diff, color="tomato", width=1.5, alpha=0.7)
    axes[1].set_title("Absolute Difference")
    axes[1].set_ylabel("Diff")
    axes[1].grid(alpha=0.3)

    plt.tight_layout()
    plt.show()

# ==============================
# メイン処理
# ==============================
if __name__ == "__main__":
    # 1. Stooqで日本株を取得
    df_stooq: Optional[pd.DataFrame] = fetch_from_stooq(
        TICKER_JP, START_DATE, END_DATE,
    )

    # 2. FREDで経済指標を取得
    df_fred: Optional[pd.DataFrame] = fetch_from_fred(
        FRED_SERIES, START_DATE, END_DATE,
    )

    # 3. Tiingoで米国株を取得(APIキー設定時のみ)
    df_tiingo: Optional[pd.DataFrame] = fetch_from_tiingo(
        TICKER_US, START_DATE, END_DATE, TIINGO_API_KEY,
    )

    # 4. フォールバック付き取得
    df_main: Optional[pd.DataFrame] = fetch_with_fallback(
        TICKER_JP, TICKER_YF, START_DATE, END_DATE,
    )

    # 5. Stooq vs yfinance の比較
    df_yf: Optional[pd.DataFrame] = fetch_from_yfinance(
        TICKER_YF, START_DATE, END_DATE,
    )
    if df_stooq is not None and df_yf is not None:
        compare_sources(df_stooq, df_yf, "Stooq", "yfinance")

    # 6. FRED取得結果の表示
    if df_fred is not None:
        print(f"n--- FRED ({FRED_SERIES}) 先頭5行 ---")
        print(df_fred.head())

コードの処理フロー解説

上記のコードは、以下の6ステップで構成されています。

* ステップ1(Stooq取得)web.DataReaderにソース名"stooq"を指定し、日本株の日足データを取得する。Stooqは日付が降順で返るためsort_index()で昇順に整列する

* ステップ2(FRED取得):ソース名"fred"で米国の経済指標(ここではFF金利)を取得する。APIキーは不要で、系列ID(Series ID)を指定するだけで取得できる

* ステップ3(Tiingo取得):ソース名"tiingo"で米国株データを取得する。無料APIキーの取得が必要だが、データ品質が高くAdjusted Closeも含まれる

* ステップ4(フォールバック取得)fetch_with_fallback関数がStooq→yfinanceの順に試行し、最初に成功したソースのデータを返す

* ステップ5(ソース比較):StooqとyfinanceのClose値を日付で結合し、差分の統計と比較グラフを出力する

* ステップ6(FRED結果表示):経済指標データの先頭5行をコンソールに出力する

fetch_with_fallback関数の候補リストにTiingoやAlpha Vantageを追加すれば、3段階・4段階のフォールバック構成も容易に構築できます。

データソースごとの特徴と使い分け

Stooq:日本株バックアップの最有力

Stooqはポーランドの金融データサイトですが、日本株の日足データを無料・APIキー不要で提供しています。銘柄コードは7203.JPのように末尾に.JPを付けます。

注意点として、1リクエストで取得できる期間が約5年に制限される場合があります。10年分のデータが必要な場合は期間を分割して取得し、結合してください。

FRED:マクロ経済分析に不可欠

FRED(Federal Reserve Economic Data)は米国セントルイス連邦準備銀行が提供するデータベースです。80万以上の経済時系列を無料で取得できます。

よく使う系列IDを以下にまとめます。

系列ID 内容
DFF フェデラルファンド実効金利
CPIAUCSL 消費者物価指数(CPI)
UNRATE 失業率
DGS10 米国10年国債利回り
DEXJPUS 米ドル/円 為替レート

株価との相関分析やレジーム分析に活用してください。

よくあるエラーと対処法

ImmediateDeprecationError が発生する

廃止済みのデータソース("google""yahoo""morningstar"等)を指定しています。pandas-datareader経由のYahoo Financeリーダーはすでに削除されています。

以下を試してください。

* データソース名を"stooq""fred"に変更する

* Yahoo Financeのデータが必要な場合はyfinanceライブラリを直接使う

* pandas-datareaderを最新版にアップデートする(pip install -U pandas-datareader

RemoteDataError: Unable to read URL

データソースのサーバーが一時的に応答していないか、銘柄コードが間違っています。Stooqの場合、日本株は.JP、米国株はシンボルそのまま(AAPL等)で指定する必要があります。

以下を試してください。

* インターネット接続を確認する

* Stooqの銘柄コード形式(.JP付き)を確認する

* 数分待ってから再実行する(レートリミットの可能性がある)

Stooqで取得したデータにVolume列がない

Stooqの一部銘柄・一部期間ではVolume(出来高)が0またはNaNで返ることがあります。これはStooq側のデータ欠損です。

出来高データが必要な場合はyfinanceをメインソースとし、Stooqは価格データのバックアップ用途に限定してください。compare_sources関数で終値の整合性だけ確認しておけば、価格データとしての信頼性は担保できます。

まとめ

この記事では、pandas-datareaderを使ってyfinance以外のデータソースから金融データを取得する方法を解説しました。

要点を整理します。

* pandas-datareaderはStooq・FRED・Tiingo等の複数データソースに対応し、yfinanceの代替・補完として機能する

* Stooqは日本株の日足データをAPIキー不要で取得でき、yfinance障害時のバックアップとして最有力である

* FREDは80万以上の米国経済指標を無料で提供しており、マクロ分析には不可欠なデータソースである

* 廃止済みリーダー(Google Finance・Morningstar等)を使うとImmediateDeprecationErrorが発生するため、動作確認済みのソースのみ使用する

* fetch_with_fallback関数でStooq→yfinanceの自動切り替え機構を構築し、データ取得の冗長性を確保する

次のステップとして、フォールバック関数をcronやタスクスケジューラで定期実行し、CSVやデータベースに自動保存するパイプラインを構築してください。ローカルにデータを蓄積しておけば、外部APIの障害に左右されない分析環境が完成します。

さらに、FREDの金利データと株価データを組み合わせたレジーム分析を行えば、「利上げ局面では自分の戦略が機能するか」といった条件付きバックテストにも発展できます。

タイトルとURLをコピーしました