LoginSignup
30
26

More than 5 years have passed since last update.

Pythonで仮想通貨を解析してみた。

Last updated at Posted at 2018-07-08

0. はじめに

2017年頃から一気に流行り始めて、一時bitcoinが2万ドルを付けました。2018年は6~7000ドル程度まで下がり始めているとはいえ、まだまだ根強い人気がありますね。様々な人が統計・機械学習手法を用いて解析をしていると思うけれど、私もWSL(Windows Subsystem for Linux)でちょっとやってみた。

参考サイト(引用)は下記です。

Analyzing Cryptocurrency Markets Using Python:
https://blog.patricktriest.com/analyzing-cryptocurrencies-python/

1. 仮想環境構築

1.1 Anacondaとは

Anacondaはデータサイエンスのプラットフォームで最も有名。Python単独だと、必要なパッケージをインストールしなければならないが、Anacondaだと機械学習や可視化等のパッケージは標準インストールできる。

Anacondaのインストール- https://www.continuum.io/download

$ wget https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.sh
$ chmod u+x Anaconda3-5.2.0-Linux-x86_64.sh
$ ./Anaconda3-5.2.0-Linux-x86_64.sh

上記コマンドでインストール用のスクリプトを取得して実行できる。

1.2 構築

はじめに仮想環境を構築する。作成はconda createで行う。デフォルトでは、condaディレクトリのenvs下に作成される。仮想環境を作り、アクティベートする。

conda create --name cryptocurrency-analysis python=3.6
source activate cryptocurrency-analysis

有効を解除するには、Linux/Macではsource deactivateにてできる。詳しくは、ユーザーガイド参照

次に、環境に必要なパッケージをインストールする。

conda install numpy pandas nb_conda jupyter plotly quandl

numpyは科学技術における数値処理操作に特化したパッケージ。pandasはデータ処理や解析に、nb_condaはanaconda上ではjupyter notebookを動かすために必要。jupyterは解析結果をブラウザ上で表示するためのノートブックとして使用する。plotlyは可視化用。matplotlibでもよいが、時系列データの可視化はploylyやdygraphsの方がキレイだし、なによりplotlyはHTML, CSS, JS取得できる。qundlは金融・経済などの数値データの検索できるAPI。これでデータを取得する。

仮想環境は、ソフトウェアのライブラリやパッケージの依存関係解いったコンフリクトを避けることができるのメリット。

仮想環境の確認は次のコマンド。

$ conda info -e
# conda environments:
#
base                  *  /home/user/anaconda3
cryptocurrency-analysis     /home/user/anaconda3/envs/cryptocurrency-analysis

1.3 Jupyter Notebook

Pythonによる実行結果をブラウザ上で表示できる。起動するためには、jupter notebookとするとlocalhost上でブラウザから起動できる。


import os
import numpy as np
import pandas as pd
import pickle
import quandl
from datetime import datetime

次に、オフラインモードでPlotlyをインポートする。

import plotly.offline as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
py.init_notebook_mode(connected=True)

2. Bitcoin価格の取得

データはQuandlのBitcoin APIから取得する。

2.1 データを得るためのHelp関数定義

def get_quandl_data(quandl_id):
    ''' Quandlの時系列データのキャッシュを取得'''
    cache_path = '{}.pkl'.format(quandl_id).replace('/','-')
    try:
        f = open(cache_path, 'rb')
        df = pickle.load(f)   
        print('Loaded {} from cache'.format(quandl_id))
    except (OSError, IOError) as e:
        print('Downloading {} from Quandl'.format(quandl_id))
        df = quandl.get(quandl_id, returns="pandas")
        df.to_pickle(cache_path)
        print('Cached {} at {}'.format(quandl_id, cache_path))
    return df

APIから得られたデータをpickleでシリアライズし、ファイルとしてデータを保存する。スクリプトを実行させるたびに同じデータを再ダウンロードするのを防げる。Pandasをデータフレームとしてデータを返す。

下記のpickleの記事がわかりやすい。https://www.lifewithpython.com/2013/05/pickle.html

2.2 Kraken為替レートの取得。

krakenからビットコインのレートを取得することできる。実際に、'BCHARTS/KARKENUSD'としてデータをシリアライズする。

btc_usd_price_kraken = get_quandl_data('BCHARTS/KRAKENUSD')

