円安で製造業株はどう動く?ドル円との相関をPythonで可視化してみた

Python実装・コード

ドル円が161円台まで円安が進んだとき、僕が持っていた製造業株(輸出系メーカー)はもっと上がるはずだと思っていました。ところが実際の値動きは鈍く、「あれ、思っていたのと違う」と感じたのです。

「円安=輸出企業に有利」は、投資を始めた頃に何度も聞いた話です。しかしその関係が今もどれくらい成り立っているのかを、自分で確かめたことは一度もありませんでした。

この記事では、ドル円と製造業株の関係を相関係数という数字で可視化します。銘柄ごとに感応度がまったく違うこと、そしてその関係が時期によって変わることまで、実データで確認していきます。

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

「円安は輸出企業に有利」の理屈

まず前提を整理します。円安が輸出企業の業績を押し上げるとされる理由は、単純です。

1台 20,000ドルで売れる自動車の場合

  1ドル = 140円 → 売上 280万円
  1ドル = 160円 → 売上 320万円

同じ1台を同じ価格で売っても、円建ての売上が40万円増える

これが教科書的な説明です。ドル建てで売っている企業は、円安になるだけで円換算の利益が増える——理屈としては明快です。

ところが実際の株価は、この理屈どおりには動きません。理由は主に3つあります。

  • 海外生産が進んだ: 現地で作って現地で売れば、円安の恩恵は限定的になる
  • 原材料の輸入コストも上がる: 円安は仕入れ値も押し上げる
  • 円安の背景が重要: 世界経済が悪化して起きた円安なら、売上そのものが減る

特に1番目の影響は大きく、自動車産業の為替感応度は、かつての半分程度まで低下していると指摘されています。「円安メリット銘柄」という言葉が、昔ほどの意味を持たなくなっているわけです。

この構造変化は、数字でも裏づけられています。かつて自動車業界の為替感応度は2%前後——為替が1%動けば利益が2%変わる水準——でしたが、現在は1%程度まで低下していると分析されています。海外生産の進展が主因です。

現地生産が進んだ企業では、現地通貨で売って現地通貨でコストを払う構造になります。そうなると、為替が動いても円換算の利益はさほど変わりません。「海外売上比率が高い=円安メリットが大きい」という単純な図式は成り立たないわけです。

だからこそ、業種で括るのではなく銘柄ごとに実測する必要があります。この記事でやろうとしているのは、まさにそれです。

📘 外部参考円安と業績(野村證券)Correlation Coefficient(Investopedia)

相関係数で関係を測る

pip install yfinance pandas numpy matplotlib scipy

ここで最も重要な注意点があります。株価とドル円の価格そのもので相関を取ってはいけません。

import yfinance as yf
import numpy as np
import pandas as pd


def load_data(tickers, period="3y"):
    """株価と為替をまとめて取得する"""
    df = yf.download(tickers, period=period, auto_adjust=True,
                     progress=False)["Close"]
    return df.dropna(how="any")


TICKERS = ["7203.T", "JPY=X"]
data = load_data(TICKERS)

# ✕ 価格同士の相関(見せかけの相関になりやすい)
price_corr = float(data["7203.T"].corr(data["JPY=X"]))

# ○ 変化率同士の相関(こちらが正しい)
rets = data.pct_change().dropna()
ret_corr = float(rets["7203.T"].corr(rets["JPY=X"]))

print(f"価格の相関   : {price_corr:>6.3f}  ← 使ってはいけない")
print(f"変化率の相関 : {ret_corr:>6.3f}  ← こちらが実態")

実行すると、2つの数字が大きく違うことに驚くはずです。価格同士の相関は0.8を超えることもありますが、変化率の相関は0.2〜0.4程度に落ち着きます。

なぜこうなるのか。どちらも長期的に上昇していれば、それだけで高い相関が出てしまうからです。これは「見せかけの相関」と呼ばれ、両者が無関係でも発生します。

