Skip to content

Instantly share code, notes, and snippets.

@darden1
Last active June 20, 2017 15:18
Show Gist options
  • Save darden1/7e700c58cdd8edf1d9137960a609de29 to your computer and use it in GitHub Desktop.
Save darden1/7e700c58cdd8edf1d9137960a609de29 to your computer and use it in GitHub Desktop.
BackTest.py
# -*- coding: utf-8 -*-
import poloniex
import time
import datetime
from sklearn import tree
import matplotlib.pyplot as plt
def main():
# --トレーニング用パラメータ
theNumberOfTrainData=29 #トレーニングデータ数
theNumberOfTrainAndKyoushiSet=30 #トレーニングデータと教師データのセット数
studyTrialTimes = 200 #予測のトライアル数(予測結果がばらつくので1回の予測結果を出すために実施する試行回数(取りあえずこのままにしておいてください。)
# --バックテストパラメータ
plotGraphFlag = 1 # バックテスト結果の資金グラフをプロットしますか?yes:1。no:0
initialFund = 1000 # 初期資金
spread = 0 #取引スプレット(手数料)
backTestDays = 30*2 # バックテスト期間(日)
dateBTC, dataBTC = getDataPoloniex()
dateBTC.reverse()
dataBTC.reverse()
data = changeData(dataBTC)
print('-----------------------------------------')
print('バックテストの実施')
print('-----------------------------------------')
print('※過去のデータから資金上昇率を算出します。上昇シグナル時に現物で買い。下降シグナル時は何もしません。ポジションは1日ごとに決裁します。')
seitouritsuUp, seitouritsuDown, increasedFundRatio, increasedBTCPriceRatio, simOutputStr = backTest(data, dateBTC, dataBTC, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes, initialFund, spread, backTestDays, plotGraphFlag)
print(simOutputStr)
def backTest(data, dateBTC, dataBTC, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes, initialFund, spread, backTestDays, plotGraphFlag):
realValue = []
predictionValue = []
fund = [initialFund]
pastDay = 0
seitouUp = 0
seitouDown = 0
for trainStartDay in range(backTestDays, 0, -1):
y_Prediction, y = predictionTommorowBTCForBackTest(data, trainStartDay, theNumberOfTrainData, theNumberOfTrainAndKyoushiSet, studyTrialTimes)
realValue.append(y)
predictionValue.append(y_Prediction)
pastDay += 1
if y_Prediction == y:
if y_Prediction == 1:
seitouUp += 1
fund.append(fund[pastDay - 1] * (1 + abs(data[trainStartDay - 1]) - spread))
else:
seitouDown += 1
#---fund.append(fund[pastDay - 1] * (1 + abs(data[trainStartDay - 1]) - spread))
fund.append(fund[pastDay - 1])
else:
if y_Prediction == 1:
fund.append(fund[pastDay - 1] * (1 - abs(data[trainStartDay - 1]) - spread))
else:
#---fund.append(fund[pastDay - 1] * (1 - abs(data[trainStartDay - 1]) - spread))
fund.append(fund[pastDay - 1])
# ----バックテスト結果出力
outputStr = '・トレーニングデータ数: ' + str(theNumberOfTrainData) +'\n'
outputStr += '・トレーニングデータと教師データのセット数: ' + str(theNumberOfTrainAndKyoushiSet)+'\n'
outputStr += '・バックテスト期間: 過去' + str(backTestDays) + '日\n'
seitouritsuUp = float(seitouUp) / sum(predictionValue)
seitouritsuDown = float(seitouDown) / (backTestDays - sum(predictionValue))
outputStr += '・正答率(上昇時): ' + str(round(seitouritsuUp * 100,1)) + '%' + '\n'
outputStr += '・正答率(下降時): ' + str(round(seitouritsuDown * 100,1)) + '%' + '\n'
trainStartDay=0
dataBTCOnBackTest = dataBTC[trainStartDay:trainStartDay+backTestDays+1]
dataBTCOnBackTest.reverse()
increasedFundRatio=(fund[-1]-fund[0])/fund[0]
increasedBTCPriceRatio=(dataBTCOnBackTest[-1]-dataBTCOnBackTest[0])/dataBTCOnBackTest[0]
outputStr += '・資金上昇率: ' + str(round(increasedFundRatio*100,1)) + '% (初期資金は$' +str(fund[0])+'。最終資金は$' +str(fund[-1])+'。)' + '\n'
outputStr += '・BTC価格上昇率: ' + str(round(increasedBTCPriceRatio*100,1)) + '% (初期BTC価格は$' +str(dataBTCOnBackTest[0])+'。最終BTC価格は$' +str(dataBTCOnBackTest[-1])+'。)' + '\n'
# ----資金推移グラフ
if(plotGraphFlag):
# ----Plot Fund
dateBTCOnBackTest = dateBTC[trainStartDay:trainStartDay + backTestDays + 1]
dateBTCOnBackTest.reverse()
fig1, ax1 = plt.subplots(figsize=(11, 6))
p1, = ax1.plot(dateBTCOnBackTest, fund, '-ob')
ax1.set_title("Simulation with past data")
ax1.set_xlabel("Day")
ax1.set_ylabel("Fund[$]")
plt.grid(fig1)
# ----Plot BTC Price
ax2 = ax1.twinx()
p2, = ax2.plot(dateBTCOnBackTest, dataBTCOnBackTest, '-or')
ax2.set_ylabel('BTC price[$]')
ax1.legend([p1, p2], ["Fund", "BTC price"], loc="upper left")
plt.show(fig1)
return seitouritsuUp, seitouritsuDown, increasedFundRatio, increasedBTCPriceRatio, outputStr
def getDataPoloniex():
polo = poloniex.Poloniex()
polo.timeout = 2
chartUSDT_BTC = polo.returnChartData('USDT_BTC', period=polo.DAY, start=time.time() - polo.DAY * 500, end=time.time())
tmpDate = [chartUSDT_BTC[i]['date'] for i in range(len(chartUSDT_BTC))]
date = [datetime.datetime.fromtimestamp(tmpDate[i]).date() for i in range(len(tmpDate))]
data = [float(chartUSDT_BTC[i]['open']) for i in range(len(chartUSDT_BTC))]
return date ,data
def changeData(data):
newData=[]
for i in range(0, len(data) - 1):
newData.append(float(data[i] - data[i + 1]) / data[i + 1])
newData.append(0)
return newData
def preparationTrainAndKyoushiSets(data,trainStartDay,theNumberOfTrainData,theNumberOfTrainAndKyoushiSet):
train_X = []
train_y = []
for i in range(0,theNumberOfTrainAndKyoushiSet):
train_X.append(data[trainStartDay+1+i:trainStartDay+theNumberOfTrainData+1+i])
train_y.append([int(0 < data[trainStartDay+i])])
return train_X, train_y
def predictionTommorowBTCForBackTest(data, trainStartDay, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes):
train_X, train_y = preparationTrainAndKyoushiSets(data, trainStartDay, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet)
X=data[trainStartDay:trainStartDay+theNumberOfTrainData]
y = int(0 < data[trainStartDay-1])
y_PredictionTommorow=[]
for i in range(0, theNumberOfTrainAndKyoushiSet):
clf = tree.DecisionTreeClassifier()
clf.fit(train_X, train_y)
y_PredictionTommorow.append(clf.predict([X])[0])
upOrDownRatio = sum(y_PredictionTommorow) * 1.0 / len(y_PredictionTommorow)
return int(upOrDownRatio>0.5),y
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment