株価データ取得API比較|日本株ならJ-Quantsが本命

yfinance・datareaderAlpha Vantageを比較 準備・環境構築

本記事はPython学習・情報提供を目的としています。投資判断はご自身の責任で行ってください。

先に結論

Pythonで株価データを取る方法を比較した記事は多いのですが、日本株を前提にすると結論がかなり変わります。海外向けの定番であるAlpha Vantageは、無料枠が1日25リクエストかつ直近100本のみに制限されており、バックテスト用途では実質的に使えません。

日本株なら、用途に応じてこう選ぶのが現実的です。

用途選ぶべきもの費用
学習・試行錯誤yfinance無料
本気のバックテスト(日本株)J-Quants API(JPX公式)無料〜月1,650円
長期の日足を無料で欲しいStooq(pandas-datareader経由)無料
経済指標・金利FRED(pandas-datareader経由)無料
財務諸表の原本EDINET API(金融庁)無料
リアルタイム・発注証券会社のAPI口座条件あり

以下、それぞれの実態と使い分けを整理します。

📘 外部参考yfinance 公式GitHubJ-Quants API(JPX公式)pandas-datareader ドキュメント

比較一覧

項目yfinanceJ-QuantsStooqAlpha Vantage
提供元非公式JPX公式非公式公式(米企業)
APIキー不要必要不要必要
日本株◎(全上場)△(欠落あり)
無料での履歴実質無制限2年(12週遅延)長期直近100本のみ
無料の回数制限明示なし5回/分明示なし25回/日
財務データ△(欠損多い)
分割・配当調整◎(調整前も)有料
安定性△(仕様変更)

yfinance:学習と試行錯誤には最適

APIキー不要で、日本株も米国株も為替も1行で取れます。ここから始めるのが正解です。

import pandas as pd
import yfinance as yf

def fetch_yf(ticker: str, period: str = "10y") -> pd.DataFrame:
    df = yf.download(ticker, period=period, auto_adjust=True, progress=False)
    if isinstance(df.columns, pd.MultiIndex):     # 1銘柄でもMultiIndexで返る
        df.columns = df.columns.get_level_values(0)
    return df.dropna()

print(fetch_yf("7203.T").tail(3))

弱点は非公式であることに尽きます。Yahoo! Finance側の都合でいつ止まってもおかしくありませんし、実際にレート制限(YFRateLimitError)で弾かれることが増えています。ライブラリ自体の仕様変更も頻繁で、auto_adjustの既定値変更や列のMultiIndex化で、過去記事のコードは軒並み動かなくなりました。

「壊れてもいい用途」に限定するのが健全な付き合い方です。運用に組み込むなら別の手段を併用してください。

J-Quants API:日本株ならこれが本命

東京証券取引所を運営するJPXが公式に提供しているAPIです。日本株の分析をするなら、無料プランだけでも登録する価値があります。

プラン月額(税込)期間呼び出し
無料¥02年(12週間遅延)5回/分
ライト¥1,6505年60回/分
スタンダード¥3,30010年120回/分
プレミアム¥16,500全期間500回/分

無料プランは12週間の遅延があります。直近3ヶ月弱のデータは取れません。これは制約ですが、バックテストなら何の問題もないので、検証用途では無料プランで十分です。逆にシグナル生成に使うならライト以上が必要になります。

# pip install jquants-api-client
import jquantsapi

cli = jquantsapi.ClientV2(api_key="YOUR_API_KEY")   # V2はAPIキー方式

df = cli.get_eq_bars_daily_range(
    code="7203", start_dt="2024-01-01", end_dt="2025-12-31")
print(df.head())

listed = cli.get_eq_listed_info()      # 全上場銘柄の一覧
print(len(listed), "銘柄")

yfinanceに対する優位点がはっきりしています。

  • 全上場銘柄の一覧が取れる。スクリーニングの母集団を正しく作れる
  • 上場廃止銘柄も含まれる。生存バイアスを避けられる
  • 調整前と調整後の両方が提供される
  • 決算発表予定日が取れる。イベント回避や検証に必須
  • 財務情報が欠損なく揃う

