見出し画像

9.bitcoinと、ドル発行量の相関を検証してみた

ビットコインとドル発行量(M2)の関係

1. 背景

ビットコインは2009年に誕生し、発行上限が約2100万BTCとプログラムで固定されています。一方、米ドルはFRB(米連邦準備制度)の政策で供給量が変動します。特に量的緩和(QE)でマネーサプライが大きく増えたとき、ビットコインは**「デジタルゴールド」**としてインフレヘッジの注目を集めてきました。

たとえば2020年のコロナ危機でFRBが積極的に金融緩和を行い、米ドル供給が急増した局面ではビットコイン価格も過去最高値を更新しました。逆に、金融引き締めに転じた2018年頃はビットコイン価格が大幅に下落しており、ドルの発行量(マネーサプライ)とビットコイン価格の間には何らかの相関があるように見えます。

2. データの取得方法

ビットコイン価格(BTC/USD)

  • Yahoo!ファイナンスやCoinbaseなどのヒストリカルデータを月次で取得

  • 今回は yfinance を使い、月末の終値を使用

米ドル発行量(M2)

  • FRED(セントルイス連銀)のデータベースから「M2SL」を月次取得

  • 期間は2009年〜直近を想定

3. 分析と結果

3-1. サンプルコード

下記は、Pythonを用いて「BTC-USD価格」と「米国M2SL」を月次で取得し、相関分析・単回帰を行う一例です。(実行環境に応じて適宜修正)

import pandas as pd
import numpy as np
import yfinance as yf
import statsmodels.api as sm
import pandas_datareader.data as web
import datetime

# ====================================
# 1. 設定
# ====================================
start_date = "2013-01-01"
end_date = datetime.datetime.today().strftime('%Y-%m-%d')

# ====================================
# 2. BTCデータ (yfinance)
# ====================================
btc_raw = yf.download(
    "BTC-USD", start=start_date, end=end_date
)

# --------------------
# 2-1) MultiIndex対策
# --------------------
# yfinanceが返すDataFrameの列が MultiIndex の場合があるため、階層をフラットにする
# 例: ("Close","BTC-USD") -> "Close_BTC-USD"
if isinstance(btc_raw.columns, pd.MultiIndex):
    btc_raw.columns = [
        "_".join(col).strip() for col in btc_raw.columns.values
    ]
# ここまでで、列名が ["Open_BTC-USD", "High_BTC-USD", ...] のような形になる想定

# --------------------
# 2-2) Close列を "BTC_USD" に
# --------------------
# フラット化した列名が "Close_BTC-USD" の可能性が高いので、該当列を探してリネーム
close_cols = [c for c in btc_raw.columns if "Close" in c]
if len(close_cols) == 1:
    # 例: "Close_BTC-USD" -> "BTC_USD"
    btc_raw.rename(columns={close_cols[0]: "BTC_USD"}, inplace=True)
elif "Close" in btc_raw.columns:
    # MultiIndexじゃないケース: "Close" がそのままある
    btc_raw.rename(columns={"Close": "BTC_USD"}, inplace=True)
else:
    raise ValueError("Close列が見つかりません。btc_raw.columns={}".format(btc_raw.columns))

# --------------------
# 2-3) 月末ベースにリサンプリング
# --------------------
btc_m = btc_raw.resample("ME").last()[["BTC_USD"]].copy()

# インデックスを「Date」列に
btc_m.reset_index(inplace=True)

# ====================================
# 3. M2データ (FRED)
# ====================================
m2_raw = web.DataReader("M2SL", "fred", start_date, end_date)
m2_m = m2_raw.resample("ME").last().copy()

# 列名を単純化
m2_m.rename(columns={"M2SL": "M2"}, inplace=True)

# インデックスを「Date」列に
m2_m.reset_index(inplace=True)
# FREDのインデックス名が "DATE" の場合があるので、それを"Date"に合わせる
if "DATE" in m2_m.columns:
    m2_m.rename(columns={"DATE": "Date"}, inplace=True)

# ====================================
# 4. マージ (Date列同士)
# ====================================
df = pd.merge(
    btc_m,        # ["Date", "BTC_USD"]
    m2_m,         # ["Date", "M2"]
    on="Date",    # 共通列
    how="inner"
)

# 欠損を除去
df.dropna(inplace=True)

# デバッグ用に確認
print("=== df.columns ===")
print(df.columns)
print("=== df.head() ===")
print(df.head())
print("=== df.info() ===")
print(df.info())

# ====================================
# 5. 相関係数
# ====================================
corr_pearson = df[["BTC_USD", "M2"]].corr(method="pearson").iloc[0,1]
print("\nPearson相関 (BTC vs M2):", corr_pearson)

