hatunina’s blog

メモと日記です

kaggleの「Bitcoin Historical Data」のカーネルを読むその3

これ

Predicting BTC Price Using RNN | Kaggle

概要

LSTMで日足を学習・予測させています。
ライブラリはkerasです。
Qiitaとかでもよく見るやつ

タメになったやつ

コードこれだけで学習できちゃうんすね。。。

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM

regressor = Sequential()
regressor.add(LSTM(units = 4, activation = 'sigmoid', input_shape = (None, 1)))
regressor.add(Dense(units = 1))
regressor.compile(optimizer = 'adam', loss = 'mean_squared_error')
regressor.fit(X_train, y_train, batch_size = 5, epochs = 100)


予測もそれっぽくは出てるけども、去年10月以降の急騰には対応できず。
まあアルゴリズムよく知らんからなんとも言えず。
この辺は本読みながらコツコツやって行きます。

kaggleの「Bitcoin Historical Data」のカーネルを読むその2

今日はこちら

Bitcoin Price. Prediction by ARIMA | Kaggle

概要

自己回帰和分移動平均モデル(ARIMAモデル)とやら。

うーむ、事前知識なさすぎて、ちょっと専門的になるとわからん
時系列データ分析に関する本も並行して読まねば

statsmodelsというライブラリを用いてトレンド、季節性、ノイズに分けたり自己相関係数とかを出してなんかしてます。
うん、なんかしてる(わからない)

詳しくはこちら
logics-of-blue.com

タメになったやつ

理論部分は全くわからなかったのでpandasのtipsです。

こんな感じのデータフレームがあります。

f:id:hatunina:20180417233144p:plain

このコードを実行すると、、、

df_day = df.resample('D').mean()
df_day.head()


こうなる!

f:id:hatunina:20180417235011p:plain


何が起きたかと言うと1日ごとにデータが調節されました。
resampleという関数を用いることで時系列データの感覚を調節することができます。
引数にDを与えているのでこの場合は1日ごとになっています。
時間の区切りだけでなく月末月初や年末年始も調節できます。
meanmaxとかと繋げられるので便利かも

詳しくはこちら

docs.pyq.jp

kaggleの「Bitcoin Historical Data」のカーネルを読むその1

カーネルを上から順番に読んだものをまとめていきます。
その1としましたが、続くかはわかりません。

概要

Bitcoin Historical Data | Kaggle
コンペとして開かれているわけでなく、学生さんがデータセットを公開していて、みんなテキトーに遊んでねって感じっぽいです。

公開されているデータは下記の通り。

bitflyerJPY_1-min_data_2017-07-04_to_2018-03-27.csv
bitstampUSD_1-min_data_2012-01-01_to_2018-03-27.csv
coinbaseUSD_1-min_data_2014-12-01_to_2018-03-27.csv
coincheckJPY_1-min_data_2014-10-31_to_2018-03-27.csv


それぞれ、タイムスタンプとHLOC、ボリュームが含まれています。

読んだやつ

これです。

Bitcoin Trading Strategy Simulation | Kaggle
bitstampUSDを使って「Turtle Trading」という手法を試しています。

前半はデータの穴埋めが中心です。
2012年と古めのデータなので取引がない日もあるのかな?
ボリュームは0にして、価格は前日の各データで穴埋めしたりしてます。

下記コードはリンク元から拝借

# First thing is to fix the data for bars/candles where there are no trades. 
# Volume/trades are a single event so fill na's with zeroes for relevant fields...
data['Volume_(BTC)'].fillna(value=0, inplace=True)
data['Volume_(Currency)'].fillna(value=0, inplace=True)
data['Weighted_Price'].fillna(value=0, inplace=True)

# next we need to fix the OHLC (open high low close) data which is a continuous timeseries so
# lets fill forwards those values...
data['Open'].fillna(method='ffill', inplace=True)
data['High'].fillna(method='ffill', inplace=True)
data['Low'].fillna(method='ffill', inplace=True)
data['Close'].fillna(method='ffill', inplace=True)


fillnamethod='ffillとすることで、一つ前のデータで埋めることができます。

で、手法自体は「Turtle Trading」とやらを使っています。
あんまりトレーディング手法は詳しくないのですが、いわゆるチャネルブレイクアウトなのかな?
詳しくはこちら

www.investopedia.com
trend is your friendとのことで、めっちゃ雑に言うとトレンドに従って売買するぜ!って手法っぽいです。
(ごめんなさい、あんまり調べてないです)

まあ、そんな感じで高値と安値が更新されたタイミングでポジションをとるらしいのですが、そこでrollingという関数を使っています。

signal_lookback = 60 * 24 * 60 # days * hours * minutes

# here's our signal columns
data['Buy'] = np.zeros(len(data))
data['Sell'] = np.zeros(len(data))

# this is our 'working out', you could collapse these into the .loc call later on and save memory 
# but I've left them in for debug purposes, makes it easier to see what is going on
data['RollingMax'] = data['Close'].shift(1).rolling(signal_lookback, min_periods=signal_lookback).max()
data['RollingMin'] = data['Close'].shift(1).rolling(signal_lookback, min_periods=signal_lookback).min()
data.loc[data['RollingMax'] < data['Close'], 'Buy'] = 1
data.loc[data['RollingMin'] > data['Close'], 'Sell'] = -1


rolling移動平均を計算することができるとのこと。
ここで第1引数に渡しているsignal_lookback60 * 24 * 60なので60日分の1分足を指します。
第2引数は計算開始時点です。
なので、60日分の1分足の高値を計算しそれを更新したら買う、安値を更新したら売る、といったアルゴリズムです。