2つ目が特に重要です。yfinanceで現在の上場銘柄だけを対象にバックテストすると、「潰れなかった会社」だけを選んで検証していることになり、成績が実際より良く出ます。これは生存バイアスと呼ばれる古典的な落とし穴です。

なお、2025年12月のV2リリースで認証方式が変わりました。リフレッシュトークン方式は廃止され、ダッシュボードで発行するAPIキー方式に統一されています。古い記事のコードは動きません。

pandas-datareader:FREDとStooqのために使う

このライブラリの「Yahoo!からデータを取る」機能は、事実上使えなくなっています。メンテナンスも活発ではありません。ただし、2つのデータソースのために今でも価値があります。

FRED(米セントルイス連銀)

import pandas_datareader.data as web
import datetime as dt

start, end = dt.datetime(2015, 1, 1), dt.datetime.today()

series = {
    "DGS10": "米10年債利回り",
    "DGS2": "米2年債利回り",
    "VIXCLS": "VIX指数",
    "DEXJPUS": "ドル円",
    "T10Y2Y": "長短金利差",
}
macro = web.DataReader(list(series), "fred", start, end).rename(columns=series)
print(macro.tail())

APIキー不要で、金利・為替・VIXなどのマクロ指標がまとめて取れます。個別株の予測モデルに外部変数を足したいとき、いちばん手軽な供給源です。

Stooq(日本株の長期日足)

def fetch_stooq(code: str, start="2000-01-01") -> pd.DataFrame:
    """Stooqの日本株は '7203.JP' 形式。降順で返るので並べ替える。"""
    df = web.DataReader(f"{code}.JP", "stooq", start)
    return df.sort_index()

try:
    s = fetch_stooq("7203")
    print(f"Stooq: {s.index[0].date()} 〜 {s.index[-1].date()}  {len(s)}行")
except Exception as e:
    print("Stooqから取得できませんでした:", e)

Stooqは無料・APIキー不要で、日本株の長期日足が取れます。yfinanceが不調なときの代替として持っておくと安心です。ただし非公式であることと、銘柄によって欠落があることには注意してください。取得結果が日付の降順で返る点も、そのまま使うと事故ります。

Alpha Vantage:無料枠では厳しい

公式APIで安定性は高いのですが、無料枠の制限が実用に耐えません。

  • 1日25リクエスト(毎分5リクエストまで)
  • outputsize=fullは有料プラン限定。無料では直近100本しか取れない
  • 米国のリアルタイム/15分遅延データも有料
  • 日本株は.Tで指定できるが、取得できない銘柄がある

100本=約5ヶ月ぶんです。これでバックテストはできません。また、25銘柄を1回ずつ取っただけで1日の枠を使い切ります。有料プランは月49.99ドルからで、日本株が主目的ならJ-Quantsのライトプラン(月1,650円)のほうが圧倒的に有利です。

import requests

def fetch_alpha(symbol: str, api_key: str) -> pd.DataFrame:
    r = requests.get("https://www.alphavantage.co/query", timeout=30, params={
        "function": "TIME_SERIES_DAILY",
        "symbol": symbol,
        "outputsize": "compact",     # full は有料プランのみ
        "apikey": api_key,
    })
    data = r.json()

    # 制限に達すると 200 で Note / Information が返る。例外にならないので要確認
    for key in ("Note", "Information", "Error Message"):
        if key in data:
            raise RuntimeError(f"{key}: {data[key]}")

    df = pd.DataFrame(data["Time Series (Daily)"]).T.astype(float)
    df.index = pd.to_datetime(df.index)
    df.columns = ["Open", "High", "Low", "Close", "Volume"]
    return df.sort_index()

このエラーチェックが必須です。Alpha Vantageは制限に達してもHTTPステータス200を返し、本文にNoteInformationを入れて返します。素朴にdata["Time Series (Daily)"]を読むとKeyErrorになり、原因が分かりません。

財務データはEDINETから

