(2023-11-05) 売買戦略に関する記述を追加しました。
本ブログの9年前(まだ投資がテーマではなかった)の記事で、時系列データの「共和分」についての解説をしました。
datapowernow.hatenablog.com
2つの単位根過程(階差をとると定常になる)の時系列が共和分の関係にあるとは、2つの系列の線形結合が定常になるような線形結合の重み係数が存在することでした。
一方、類似した価格推移をする2つの金融商品に注目し、双方の価格差が開いたり狭まったりした時に売買して、超過収益を狙う戦略を「ペアトレード」といいます。最近、上記「共和分」の性質を用いたペアトレード(統計的裁定取引)について少し学習したので、その基本的な内容とコードを記載します。
原理としては、共和分の関係にある2つの株価の系列は、一旦その差が開いてもまた元にもどる(平均回帰)傾向があることを利用するものです。
まずいつものように必要なライブラリをインポートします。
import pandas as pd import numpy as np import statsmodels.api as sm import yfinance as yf from pandas_datareader import data as pdr
次に、動きが似ていそうな2つの銘柄の株価データを取得します。
symbol1 = '9201.T' # 9201は日本航空 symbol2 = '9202.T' # 9202はANAホールディングス start_date = '2020-01-01' end_date = '2023-10-31' yf.pdr_override() # yahooサイトからデータをダウンロード security1_data = pdr.get_data_yahoo(symbol1, start_date, end_date) security2_data = pdr.get_data_yahoo(symbol2, start_date, end_date)
次に、statsmodelsライブラリを用いて共和分に関する検定(帰無仮説は共和分なし)を実施します。p値が0.05よりも小さければ共和分ありとみなし、回帰係数をもとにスプレッド(残差)を計算して標準化します。
# 共和分についての検定の実施 result = sm.tsa.stattools.coint(security1_data['Close'], security2_data['Close']) # 線形回帰モデルのあてはめ model = sm.OLS(security1_data['Close'], security2_data['Close']).fit() if result[1] < 0.05: # 共和分が存在する場合に、スプレッド(残差)とそのZスコアを求める spread = security1_data['Close'] - model.params[0] * security2_data['Close'] mean = np.mean(spread) std = np.std(spread) zscore = (spread - mean) / std zscore.plot()
この銘柄ペアの場合、共和分に関する検定のP値は0.034となり、共和分ありと判定されました。実際の売買戦略は、上記のZスコアとしきい値に基づいて立てることになります。例えば、最新のzscore < -1.5ならばsecurity1を買ってsecurity2を空売り、そのあと平均値に回帰する価格変動を狙います。もちろん、いわゆる「裁定取引」のように必ず儲かるわけではありません。また銘柄のペアの見つけ方も課題となります。特に上記データの期間には「新型コロナ」という特殊要因が含まれているため、その点にも注意が必要と思われます。