# 無関係な2つの系列でも、上昇トレンドがあれば相関は高く出る
rng = np.random.default_rng(42)
n = 500

a = np.cumsum(rng.normal(0.1, 1, n))    # 上昇トレンドのあるランダム系列
b = np.cumsum(rng.normal(0.1, 1, n))    # 完全に独立した別の系列

print(f"価格の相関   : {np.corrcoef(a, b)[0, 1]:>6.3f}  ← 無関係なのに高い")
print(f"変化率の相関 : {np.corrcoef(np.diff(a), np.diff(b))[0, 1]:>6.3f}")

完全に独立した2つの系列でも、価格ベースでは高い相関が出ます。これを見れば、変化率で計算すべき理由が納得できるはずです。

相関係数の基本的な扱い方は相関係数を計算して銘柄間の関係を数値化する方法で詳しく解説しています。

銘柄ごとの感応度を比べる

製造業といっても、企業によって事業構造はまるで違います。実際に並べてみると、その差がはっきり出ます。

import statsmodels.api as sm

STOCKS = {
    "7203.T": "トヨタ自動車",
    "7267.T": "ホンダ",
    "6902.T": "デンソー",
    "6501.T": "日立製作所",
    "6367.T": "ダイキン工業",
    "8035.T": "東京エレクトロン",
    "9432.T": "NTT",          # 内需の比較対象
    "9843.T": "ニトリ",        # 円安がマイナスに働く例
}


def fx_sensitivity(stock_ticker, fx="JPY=X", period="3y"):
    """為替に対する感応度(相関とベータ)を求める"""
    df = load_data([stock_ticker, fx], period)
    if len(df) < 100:
        return None

    rets = df.pct_change().dropna()
    x, y = rets[fx], rets[stock_ticker]

    corr = float(x.corr(y))
    model = sm.OLS(y, sm.add_constant(x)).fit()

    return {
        "相関": round(corr, 3),
        "感応度": round(float(model.params.iloc[1]), 3),
        "R2": round(float(model.rsquared), 3),
        "p値": float(model.pvalues.iloc[1]),
    }


rows = []
for code, name in STOCKS.items():
    try:
        r = fx_sensitivity(code)
        if r:
            r["銘柄"] = name
            r["有意"] = "○" if r["p値"] < 0.05 else "×"
            rows.append(r)
    except Exception as e:
        print(f"{name}: {e}")

df_res = pd.DataFrame(rows)[["銘柄", "相関", "感応度", "R2", "有意"]]
print(df_res.sort_values("相関", ascending=False).to_string(index=False))

「感応度」は、ドル円が1%円安になったとき、その株が何%動くかを表します。ベータ値と同じ考え方です。

結果を見ると、次のような傾向が現れます。

タイプ相関解釈
自動車・電機プラス(0.2〜0.4程度)円安メリットはあるが限定的
半導体製造装置プラスだが変動大世界景気の影響のほうが大きい
通信・内需ほぼゼロ為替とは無関係に動く
小売(輸入型)マイナス円安は仕入れコスト増でマイナス

ここでR²の低さにも注目してください。相関が0.3程度あっても、R²は0.1未満ということがよくあります。これは「株価の動きのうち、為替で説明できるのは1割にも満たない」という意味です。

つまり「円安だからこの株を買う」という判断は、根拠の9割が抜け落ちていることになります。僕が期待外れに感じたのも当然でした。

関係は時期によって変わる

もう1つ重要な発見がありました。相関は固定値ではなく、時期によって大きく動きます。

import matplotlib.pyplot as plt


def rolling_correlation(stock_ticker, fx="JPY=X", window=60, period="5y"):
    """相関の時系列推移を計算する"""
    df = load_data([stock_ticker, fx], period)
    rets = df.pct_change().dropna()
    return rets[stock_ticker].rolling(window).corr(rets[fx]).dropna()


roll = rolling_correlation("7203.T")

