【米国株対応】yfinanceでAppleやAmazonの株価データを取得するコード

Python実装・コード

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

Pythonで株価データを取得する方法を学んだ後、「米国株にも応用したい」と考える個人投資家は多いはずです。

Apple・Amazon・Google・Teslaといった世界的な企業の株価データを自分の手元で分析できれば、SBI証券や楽天証券での米国株取引において、データに基づいた投資判断が可能になります。

yfinanceは日本株だけでなく米国株にも対応しており、ティッカーシンボルを変えるだけで同じコードが使えます。

しかし、米国株特有の注意点(ティッカーシンボルの調べ方、ドル建てデータの扱い、取引時間の違い、株式分割の影響など)を理解していないと、取得したデータを正しく解釈できません。

この記事では、yfinanceで米国株の株価データを取得し、日本円換算・テクニカル指標の算出・複数銘柄の比較チャート作成までを一気に行うコードを提供します。

すべてコピペでそのまま動作する実装に限定していますので、自分の分析対象に差し替えて応用してください。

米国株データ取得の基礎知識

yfinanceで米国株を扱う前に、日本株との違いを正確に把握しておく必要があります。

ティッカーシンボルの指定方法

yfinanceでは、銘柄をティッカーシンボル(Ticker Symbol)で指定します。

日本株は「7203.T」のように数字+取引所コードですが、米国株はアルファベットのティッカーシンボルをそのまま指定します。

* Apple:AAPL

* Amazon:AMZN

* Google(Alphabet):GOOGL

* Tesla:TSLA

* Microsoft:MSFT

