ふくふくHukuhuku Inc.
EP.15Open Data 12分公開: 2026-05-10

過去の株価推移をPythonで取得する:yfinance/Stooq で日経225・TOPIX・個別株を社内分析に重ねる

「自社の売上は景気と連動してる?」を確かめる第一歩。api キー不要の yfinance と Stooq で、nikkei225・TOPIX・個別銘柄の長期ヒストリカルを 5 行で取得し、ローソク足・移動平均・前年比のグラフに落とし込むまで。

#株価#金融データ#yfinance#Stooq
CO📔 Google Colab で開く(上から順にセルを実行)
シェア

「うちの売上は景気と連動してる?」「同業他社の株価と一緒に動いてる?」 ── 経営会議で時々出る話題ですが、いざ調べようとすると「日経平均の過去データってどこで取るんだ」で止まりがちです。実は を使えば、 キーなしで世界中の株価・指数の長期ヒストリカルが 5 行で取得できます。

データソースの選択肢を整理する

「過去の株価データ」と一口に言っても、ソースによってカバレッジ・更新頻度・商用利用可否がまったく違います。最初に整理しておきます。

主要な株価ヒストリカルデータソース比較
ソースコストカバレッジ履歴API キー商用利用
無料日米欧アジア全銘柄、指数、為替、先物20年以上不要⚠️ Yahoo 規約による(個人/研究は OK、再配布は NG)
無料日米欧、指数、為替、先物、商品30年以上不要⚠️ 同上(出典明記推奨)
Free〜Premium日本株のみFree=12週、上位プランで遡る必要✅ JPX 公式(個人投資家向け)
JPX 直配信個別契約(高額)日本株フル全期間必要
Bloomberg / Refinitiv月数十万円〜全市場全期間必要✅ プロ仕様
個人・社内分析の最初の選択

まずは で動かす → うまく取れない銘柄や落ちた時のバックアップに → 商用ダッシュボードに組み込む段階で へ移行、というステップが実用的。

1. yfinance で日経平均を取得する(30秒)

で `pip install yfinance` するだけ。コードは本当に 5 行で済みます。

日経225(^N225)の過去5年分を取得
Python
!pip install -q yfinanceimport yfinance as yf
# 日経225 のヒストリカル(過去5年)n225 = yf.Ticker("^N225").history(period="5y")print(n225.tail())print(f"\n期間: {n225.index.min().date()}{n225.index.max().date()}, {len(n225)} 営業日")
ティッカー記号の探し方

Yahoo Finance の検索窓に銘柄名を入れて、上部に表示される `^N225` `7203.T` のような記号がティッカーです。日本株は `<証券コード>.T`(東証)、米国株はそのまま(例: AAPL, MSFT)。

2. 移動平均と出来高を可視化する

ヒストリカルデータが取れたら、次は 移動平均(MA: Moving Average) を引いてトレンドを見ます。25日 MA は短期、200日 MA は長期トレンドの定番。ゴールデンクロス(25日が200日を下から抜ける)は買いシグナル、デッドクロス(上から下に抜ける)は売りシグナルとして語られます。

終値 + 25日/200日移動平均 + 出来高
Python
import matplotlib.pyplot as pltimport japanize_matplotlib  # noqa: F401
n225["MA25"]  = n225["Close"].rolling(25).mean()n225["MA200"] = n225["Close"].rolling(200).mean()
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 7), sharex=True,                                gridspec_kw={"height_ratios": [3, 1]})ax1.plot(n225.index, n225["Close"],  label="終値", linewidth=1.2, color="#1f77b4")ax1.plot(n225.index, n225["MA25"],   label="25日 MA", color="#ff7f0e", linewidth=1)ax1.plot(n225.index, n225["MA200"],  label="200日 MA", color="#d62728", linewidth=1.2)ax1.set_ylabel("価格(円)"); ax1.set_title("日経225 の終値と移動平均")ax1.legend(); ax1.grid(alpha=0.3)
ax2.bar(n225.index, n225["Volume"], color="#999", width=1.0)ax2.set_ylabel("出来高"); ax2.grid(alpha=0.3)plt.tight_layout(); plt.show()

3. 個別銘柄を取って業界を比べる

次は個別企業を比較してみます。「自社が属する業界全体が伸びているのか、自社だけ伸びているのか」を判断する基本動作です。

自動車セクター3社の正規化リターン比較
Python
import yfinance as yfimport pandas as pdimport matplotlib.pyplot as pltimport japanize_matplotlib  # noqa: F401
tickers = {"7203.T": "トヨタ", "7201.T": "日産", "7267.T": "ホンダ"}df = yf.download(list(tickers.keys()), period="3y", auto_adjust=True)["Close"]
# 開始日=100 で正規化(リターン比較)norm = df / df.iloc[0] * 100
fig, ax = plt.subplots(figsize=(11, 5))for code, label in tickers.items():    ax.plot(norm.index, norm[code], label=label, linewidth=1.5)ax.set_title("自動車3社の株価推移(開始日=100で正規化)")ax.set_ylabel("正規化リターン"); ax.axhline(100, color="gray", linestyle="--", alpha=0.4)ax.legend(); ax.grid(alpha=0.3); plt.tight_layout(); plt.show()
なぜ「開始日=100」で正規化するのか

