2022.04.07

暗号資産インデックスを作ってCAPMで実証分析してみた

こんにちは、次世代システム研究室のT.Yです。株式投資の世界では日経225やTOPIXなどの有名なインデックスがありますが、暗号資産はまだアセットクラスの誕生からの経過年月が浅いこともあって知名度の高い投資指標はあまりありません。そこで、この記事では暗号資産のマーケットデータを取得して暗号資産インデックスを作り、CAPMのフレームワークで各銘柄のリスク特性を考察してみました。

サマリー

  1. 時価総額加重平均型の暗号資産インデックスを作りました
  2. Bitcoinはマーケットポートフォリオに対してディフェンシブ傾向
  3. 新興アルトコインはアグレッシブ傾向

金融商品のインデックス

金融商品におけるインデックスとは市場の変動等の情報を表す指数のことです。「東証マザーズ上場銘柄」など、一定の基準で選別された株式や債券などの金融資産のグループの全体的な価格変動を表すために計算されます。日経平均株価指数やTOPIXなど、新聞やニュース等で一度は聞いたことがあるのではないでしょうか。これらの指数はただ市場動向をサマリーして伝えるための情報として提供されているのではなく、投資信託やETF(Exchange Traded Fund)などの金融商品を設計する際にベンチマークとして参照されることが多く、実際に値動きが何らかのインデックスに連動するよう作られる金融商品も多々あります。
例として、米国株式代表銘柄500種の資産価格を代表するS&P500のチャートを掲載しておきます。S&P500指数に連動する投資信託は指数連動型投資信託の中で、2022年4月現在で最も人気の高い金融商品です。


CAPM(Capital Asset Pricing Model)

投資の入門段階でパッシブ型投資信託などのインデックス連動型商品が推奨される際の理論的根拠としてCAPM(Capital Asset Pricing Model)という金融理論があります。これは、大ざっぱに説明すると、一定の強い仮定の下、分散投資により価格変動のリスクとリターンのバランスを適正化する効率的な資産配分を構成するポートフォリオマネジメントのフレームワークです。「できるだけリターンを大きくしたいけどリスクは取りたくない」という投資のトレードオフを解消するにはどうすればよいでしょうか。その最適解は、マーケットポートフォリオ(すべての証券の時価総額比率のバスケット)と安全資産の組み合わせで投資することだとCAPMは主張します。以下はCAPMの要旨です。

CAPMの仮定

  1. 投資家は平均分散アプローチで投資行動を選択する(投資家の目的関数に関する仮定)
  2. 投資家は金融資産のリターンの平均・分散について同一の予想を持つ
  3. 金融市場が完全市場で、無リスク資産が存在する
上記の仮定のもとで、マーケットポートフォリオは、効率的フロンティア(所与のリスクでリターンが最大となるポートフォリオ集合)上でシャープレシオ(リスク1単位あたりのリスクプレミアム)が最大になる点(接点ポートフォリオ)と一致します。



考え方としては、平均分散アプローチの結果、全ての投資家の最適ポートフォリオは資本市場線上に存在するので、リスク資産の保有比率(接点ポートフォリオの構成比)としては全員同じ、すなわち市場の構成比であるマーケットポートフォリオに収束するというロジックです。

CAPMはかなり強い仮定を置いており、現実にうまく当てはまらないという実証分析の報告もありますが、数理モデルがシンプルであり解析が容易なことから、現代ポートフォリオ理論のベーシックなモデルとして位置付けられています。上述の考え方に基づき、各銘柄のリスクプレミアムをマーケットポートフォリオのリスクプレミアムで説明する以下のモデルを得ます。



以下ではこのモデルで暗号資産の日次リターンを分析します。方針としては、マーケットポートフォリオの変動に対して各銘柄のリターンがどれだけ連動するかを考察します。具体的には、回帰係数ベータの値により各銘柄がアグレッシブ(ベータの絶対値 > 1)かディフェンシブ(ベータの絶対値 <= 1)かを判断します。

