J-Quants で最も使用頻度が高いのが /equities/bars/daily です。本記事では、日次の四本値(始値・高値・安値・終値)を取得する基本パターンと、複数銘柄をまとめて取得する場合の流れ、欠損日への対応を整理します。
目次
- エンドポイント概要
- レスポンスの主なフィールド
- 単一銘柄の取得
- 複数銘柄をまとめて取得する
- ワイド形式に整える
- 欠損日への対応
エンドポイント概要
| 項目 | 内容 |
|---|---|
| パス | /equities/bars/daily |
| メソッド | GET |
| ベース URL | https://api.jquants.com/v2 |
| 認証 | x-api-key: <API キー> |
| 主なクエリ | code(銘柄コード)、from / to(期間 YYYY-MM-DD)、date(単一日) |
クエリの組み合わせは大きく次の 3 パターンです。
| 組み合わせ | 取得内容 |
|---|---|
code + from / to | 単一銘柄の期間データ |
code のみ | 単一銘柄の取得可能な全期間 |
date のみ | 指定日の全銘柄 |
レート制限・履歴の長さはプランに依存します(#6-1「J-Quants API とは何か」)。
レスポンスの主なフィールド
| フィールド | 内容 |
|---|---|
Date | 取引日(YYYY-MM-DD) |
Code | 銘柄コード |
O / H / L / C | 始値・高値・安値・終値 |
Vo | 出来高 |
Va | 売買代金 |
AdjC | 調整済み終値(分割・併合反映) |
AdjFactor | 調整係数 |
長期分析では AdjC(調整済み終値) を使うのが基本です。分割があった日の偽のリターンを避けられます。
単一銘柄の取得
期間を指定して 1 銘柄を取る最小例です。JQUANTS_API_KEY は環境変数に設定済みとします。
import osimport requestsimport pandas as pd
BASE_URL = "https://api.jquants.com/v2"
def fetch_daily_quotes( headers: dict, code: str, date_from: str, date_to: str,) -> pd.DataFrame: """単一銘柄の期間データを取得する。""" url = f"{BASE_URL}/equities/bars/daily" params = {"code": code, "from": date_from, "to": date_to}
rows = [] pagination_key: str | None = None while True: if pagination_key: params["pagination_key"] = pagination_key response = requests.get(url, headers=headers, params=params, timeout=30) response.raise_for_status() payload = response.json() rows.extend(payload.get("data", [])) pagination_key = payload.get("pagination_key") if not pagination_key: break
df = pd.DataFrame(rows) if df.empty: return df df["Date"] = pd.to_datetime(df["Date"]) return df.sort_values("Date").reset_index(drop=True)
# API キーは環境変数から読む(ハードコード禁止)headers = {"x-api-key": os.environ["JQUANTS_API_KEY"]}prices = fetch_daily_quotes(headers, code="7203", date_from="2024-01-01", date_to="2024-03-31")print(prices.head())レスポンスが大きいときは pagination_key がレスポンスに含まれるため、ループで継続取得します。上のコードは取りこぼしを避けるためにこの方式を組み込んでいます。
複数銘柄をまとめて取得する
複数銘柄を同じ期間で取りたい場合、銘柄ごとにループします。レート制限の対策はバックオフ(#6-8「レート制限・エラー時のリトライ設計」)で行います。
def fetch_quotes_multi( headers: dict, codes: list[str], date_from: str, date_to: str,) -> pd.DataFrame: """複数銘柄をまとめて取得し、1 つの DataFrame に縦に積む。""" frames: list[pd.DataFrame] = [] for code in codes: df = fetch_daily_quotes(headers, code, date_from, date_to) if df.empty: continue frames.append(df) if not frames: return pd.DataFrame() return pd.concat(frames, ignore_index=True)
codes = ["7203", "9984", "6758"]all_prices = fetch_quotes_multi(headers, codes, "2024-01-01", "2024-03-31")print(all_prices.groupby("Code").size())「指定日の全銘柄」を取りたい場合は、date クエリの方が効率的です。
def fetch_quotes_by_date(headers: dict, date: str) -> pd.DataFrame: """指定日の全銘柄の四本値を取得する。""" url = f"{BASE_URL}/equities/bars/daily" params = {"date": date}
rows = [] pagination_key: str | None = None while True: if pagination_key: params["pagination_key"] = pagination_key response = requests.get(url, headers=headers, params=params, timeout=30) response.raise_for_status() payload = response.json() rows.extend(payload.get("data", [])) pagination_key = payload.get("pagination_key") if not pagination_key: break
return pd.DataFrame(rows)ワイド形式に整える
複数銘柄を、列が銘柄コード・行が日付のワイド形式にしたいときは pivot_table を使います。
wide = all_prices.pivot_table( index="Date", columns="Code", values="AdjC").sort_index()print(wide.head())リターン計算には pct_change がそのまま使えます。
returns = wide.pct_change()print(returns.head())欠損日への対応
四本値データには次のような欠損が入りやすいので、扱いを決めておきます。
- 休場日(土日祝): そもそも行がない。連続日付の DatetimeIndex を作って合わせるなら
reindexが必要 - 個別銘柄の取引停止日: その日の行が抜ける、または
Voが 0 - 新規上場前 / 上場廃止後: その期間は
NaN - 配当落ち・分割の調整:
AdjCを使えば連続的に補正される
連続営業日のインデックスに揃える例です。
business_days = pd.bdate_range(wide.index.min(), wide.index.max())wide_aligned = wide.reindex(business_days)print(f"再インデックス前: {wide.shape}, 後: {wide_aligned.shape}")
# 欠損は前日値で埋めない方が安全(将来情報の混入は避ける)# どうしても埋めたいなら ffill を使うが、用途を限るwide_filled = wide_aligned.ffill()ffill(前日埋め)を機械的に当てると、リターン計算が 0 になる日が増えるため、用途を確認してから使います。
注意点
- リターン計算では 調整済み終値(
AdjC)を使う Dateは文字列で返るので、pd.to_datetimeで型変換しておく- 銘柄コードは先頭 0 を保持するため、文字列のまま扱う
- リクエスト数が増えるとレート制限に当たります(#6-8「レート制限・エラー時のリトライ設計」)
- 過去データは Free プランだと範囲が短いため、長期分析は Light 以上を検討
生成AI へのプロンプト例
期間と銘柄リストから、長形式 / ワイド形式の両方を返す関数の例です。
J-Quants API の /equities/bars/daily から、複数銘柄の調整済み終値を取得し、次の 2 つを返す関数 fetch_close_prices(api_key, codes, date_from, date_to) を書いてください。
戻り値: tuple- long_df: 列が Date / Code / AdjC の長形式 DataFrame- wide_df: 行が Date、列が Code、値が調整済み終値のワイド形式 DataFrame
要件:- 認証は API キーを引数で受け取り、x-api-key ヘッダに乗せる(トークン交換は不要)- pagination_key を使ったページング処理を含める- pandas 2.2 系の API を使う- docstring を日本語で書くまとめ
/equities/bars/dailyは日次四本値の取得エンドポイントcode+from/toで単一銘柄、dateで全銘柄を取得- レスポンスが大きい場合は
pagination_keyでページング - リターン計算には調整済み終値を使う
- 欠損日への対応(
reindex/ffill)は用途に応じて選ぶ