自己相関の検定

時系列データが自己相関を持つか=標本自己相関≠0の検定。与えられた時系列データがiid系列と仮定すれば標本自己相関の漸近分布は平均0分散1/Tの正規分布に従う。iid系列という仮定が結構強い気もするけど、とりあえずやってみる。

参考サイト

statsmodels.graphics.tsaplots.plot_acf — statsmodels

Pythonで自己相関グラフ(コレログラム)を描く - Qiita

やってみた

pd.plottingを使うなどの方法もあったけど、パラメータ設定がやりやすそうだったので今回はstatsmodelsで行うことに。それっぽいものはできたけど、95%信頼区間はBartlett’s formulaなるものを用いているらしい。ARMA過程やらの考えを用いているみたいだけど、ちょっとドツボにはまりそうだったので、おいおいということで一旦はそれっぽいものとしておいておく。。でも、ネットで落ちているようなコレログラムをみると信頼区間はラグによって結構動いているけど、今回はどれもほぼほぼ一定に見えるのでもしかしたらこれは特徴的?

from statsmodels.graphics.tsaplots import plot_acf

name= "USDJPY Curncy"
col = "log_chg"

tmp = df[df.id == name]\
    .sort_values("date")\
    .loc[:, col]

plot_acf(
    x= tmp.dropna().values,
    lags= 20, # ラグいくつまで表示するか
    alpha= 0.05, # 信頼区間
    zero= False, # lag= 0を表示するか
    title= name.split(" ")[0] + " Autocorrelation", # title
    # missing= "drop", # トキュメントにはあるのに使えなかった
);

f:id:iiiiikamirin:20220219141959p:plain

例の通り、各資産についてやってみた。自己相関がそんなに強いものはあまりない印象。TPXやUSDJPYは逆相関強いという噂はなんとなく聞いていたけど、過去20年に限ってはTPXがラグ1-3でそれなりにあるかな?という感じ。SP500(ES)のラグ1が最も大きくしかも逆相関なのは意外。大きく下落する前に極まって最後の上昇を見せることがあるけど、その影響が強く出ている?米債(TY)のラグ20も比較的大きく逆相関なのは、20って1カ月くらいだからちょっと気になる。

name = "log_chg"

fig, ax = plt.subplots(3,2, figsize= (15,12))

for i, id_ in enumerate(param['ticker']):
    
    tmp = df[df.id == id_]\
        .sort_values("date")\
        .dropna()\
        .loc[:, name]\
        .values
    
    plot_acf(
        x= tmp,
        lags= 20, # ラグいくつまで表示するか
        alpha= 0.05, # 信頼区間
        zero= False, # lag= 0を表示するか
        title= id_.split(" ")[0] + " Autocorrelation", # title
        ax = ax[i // 2][i % 2],
    );
    ax[i // 2][i % 2].set_ylim(-.12, .12)

plt.show()
# fig.savefig("figs/autcorr.png")

f:id:iiiiikamirin:20220219143639p:plain

SPとTPのラグ0とラグ1を散布図でプロットしてみると、5%以上動いた際の挙動で自己相関が大きく決定している気が。なので、ラグ0,ラグ11ともに5%以下のときに絞ってもコレログラムを作成してみた。5%以上動かないときが99.5%なのでほぼこの範囲内に含まれている。すると、それほど特徴のない結果に。ほとんど有意に自己相関を持つ資産やラグがない。。3%や2%も試したけど似たような結果でした。

id_ = "ES1 Index"
col = "log_chg"

# 自己相関算出
shift= 1
series = df[df.id == id_]\
    .sort_values("date")\
    .loc[:, col]\
    .dropna()
corr = np.corrcoef(
    series.values[shift:], 
    np.roll(series.values, shift= shift)[shift:],
)
print(corr)

# ラグnでプロット
fig, ax = plt.subplots()
pd.plotting.lag_plot(series, lag=shift, ax= ax)
ax.set_xlim([-.15, .15])
ax.set_ylim([-.15, .15])
ax.grid(axis= "x")
ax.grid(axis= "y")
ax.set_title("SPX")
fig.show()

f:id:iiiiikamirin:20220219153003p:plain TPX版 f:id:iiiiikamirin:20220219153026p:plain

df_small = df[
    (df.log_chg.abs() <= .05) & (df.log_chg_lag_1.abs() <= .05)
]
print(len(df.dropna(subset= ["log_chg", "log_chg_lag_1"])))
print(len(df_small))
print(len(df_small) / len(df.dropna(subset= ["log_chg", "log_chg_lag_1"])))

name = "log_chg"
fig, ax = plt.subplots(3,2, figsize= (15,12))

for i, id_ in enumerate(param['ticker']):
    
    # tmp = df[df.id == id_]\
    #     .sort_values("date")\
    #     .dropna()\
    #     .loc[:, name]\
    #     .values
    tmp = df_small[df_small.id == id_]\
        .sort_values("date")\
        .dropna()\
        .loc[:, name]\
        .values
    
    plot_acf(
        x= tmp,
        lags= 20, # ラグいくつまで表示するか
        alpha= 0.05, # 信頼区間
        zero= False, # lag= 0を表示するか
        title= id_.split(" ")[0] + " Autocorrelation", # title
        ax = ax[i // 2][i % 2],
    );
    ax[i // 2][i % 2].set_ylim(-.12, .12)

plt.show()
# fig.savefig("figs/autcorr.png")

f:id:iiiiikamirin:20220219153144p:plain

まとめ

株価等のデータは裾が厚いという特徴あり+相関は外れ値の影響受けやすい=全データを対象に自己相関について判断すると米株は逆相関が強いみたいなミスリードが生じるので注意が必要ですな。

特に株価が3%ほど大きく動いた際に米株が逆相関っぽくなっているのは、おそらく米株が下落後に反転する力が強いとかが原因な気が。半面、コロナやリーマンのときらへんに前日大きく上昇&翌日大きく下落のような場面もみるので、まあこんなところが逆相関っぽくみえるところに影響したのではないかと思います。