CoinGecko APIでデータ取得してみる



仮想通貨データアグリゲーターCoinGeckoは、50コール/1分の制限付きで無料APIによる暗号資産関連データの提供を行なっています。公式ドキュメントに従ってWeb APIを利用すれば簡単にマーケットデータを入手できます。

以下のコードではコミュニティが開発した非公式Python wrapperを使用しています。
import time
import datetime
import numpy as np
import pandas as pd
import seaborn as sns
from pandas import to_datetime
from pycoingecko import CoinGeckoAPI
from matplotlib import pyplot as plt

def to_unix_time(timestamp):
    return int(time.mktime(to_datetime (timestamp).timetuple()))

# coin gecko api インスタンス
cg = CoinGeckoAPI()

# 最新のマーケット情報を取得
coin_markets = cg.get_coins_markets(vs_currency='jpy')
coin_market_df = pd.concat(
    [pd.DataFrame(data, index=[n]) for n, data in enumerate(coin_markets)])

def get_price_by_id(id, vs_currency, from_timestamp, to_timestamp) -> pd.DataFrame:
    tmp_data = cg.get_coin_market_chart_range_by_id(
        id=id, vs_currency=vs_currency,     
        from_timestamp=from_timestamp, to_timestamp=to_timestamp)

    prices =pd.DataFrame(tmp_data['prices'], columns=['timestamp', 'price'])
    market_caps =pd.DataFrame(tmp_data['market_caps'], columns=['timestamp', 'caps'])
    total_volumes =pd.DataFrame(tmp_data['total_volumes'], columns=['timestamp', 'total_volumes'])
    
    tmp_df = pd.merge(prices, market_caps, on='timestamp')
    tmp_df['id'] = id
    tmp_df['trade_datetime'] = tmp_df['timestamp'].map(
        lambda x: datetime.datetime.fromtimestamp(x/1000))
    tmp_df['trade_date'] = tmp_df['trade_datetime'].map(lambda x: x.date())

    return tmp_df

days = 366
start_ts = "2021/04/01 00:00:00"
end_ts = str(to_datetime("2021/04/01 00:00:00") + datetime.timedelta(days=days))
from_timestamp = to_unix_time(start_ts)
to_timestamp = to_unix_time(end_ts)

n = 50 # 上位n銘柄
ticker_list = coin_market_df.id.tolist()[:n]
vs_currency = 'jpy'

historical_price_df = pd.concat([get_price_by_id(id, vs_currency, from_timestamp, to_timestamp) for id in ticker_list])
historical_price_df = historical_price_df.reset_index(drop=True)
historical_price_df = historical_price_df[historical_price_df['id'] != 'shiba-inu'] # シバイヌが暴れているので除外
直近のマーケット規模の上位50銘柄について2021年4月から1年分の価格と時価総額のデータを取得しました。上位の時価総額の推移を見てみると、Bitcoinのドミナンスがかなり高い状態であることがわかります。



なお、後続の分析結果の解釈性を高めるため、やや恣意的ですがこの期間中に大きく騰落したシバイヌのデータを異常値として除外しています。

Market Capitalization Weighted Index

時価総額加重平均指数(Market Capitalization Weighted Index, 以下MCWI)で市場動向を把握するメリットはCAPMの説明で触れましたので、既に取得したデータセットを用いて暗号資産のマーケットポートフォリオの推移を実際に計算していきます。
# Start時点のpriceで規格化
historical_price_std = pd.merge(
    historical_price_df,
    historical_price_df.loc[
        historical_price_df.groupby(['id'])['timestamp'].transform(lambda g: g.min()==g),
        ['id', 'price']],
    on=['id'], how='left',
    suffixes=('', '_start'))

historical_price_std['std_price'] = historical_price_std['price'] / historical_price_std['price_start']

# 日足データ
daily_price = historical_price_std[['id', 'trade_date', 'std_price', 'caps']] \
  .set_index(['id', 'trade_date']).unstack('id')