株価は銘柄ごとに桁が違うため(トヨタは数千円、日産は数百円)、そのまま重ねるとスケールが噛み合わず、トレンドが読めません。開始日を 100 に揃えることで「期間内の上昇率」を比較できます。これは投資レポートの常套手段。

4. Stooq でバックアップ取得(商品先物 / 為替も同じ流れ)

yfinance はたまに不安定(Yahoo の HTML が変わると壊れる)になります。そんな時のバックアップが `pandas-datareader` 経由で同じインターフェースで使えます。

Stooq から日経225 + 米ドル/円を取る
Python
!pip install -q pandas-datareaderimport pandas_datareader.data as webimport datetime as dt
end   = dt.date.today()start = end - dt.timedelta(days=365 * 5)
# Stooq のシンボル: 日経225 = ^nkx, 米ドル円 = jpyusd(逆数)n225 = web.DataReader("^nkx",   "stooq", start, end).sort_index()usd  = web.DataReader("usdjpy", "stooq", start, end).sort_index()
print("日経225:", n225.tail(3))print("\nUSD/JPY:", usd.tail(3))

5. 自社売上 × 株価指数の相関を見る(実用例)

ここまでが「データの取り方」。本題は 自社データに重ねて使うところ。例えば BtoC 企業なら「TOPIX が上がると消費が増えるか?」、輸出企業なら「ドル円と売上の相関は?」が分かります。

TOPIX 月次変化率 × 自社売上の散布図
Python
# 自社売上(仮データ:実際は社内 DWH から取得)sales_monthly = pd.DataFrame({    "month": pd.date_range("2020-01", "2025-12", freq="MS"),    "sales": [...],  # 月次売上}).set_index("month")
# TOPIX 月次(^TPX は yfinance ではダメなので Stooq か日経のミラーを使う)topix = yf.Ticker("^TPX").history(period="6y")["Close"].resample("MS").last()
# 月次変化率df = pd.DataFrame({"sales": sales_monthly["sales"], "topix": topix})df_pct = df.pct_change().dropna()
fig, ax = plt.subplots(figsize=(7, 6))ax.scatter(df_pct["topix"]*100, df_pct["sales"]*100, alpha=0.6, s=50)ax.set_xlabel("TOPIX 月次変化率(%)"); ax.set_ylabel("売上 月次変化率(%)")corr = df_pct["topix"].corr(df_pct["sales"])ax.set_title(f"TOPIX × 自社売上の月次相関(r={corr:.2f})")ax.axhline(0, color="gray", linewidth=0.5); ax.axvline(0, color="gray", linewidth=0.5)ax.grid(alpha=0.3); plt.tight_layout(); plt.show()

ローソク足チャートで描く(mplfinance)

ローソク足」()は金融データの定番表現。`mplfinance` でデフォルト設定が綺麗です。

日経225 直近6ヶ月のローソク足
Python
!pip install -q mplfinanceimport mplfinance as mpf
n225_6m = yf.Ticker("^N225").history(period="6mo")mpf.plot(n225_6m, type="candle", style="yahoo", volume=True,         mav=(5, 25), title="日経225(直近6ヶ月)",         figsize=(12, 7))

留意点(重要)

yfinance の商用利用について

yfinance は Yahoo Finance の非公開エンドポイントを叩く非公式ライブラリです。Yahoo の利用規約上、データの大量取得・再配布・商用販売は禁止されています。社内分析や研究は問題ありませんが、顧客向けダッシュボードに組み込む段階では やデータベンダーへの切替を検討してください。

  • レート制限: yfinance は短時間に大量リクエストすると Yahoo に弾かれる。`time.sleep(0.1)` を挟むか、まとめて取得(`yf.download(list_of_tickers)`)する
  • Adjust 補正: 配当・株式分割の補正には `auto_adjust=True` を使う。生の終値(`Close`)と補正済(`Adj Close`)は意味が異なる
  • 営業日カレンダー: 日本市場の祝日・年末年始は土日扱いではないため、月次集計時はカレンダーを意識する
  • 通貨: 外国株はドル建て・現地通貨建てで返るため、JPY 換算が必要
  • データの正確性は保証されない: yfinance / Stooq とも個人データ。重要な意思決定の根拠にする場合は JPX や Bloomberg の公式ソースで再確認する

ふくふくの進め方

BtoC や輸出比率の高い企業から「自社の売上と景気指標の関係を見える化したい」というご相談を頂きます。1〜2ヶ月で月次の相関ダッシュボード( / 3〜6ヶ月で売上予測モデル を特徴量に組み込み)が現実的なロードマップ。社内 / )に金融データを定期取り込みする の設計も併せて承ります。

次回予告

EP.16 では、コモディティ・為替・先物データを使ったマクロ環境分析 と為替、(恐怖指数)から景気の風向きを読み、自社の在庫・調達計画にフィードバックする実践レシピを扱います。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp