J-Quants で最も使用頻度が高いのが /equities/bars/daily です。本記事では、日次の四本値(始値・高値・安値・終値)を取得する基本パターンと、複数銘柄をまとめて取得する場合の流れ、欠損日への対応を整理します。

目次

  1. エンドポイント概要
  2. レスポンスの主なフィールド
  3. 単一銘柄の取得
  4. 複数銘柄をまとめて取得する
  5. ワイド形式に整える
  6. 欠損日への対応

エンドポイント概要

項目内容
パス/equities/bars/daily
メソッドGET
ベース URLhttps://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 os
import requests
import 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)は用途に応じて選ぶ