意外と知られていませんが、金融庁のEDINET APIは無料・登録のみで、有価証券報告書や四半期報告書の原本(XBRL)が取得できます。yfinanceの財務データは日本株では欠損が多いので、真面目にやるならこちらです。

def edinet_documents(date: str, api_key: str) -> pd.DataFrame:
    """指定日に提出された書類の一覧を取得する。"""
    r = requests.get(
        "https://api.edinet-fsa.go.jp/api/v2/documents.json",
        params={"date": date, "type": 2, "Subscription-Key": api_key},
        timeout=30)
    r.raise_for_status()
    docs = pd.DataFrame(r.json().get("results", []))
    if docs.empty:
        return docs
    return docs[["docID", "filerName", "docDescription",
                 "secCode", "submitDateTime"]]

ただし、XBRLの解析はそれなりに手間がかかります。「決算数値を正確に押さえたい」という段階に来てから取り組めば十分です。

複数ソースを突き合わせて検品する

どのソースにも欠損や誤りがあります。重要な分析の前に、2つのソースを突き合わせるのが安全です。

import numpy as np

def cross_check(code: str = "7203") -> None:
    a = fetch_yf(f"{code}.T", period="5y")["Close"]
    try:
        b = fetch_stooq(code)["Close"]
    except Exception as e:
        print("比較先が取得できません:", e)
        return

    both = pd.DataFrame({"yf": a, "stooq": b}).dropna()
    if both.empty:
        print("共通の日付がありません")
        return

    # 調整方法が違うと水準がずれるので、リターンで比べる
    ra, rb = both["yf"].pct_change(), both["stooq"].pct_change()
    diff = (ra - rb).abs()

    print(f"共通日数        : {len(both)}")
    print(f"リターン相関    : {ra.corr(rb):.6f}")
    print(f"日次差の中央値  : {diff.median() * 100:.4f}%")
    print(f"0.5%以上ずれた日: {int((diff > 0.005).sum())}日")
    if (diff > 0.005).sum() > 0:
        print(diff.sort_values(ascending=False).head(5))

cross_check()

水準ではなくリターンで比較するのがコツです。分割や配当の調整方法が違えば価格の水準はずれますが、日々のリターンは一致するはずです。相関が0.999を下回るなら、どちらかにデータの欠陥があります。

ずれた日のリストを見ると、たいてい株式分割の前後特別配当の権利落ち日です。そこを確認すれば、どちらのソースが正しいか判断できます。

現実的な組み合わせ

1つに絞る必要はありません。自分は次のように使い分けています。

段階使うもの理由
アイデアを試すyfinance1行で書ける
本格的な検証J-Quants(無料)全銘柄・生存バイアス回避
外部変数を足すFRED金利・VIX・為替が無料
データ検品Stooq突き合わせ用の第2ソース
運用シグナルJ-Quants(ライト)遅延なし・安定
発注証券会社APIほかに手段がない

大事なのは、取得処理を関数の裏に隠しておくことです。fetch(ticker, period)という共通の入口を1つ作っておけば、ソースを乗り換えるときに分析コードを触らずに済みます。yfinanceの仕様変更で全スクリプトが止まった経験があると、この設計のありがたみが分かります。

まとめ

  • 学習はyfinance。1行で書けるのが最大の価値。ただし壊れる前提で使う
  • 日本株の本気の検証はJ-Quants。無料プランでも全上場銘柄と決算予定日が取れる
  • Alpha Vantageの無料枠は使えない。25回/日、直近100本のみ
  • pandas-datareaderはFREDとStooqのために残しておく
  • 財務データの原本が要るならEDINET API
  • 重要な分析の前に2ソースをリターンで突き合わせる

データの質は分析の質の上限を決めます。無料で始められる選択肢が揃っているので、まずyfinanceで手を動かし、真剣に検証する段になったらJ-Quantsに登録する。この順番がおすすめです。

🔗 関連記事

Pythonで株価取得|yfinanceの仕様変更とエラー対処
yfinanceで日本株を取得できない時の原因と対処法【エラー別】

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