Pythonとyfinanceで日本株データを無料取得する入門コード

Python実装・コード

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

Pythonで株価データを取得したいと考えたとき、多くの投資家がまず思い浮かべるのはSBI証券や楽天証券のAPIです。しかし、これらの国内証券会社は個人向けにオープンなREST APIを広く公開しておらず、Pythonから自由にデータを取得できる環境は整っていません。

そこで活用すべきがyfinance(ワイファイナンス)です。yfinanceはYahoo Financeのデータを取得できるオープンソースライブラリで、世界中の開発者に利用されています。登録不要・無料で、日本株(東証銘柄)のデータも取得可能です。

この記事では、yfinanceのインストールから、単一銘柄の株価取得、複数銘柄の一括取得、そしてCSVファイルへの保存まで、コピペでそのまま動くコードを段階的に提供します。

yfinanceとは何か

コードを書き始める前に、yfinanceの特徴と制約を正しく理解しておく必要があります。

yfinanceの基本情報

yfinanceはPythonのオープンソースライブラリで、Yahoo Financeが提供する株価・財務データにアクセスするためのラッパーです。

項目 内容
ライブラリ名 yfinance
ライセンス Apache 2.0(商用利用可)
対応市場 米国株、日本株、欧州株、暗号資産など多数
登録・APIキー 不要
料金 無料
データ遅延 数分〜20分程度(リアルタイムではない)
GitHubスター数 14,000以上(2026年2月時点)

yfinanceで取得できるデータの種類

yfinanceが提供するデータは多岐にわたります。

  • 株価データ(OHLCV): 始値・高値・安値・終値・出来高
  • 財務データ: 損益計算書・貸借対照表・キャッシュフロー計算書
  • 配当・株式分割履歴
  • 企業情報: セクター・業種・時価総額・従業員数など
  • オプションデータ: 対応銘柄のオプションチェーン

yfinanceの制約と注意点

無料で強力なライブラリですが、以下の制約を認識した上で使用してください。

  • リアルタイムデータではない: 数分〜20分の遅延があるため、デイトレードには不向き
  • 発注機能はない: データの取得専用であり、売買注文は出せない
  • Yahoo Finance側の仕様変更リスク: 過去に一時的にデータ取得が不安定になったことがある
  • 過度なリクエストは避ける: 短時間に大量のリクエストを送るとIPがブロックされる可能性がある

yfinanceは「データ分析・バックテスト用」として最適なツールです。リアルタイム取引には、別途証券会社のAPIや有料データフィードの検討が必要になります。

事前準備:yfinanceのインストール

コードを実行する前に、必要なライブラリをインストールします。

インストールコマンド

コマンドプロンプトで以下を実行してください。


pip install yfinance pandas

yfinanceはpandasに依存しているため、pandasも一緒にインストールしておきます。

インストール確認

以下のコマンドでインストールが完了しているか確認できます。


pip show yfinance

バージョン番号とインストールパスが表示されれば正常です。

日本株の銘柄コード指定ルール

yfinanceで日本株を取得する場合、銘柄コードの末尾に「.T」を付ける必要があります。これは東京証券取引所(Tokyo Stock Exchange)を示すサフィックスです。

銘柄 yfinanceでの指定
トヨタ自動車(7203) 7203.T
ソニーグループ(6758) 6758.T
任天堂(7974) 7974.T
ソフトバンクグループ(9984) 9984.T
日経225 ETF(1321) 1321.T

「.T」を付け忘れると、米国市場の同一コードの銘柄が取得されるか、データが空で返ってきます。日本株を取得する場合は必ず「.T」を付与してください。

【コピペOK】単一銘柄の株価データを取得する

まずは最もシンプルなコードから始めます。トヨタ自動車(7203.T)の過去1年分の株価データを取得します。

基本コード:1銘柄の日足データ取得


import yfinance as yf
import pandas as pd

# ==============================
# 設定エリア
# ==============================
SYMBOL = "7203.T"  # トヨタ自動車
PERIOD = "1y"       # 取得期間(1年分)

# ==============================
# データ取得処理
# ==============================
def fetch_single_stock():
    print(f"--- {SYMBOL} の株価データを取得中 ---")

    ticker = yf.Ticker(SYMBOL)
    df = ticker.history(period=PERIOD)

    if df.empty:
        print("データが取得できませんでした。銘柄コードを確認してください。")
        return

    # 日本語のカラム名に変換
    df = df.rename(columns={
        "Open": "始値",
        "High": "高値",
        "Low": "安値",
        "Close": "終値",
        "Volume": "出来高"
    })

    # 不要なカラムを除外
    df = df[["始値", "高値", "安値", "終値", "出来高"]]

    print(f"n取得件数: {len(df)}件")
    print(f"期間: {df.index[0].strftime('%Y-%m-%d')} 〜 {df.index[-1].strftime('%Y-%m-%d')}")
    print(f"n--- 直近5日間 ---")
    print(df.tail())

    return df

