今日は前に書いた記事の若干発展版で、もうExcelを使わずにトレードバックテストまでやってゆきましょう、という記事です。
Excelは便利で、細かな調整等に向いていますが、大まかな調査についてはプログラミングで実施した方が良いと思いますし、データ量が多くなってくると、Excelでは難しいものがあります。
今回は上の記事を、少し趣向を変えて、全てPythonでやってしまおう、というのが今回の記事ですが、それでは面白くないので、トレード期間と対象銘柄を変更しております。
なので、展開がわかっている人も少しは役に立つかもしれません。
では行きましょう。
#まずは準備。必要なライブラりをそろえる
import pandas as pd
import pandas_datareader.data as web #データのダウンロードライブラリ
#株価の用意する。
#^GSPCはS&P500の意味
df_1 = web.DataReader("^GSPC","yahoo","2009/12/31").dropna()
#データの中のAdj Close(終値)を用いて、前日比を求める
df_11=df_1.loc[:,'Adj Close'].pct_change()*100
#データ型を変換。seriesからdata frameへ
df_11=pd.DataFrame(df_11)
#行に名前を付ける
df_11.columns=['SP500_change']
print(df_11)
上のコードではS&P500の株価を取得した後、S&P500の前日比リターンを割り出していますね。
結果は以下です。
SP500_change Date 2009-12-30 NaN 2009-12-31 -1.004960 2010-01-04 1.604342 2010-01-05 0.311568 2010-01-06 0.054552 ... ... 2021-09-13 0.227649 2021-09-14 -0.574664 2021-09-15 0.847400 2021-09-16 -0.155114 2021-09-17 -0.911087 [2950 rows x 1 columns]
次に日本株のTOPIX・ETF(1306)の価格を取得してゆきます。
皆さんは良く知っておいて欲しいのですが、TOPIXとNIKKEI225ではちょっとだけ性質が違います。構成銘柄が全く違うので、異なるのは当たり前ですが、ボラティリティをはじめ、色々な感応度が異なります。
#日本株のデータをダウンロード。TOPIXを使ってみる。
df_2 = web.DataReader("1306.T","yahoo","2010/1/1").dropna()#jpy
#日本株の日中の動きを米国株の上げ下げで予想するため、openからclose(寄りから引け)までのリターンを計算する
df_21=(df_2['Close']-df_2['Open'])/df_2['Open']*100
#seriesになったデータを再度daraframeにする
df_21=pd.DataFrame(df_21)
#行に名前をいれる
df_21.columns=['Topix_change']
print(df_21)
結果は以下です。
Topix_change Date 2010-01-04 0.107759 2010-01-05 -0.743100 2010-01-06 0.531350 2010-01-07 -0.316456 2010-01-08 0.419727 ... ... 2021-09-13 0.464684 2021-09-14 0.459982 2021-09-15 -0.230627 2021-09-16 -0.599078 2021-09-17 0.185185 [2885 rows x 1 columns]
どんどん行きましょう。
次はデータ結合。前回記事を読んでいればここまではほぼ同一です。
#S&P500と日経225のリターンデータを結合する。ポイントはS6P500の前日のリターンで予測すするのでデータは一日前にずらす。
df_11=df_11.shift()
conbine_price=df_11.merge(df_21,on='Date')
print(conbine_price)
print(conbine_price.corr())
SP500_change Topix_change Date 2010-01-04 -1.004960 0.107759 2010-01-05 1.604342 -0.743100 2010-01-06 0.311568 0.531350 2010-01-07 0.054552 -0.316456 2010-01-08 0.400120 0.419727 ... ... ... 2021-09-13 -0.772258 0.464684 2021-09-14 0.227649 0.459982 2021-09-15 -0.574664 -0.230627 2021-09-16 0.847400 -0.599078 2021-09-17 -0.155114 0.185185 [2787 rows x 2 columns] SP500_change Topix_change SP500_change 1.000000 -0.111822 Topix_change -0.111822 1.000000
ここでポイントはcorrで相関係数を求めているところです。
ここで見て欲しいのはTOPIXはS&P500の騰落に対して日中は負の相関且つ、絶対値が0.1以上という強い相関を持っているという事です。
いつも言っているように決定係数が0.01を超えていれば、相関が強いと言っておりますが、
この決定係数は相関係数の2乗の値なので、相関係数で考えると絶対値0.1以上が相関が強いと言っていいのです。
では負の相関であることから、S&P500が上がっていれば売り、下がっていれば買いというトレードで儲かる可能性が高いので、そのままシグナルを作るためにコードに書いてみましょう。
売りであればー1、買いであれば1を出力します。
#売買シグナルを作ってゆきましょう。逆張りなので、下の式では最後に-1がかけてあります。
Signal=conbine_price['SP500_change']/abs(conbine_price['SP500_change'])*(-1)
Signal=pd.DataFrame(Signal)
print (Signal)
SP500_change Date 2010-01-04 1.0 2010-01-05 -1.0 2010-01-06 -1.0 2010-01-07 -1.0 2010-01-08 -1.0 ... ... 2021-09-13 1.0 2021-09-14 -1.0 2021-09-15 1.0 2021-09-16 -1.0 2021-09-17 1.0 [2787 rows x 1 columns]
もうここまでくれば簡単ですね。
これをリターンにかけ合わせれば、トレードの結果になるのです。
Return=conbine_price['Topix_change']*Signal['SP500_change']
Return=pd.DataFrame(Return)
Return.columns=['Topix_trade_return']
print(Return)
Topix_trede_return Date 2010-01-04 0.107759 2010-01-05 0.743100 2010-01-06 -0.531350 2010-01-07 0.316456 2010-01-08 -0.419727 ... ... 2021-09-13 0.464684 2021-09-14 -0.459982 2021-09-15 -0.230627 2021-09-16 0.599078 2021-09-17 0.185185 [2787 rows x 1 columns]
ここからはExcelでもできる作業ですが、今回はPythonでやってゆきましょう。
時系列のリターン累積をcumsumを使って出しましょう。
import numpy as np
Total_return=np.cumsum(Return)
print(Total_return)
Topix_trede_return Date 2010-01-04 0.107759 2010-01-05 0.850858 2010-01-06 0.319509 2010-01-07 0.635964 2010-01-08 0.216237 ... ... 2021-09-13 139.611989 2021-09-14 139.152008 2021-09-15 138.921380 2021-09-16 139.520459 2021-09-17 139.705644 [2787 rows x 1 columns]
最後はプロット作業。
ラベルとか無視するならば、plt.plot(Total_Return)で一発ででます。
fig, ax = plt.subplots()
ax.plot(Total_return)
ax.set_xlabel('Time [year]', fontsize=12)
ax.set_ylabel('Return [%]', fontsize=12)
ax.set_title('S&P500 contrary trade', fontsize=16)
plt.show()
トレード期間10年ですが、長期でみればええ感じの右肩上がりのグラフができました。
ここで見て欲しいのは2020年初頭のコロナショックではエグイリターンを叩き出しています。
一方で、東日本大震災の際にはかなり下げています。
ここからは私の推論ですが、アメリカ発のショックにはNY逆張りは有効で、その逆の日本初のショックには弱いという側面があるのかと思います。
アメリカ出来事には課題に朝寄付きで反応し、徐々に日中で修正するという事ではないでしょうか。
前回の記事でも書いたように、日本以外の国でのショックに関しては逆張りが有効であると推察されるということで、過剰反応系に対応したトレードストラテジーも組んではいかがでしょうか。