fig, ax = plt.subplots(figsize=(11, 4.5))
ax.plot(roll.index, roll, linewidth=1.2)
ax.axhline(0, color="gray", linewidth=0.8)
ax.axhline(float(roll.mean()), color="crimson", linestyle="--",
           linewidth=1, label=f"平均 {float(roll.mean()):.2f}")
ax.set_ylabel("相関係数(60日ローリング)")
ax.set_title("トヨタ株とドル円の相関の推移")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("rolling_fx_corr.png", dpi=120)

print(f"平均   : {float(roll.mean()):>6.3f}")
print(f"最大   : {float(roll.max()):>6.3f}")
print(f"最小   : {float(roll.min()):>6.3f}")
print(f"マイナスだった期間: {float((roll < 0).mean()) * 100:>5.1f} %")

実行すると、相関が0.6を超える時期もあれば、マイナスになる時期もあることが分かります。「円安だから上がる」が成り立つ時期と、まったく成り立たない時期が交互に来るわけです。

この変動には理由があります。円安の「原因」が違うからです。

円安の背景株価への影響相関
米国景気が好調で金利上昇世界需要も強い。株高プラス
日本の金融緩和輸出企業の採算改善プラス
日本売り・リスクオフ株も一緒に売られるマイナス
資源高によるコスト増仕入れ値上昇で採算悪化マイナス

「円安」という現象は同じでも、その裏にある事情によって株価への影響は正反対になります。相関係数だけを見ても、この違いは区別できません。

局面を分けて分析する

それなら、局面ごとに分けて集計してみます。「円安のときに株が上がったか」を直接確認する方法です。

def analyze_by_regime(stock_ticker, fx="JPY=X", period="5y"):
    """円安・円高の局面ごとに、株価の反応を集計する"""
    df = load_data([stock_ticker, fx], period)
    rets = df.pct_change().dropna() * 100

    # 為替の動きで4つに区分する
    bins = [-np.inf, -0.5, 0, 0.5, np.inf]
    labels = ["大幅円高", "円高", "円安", "大幅円安"]
    rets["regime"] = pd.cut(rets[fx], bins=bins, labels=labels)

    summary = rets.groupby("regime", observed=True)[stock_ticker].agg(
        日数="count",
        平均="mean",
        上昇率=lambda s: (s > 0).mean() * 100,
    ).round(3)
    return summary


for code, name in [("7203.T", "トヨタ"), ("9432.T", "NTT"),
                   ("9843.T", "ニトリ")]:
    print(f"\n=== {name} ===")
    print(analyze_by_regime(code).to_string())

この表の見方が重要です。「大幅円安の日に、その株の上昇率が何%だったか」を見ます。全体平均の50%と比べて明確に高ければ、円安メリットが実際に働いていることになります。

実際に計算すると、トヨタでも大幅円安の日の上昇率は55〜60%程度にとどまります。「円安なら必ず上がる」からは程遠い数字です。

日経平均の影響を取り除く

さらに一歩踏み込みます。円安の日は日経平均全体も上がっていることが多いので、個別銘柄の反応が「円安のおかげ」なのか「単に市場全体が上がったから」なのか区別がつきません。

def excess_sensitivity(stock_ticker, fx="JPY=X",
                       market="^N225", period="3y"):
    """市場全体の影響を除いた、為替への感応度を求める"""
    df = load_data([stock_ticker, fx, market], period)
    rets = df.pct_change().dropna()

    # 説明変数に市場リターンと為替を両方入れる
    X = sm.add_constant(rets[[market, fx]])
    model = sm.OLS(rets[stock_ticker], X).fit()

    return {
        "市場ベータ": round(float(model.params.iloc[1]), 3),
        "為替感応度": round(float(model.params.iloc[2]), 3),
        "為替のp値": float(model.pvalues.iloc[2]),
        "R2": round(float(model.rsquared), 3),
    }