# ==============================
# 実行
# ==============================
if __name__ == "__main__":
    fetch_single_stock()

取得期間(period)の指定オプション

ticker.history()period パラメータには以下の値を指定できます。

意味
1d 直近1日
5d 直近5日
1mo 直近1ヶ月
3mo 直近3ヶ月
6mo 直近6ヶ月
1y 直近1年
2y 直近2年
5y 直近5年
10y 直近10年
ytd 年初来
max 取得可能な全期間

日付範囲を指定して取得する方法

period の代わりに startend で日付範囲を直接指定することも可能です。


df = ticker.history(start="2024-01-01", end="2024-12-31")

バックテストなどで特定の期間のデータが必要な場合は、こちらの指定方法が便利です。

【コピペOK】複数銘柄の株価データを一括取得する

ポートフォリオ分析やスクリーニングを行う場合、複数銘柄のデータを一括取得する必要があります。

複数銘柄の一括取得コード


import yfinance as yf
import pandas as pd

# ==============================
# 設定エリア
# ==============================
SYMBOLS = [
    "7203.T",   # トヨタ自動車
    "6758.T",   # ソニーグループ
    "7974.T",   # 任天堂
    "9984.T",   # ソフトバンクグループ
    "6861.T",   # キーエンス
]
PERIOD = "3mo"  # 直近3ヶ月

# ==============================
# 一括取得処理
# ==============================
def fetch_multiple_stocks():
    print(f"--- {len(SYMBOLS)}銘柄のデータを一括取得中 ---n")

    results = {}

    for symbol in SYMBOLS:
        ticker = yf.Ticker(symbol)
        df = ticker.history(period=PERIOD)

        if df.empty:
            print(f"  [警告] {symbol}: データ取得失敗")
            continue

        results[symbol] = df
        latest = df.iloc[-1]
        print(f"  {symbol}: 終値 {latest['Close']:,.0f}円 / 出来高 {latest['Volume']:,.0f}")

    print(f"n--- 取得完了: {len(results)}/{len(SYMBOLS)}銘柄 ---")
    return results

# ==============================
# 実行
# ==============================
if __name__ == "__main__":
    data = fetch_multiple_stocks()

yf.downloadによる高速一括取得

yf.download() 関数を使うと、複数銘柄のデータを1回のリクエストで効率的に取得できます。


import yfinance as yf

# ==============================
# yf.downloadによる一括取得
# ==============================
SYMBOLS = ["7203.T", "6758.T", "7974.T"]

df = yf.download(
    tickers=SYMBOLS,
    period="1mo",
    group_by="ticker"
)

# 各銘柄の終値を表示
for symbol in SYMBOLS:
    print(f"n--- {symbol} 直近5日間の終値 ---")
    print(df[symbol]["Close"].tail())

yf.download() はループで個別取得するよりも高速です。10銘柄以上を取得する場合は、こちらの方法を推奨します。

【コピペOK】取得データをCSVファイルに保存する

取得したデータを分析やバックテストに再利用するために、CSVファイルとして保存する方法を解説します。

単一銘柄のCSV保存


import yfinance as yf
import pandas as pd
import os

# ==============================
# 設定エリア
# ==============================
SYMBOL = "7203.T"
PERIOD = "1y"
OUTPUT_DIR = "data"

# ==============================
# CSV保存処理
# ==============================
def save_to_csv():
    # 出力フォルダを作成
    os.makedirs(OUTPUT_DIR, exist_ok=True)

    print(f"--- {SYMBOL} のデータを取得中 ---")
    ticker = yf.Ticker(SYMBOL)
    df = ticker.history(period=PERIOD)

    if df.empty:
        print("データが取得できませんでした。")
        return

    # ファイル名を生成(例: data/7203_T.csv)
    filename = os.path.join(OUTPUT_DIR, f"{SYMBOL.replace('.', '_')}.csv")
    df.to_csv(filename, encoding="utf-8-sig")

    print(f"保存完了: {filename}")
    print(f"データ件数: {len(df)}件")

# ==============================
# 実行
# ==============================
if __name__ == "__main__":
    save_to_csv()

encoding指定のポイント

CSVファイルの保存時に encoding="utf-8-sig" を指定しています。これはExcelでCSVを開いた際に日本語が文字化けするのを防ぐための指定です。

encoding指定 Excelでの表示 Python間の受け渡し
utf-8 文字化けする場合あり 問題なし
utf-8-sig 正常表示 問題なし
shift_jis 正常表示 一部の特殊文字で問題あり

ExcelとPythonの両方で使用するCSVは utf-8-sig で保存するのがベストプラクティスです。

複数銘柄の一括CSV保存


import yfinance as yf
import pandas as pd
import os
import time