# 時価総額加重平均指数
daily_price[('std_price', 'MCWI')] = (daily_price['std_price'] * daily_price['caps']).sum(axis=1) \
  / daily_price['caps'].sum(axis=1)

pct_change_df = daily_price['std_price'].pct_change(1)
MCWI算出時の主なポイントは以下の3点です。
  1. 値がさ銘柄の影響を抑えるため、基準日時点で1となるよう規格化
  2. ステーブルコインもトラッキングエラーや為替リスクで変動し得るため算入
  3. 時価総額は総循環供給量に基づく2022年4月集計時点上位50位で計算
参考としてMCWIとBitcoinの推移を示します。



また、インデックスの日次リターンを集計しましたのでこちらも可視化します。


ベータの考察

CAPMの回帰係数を算出して各暗号資産のリスク傾向を分析します。
# MCWIの標準偏差
stdev_m = pct_change_df['MCWI'].std()
# 各銘柄の標準偏差
stdev_i = pct_change_df[pct_change_df.columns[:-1]].std()
# 各銘柄とMCWIの相関係数
corr_mat = pct_change_df.corr()
rho_im = corr_mat['MCWI'][:-1]
# CAPMのベータ
beta_im = rho_im * stdev_i / stdev_m
ベータを可視化すると以下のようになりました。傾向としては、BitcoinやEthereumなどの比較的流通量の多い銘柄はベータが1を下回るディフェンシブな銘柄であり、apecoinやaxie-infinityなどの比較的最近セールスされた新興のアルトコインはマーケット平均を上回るアグレッシブな銘柄になっていると言えそうです。


最後に:おまけと今後の課題

これまでの分析の前提として、暗号資産というアセットクラスの中で投資家がアロケーションを考えることを暗黙的に想定していましたが、実際は株などのアセットクラスと並行して暗号資産に投資すると考えられます。また、暗号資産開発者が会社に所属しているケースが多いと想定すると株式との相関が気になります。実際、暗号資産の値動きとS&P500のリターンの相関が高いという説があるのでMCWIを使用してこの機会に確かめてみました。以下、簡単に結果を示します。
import pandas_datareader.data as pdr
start_dt = pd.to_datetime(start_ts)
end_dt = pd.to_datetime(end_ts)

sp_data = pdr.DataReader('SP500', 'fred', start_dt, end_dt)
sp_data = sp_data.dropna()
daily_price.index = pd.to_datetime(daily_price['std_price'][['MCWI']].index)
sp_mcwi = pd.merge(
    left=pct_change_df[['MCWI']].dropna(), 
    right=sp_data.pct_change(1).dropna(), 
    how='inner', left_index=True, right_index=True)

sns.regplot(data=sp_mcwi, x='MCWI', y='SP500', color='black', marker='s')
相関の傾向としては意外とあまりなく、相関係数は0.074程度でした。



さて、今回は時価総額上位銘柄のデータでシンプルな時価総額加重平均型の暗号資産インデックスを作って市場の考察を行いました。暗号資産と一口に言っても、ブロックチェーンのネイティブトークンやGamiFiのプラットフォームトークン、ミームコインなど様々な種類があることから、今後の方針として各カテゴリごとに細分化して値動きを指数化する手法が考えられます。次回は、CAPMや時価総額の大きさに捉われず、より銘柄の種類を増やしてクラスタリング等の別の切り口での分析を検討してみたいと思います。

次世代システム研究室では、ビッグデータ解析プラットフォームの設計・開発を行うアーキテクトとデータサイエンティストを募集しています。興味を持って頂ける方にはぜひ 募集職種一覧からご応募をお願いします。

一緒に勉強しながら楽しく働きたい方のご応募をお待ちしております。

  • Twitter
  • Facebook
  • はてなブックマークに追加

グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

 
  • AI研究開発室
  • 大阪研究開発グループ

関連記事