print(f"{'銘柄':<16s} {'市場β':>8s} {'為替感応度':>11s} {'p値':>8s} {'判定':>6s}")
for code, name in STOCKS.items():
    try:
        r = excess_sensitivity(code)
        mark = "○" if r["為替のp値"] < 0.05 else "×"
        print(f"{name:<16s} {r['市場ベータ']:>8.3f} {r['為替感応度']:>11.3f} "
              f"{r['為替のp値']:>8.3f} {mark:>6s}")
    except Exception:
        continue

これが本記事で一番見てほしい分析です。市場全体の影響を除いてもなお為替感応度が残るなら、それは本物の「円安メリット銘柄」だと言えます。

実際にやってみると、単純な相関では高く見えた銘柄の多くが、市場要因を除くと有意でなくなります。「円安メリット」だと思っていたものの正体が、単に日経平均との連動だったというケースは珍しくありません。

市場全体との連動を測るベータ値についてはベータ値(β)って結局何?で詳しく扱っています。

分析して考えが変わったこと

「円安メリット銘柄」という括りが雑すぎた

同じ「輸出企業」でも、海外生産の比率によって感応度はまったく違います。現地で作って現地で売る企業なら、円安の恩恵はほとんどありません。

逆に、国内で作って輸出している企業——精密機械や一部の素材メーカーなど——のほうが、感応度が高く出ることがあります。「自動車=円安メリット」という単純な図式は、もう当てにならないということです。

相関を見るなら、必ず期間も確認する

「トヨタとドル円の相関は0.35」と言われても、それがいつの期間の話かで意味がまるで違います。ローリングで推移を見る習慣がついてから、単一の数字を信じなくなりました。

# 期間を変えると相関がどう変わるか
for period in ("6mo", "1y", "3y", "5y"):
    try:
        df = load_data(["7203.T", "JPY=X"], period)
        rets = df.pct_change().dropna()
        corr = float(rets["7203.T"].corr(rets["JPY=X"]))
        print(f"{period:>5s} (n={len(rets):>4d}): 相関 {corr:>6.3f}")
    except Exception:
        continue

期間によって0.1から0.5まで動くこともあります。都合のいい期間を選べば、どんな結論でも作れてしまうということでもあります。

為替は「材料の1つ」でしかない

R²が0.1未満という事実は、株価の動きの9割以上は為替以外の要因で決まっていることを意味します。決算、業界動向、市場全体の地合い、個別のニュース——為替はその中の1つにすぎません。

この認識に変わってから、「円安だから買う」という判断をやめました。代わりに、決算や業績見通しといった、より直接的な材料を見るようになっています。

まとめ

円安と製造業株の関係を、相関係数で実際に確かめた記録をまとめました。

  • 相関は価格ではなく変化率で計算する。価格同士では見せかけの相関が出る
  • 自動車・電機の為替相関は0.2〜0.4程度。思ったより弱い
  • R²は0.1未満。株価の動きの9割以上は為替以外の要因で決まる
  • 相関は時期によって0.6からマイナスまで変動する。円安の背景が違うため
  • 市場全体の影響を除くと、多くの銘柄で為替感応度は有意でなくなる
  • 海外生産が進んだ企業ほど、円安の恩恵は限定的になっている
  • 単一の相関係数を信じない。必ず期間とローリング推移を確認する

冒頭の「思ったのと違う」という感覚は、正しかったわけです。円安メリットは存在するものの、株価を動かす要因としては小さく、しかも時期によって消えたり逆転したりします。

この検証をやって良かったのは、「よく聞く話」を自分の手で確かめる価値を実感できたことでした。教科書に書いてあることが今も成り立つとは限りません。数字で確認すれば、自分の期待値を現実に合わせられます。

まずは自分の保有銘柄で、ドル円との変化率ベースの相関とR²を計算してみてください。「思っていたほど関係なかった」と分かるだけでも、判断材料の優先順位が変わるはずです。

なお、相関が弱いこと自体は悪いニュースではありません。為替に振り回されない銘柄を持っているなら、それは為替リスクを取っていないということでもあります。大事なのは、自分が実際に何のリスクを取っているのかを正しく把握することです。

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