# ==============================
# 設定エリア
# ==============================
SYMBOLS = ["7203.T", "6758.T", "7974.T", "9984.T", "6861.T"]
PERIOD = "1y"
OUTPUT_DIR = "data"
WAIT_SEC = 1  # リクエスト間隔(秒)

# ==============================
# 一括CSV保存処理
# ==============================
def batch_save():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    success_count = 0

    print(f"=== {len(SYMBOLS)}銘柄のCSV一括保存を開始 ===n")

    for symbol in SYMBOLS:
        print(f"  [{symbol}] 取得中...", end=" ")
        ticker = yf.Ticker(symbol)
        df = ticker.history(period=PERIOD)

        if df.empty:
            print("失敗(データなし)")
            continue

        filename = os.path.join(OUTPUT_DIR, f"{symbol.replace('.', '_')}.csv")
        df.to_csv(filename, encoding="utf-8-sig")
        print(f"完了 → {filename}({len(df)}件)")
        success_count += 1

        time.sleep(WAIT_SEC)

    print(f"n=== 保存完了: {success_count}/{len(SYMBOLS)}銘柄 ===")

# ==============================
# 実行
# ==============================
if __name__ == "__main__":
    batch_save()

コード内の time.sleep(WAIT_SEC) は、Yahoo Financeへの過度なリクエストを避けるためのウェイトです。銘柄数が多い場合は、この間隔を2〜3秒に増やすことを推奨します。

企業情報・財務データの取得

株価データだけでなく、企業の基本情報や財務データもyfinanceで取得できます。

【コピペOK】企業基本情報の取得


import yfinance as yf

# ==============================
# 企業情報取得
# ==============================
SYMBOL = "7203.T"

def fetch_company_info():
    ticker = yf.Ticker(SYMBOL)
    info = ticker.info

    display_keys = [
        ("企業名", "longName"),
        ("セクター", "sector"),
        ("業種", "industry"),
        ("時価総額", "marketCap"),
        ("PER(予想)", "forwardPE"),
        ("PBR", "priceToBook"),
        ("配当利回り", "dividendYield"),
        ("52週高値", "fiftyTwoWeekHigh"),
        ("52週安値", "fiftyTwoWeekLow"),
    ]

    print(f"=== {SYMBOL} 企業情報 ===n")
    for label, key in display_keys:
        value = info.get(key, "データなし")
        if key == "marketCap" and isinstance(value, (int, float)):
            value = f"{value:,.0f}円"
        elif key == "dividendYield" and isinstance(value, float):
            value = f"{value * 100:.2f}%"
        elif isinstance(value, float):
            value = f"{value:.2f}"
        print(f"  {label}: {value}")

if __name__ == "__main__":
    fetch_company_info()

ticker.info はリクエスト負荷が高めのため、ループ内で大量に呼び出す場合は十分なウェイトを設けてください。

よくあるエラーと対処法

「No data found for this date range」と表示される

指定した期間にデータが存在しない場合に発生します。主な原因は以下のとおりです。

  • 銘柄コードの末尾に「.T」が付いていない
  • 上場廃止済みの銘柄を指定している
  • 休場日のみの極端に短い期間を指定している

まずは period="1mo" など広めの期間で再取得してみてください。

「JSONDecodeError」が発生する

Yahoo Finance側の一時的な障害やメンテナンス時に発生することがあります。数分〜数時間待ってから再実行してください。

頻発する場合は、yfinanceのバージョンを最新にアップグレードしてください。


pip install --upgrade yfinance

データの値が明らかにおかしい(株式分割の影響)

yfinanceが返す株価データは、デフォルトで株式分割調整済みです。過去のデータと現在のデータを単純比較する際は、この点を認識しておく必要があります。

未調整データが必要な場合は、以下のように auto_adjust=False を指定してください。


df = ticker.history(period="1y", auto_adjust=False)

まとめ

yfinanceを使えば、登録不要・無料で日本株の株価データをPythonから取得できます。この記事で紹介したコードのポイントを整理します。

  • 日本株の銘柄コードには末尾に「.T」を必ず付与する
  • ticker.history(period="1y") で過去1年分の日足データを取得できる
  • 複数銘柄を取得する場合は yf.download() が高速で効率的
  • CSVファイルの保存時は encoding="utf-8-sig" を指定するとExcelでも文字化けしない
  • 短時間に大量のリクエストを送らないよう、time.sleep() でウェイトを挟む

yfinanceで取得したデータは、テクニカル分析・バックテスト・ポートフォリオ分析の基盤として活用できます。次のステップとして、移動平均線やRSIなどのテクニカル指標の計算に進んでください。

次のデータを入力してください。

🔗 関連記事

Pythonで株価を取得する方法【yfinanceで日本株も対応】

🔗 関連記事

yfinanceで日本株を取得できない時の原因と対処法【エラー別】

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