# ====================================
# 6. ログ変換 & 回帰分析
# ====================================
df["log_BTC"] = np.log(df["BTC_USD"])
df["log_M2"]  = np.log(df["M2"])

X = sm.add_constant(df["log_M2"])
y = df["log_BTC"]

model = sm.OLS(y, X).fit()
print("\n=== 回帰分析結果 ===")
print(model.summary())

3-2. 出力例

実際に上記コードを動かした場合の主な出力は、以下のようになります。(※実行時期やデータ更新により数値は微妙に変動します)


% python python_analysis.py 
YF.download() has changed argument auto_adjust default to True
[*********************100%***********************]  1 of 1 completed
=== df.columns ===
Index(['Date', 'BTC_USD', 'M2'], dtype='object')
=== df.head() ===
        Date     BTC_USD       M2
0 2014-09-30  386.944000  11503.7
1 2014-10-31  338.321014  11577.5
2 2014-11-30  378.046997  11618.2
3 2014-12-31  320.192993  11701.9
4 2015-01-31  217.464005  11774.2
=== df.info() ===
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 124 entries, 0 to 123
Data columns (total 3 columns):
 #   Column   Non-Null Count  Dtype         
---  ------   --------------  -----         
 0   Date     124 non-null    datetime64[ns]
 1   BTC_USD  124 non-null    float64       
 2   M2       124 non-null    float64       
dtypes: datetime64[ns](1), float64(2)
memory usage: 3.0 KB
None

Pearson相関 (BTC vs M2): 0.813820915644199

=== 回帰分析結果 ===
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                log_BTC   R-squared:                       0.838
Model:                            OLS   Adj. R-squared:                  0.836
Method:                 Least Squares   F-statistic:                     629.6
Date:                Sat, 22 Feb 2025   Prob (F-statistic):           5.33e-50
Time:                        13:16:36   Log-Likelihood:                -138.25
No. Observations:                 124   AIC:                             280.5
Df Residuals:                     122   BIC:                             286.1
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const        -63.7134      2.892    -22.033      0.000     -69.438     -57.989
log_M2         7.4779      0.298     25.093      0.000       6.888       8.068
==============================================================================
Omnibus:                        7.178   Durbin-Watson:                   0.078
Prob(Omnibus):                  0.028   Jarque-Bera (JB):                5.620
Skew:                           0.412   Prob(JB):                       0.0602
Kurtosis:                       2.362   Cond. No.                         424.
==============================================================================

=======

  • 相関係数が約0.81:ビットコイン価格とM2SLの間には強い正の相関が確認できる

  • 回帰分析のR^2が約0.84:M2の変化でビットコイン価格の対数変動のおよそ85%を説明可能

さらに、回帰式は

と推定され、指数形式に直すと

というべき乗則(非線形)に近い関係が示唆されます。

4. 考察

  • 流動性相場の影響: 金融緩和でマネーサプライが拡大すると、余剰資金がリスク資産(株式や暗号資産など)に流れやすくなります。ビットコインはとくに流動性に敏感で、過去データ上はM2と高い相関を示しました。

  • インフレヘッジとして: 米ドルの価値が希薄化する局面では、希少性を持つビットコインに需要が移る動きが見られます。

  • 相関の例外: 2018年の暴落など、マネーサプライ以外に暗号資産のバブル崩壊や規制ニュースなどが原因で価格が大きく振れることもあります。

  • ビットコイン固有のサイクル: 4年ごとの半減期(ハルビング)や投機的な過熱など、M2の伸びだけでは説明しきれない独自要因も存在します。

  • 注意点: 相関はあくまで過去の同時的な動きであり、因果関係を保証するものではありません。

5. まとめ

  • ビットコイン価格と米ドル発行量(M2)は、過去のデータをみると非常に高い正の相関があります。

  • 回帰分析でもR^2が0.85前後と、ビットコイン価格の多くをM2の変化が説明する可能性が示されました。

  • ただし、ビットコインにはハルビングやバブル的要因など固有の影響もあり、短期的にはマクロ要因と異なる動きをする場合もあります。

  • 今後も金融政策や景気動向次第でマネーサプライが増減すれば、ビットコイン価格にも大きく影響を与える可能性があります。

  • 結局のところ、「ビットコインとドルの行方」は切り離せないといえ、マクロ経済指標のチェックはビットコイン投資の一つの鍵になるでしょう。

本記事の分析結果は過去データに基づくものであり、将来を保証するものではありません。投資判断の際は、マクロ要因だけでなくビットコイン固有の要因やリスクも総合的に考慮することをおすすめします。


参考

いいなと思ったら応援しよう!

三原走己/AI社長
チップくれたら、あなたにチップをお返ししにいきましょう。