ビットコイン価格予測プログラムを作ってみる

↓の記事を参考にして、

「線形回帰」を利用したビットコインFX予測プログラムを実行してみた。

過去25日の終値を使って、ビットコインの翌日の終値を予想する。

↓学習データのビットコイン価格は下記サイトからダウンロードできます。

結果は

正答率49%で全然うまくいかなかった。線形回帰だけで予想するのは難しいようです。

予測日数:1147、正答日数:567、正答率:49.43330427201395
利益合計:2753198.000

↓横軸が予想値動き、縦軸が実際の値動き

画像1

↓横軸が日数、縦軸が損益

画像2

↓使ったプログラム(Python)

import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
# http://nipper.work/btc/index.php?market=bitFlyer&coin=BTCJPY&periods=86400&after=1420070400
data_dir = "./"
data = pd.read_csv(data_dir + "btc.csv") # FXデータの読み込み(データは同じリポジトリのdataフォルダに入っています)
data.head() # データの概要を見てみます
data2 = np.array(data)
# 説明変数となる行列Xを作成します
day_ago = 25 # 何日前までのデータを使用するのかを設定
num_sihyou = 1 # 終値
X = np.zeros((len(data2), day_ago*num_sihyou)) 
# 終値をfor文でday_ago日前まで一気に追加する
for i in range(0, day_ago):
   X[i:len(data2),i] = data2[0:len(data2)-i,4]
   
# 被説明変数となる Y = pre_day後の終値-当日終値 を作成します
Y = np.zeros(len(data2))
# 何日後の値段の差を予測するのか決めます
pre_day = 1
Y[0:len(Y)-pre_day] = X[pre_day:len(X),0] - X[0:len(X)-pre_day,0]
# 【重要】X, Yを正規化します
original_X = np.copy(X) # コピーするときは、そのままイコールではダメ
tmp_mean = np.zeros(len(X))
for i in range(day_ago,len(X)):
   tmp_mean[i] = np.mean(original_X[i-day_ago+1:i+1,0]) # 25日分の平均値
   for j in range(0, X.shape[1]): 
       X[i,j] = (X[i,j] - tmp_mean[i]) # Xを正規化
   Y[i] =  Y[i]  # X同士の引き算しているので、Yはそのまま
# XとYを学習データとテストデータに半分に分ける
X_train = X[25:int(len(data2)/2),:] 
Y_train = Y[25:int(len(data2)/2)] 
X_test = X[int(len(data2)/2):len(X)-pre_day,:] 
Y_test = Y[int(len(data2)/2):len(Y)-pre_day]
# 学習データを使用して、線形回帰モデルを作成します
from sklearn import linear_model # scikit-learnライブラリの関数を使用します
linear_reg_model = linear_model.LinearRegression()
linear_reg_model.fit(X_train, Y_train) # モデルに対して、学習データをフィットさせ係数を学習させます
print("回帰式モデルの係数")
print(linear_reg_model.intercept_) 
print(linear_reg_model.coef_)
# 前半のデータで予想し、グラフで予測具合を見る
Y_pred = linear_reg_model.predict(X_test) # 予測する
result = pd.DataFrame(Y_pred) # 予測
result.columns = ['Y_pred']
result['Y_test'] = Y_test
sns.set_style('darkgrid') 
sns.regplot(x='Y_pred', y='Y_test', data=result) #plotする
plt.show()
# 正答率を計算
success_num = 0
for i in range(len(Y_pred)):
   if Y_pred[i] * Y_test[i] >=0:
       success_num+=1
print("予測日数:"+ str(len(Y_pred))+"、正答日数:"+str(success_num)+"、正答率:"+str(success_num/len(Y_pred)*100))
# 予測結果の合計を計算ーーーーーーーーー
# 前々日終値に比べて前日終値が高い場合は、買いとする
sum_2017 = 0
for i in range(0,len(Y_test)): # len()で要素数を取得しています
   if Y_pred[i] >= 0:
       sum_2017 += Y_test[i]
   else:
       sum_2017 -= Y_test[i]
print("利益合計:%1.3lf" %sum_2017) 

# 予測結果の総和グラフを描くーーーーーーーーー
total_return = np.zeros(len(Y_test))
if Y_pred[i] >=0: # 初日を格納
   total_return[0] = Y_test[i]
else:
   total_return[0] = -Y_test[i]
for i in range(1, len(result)): 
   if Y_pred[i] >=0:
       total_return[i] = total_return[i-1] + Y_test[i]
   else:
       total_return[i] = total_return[i-1] - Y_test[i]
print(total_return)
plt.plot(total_return)
plt.show()


↓学習データ(2015-06-26から2021-10-08)



この記事が気に入ったらサポートをしてみませんか?