· 9 years ago · Dec 07, 2016, 11:28 AM
1# -*- coding: utf-8 -*-
2import poloniex
3import time
4import datetime
5import numpy as np
6from sklearn import tree
7import matplotlib.pyplot as plt
8
9import smtplib
10from email.Utils import formatdate
11from email.MIMEMultipart import MIMEMultipart
12from email.MIMEText import MIMEText
13
14
15def main():
16 # --トレーニング用パラメータ
17 theNumberOfTrainData=29 #トレーニングデータ数
18 theNumberOfTrainAndKyoushiSet=26 #ãƒˆãƒ¬ãƒ¼ãƒ‹ãƒ³ã‚°ãƒ‡ãƒ¼ã‚¿ã¨æ•™å¸«ãƒ‡ãƒ¼ã‚¿ã®ã‚»ãƒƒãƒˆæ•°
19 studyTrialTimes = 200 #予測ã®ãƒˆãƒ©ã‚¤ã‚¢ãƒ«æ•°(äºˆæ¸¬çµæžœãŒã°ã‚‰ã¤ãã®ã§1回ã®äºˆæ¸¬çµæžœã‚’出ã™ãŸã‚ã«å®Ÿæ–½ã™ã‚‹è©¦è¡Œå›žæ•°(å–りã‚ãˆãšã“ã®ã¾ã¾ã«ã—ã¦ãŠã„ã¦ãã ã•ã„。)
20
21 # --ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆãƒ‘ラメータ
22 plotGraphFlag = 0 # ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆçµæžœã®è³‡é‡‘グラフをプãƒãƒƒãƒˆã—ã¾ã™ã‹ï¼Ÿyes:1。no:0 (スケジューラã§è‡ªå‹•実行ã•ã›ã‚‹æ™‚ã¯0ã«ã—ã¦ãã ã•ã„。)
23 initialFund = 1000 # åˆæœŸè³‡é‡‘
24 spread = 0 #å–引スプレット(手数料)
25 backTestDays = 30*2 # ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆæœŸé–“(æ—¥)
26
27 #--メールé€ä¿¡ãƒ‘ラメータ
28 sendMailFlag= 1 #明日ã®BTCä¾¡æ ¼ã®äºˆæƒ³çµæžœã‚’メールé€ä¿¡ã—ã¾ã™ã‹ï¼Ÿ yes:1。no:0
29 yourGmailAddress = "***********@gmail.com" #---é€ä¿¡æ™‚ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹(自分ã®Gメールアドレス。自分自身ã«é€ä¿¡ã—ã¾ã™ã€‚)
30 yourGmailAddressPassword = "***********" #---Gメールã®ãƒã‚°ã‚¤ãƒ³ãƒ‘スワード
31
32 outputStr = '-----------------------------------------\n'
33 outputStr += 'BTCä¾¡æ ¼ãƒ‡ãƒ¼ã‚¿ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰\n'
34 outputStr += '-----------------------------------------\n'
35 dateBTC, dataBTC = getDataPoloniex()
36 dateBTC.reverse()
37 dataBTC.reverse()
38 todayStr = str(datetime.datetime.today())[0:10]
39 outputStr += '今日ã¯' + todayStr + 'ã§ã™ã€‚Poloniexã‹ã‚‰BTCä¾¡æ ¼ãƒ‡ãƒ¼ã‚¿ã‚’ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰ã—ã¾ã™ã€‚\n'
40 outputStr += 'å–得データファイルä¸ã«ã‚ã‚‹æœ€æ–°ã®æ—¥ä»˜ã¯' + str(dateBTC[0])[0:10] + 'ã§ãã®æ™‚ã®BTCã‚ªãƒ¼ãƒ—ãƒ³ä¾¡æ ¼ã¯$' + str(dataBTC[0]) + 'ã§ã™ã€‚\n'
41
42 data = changeData(dataBTC)
43
44 outputStr += '-----------------------------------------\n'
45 outputStr += 'ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆã®å®Ÿæ–½\n'
46 outputStr += '-----------------------------------------\n'
47 outputStr += '※éŽåŽ»ã®ãƒ‡ãƒ¼ã‚¿ã‹ã‚‰è³‡é‡‘上昇率を算出ã—ã¾ã™ã€‚上昇シグナル時ã«ç¾ç‰©ã§è²·ã„。下é™ã‚·ã‚°ãƒŠãƒ«æ™‚ã¯ä½•ã‚‚ã—ã¾ã›ã‚“。ãƒã‚¸ã‚·ãƒ§ãƒ³ã¯1æ—¥ã”ã¨ã«æ±ºè£ã—ã¾ã™ã€‚\n'
48 seitouritsuUp, seitouritsuDown, increasedFundRatio, increasedBTCPriceRatio, simOutputStr = backTest(data, dateBTC, dataBTC, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes, initialFund, spread, backTestDays, plotGraphFlag)
49 outputStr += simOutputStr
50
51 outputStr += '-----------------------------------------\n'
52 outputStr += '明日ã®BTCä¾¡æ ¼äºˆæƒ³\n'
53 outputStr += '-----------------------------------------\n'
54 outputStr += str(dateBTC[0])[0:10] + 'ã¾ã§ã®BTCã‚ªãƒ¼ãƒ—ãƒ³ä¾¡æ ¼ãƒ‡ãƒ¼ã‚¿ã‹ã‚‰' + str(dateBTC[0] + datetime.timedelta(days=1))[0:10] + 'ã®BTCã‚ªãƒ¼ãƒ—ãƒ³ä¾¡æ ¼ã‚’äºˆæ¸¬ã—ã¾ã™ã€‚\n'
55 outputStr += '・トレーニングデータ数: ' + str(theNumberOfTrainData)+ '\n'
56 outputStr += 'ãƒ»ãƒˆãƒ¬ãƒ¼ãƒ‹ãƒ³ã‚°ãƒ‡ãƒ¼ã‚¿ã¨æ•™å¸«ãƒ‡ãƒ¼ã‚¿ã®ã‚»ãƒƒãƒˆæ•°: ' + str(theNumberOfTrainAndKyoushiSet)+ '\n'
57
58 upOrDownRatio=predictionTommorowBTC(data, theNumberOfTrainData, theNumberOfTrainAndKyoushiSet, studyTrialTimes)
59
60 if upOrDownRatio > 0.5:
61 outputStr += '\n明日ã®BTCä¾¡æ ¼ã¯'+ str(round(upOrDownRatio*100,1)) +'%ã®ç¢ºçއã§ä¸Šæ˜‡ã—ã¾ã™ã€‚\n'
62 else:
63 outputStr += '\n明日ã®BTCä¾¡æ ¼ã¯' + str(round((1-upOrDownRatio) * 100,1)) + '%ã®ç¢ºçއã§ä¸‹è½ã—ã¾ã™ã€‚\n'
64
65 print(outputStr)
66
67 if (sendMailFlag):
68 subject = '明日ã®BTCä¾¡æ ¼äºˆæƒ³'
69 body = outputStr
70 sendMail(subject, body, yourGmailAddress, yourGmailAddressPassword)
71
72
73
74def sendMail(subject,body,yourGmailAddress,yourGmailAddressPassword):
75 #---Parameters
76 SMTP = "smtp.gmail.com"
77 PORT = 587
78 from_addr=yourGmailAddress
79 to_addr = yourGmailAddress
80 #---Create message
81 msg = MIMEMultipart()
82 msg["From"] = from_addr
83 msg["To"] = to_addr
84 msg["Date"] = formatdate()
85 msg["Subject"] = subject
86 body = MIMEText(body)
87 msg.attach(body)
88 #---Send mail
89 smtpobj = smtplib.SMTP(SMTP, PORT)
90 smtpobj.ehlo()
91 smtpobj.starttls()
92 smtpobj.login(yourGmailAddress, yourGmailAddressPassword)
93 smtpobj.sendmail(from_addr, to_addr, msg.as_string())
94 smtpobj.close()
95
96def getDataPoloniex():
97 polo = poloniex.Poloniex()
98 polo.timeout = 2
99 chartUSDT_BTC = polo.returnChartData('USDT_BTC', period=polo.DAY, start=time.time() - polo.DAY * 500, end=time.time())
100 tmpDate = [chartUSDT_BTC[i]['date'] for i in range(len(chartUSDT_BTC))]
101 date = [datetime.datetime.fromtimestamp(tmpDate[i]).date() for i in range(len(tmpDate))]
102 data = [float(chartUSDT_BTC[i]['open']) for i in range(len(chartUSDT_BTC))]
103 return date ,data
104
105def changeData(data):
106 newData=[]
107 for i in range(0, len(data) - 1):
108 newData.append(float(data[i] - data[i + 1]) / data[i + 1])
109 newData.append(0)
110 return newData
111
112def preparationTrainAndKyoushiSets(data,trainStartDay,theNumberOfTrainData,theNumberOfTrainAndKyoushiSet):
113 train_X = []
114 train_y = []
115 for i in range(0,theNumberOfTrainAndKyoushiSet):
116 train_X.append(data[trainStartDay+1+i:trainStartDay+theNumberOfTrainData+1+i])
117 train_y.append([int(0 < data[trainStartDay+i])])
118 return train_X, train_y
119
120def predictionTommorowBTC(data,theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes):
121 trainStartDay=0
122 train_X, train_y = preparationTrainAndKyoushiSets(data,trainStartDay,theNumberOfTrainData,theNumberOfTrainAndKyoushiSet)
123 X=data[trainStartDay:trainStartDay+theNumberOfTrainData]
124 y_PredictionTommorow=[]
125 for i in range(0, studyTrialTimes):
126 clf = tree.DecisionTreeClassifier()
127 clf.fit(train_X, train_y)
128 y_PredictionTommorow.append(clf.predict([X])[0])
129 upOrDownRatio = sum(y_PredictionTommorow) * 1.0 / len(y_PredictionTommorow)
130 return upOrDownRatio
131
132def predictionTommorowBTCForBackTest(data, trainStartDay, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes):
133 train_X, train_y = preparationTrainAndKyoushiSets(data, trainStartDay, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet)
134 X=data[trainStartDay:trainStartDay+theNumberOfTrainData]
135 y = int(0 < data[trainStartDay-1])
136 y_PredictionTommorow=[]
137 for i in range(0, theNumberOfTrainAndKyoushiSet):
138 clf = tree.DecisionTreeClassifier()
139 clf.fit(train_X, train_y)
140 y_PredictionTommorow.append(clf.predict([X])[0])
141 upOrDownRatio = sum(y_PredictionTommorow) * 1.0 / len(y_PredictionTommorow)
142 return int(upOrDownRatio>0.5),y
143
144def backTest(data, dateBTC, dataBTC, theNumberOfTrainData,theNumberOfTrainAndKyoushiSet, studyTrialTimes, initialFund, spread, backTestDays, plotGraphFlag):
145 realValue = []
146 predictionValue = []
147 fund = [initialFund]
148 pastDay = 0
149 seitouUp = 0
150 seitouDown = 0
151 for trainStartDay in range(backTestDays, 0, -1):
152 y_Prediction, y = predictionTommorowBTCForBackTest(data, trainStartDay, theNumberOfTrainData, theNumberOfTrainAndKyoushiSet, studyTrialTimes)
153 realValue.append(y)
154 predictionValue.append(y_Prediction)
155 pastDay += 1
156 if y_Prediction == y:
157 if y_Prediction == 1:
158 seitouUp += 1
159 fund.append(fund[pastDay - 1] * (1 + abs(data[trainStartDay - 1]) - spread))
160 else:
161 seitouDown += 1
162 #---fund.append(fund[pastDay - 1] * (1 + abs(data[trainStartDay - 1]) - spread))
163 fund.append(fund[pastDay - 1])
164 else:
165 if y_Prediction == 1:
166 fund.append(fund[pastDay - 1] * (1 - abs(data[trainStartDay - 1]) - spread))
167 else:
168 #---fund.append(fund[pastDay - 1] * (1 - abs(data[trainStartDay - 1]) - spread))
169 fund.append(fund[pastDay - 1])
170
171 # ----ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆçµæžœå‡ºåŠ›
172 outputStr = '・トレーニングデータ数: ' + str(theNumberOfTrainData) +'\n'
173 outputStr += 'ãƒ»ãƒˆãƒ¬ãƒ¼ãƒ‹ãƒ³ã‚°ãƒ‡ãƒ¼ã‚¿ã¨æ•™å¸«ãƒ‡ãƒ¼ã‚¿ã®ã‚»ãƒƒãƒˆæ•°: ' + str(theNumberOfTrainAndKyoushiSet)+'\n'
174 outputStr += '・ãƒãƒƒã‚¯ãƒ†ã‚¹ãƒˆæœŸé–“: éŽåŽ»' + str(backTestDays) + 'æ—¥\n'
175 seitouritsuUp = float(seitouUp) / sum(predictionValue)
176 seitouritsuDown = float(seitouDown) / (backTestDays - sum(predictionValue))
177 outputStr += '・æ£ç”率(上昇時): ' + str(round(seitouritsuUp * 100,1)) + '%' + '\n'
178 outputStr += '・æ£ç”率(䏋陿™‚): ' + str(round(seitouritsuDown * 100,1)) + '%' + '\n'
179 trainStartDay=0
180 dataBTCOnBackTest = dataBTC[trainStartDay:trainStartDay+backTestDays+1]
181 dataBTCOnBackTest.reverse()
182 increasedFundRatio=(fund[-1]-fund[0])/fund[0]
183 increasedBTCPriceRatio=(dataBTCOnBackTest[-1]-dataBTCOnBackTest[0])/dataBTCOnBackTest[0]
184 outputStr += '・資金上昇率: ' + str(round(increasedFundRatio*100,1)) + '% (åˆæœŸè³‡é‡‘ã¯$' +str(fund[0])+'。最終資金ã¯$' +str(fund[-1])+'。)' + '\n'
185 outputStr += '・BTCä¾¡æ ¼ä¸Šæ˜‡çŽ‡: ' + str(round(increasedBTCPriceRatio*100,1)) + '% (åˆæœŸBTCä¾¡æ ¼ã¯$' +str(dataBTCOnBackTest[0])+'。最終BTCä¾¡æ ¼ã¯$' +str(dataBTCOnBackTest[-1])+'。)' + '\n'
186
187 # ----資金推移グラフ
188 if(plotGraphFlag):
189 # ----Plot Fund
190 dateBTCOnBackTest = dateBTC[trainStartDay:trainStartDay + backTestDays + 1]
191 dateBTCOnBackTest.reverse()
192 fig1, ax1 = plt.subplots()
193 p1, = ax1.plot(dateBTCOnBackTest, fund, '-ob')
194 ax1.set_title("Simulation with past data")
195 ax1.set_xlabel("Day")
196 ax1.set_ylabel("Fund[$]")
197 plt.grid(fig1)
198 # ----Plot BTC Price
199 ax2 = ax1.twinx()
200 p2, = ax2.plot(dateBTCOnBackTest, dataBTCOnBackTest, '-or')
201 ax2.set_ylabel('BTC price[$]')
202 ax1.legend([p1, p2], ["Fund", "BTC price"], loc="upper left")
203 plt.show(fig1)
204 return seitouritsuUp, seitouritsuDown, increasedFundRatio, increasedBTCPriceRatio, outputStr
205
206if __name__ == "__main__":
207 main()