ビットコインとS&P500の相関

Pythonを使って相関を計算してみました。

 ビットコインとS&P500の相関を計算してみました。前からやってみたかったのだけれど、ちょっと色々難しいところがありまして、今回もちょっと分かってきたので、3時間もかからないだろうと思ったら、丸1日かかりっきりだったという。何というか、こんな簡単なことにという感じですが、まぁ、落ちているCSVとかってどうやって作られているかわからないので、ちゃんとデータ全体を見てからやりましょうというのが、今回学んだ教訓です。

 あと、前までできたことでも、少しやらないと忘れてしまうことが多いので、今回悩んだところはちょっとプログラミングというほどでなく、1行とかだけど、メモを残して見返せるようにしておきます。でも、プログラミングのことは良く分かってないので、みんなが見て分かる形なのかどうなのかはわかりません。

 あと、なぜ相関に興味があるかという点だけ話しておくと、中央銀行が資金をじゃぶじゃぶにしてしまった今、色々な資産の相関は高くなっています。もしも相関が低い資産があれば、分散投資という点からでも、投資価値のある資産であるということができるのではないかなぁということを考え、それにビットコインとか仮想通貨が当てはまるのであれば、今後も研究する価値があるという考えからです。あと、実際の動きからそういう面も感じられたからです。

まずは結果から。

 結果から示します。使った値はビットコインはCoindeskにあるビットコインインデックス(ドル建て)の全ての値のCSV、SP500はFEDのページからとったと思うのですが、これが、最後まで悩み苦しむ原因になるとは思いませんでした。相関は250日で計算です。チャートはまた作り直そうと思うくらいしょぼいのが申し訳ないのですが、結論を見ると、ビットコインは若干SP500と逆相関であると言え、ポートに組み入れる価値のある資産だなぁと言えます。しかし、注意したいのは日本人の場合、円建てになるのでこれがどうなるのかというのはもう一度計算しなおしたいところであるなというところです。

f:id:mazarimono:20160718004955p:plain

 というわけで、この辺は明日にでも日経平均と円建てビットコイン価格で計算しなおしたいと思います。

Pythonメモ

 さて、その辺で落ちている資料を組み合わせたりしながらやることの難しさを痛感させられた今回の資料作りですが、最終的に考えるとやらなくても良かった部分もあったりしましたが、まぁ、それも今後の力となるということで、面白かったことにしましょう。初心者なので超絶簡単なところに引っかかっているのは自分でもわかりますが、自分がまたわからなくなった時用に、ウェブに書いておきます。

 分からなかったり、行き詰まったところは以下のような感じです。

  • coindeskの資料の日付に時間が入っているけどどうしたら日付だけにできるのか?

 一先ずSP500のCSVとドッキングして計算してみたいな計画だったので、日付を合わせてマージしないといけないので、日付をいじくるのはどうしたらよいのかと悩んでいました。サイトは失念してしまいましたが、DataFrameからSeriesを抜き出し、文字列を操作し、再びDataFrameに連結するという作業でできました。

hiduke.py
Hiduke = pd.Series(df.columns_name.str[:n],name='つけたい名前')
new_df = pd.concat([df,Hiduke],axis=1)

こんな感じ。で、またDataFrameでいらんColumnsをdrop()を使って削りましょう。

  • データフレームに入っているSP500の値段がObject型だった。

 これは文字列問題に入るのか良く分かりませんが、面倒な問題でした。pandas本を調べていると、numpyのdtypeの変更(キャスト)にはnumpyのastypeを使いましょうとかあるのを見て喜んだができませんでしたので、がっかりと肩を落としたのは昨日のことでした。で、調べているとブログで取り上げられている方がおられ、助かりました。

pandasで例外を無視しつつObject(文字列)を数値に変換する : mwSoft blog

numeric.py
df.name.convert_objects(convert_numeric=True)

で、変わってくれました。

 あとこれはpandas本とかに載っていたのですが、前日比率を計算するのもpct_change()使ったら一発です。僕は知らずに引き算して、割り算してってのを前回使ったような気がします。これにはshift()というのを使います。例えば下に行くほど新しい日があるDataFrameの場合、下のような感じで作れることが分かり、感心していたりしたのですが。

pct_change.py
pct_c = (df.name.shift(1)-df.name.shift(0))/df.name.shift(0)
  • データがどうなっているかよく見る。

 基本的なことなのでしょうが、データがどうなっているかをよく見てから、加工しないといけません。前日比率とか全部整え、最後にpd.rolling_corr()を使って移動相関を出そうとすると、エラーが出ないのに、計算値がすべてNaNになって帰ってくるという事態に見舞われました。最後の最後でという感じで、シリーズの作り方に問題があるのかなと、色々いじくっていましたが出ませんでした。エラー出ないし計算はできているのになぁとか思いながら、こんな単純作業早く終わってほしいなぁと思ったりしていましたが、できないのに終わることはできない。そして、期間を250日に取っていたのを7日とか短くしたら、数字が出ました。どういうことかなと考えると、つまりは数字がない部分があったということがわかりました。FEDはありがたくないことに、米国の休場の日の株価の欄に「.」を入れていたのです。dropna()は文字列を入れるときにやっていたのですが、数値に変える時にやっていなかったのか、それがネックとなっていました。というわけで、それをはじいたらきれいに数字が出ました。問題集やらの数値データは落とした瞬間使えるけど、何だか良く分からないデータは何だか良く分からない使い勝手良いのか悪いのかわからない、特色があるということで、加工する前にちゃんと確認しておかないといけないということを思い知らされました。


 ほかにもたくさん躓いたところはありますが、今思い出せるのはこれだけです。別にも、MACで仮想環境を作ろうとしたらanacondaが妙に威張って出てきて、anaconda消したつもりが、フォルダがあって、それで良く分からん状態とかあるけど、まぁ、初学者はいろんなことにつまずきながら、気づけば私もこのようなことができるようになったのかと思えるように、頑張りたい。次は、栗さんを追って、ツイッターボットを作りたい。というか、自分が見たいものを表示させたいだけなのだけれど。グーグル良く分からないよグーグル。