カーネルの最後ではテスト結果が描画されており、とりあえずはうまくいっていそう。。。

まあ、rollingなんてあるんだ〜勉強になりました〜って感じです。

「ベイズ推定入門」を読みました

読みました。

shop.ohmsha.co.jp

完全に息抜きです。
余裕のあるうちにちょっとでも語彙力を増やす。

以下目次です。

第1章 こんなところにベイズ推定
第2章 確率分布とベイズ推定
第3章 機械学習ベイズ推定
第4章 不可能を可能にするベイズ推定
第5章 カーネル法ベイズ的最適化
第6章 無限の可能性を考えるベイズ推定
その後の兵士さん(参考文献)
あとがき
索  引

ベイズ推定入門 モデル選択からベイズ的最適化まで | 理工学専門書,情報科学,情報科学一般・情報社会 | Ohmsha

ベイズに関しては大学の時にちょろっと聞いて、なんやこれめっちゃ便利やんって思った記憶があります。
あとは、「はじパタ」の第3章で出会った以来の再会です。

「はじパタ」ではクラス条件付き確率は密度関数とか言われた時点で思考停止しました。

この本の場合、「ベイズ推定は点推定ではなく分布推定」という話をしてくれます。
分布の形を見て推定するので強力とのことです。
詳しい部分は全く理解できていませんが、今後、別の本を読む時にイメージできていればいいかな、と。

あと、ちょっと副産物なんですが4章でL1ノルムとL2ノルムの話が出てきます。
今までは、正則化でオーバーフィッティングを防ぐよ〜、正則化パラメータに応じて重みパラメータが変わるよ〜程度の認識でしたが、ちゃんと図を書いてくれているのでL1ノルムとL2ノルムの使い分けが理解できます。

ついでに、TJOさんのブログを読むとさらによくわかる

tjo.hatenablog.com

L2ノルムは円形ですがL1ノルムは正方形(ひし形?)なので誤差項とぶつかる箇所はどこかの軸が0になり不要なパラメータを削ることができるということですね(スパースな解が出てくる)。


この辺もちゃんと勉強しなきゃな〜

bitflyerから日付を指定して約定履歴を取得するスクリプトを改良しました

これの続きです。

hatunina.hatenablog.com

追加したところ

・データ取得開始日だけでなく取得終了日(時間)まで指定できるようになりました。
・取得したデータを1分足、1時間足、日足のHLOC(高値、安値、始値終値) + 出来高に変換できるようになりました。
・変換したHLOC + 出来高を描画できるようになりました。

使い方

必要ライブラリは変わらずです。

pip install pandas
pip install progressbar2

gitからクローン後、プロジェクト直下にdata, log, hlocディレクトリを作成します。
で、各々のモジュールを実行するとデータ取得したり変換したり描画したりします。

getbtc.py

データ取得開始と取得終了日を指定してデータを保存します。

こんな感じで実行します。

python src/getbtc.py -s 2018-01-01-00:00:00 -f 2018-04-11-23:14:00

この場合は上記の期間でデータを取得します。

-fオプションは省略できます。

python src/getbtc.py -s 2018-01-01-00:00:00

省略された場合は取得開始日からモジュール実行時の時刻までを取得します。

generatehloc.py

getbtc.pyで取得したデータをHLOCと出来高に変換します。
変換結果はhlocディレクトリへ出力されます。

コマンドはこんな感じ

python src/generatehloc.py -d ./data -t one_minute

-dオプションで変換するデータがあるパスを指定します。
getbtc.pyを実行した流れで-d ./dataとすると、取得した全データを変換するので、小分けにしたいとかいう場合は別ディレクトリへファイルを移動して引数を変えるとかしてください。
データ取得に比べるとそんなに時間はかかりません。
一つのファイルを変換するのに、たぶん30秒ぐらいだと思います。

-tオプションで変換する足を指定します。
1分足、1時間足、日足しかないですごめんなさい。
各足の指定方法は下記の通りです。

1分足 -> one_minute
1時間足 -> one_hour
日足 -> one_day

plotchart.py

引数で指定されたファイルを描画します。

python ./src/plotchart.py -f ./hloc/hloc_one_day_2018-01-01-00:00:00_2018-04-09-00:00:00.csv

-fオプションでファイルを指定します。
変換したデータがの雰囲気が知りたい時とかに使ってあげてください。

こんな感じで描画されます。

f:id:hatunina:20180415221401p:plain

詳しくはREADMEを読んでください

ついでにスター押してもらえると喜びます。

github.com

ちゃんと作り込んでない箇所

HLOCへの変換が1分足、1時間足、日足までしか対応していません。
個人的に1時間足と日足があれば事足りそうなので、簡単に作れるとこまでしかやっていません。
一手間加えれば多分作れると思うのでどなたかにお任せします。

ただ、そもそもbitflyerの日足って0時ジャストで更新なんですか?
とりあえず0時で区切ってますが正しいのかな。。。
朝9時とか8時とかだった気がしなくもない、、、

あと、描画モジュールがテキトーです。
チャートの雰囲気が見れればいいやぐらいの軽い気持ちで作ってあるので厳密なものはあまり期待しないでください。

分析します

これでデータが準備できたので、何かしら分析にかけてみようかと思います。
というより、kaggleで議論されているのを発見したので、とりあえずここのカーネルを眺めようかな。
なんなら、データセットも公開されてるやんけ。。。

Bitcoin Historical Data | Kaggle

参考

HLOC変換と描画に関して参考にさせていただきました。
www.madopro.net