#Downloading BCHARTS/KRAKENUSD from Quandl
#Cached BCHARTS/KRAKENUSD at BCHARTS-KRAKENUSD.pkl

Pandasのデータフレームなので、head()を実行すると

In [1] : btc_use_price_kraken.head()
Out[1] :
               Open     High        Low        Close       Volume (BTC) Volume (Currency)   Weighted Price
Date                            
2014-01-07  874.67040   892.06753   810.00000   810.00000   15.622378   13151.472844    841.835522
2014-01-08  810.00000   899.84281   788.00000   824.98287   19.182756   16097.329584    839.156269
2014-01-09  825.56345   870.00000   807.42084   841.86934    8.158335    6784.249982    831.572913
2014-01-10  839.99000   857.34056   817.00000   857.33056    8.024510    6780.220188    844.938794
2014-01-11  858.20000   918.05471   857.16554   899.84105   18.748285   16698.566929    890.671709

データフレームとして時刻、始値、高値、安値、終値、ボリュームなど得られている。この時系列データをプロットしよう。まずは単純にx軸にはindex (Date), y軸にはWeighted Price値を指定する。

# Chart the BTC pricing data
btc_trace = go.Scatter(x=btc_usd_price_kraken.index, y=btc_usd_price_kraken['Weighted Price'])
py.iplot([btc_trace])

BTC_USDplot.png

2017年付近から2018年7月までのチャート。2017年の時に買って、年末売っていれば億り人でしたね・・・

2.3 他の交換所のビットコインレートを取得する

上記の画像では表示させていないが、Krakenのビットコインはスパイクデータが多数あるため、他の交換所のデータもプルする。取得したデータをデータフレームのカラムに追加して、それらの平均をとっておく。

# 他の交換所のレートを取得する
exchanges = ['COINBASE', 'BITSTAMP', 'ITBIT']
exchange_data = {}
exchange_data['KRAKEN'] = btc_usd_price_kraken

for exchange in exchanges:
    exchange_code = 'BCHARTS/{}USD'.format(exchange)
    btc_exchange_df = get_quandl_data(exchange_code)
    exchange_data[exchange]=btc_exchange_df

def merge_dfs_on_column(dataframes, labels, col):
    '''データフレームへ新しいカラムを追加する'''
    series_dict = {}
    for index in range(len(dataframes)):
        series_dict[labels[index]] = dataframes[index][col]

    return pd.DataFrame(series_dict)

btc_usd_datasets = merge_dfs_on_column(list(exchange_data.values()), list(exchange_data.keys()), 'Weighted Price')

# 各交換所のビットコインレートの平均をとる。
btc_usd_datasets['avg_btc_price_usd']=btc_usd_datasets.mean(axis=1)

3. アルトコインの価格データを取得する

3.1 Poloniex API

仮想通過のデータを取ってくるために、Poloniex APIを使用する。アルトコインデータを取得のために、このAPIからJSONデータをダウンロードしキャッシュする関数を定義する。初めにURLからJSONデータを得るget_json_dataを定義する。

def get_json_data(json_url, cache_path):
    '''Download and cache JSON data, return as a dataframe.'''
    try:        
        f = open(cache_path, 'rb')
        df = pickle.load(f)   
        print('Loaded {} from cache'.format(json_url))
    except (OSError, IOError) as e:
        print('Downloading {}'.format(json_url))
        df = pd.read_json(json_url)
        df.to_pickle(cache_path)
        print('Cached {} at {}'.format(json_url, cache_path))
    return df

次に、Poloniex API HTTP requestsを生成する関数を定義し、続いて、get_json_data関数を呼び出す。

base_polo_url = 'https://poloniex.com/public?command=returnChartData&currencyPair={}&start={}&end={}&period={}'
start_date = datetime.strptime('2015-01-01', '%Y-%m-%d') # get data from the start of 2015
end_date = datetime.now() # up until today
pediod = 86400 # pull daily data (86,400 seconds per day)

def get_crypto_data(poloniex_pair):
    '''Retrieve cryptocurrency data from poloniex'''
    json_url = base_polo_url.format(poloniex_pair, start_date.timestamp(), end_date.timestamp(), pediod)
    data_df = get_json_data(json_url, poloniex_pair)
    data_df = data_df.set_index('date')
    return data_df

