見落としがちな相関係数の話
突然ですが、皆さんは相関係数について完全に理解されていますでしょうか。
例えば金融データにおいて、資産Aの系列と資産Bの系列があったとして、どのように相関を計るのが良いのでしょうか。
今回は2006年〜2015年の日経平均指数とドル円レートを例にとって考えていこうと思います。
%matplotlib inline import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import datetime, date import statsmodels.api as sm from scipy.optimize import minimize from arch import arch_model plt.style.use("Solarize_Light2") plt.rcParams["axes.labelcolor"] = "#202020" plt.rcParams["xtick.color"] = "#202020" plt.rcParams["ytick.color"] = "#202020" plt.rcParams["figure.dpi"] = 100 ############# # Variable Input code = ['NI225','USDJPY'] start_y = 2006 start_m = 1 end_y = 2016 end_m = 1 ############# ############# # stock_plot ############# start = str(start_y)+'-'+str(start_m) start = datetime.strptime(start, '%Y-%m') end = str(end_y)+'-'+str(end_m) end = datetime.strptime(end, '%Y-%m') for i in range(len(code)): if i == 0: data = pd.read_csv("csv/"+str(code[i])+".csv") data.date = pd.to_datetime(data.date) data.set_index('date', inplace=True) else: tmp = pd.read_csv("csv/"+str(code[i])+".csv") tmp.date = pd.to_datetime(tmp.date) tmp.set_index('date', inplace=True) data = pd.concat([data,tmp],axis=1) data.columns = code data = data.astype(float) data = data.interpolate() data = data[start:end] display(data.head()) display(data.tail()) fig, ax1 = plt.subplots() ax1.plot(data.iloc[:,0],label='Nikkei225') ax2 = ax1.twinx() ax2.plot(data.iloc[:,1],color='orange',label='USDJPY') h1, l1 = ax1.get_legend_handles_labels() h2, l2 = ax2.get_legend_handles_labels() ax1.legend(h1+h2, l1+l2, loc='lower right') plt.title('Close Price') ax1.set_xlabel('Year') ax1.set_ylabel('Nikkei225(¥)') ax2.set_ylabel('USDJPY(¥)') plt.show()
このように2軸プロットをしてみるとかなり相関が高いように思われます。
円安になると輸出企業の業績が良くなって、株高になる。そういった経済学のセオリーがそのまま現れています。
plt.scatter(data.iloc[:,1],data.iloc[:,0]) plt.title('NI225 - USDJPY plot') plt.xlabel('USDJPY(¥)') plt.ylabel('NI225(¥)') plt.show() display('相関係数') display(data.corr().iloc[1,0])
散布図にプロットしてみても相関があるように思われます。
相関係数はなんと
############# # Log Return ############# data = np.log(data) N = len(data) for i in range(len(code)): for j in range(1,N): data.iloc[N-j,i] = data.iloc[N-j,i]-data.iloc[N-j-1,i] tmp = data.index.values[0] data = data.drop(tmp) display(data.head()) plt.title('Log Return') plt.xlabel('Year') plt.ylabel('Daily Return') plt.plot(data.iloc[:,0], alpha=0.9) plt.plot(data.iloc[:,1], alpha=0.9,color='orange') plt.show()
例によって対数収益率に変換してみました。
この収益率系列に対して相関をとってみたものが以下です。
plt.scatter(data.iloc[:,1],data.iloc[:,0]) plt.title('Return plot') plt.xlabel('Return of USDJPY') plt.ylabel('Return of NI225') plt.show() display('相関係数') display(data.corr().iloc[1,0])
相関係数はまさかの
一体どういうことでしょう。
価格の相関 vs 収益率の相関
ここからの話はCorrelation with prices or returns: that is the question | Quantdareからアイデアを拝借いたします。
話を簡単にするために、とある資産A, B, Cを考えます。以下のプロットはその価格推移です。
これを見ると直観的には「資産Aと資産Bの間に強い相関があり、資産AやBと資産Cの間の相関はやや小さい」という風に思えるのではないでしょうか。
例えばこれら3つの資産から2つを選んでポートフォリオを組むとするなら、「(A, B)の組み合わせはハイリスクに見えるので避けて、(A, C)や(B, C)の組み合わせでリスクを低くしていく」ような戦略が魅力的に思える気がします。
そろそろ種明かしをしましょう。
a = np.array([3,-1,4,2,0,2,5,3,-1]) #Aのリターン sample = pd.DataFrame({'A':a, 'B':4-a, #BはAと真逆の動きをする 'C':0.5*a}) #CはAより小幅にAと同じ動きをする sample.index = np.arange(1, len(sample) + 1) display('収益率') display(sample) plt.scatter(sample['A'],sample['B'],label='AvsB') plt.scatter(sample['A'],sample['C'],label='AvsC') plt.legend() plt.title('Return Plot') plt.xlabel('Return of A(%)') plt.ylabel('Return of B or C(%)')
この系列はAとBが反対方向の動きをするように、AとCが同じ方向の動きをするように作られているのです。
数式で言うなら、
では先ほどのポートフォリオの話に戻ってみましょう。
(A,B)のポートフォリオは常に4%の収益を上げ続けるのに対して、(A,C)のポートフォリオは全く同じ方向に動くので共倒れのリスクがあります。
あれ?さっきと言っていることが真逆ですね。
「価格の相関」の誤り
当然、後者の方が正しいわけですが、価格間の相関を求めることは何が誤っているのでしょうか。
Correlation with prices or returns: that is the question | Quantdareには面白い記述があります。
各時点における資産の価格は、それまでの各期間での収益をとして
1期目での収益は回現れていますが、期目の収益は1度しか現れていません。価格で相関を取るならば、これらの収益を不平等に扱うことになります。
前半での収益の影響が大きく現れた相関係数は、資産間の関係性を正しく表したものとは言えません。