ティッカーシンボルが不明な場合は、Yahoo Finance(https://finance.yahoo.com/)の検索窓に企業名を入力すれば確認できます。

日本株との3つの違い

米国株データを扱う際に意識すべき相違点は以下の3つです。

* 通貨単位:株価はUSドル建てで取得されます。日本円での評価額を算出するには、為替レート(USD/JPY)との掛け算が必要です

* 取引時間:米国市場の取引時間は日本時間の23:30〜翌6:00(サマータイム中は22:30〜翌5:00)です。日足データのタイムスタンプは米国東部時間(ET)基準となります

* 株式分割の自動調整:yfinanceの history() メソッドはデフォルトで株式分割を調整済みの株価(Adjusted Close)を返します。Appleは2020年に1:4の株式分割を実施していますが、取得データには分割調整済みの値が反映されています

株式分割の調整が不要な場合は auto_adjust=False を指定してください。ただし、テクニカル指標の計算やチャート描画では調整済みデータを使うのが一般的です。

【コピペOK】米国株データ取得+日本円換算+指標算出コード

ここからは実際のコードを提示します。

米国株5銘柄の株価データを取得し、USD/JPYレートで日本円換算した上で、RSIと移動平均線を算出してチャートとして保存します。

事前準備:ライブラリのインストール


pip install yfinance pandas matplotlib

【コピペOK】米国株データ取得+分析コード


import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt

# ==============================
# 設定エリア
# ==============================
SYMBOLS = ["AAPL", "AMZN", "GOOGL", "TSLA", "MSFT"]  # 取得する米国株銘柄
PERIOD = "1y"              # 取得期間(1年間)
SMA_SHORT = 25             # 短期移動平均線の期間
SMA_LONG = 75              # 長期移動平均線の期間
RSI_WINDOW = 14            # RSI計算期間
USDJPY_SYMBOL = "JPY=X"   # USD/JPYの為替ティッカー

# ==============================
# データ取得
# ==============================
def fetch_stock_data(symbol: str, period: str) -> pd.DataFrame:
    '"指定銘柄の株価データを取得します。'"
    ticker = yf.Ticker(symbol)
    df = ticker.history(period=period)
    if df.empty:
        raise ValueError(f"{symbol} のデータを取得できませんでした。")
    return df

def fetch_usdjpy_rate(period: str) -> pd.Series:
    '"USD/JPYの為替レートを取得します。'"
    ticker = yf.Ticker(USDJPY_SYMBOL)
    df = ticker.history(period=period)
    if df.empty:
        raise ValueError("USD/JPYの為替データを取得できませんでした。")
    return df["Close"]

# ==============================
# 日本円換算
# ==============================
def convert_to_jpy(df: pd.DataFrame, usdjpy: pd.Series) -> pd.DataFrame:
    '"ドル建て株価を日本円に換算した列を追加します。'"
    df = df.copy()
    # 日付インデックスを揃えてマージ
    usdjpy_aligned = usdjpy.reindex(df.index, method="ffill")
    df["Close_JPY"] = df["Close"] * usdjpy_aligned
    df["USD_JPY"] = usdjpy_aligned
    return df

# ==============================
# テクニカル指標の算出
# ==============================
def calc_indicators(df: pd.DataFrame) -> pd.DataFrame:
    '"移動平均線とRSIを算出します。'"
    df = df.copy()
    df["SMA_Short"] = df["Close"].rolling(window=SMA_SHORT).mean()
    df["SMA_Long"] = df["Close"].rolling(window=SMA_LONG).mean()

    # RSI(Wilder方式)
    delta = df["Close"].diff()
    gain = delta.where(delta > 0, 0.0)
    loss = (-delta).where(delta < 0, 0.0)
    avg_gain = gain.ewm(alpha=1/RSI_WINDOW, min_periods=RSI_WINDOW, adjust=False).mean()
    avg_loss = loss.ewm(alpha=1/RSI_WINDOW, min_periods=RSI_WINDOW, adjust=False).mean()
    rs = avg_gain / avg_loss
    df["RSI"] = 100 - (100 / (1 + rs))

    return df

# ==============================
# 個別銘柄チャートの描画+保存
# ==============================
def plot_single_stock(df: pd.DataFrame, symbol: str):
    '"1銘柄の株価・移動平均線・RSIを3段チャートで保存します。'"
    fig, axes = plt.subplots(3, 1, figsize=(14, 12), sharex=True)

    # --- 1段目:株価(USD)+移動平均線 ---
    ax1 = axes[0]
    ax1.plot(df.index, df["Close"], color="black", linewidth=1.0, label="Close (USD)")
    ax1.plot(df.index, df["SMA_Short"], color="blue", linewidth=0.8, linestyle="--", label=f"SMA {SMA_SHORT}")
    ax1.plot(df.index, df["SMA_Long"], color="red", linewidth=0.8, linestyle="--", label=f"SMA {SMA_LONG}")
    ax1.set_title(f"{symbol} - Price & Moving Averages", fontsize=13)
    ax1.set_ylabel("Price (USD)")
    ax1.legend(loc="upper left", fontsize=9)
    ax1.grid(True, alpha=0.3)

    # --- 2段目:RSI ---
    ax2 = axes[1]
    ax2.plot(df.index, df["RSI"], color="purple", linewidth=1.0, label="RSI (14)")
    ax2.axhline(70, color="red", linestyle="--", alpha=0.5)
    ax2.axhline(30, color="green", linestyle="--", alpha=0.5)
    ax2.set_title("RSI (14)", fontsize=13)
    ax2.set_ylabel("RSI")
    ax2.set_ylim(0, 100)
    ax2.legend(loc="upper left", fontsize=9)
    ax2.grid(True, alpha=0.3)

    # --- 3段目:日本円換算株価 ---
    ax3 = axes[2]
    ax3.plot(df.index, df["Close_JPY"], color="darkorange", linewidth=1.0, label="Close (JPY)")
    ax3.set_title(f"{symbol} - Price in JPY", fontsize=13)
    ax3.set_ylabel("Price (JPY)")
    ax3.legend(loc="upper left", fontsize=9)
    ax3.grid(True, alpha=0.3)

    plt.tight_layout()
    filename = f"{symbol}_chart.png"
    fig.savefig(filename, dpi=150, bbox_inches="tight", facecolor="white")
    plt.close(fig)
    print(f"✔ チャートを保存しました: {filename}")

# ==============================
# 複数銘柄の騰落率比較チャート
# ==============================
def plot_comparison(all_data: dict):
    '"複数銘柄の期間騰落率を1つのチャートで比較します。'"
    fig, ax = plt.subplots(figsize=(14, 7))

    for symbol, df in all_data.items():
        close = df["Close"].dropna()
        if close.empty:
            continue
        # 期間先頭を100として正規化
        normalized = (close / close.iloc[0]) * 100
        ax.plot(normalized.index, normalized, linewidth=1.2, label=symbol)

    ax.axhline(100, color="gray", linestyle="--", alpha=0.5)
    ax.set_title("US Stocks - Normalized Performance Comparison", fontsize=13)
    ax.set_ylabel("Normalized Price (Start = 100)")
    ax.legend(loc="upper left", fontsize=10)
    ax.grid(True, alpha=0.3)

    fig.savefig("us_stocks_comparison.png", dpi=150, bbox_inches="tight", facecolor="white")
    plt.close(fig)
    print("✔ 比較チャートを保存しました: us_stocks_comparison.png")

# ==============================
# データサマリー表示
# ==============================
def print_summary(symbol: str, df: pd.DataFrame):
    '"直近日の株価・指標値・日本円換算をコンソールに表示します。'"
    latest = df.iloc[-1]
    date_str = df.index[-1].strftime("%Y-%m-%d")

    print(f"n--- {symbol}({date_str})---")
    print(f"  終値(USD):     {latest['Close']:.2f}")
    print(f"  終値(JPY):     {latest['Close_JPY']:.0f}")
    print(f"  USD/JPY:       {latest['USD_JPY']:.2f}")
    print(f"  SMA{SMA_SHORT}:        {latest['SMA_Short']:.2f}")
    print(f"  SMA{SMA_LONG}:        {latest['SMA_Long']:.2f}")
    print(f"  RSI(14):       {latest['RSI']:.2f}")

# ==============================
# メイン処理
# ==============================
if __name__ == "__main__":
    print(f"=== 米国株データ取得・分析を開始 ===n")
    print(f"対象銘柄: {', '.join(SYMBOLS)}")
    print(f"取得期間: {PERIOD}n")

    # 1. USD/JPYレートの取得
    usdjpy = fetch_usdjpy_rate(PERIOD)

    # 2. 各銘柄のデータ取得・分析・チャート保存
    all_data = {}
    for symbol in SYMBOLS:
        try:
            df = fetch_stock_data(symbol, PERIOD)
            df = convert_to_jpy(df, usdjpy)
            df = calc_indicators(df)
            all_data[symbol] = df

            print_summary(symbol, df)
            plot_single_stock(df, symbol)
        except ValueError as e:
            print(f"⚠ {e}")

    # 3. 複数銘柄の比較チャート
    if len(all_data) >= 2:
        plot_comparison(all_data)

    # 4. CSV出力
    for symbol, df in all_data.items():
        output_cols = ["Close", "Close_JPY", "USD_JPY", "Volume", "SMA_Short", "SMA_Long", "RSI"]
        df[output_cols].to_csv(f"{symbol}_data.csv")
    print("n✔ 全銘柄のCSVを保存しました")

コードの処理フロー解説

上記のコードは、以下の4ステップで構成されています。

* USD/JPYレート取得:yfinanceで為替レートを取得し、日本円換算の基準データを用意します

* 銘柄別データ取得・分析:5銘柄それぞれの株価を取得し、円換算・移動平均線・RSIを算出して個別チャートをPNG保存します

* 比較チャート作成:全銘柄の期間騰落率を正規化(先頭を100として比較)し、1枚のチャートにまとめて保存します

* CSV出力:各銘柄の株価・指標データをCSVファイルとして保存します

SYMBOLS リストの銘柄を変更するだけで、任意の米国株に対応できます。ETF(SPYQQQVTI 等)のティッカーを指定すれば、インデックス分析にも応用可能です。

米国株データの読み解き方と実践的な活用法

データを取得できても、米国株特有の要素を理解していないと正しい分析ができません。

ここでは、取得データを実際の投資判断に活用する際のポイントを解説します。

日本円換算の重要性

米国株はドル建てで取引されるため、株価が上昇していても為替が円高に動けば、日本円ベースではマイナスになるケースがあります。

たとえば、株価が5%上昇しても同期間でドル円が7%下落すれば、円建てリターンは約-2%です。

SBI証券や楽天証券で米国株を保有する際は、ドル建ての損益と円建ての損益を必ず分けて把握してください。本コードの Close_JPY 列を使えば、日本円ベースでの資産推移を正確にトラッキングできます。

複数銘柄の比較チャートの読み方

比較チャートでは、期間先頭の株価を100に正規化しています。

この正規化により、株価の絶対額が異なる銘柄(Apple: 約170ドル vs Amazon: 約180ドル vs Google: 約170ドル)を同一のスケールで騰落率を比較できます。

* 100より上:期間中に値上がりしたことを意味します

* 100より下:期間中に値下がりしたことを意味します

* 線の傾きの急さ:値動きの勢い(モメンタム)を視覚的に把握できます

特定の期間だけ急騰・急落している銘柄がある場合、その時期に決算発表や業界ニュースがなかったかを調べることで、ファンダメンタルズ分析との紐付けが可能になります。

テクニカル指標の解釈は日本株と同じ

RSIや移動平均線の読み方は、日本株と米国株で違いはありません。

* RSIが70以上:買われすぎの水準です。短期的な反落リスクを意識してください

* RSIが30以下:売られすぎの水準です。反発の可能性を検討してください

* 短期SMAが長期SMAを上抜け(ゴールデンクロス):上昇トレンド転換のシグナルです

* 短期SMAが長期SMAを下抜け(デッドクロス):下降トレンド転換のシグナルです

ただし、米国株は日本株に比べてトレンドが長期間持続しやすい傾向があるため、逆張り戦略よりも順張り戦略のほうが機能しやすい局面が多い点を意識してください。

【コピペOK】セクター別ETFで市場全体のトレンドを把握するコード

個別銘柄の分析だけでなく、セクター別ETFの値動きを比較することで、市場全体の資金の流れを把握できます。

【コピペOK】セクターETF比較コード


import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt

# ==============================
# 設定エリア
# ==============================
SECTOR_ETFS = {
    "XLK": "テクノロジー",
    "XLF": "金融",
    "XLE": "エネルギー",
    "XLV": "ヘルスケア",
    "XLY": "一般消費財",
}
PERIOD = "6m"  # 比較期間(6ヶ月)

# ==============================
# セクターETFデータ取得+比較チャート
# ==============================
def plot_sector_comparison(etfs: dict, period: str):
    '"セクターETFの騰落率比較チャートを作成します。'"
    fig, ax = plt.subplots(figsize=(14, 7))

    for ticker, name in etfs.items():
        data = yf.Ticker(ticker).history(period=period)
        if data.empty:
            print(f"⚠ {ticker}({name}) のデータを取得できませんでした。")
            continue
        close = data["Close"].dropna()
        normalized = (close / close.iloc[0]) * 100
        ax.plot(normalized.index, normalized, linewidth=1.2, label=f"{ticker} ({name})")

    ax.axhline(100, color="gray", linestyle="--", alpha=0.5)
    ax.set_title("US Sector ETF - Performance Comparison", fontsize=13)
    ax.set_ylabel("Normalized Price (Start = 100)")
    ax.legend(loc="upper left", fontsize=9)
    ax.grid(True, alpha=0.3)

    fig.savefig("sector_comparison.png", dpi=150, bbox_inches="tight", facecolor="white")
    plt.close(fig)
    print("✔ セクター比較チャートを保存しました: sector_comparison.png")

# ==============================
# メイン処理
# ==============================
if __name__ == "__main__":
    print("=== セクターETF比較を開始 ===n")
    plot_sector_comparison(SECTOR_ETFS, PERIOD)

このコードでは、SECTOR_ETFS 辞書のティッカーとセクター名を変更するだけで、任意のETFを比較対象に追加できます。

SPY(S&P500)や QQQ(NASDAQ100)を追加すれば、セクターごとの値動きが市場平均を上回っているか下回っているかを一目で判断できます。

よくあるエラーと対処法

米国株データの取得・分析で初心者がつまずきやすいポイントを整理します。

ティッカーシンボルを間違えてデータが取得できない

yfinanceはティッカーシンボルが間違っていてもエラーを出さず、空のDataFrameを返すことがあります。

データが取得できない場合は以下を確認してください。

* Yahoo Financeでティッカーを検索する:企業名で検索し、正確なティッカーシンボルを確認してください

* クラス違いに注意する:Googleの場合、GOOGL(Class A)と GOOG(Class C)の2種類が存在します。どちらも有効ですが、流動性が高い GOOGL を推奨します

* 上場廃止・ティッカー変更を確認する:Meta(旧Facebook)は FB から META にティッカーが変更されています

日本円換算の値がNaNになる

株価データと為替データの取得期間がずれている場合、日付の不一致により NaN が発生します。

本コードでは reindex(method="ffill") で前方補完していますが、株式市場の休場日と為替市場の休場日が異なるため、完全には一致しません。

NaN が多数発生する場合は、usdjpy のデータが正しく取得できているか print(usdjpy.head()) で確認してください。為替データが空の場合は、USDJPY=X ではなく JPY=X をティッカーとして指定してください(本コードではこちらを採用しています)。

取得データの時刻がずれている

yfinanceの米国株データは米国東部時間(ET)基準のタイムスタンプで返されます。

日本時間(JST)に変換したい場合は以下のコードを追加してください。


df.index = df.index.tz_convert("Asia/Tokyo")

タイムゾーン情報が付与されていない場合は、先に tz_localize("US/Eastern") で東部時間を明示してから変換してください。日足データの分析ではタイムゾーンの違いが結果に影響することは少ないため、分足・時間足データを扱う場合にのみ変換を推奨します。

まとめ

この記事では、yfinanceを使って米国株の株価データを取得し、日本円換算・テクニカル指標の算出・複数銘柄の比較チャート作成までを行うPythonコードを解説しました。

要点を整理します。

* 米国株のティッカーシンボルはアルファベットで指定し、日本株のような取引所コード(.T)は不要です

* ドル建て株価と日本円換算を両方把握することで、為替変動リスクを含めた正確な損益管理ができます

* 複数銘柄の比較には、期間先頭を100に正規化した騰落率チャートが有効です

* 米国株はトレンドが長期間持続しやすい傾向があるため、順張り系のテクニカル指標との相性が良い点を意識してください

* セクターETFの比較を通じて、市場全体の資金の流れを把握してから個別銘柄の分析に入ると精度が上がります

次のステップとして、取得した米国株データにバックテストのフレームワークを適用し、移動平均線クロスやRSI逆張りなどの売買戦略を米国株で検証してみてください。

SYMBOLS リストと fetch_stock_data() 関数はそのまま流用できるため、バックテスト用の generate_signals() 関数を追加するだけで戦略検証に拡張できます。

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