3.2 Poloniexから取引データをダウンロードする

ほとんどのアルトコインはドルで直接購入できない。これらのコインを購入するためにはビットコイン建ての必要がある。そのため、それぞれのコインの価格はBTCを用いてUSDへと変換する。

altcoins = ['ETH','LTC','XRP','ETC','STR','DASH','SC','XMR','XEM']

def get_altcoin():
    altcoin_data = {}
    for altcoin in altcoins:
        coinpair = 'BTC_{}'.format(altcoin)
        crypto_price_df = get_crypto_data(coinpair)
        altcoin_data[altcoin] = crypto_price_df
    return(altcoin_data)

3.3 Convert Prices to USD

BTC/ALTの為替レートが得られたので、USD/BTCレートからそれぞれのアルトコインの価格が計算できる。

\text{ALT/USD = ALT/BTC * BTC/USD}
# それぞれのアルトコインのデータフレームへ新しいカラムとしてUSDの価格を計算する
for altcoin in altcoin_data.keys():
    altcoin_data[altcoin]['price_usd'] =  altcoin_data[altcoin]['weightedAverage'] * btc_usd_datasets['avg_btc_price_usd']

# 単一のデータフレームへ統合する。
combined_df = merge_dfs_on_column(list(altcoin_data.values()), list(altcoin_data.keys()), 'price_usd')

# データフレームへBTC価格を追加
combined_df['BTC'] = btc_usd_datasets['avg_btc_price_usd']

3.4 各通貨の相関解析

ピアソンの相関係数を計算してみる。

combined_df_2018 = combined_df[combined_df.index.year == 2018]
combined_df_2018.pct_change().corr(method='pearson')

corr.PNG

2018年度の相関係数を見ると、ほとんど全ての通貨に相関がある。これはヘッジファンドの影響だとか。

3.5 散布図

散布図を見てみると次のようなる。

altcoins = ['ETH','LTC','XRP','ETC','STR','DASH','SC','XMR','XEM', 'BTC']

traced = go.Splom(dimensions=[dict(label=altcoin, values=combined_df_2018[altcoin]) for altcoin in altcoins],
                  marker=dict(#color=color_vals,
                              size=5,
                              #colorscale=pl_colorscaled,
                              line=dict(width=0.5,
                                        color='rgb(230,230,230)') ),
                  #text=textd,
                  diagonal=dict(visible=True))
fig = dict(data=[traced]) #, layout=layout)
py.iplot(fig, filename='large')

scatter.PNG

上記のように相関係数はほとんどが0.7以上なので、散布図を見ても相関関係があるのが一目でわかる。

4. Your Turn

他の方も試してみてくださいとのこと。アイデアは下記の通り。

  • より仮想通貨を追加して解析してみる。

  • トレンドの時間軸、粒度を変更して相関解析をしてみる。

  • 取引量やブロックチェーンマイニングデータセットのトレンドを検索してみる。売/買量の比率は生データよりも将来の変動を予測したいなら関係性がある可能性が高い。

  • 株やコモディティなどのデータを追加して、それらと仮想通貨の関係性をみてみる。

  • Event Registry, GDELTやGoogle Trendsを利用して、特定の仮想通貨まわりのバズを量的化してみる。

  • 機械学習モデルを利用して明日の価格を予測してみる。もし、より野心があるなら、再帰的ニューラルネットワーク(RNN)を試してみる。

  • 例えばPoloniex or CoinbaseのAPIを使って自動化された取引Botを作るために解析を利用してみる。ただし、貧弱に最適化されたbotはお金を直ぐに減らすだけ。

  • 発見を共有しよう! ビットコインのベストの部分は、仮想通貨一般として、脱中央主義の特性から他のアセットよりもより自由。解析をオープンソースにして、コミュニティに参加して、ブログに投稿しよう

所感

時系列データの場合は、自己相関をみて自己回帰,移動平均などで解析をしますがどうなんでしょうか。引用元にも記述されていますがRNN, LSTMも試してみたいですね。

時系列解析ですが、prophetを使って解析してみました。ぜひご覧になってください。
ProphetとRで仮想通貨を時系列解析してみた

参考

Analyzing Cryptocurrency Markets Using Python:
https://blog.patricktriest.com/analyzing-cryptocurrencies-python/

30
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
26