Spaces:
Runtime error
Runtime error
Commit
β’
2fbaf0f
1
Parent(s):
46fc4d7
Upload 9 files
Browse files- Bitcoin Analysis Using With Forecasting LSTM,ARIMAX,SARIMAX,FbProphet,Neural Prophet,TFT Model.ipynb +0 -0
- LSTM_build.h5 +3 -0
- README.md +2 -12
- Scheduler.py +18 -0
- app.py +201 -0
- build_model.py +40 -0
- isdone.txt +1 -0
- prevdays.txt +1 -0
- started.txt +1 -0
Bitcoin Analysis Using With Forecasting LSTM,ARIMAX,SARIMAX,FbProphet,Neural Prophet,TFT Model.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
LSTM_build.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f9338093101ceb351a4433d010cbc64ad742e26114109c25b9fc341d504d2fe8
|
3 |
+
size 5489056
|
README.md
CHANGED
@@ -1,13 +1,3 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
emoji: π
|
4 |
-
colorFrom: red
|
5 |
-
colorTo: indigo
|
6 |
-
sdk: streamlit
|
7 |
-
sdk_version: 1.10.0
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
license: mit
|
11 |
-
---
|
12 |
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
+
# Bitcoin Price Prediction Using Continously Trained LSTM and Analysis With ARIMAX, SARIMAX, FBprophet, LSTM, NeuralProphet and Temporal-Fusion-Transformer
|
2 |
+
Perdicting Bitcoin Closing Prices using differnet Timeseries based model. Deployed using Streamlit and Hugging Face Spaces with LSTM Model That automatcally retrains every 10th day For eg if last trained was 2022-10-16 then it will train automatically with all the new data on 10th day that is 2022-10-26. Read More to understand how it works or check out the notebook to understand why we chose LSTM Over others for deployment.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
|
Scheduler.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from datetime import datetime
|
3 |
+
data = requests.get("http://worldtimeapi.org/api/timezone/Asia/Kolkata")
|
4 |
+
date = data.json()['datetime'].split('T')[0]
|
5 |
+
date = date[2:]
|
6 |
+
date = datetime.strptime(date, '%y-%m-%d')
|
7 |
+
|
8 |
+
# This will check if its more then 19 days for our model to get retrained
|
9 |
+
def isscheduled():
|
10 |
+
with open('prevdays.txt') as file:
|
11 |
+
previous_date = file.readline()
|
12 |
+
previous_date = previous_date.strip()
|
13 |
+
file.close()
|
14 |
+
previous_date = datetime.strptime(previous_date[2:], '%y-%m-%d')
|
15 |
+
if str(date-previous_date).split(' ')[0] == '10':
|
16 |
+
return True
|
17 |
+
else:
|
18 |
+
return False
|
app.py
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
from Scheduler import isscheduled
|
4 |
+
from build_model import model_builder
|
5 |
+
from sklearn.preprocessing import MinMaxScaler
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
from tensorflow import keras
|
8 |
+
import yfinance
|
9 |
+
import requests
|
10 |
+
import streamlit as st
|
11 |
+
from datetime import datetime
|
12 |
+
import os
|
13 |
+
# Getting Current Date
|
14 |
+
|
15 |
+
def main():
|
16 |
+
|
17 |
+
if 'Season' not in st.session_state:
|
18 |
+
st.session_state['Season'] = True
|
19 |
+
else:
|
20 |
+
st.session_state['Season'] = False
|
21 |
+
with open("prevdays.txt",'r') as file:
|
22 |
+
previous_date = file.readline()
|
23 |
+
file.close()
|
24 |
+
with open("isdone.txt",'r') as file:
|
25 |
+
isdone = file.readline()
|
26 |
+
file.close()
|
27 |
+
isExist = os.path.exists('LSTM_build.h5')
|
28 |
+
data = requests.get("http://worldtimeapi.org/api/timezone/Asia/Kolkata")
|
29 |
+
current_date = data.json()['datetime'].split('T')[0]
|
30 |
+
if isExist == False and isdone == 'Done':
|
31 |
+
with open("isdone.txt",'w') as file:
|
32 |
+
file.write("Not Done")
|
33 |
+
file.close()
|
34 |
+
|
35 |
+
with st.spinner(f'Wait for Model Updation It will Retrain Every 10th day from the retraining day which was on {previous_date} It Will take only 15-20 mins Please Wait **Do not close The window**...'):
|
36 |
+
builder = model_builder()
|
37 |
+
# We will Schedule Our APP to re build model after 10 days
|
38 |
+
with open('isdone.txt') as file:
|
39 |
+
isDone = file.readline()
|
40 |
+
file.close()
|
41 |
+
|
42 |
+
|
43 |
+
isDone = isDone.strip()
|
44 |
+
if isscheduled()==True or isExist==False and isDone != 'Done':
|
45 |
+
# Getting The data
|
46 |
+
with open('started.txt','w') as file:
|
47 |
+
file.write("True")
|
48 |
+
file.close()
|
49 |
+
X = yfinance.download('BTC-USD',start = '2017-01-01')
|
50 |
+
X = X['Close']
|
51 |
+
data = X
|
52 |
+
# Preprocessing data
|
53 |
+
|
54 |
+
X = X[:len(X)-30]
|
55 |
+
X_test = data[len(X):len(data)]
|
56 |
+
# Scaling
|
57 |
+
scaled = MinMaxScaler()
|
58 |
+
values = scaled.fit_transform(np.array(X).reshape(-1,1))
|
59 |
+
X_train = values
|
60 |
+
X_test = scaled.fit_transform(np.array(X_test).reshape(-1,1))
|
61 |
+
|
62 |
+
# Creating Time Series data to Feed To LSTM
|
63 |
+
X_train,y_train = builder.preprocess_data(X_train,10)
|
64 |
+
X_test,y_test = builder.preprocess_data(X_test,10)
|
65 |
+
X_train = X_train[...,np.newaxis]
|
66 |
+
X_test = X_test[...,np.newaxis]
|
67 |
+
|
68 |
+
model = builder.fit(X_train,y_train)
|
69 |
+
model.save('LSTM_build.h5',save_format = 'h5',overwrite = True)
|
70 |
+
with open('isdone.txt','w') as file:
|
71 |
+
file.write('Done')
|
72 |
+
file.close()
|
73 |
+
with open('prevdays.txt','w') as file:
|
74 |
+
data = requests.get("http://worldtimeapi.org/api/timezone/Asia/Kolkata")
|
75 |
+
date = data.json()['datetime'].split('T')[0]
|
76 |
+
file.write(date)
|
77 |
+
file.close()
|
78 |
+
|
79 |
+
if previous_date != current_date and isscheduled()==False and isExist==True:
|
80 |
+
with open('isdone.txt','w') as file:
|
81 |
+
file.write('NotDone')
|
82 |
+
file.close()
|
83 |
+
with open("started.txt",'w') as file:
|
84 |
+
file.write("False")
|
85 |
+
file.close()
|
86 |
+
|
87 |
+
model = keras.models.load_model('LSTM_build.h5')
|
88 |
+
elif previous_date == current_date and isdone == 'Done' and isExist == True:
|
89 |
+
model = keras.models.load_model('LSTM_build.h5')
|
90 |
+
elif isExist == False and isdone =='Done':
|
91 |
+
st.write("There Might Be some issues or the model is rebuilding in background please try and reload application after 5mins.")
|
92 |
+
if st.session_state['Season'] == True:
|
93 |
+
if int(current_date.split("-")[1])>=10 or int(current_date.split("-")[1])<=2:
|
94 |
+
st.snow()
|
95 |
+
st.session_state['season'] = 'Winter'
|
96 |
+
else:
|
97 |
+
st.balloons()
|
98 |
+
st.session_state['season']= 'Summer'
|
99 |
+
|
100 |
+
with open("prevdays.txt",'r') as file:
|
101 |
+
previous_date = file.readline()
|
102 |
+
file.close()
|
103 |
+
st.success(f"Model Is updated On {previous_date} and will next Update after 10 days ")
|
104 |
+
|
105 |
+
# Creating Future Outcomes
|
106 |
+
def forecast_day():
|
107 |
+
df = yfinance.download('BTC-USD',start = '2017-01-01')
|
108 |
+
df = df.reset_index()
|
109 |
+
X_future = df['Close'].shift(-2)
|
110 |
+
X_dates = df['Date'].shift(-2)
|
111 |
+
X_dates = X_dates[len(X_dates)-12:len(X_dates)]
|
112 |
+
X_dates = X_dates[...,np.newaxis]
|
113 |
+
X_dates = builder.preprocess_data(X_dates,10)
|
114 |
+
|
115 |
+
X_future = X_future[len(X_future)-12:len(X_future)]
|
116 |
+
scaled = MinMaxScaler()
|
117 |
+
X_future = scaled.fit_transform(np.array(X_future).reshape(-1,1))
|
118 |
+
X_future,y_future = builder.preprocess_data(X_future,10)
|
119 |
+
|
120 |
+
X_future = X_future[...,np.newaxis]
|
121 |
+
result = model.predict(X_future)
|
122 |
+
ans = scaled.inverse_transform(result)
|
123 |
+
if ans>df['Close'].iloc[-1]:
|
124 |
+
return 'Positive π’',ans
|
125 |
+
else:
|
126 |
+
return 'Negative π΄ ',ans
|
127 |
+
|
128 |
+
def create_sample_data(df,days):
|
129 |
+
store_index = []
|
130 |
+
for day in range(days):
|
131 |
+
# Creating Temporary DataFrame
|
132 |
+
dt = df.index + pd.Timedelta(days = 1)
|
133 |
+
next_data = pd.DataFrame({'Close':[1]},index =[dt[-1]])
|
134 |
+
df = pd.concat([df,next_data])
|
135 |
+
store_index.append(dt[-1])
|
136 |
+
return df,store_index
|
137 |
+
|
138 |
+
# This function Forecast Prices For 10 Days or less.
|
139 |
+
def forecast_timeline(X,days):
|
140 |
+
if days>10:
|
141 |
+
return False
|
142 |
+
final_values = []
|
143 |
+
temp_data = X.iloc[-1]
|
144 |
+
for day in range(days):
|
145 |
+
X = X.shift(-2)
|
146 |
+
X_future = X[len(X)-12:len(X)]
|
147 |
+
X = X.dropna()
|
148 |
+
scaled = MinMaxScaler()
|
149 |
+
X_future = scaled.fit_transform(np.array(X_future).reshape(-1,1))
|
150 |
+
X_future,y_future = builder.preprocess_data(X_future,10)
|
151 |
+
result = model.predict(X_future)
|
152 |
+
X = X.to_list()
|
153 |
+
X.append(scaled.inverse_transform(result).reshape(1)[0])
|
154 |
+
X = pd.Series(X)
|
155 |
+
final_values.append(scaled.inverse_transform(result).reshape(1)[0])
|
156 |
+
final_values.insert(0,temp_data)
|
157 |
+
return final_values
|
158 |
+
|
159 |
+
def predict_future(days):
|
160 |
+
df = yfinance.download('BTC-USD',start = '2017-01-01')
|
161 |
+
df.reset_index(inplace = True)
|
162 |
+
X = df['Close']
|
163 |
+
future_Values = forecast_timeline(X,days)
|
164 |
+
df = df[['Close','Date']]
|
165 |
+
df.set_index('Date',inplace = True)
|
166 |
+
final_df,store_index = create_sample_data(df,days)
|
167 |
+
for i,index in enumerate(store_index):
|
168 |
+
final_df['Close'].loc[index] = future_Values[i]
|
169 |
+
|
170 |
+
return final_df,future_Values
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
st.title('Bitcoin Price Prediction βΏ')
|
175 |
+
st.write(f"HOWDY! Wonderfull ***{st.session_state['season']}*** Season. Welcome to Bitcoin ( βΏ ) Price Prediction APP It will Predict Closing Price For Bitcoin. These Predictions are based on **LSTM** Model Trained Over Historical Bitcoin Data From **2017 till {previous_date}** . the Model retratins every 10th day, The Prediction are totally based on previous Closing Values so do not invest money based on Such Predictions. Its only for Educational Purposes and should not be used for finacial purpose.")
|
176 |
+
st.write("Why LSTM ? Because it Performed well on the data, I used LSTM,ArimaMax,SariMax,Temporal Fusion transformer,FbProphet, NeuralProphet many different time series model for predictions in which lstm performed the best so I Selected LSTM. If you want To check how we came to conclusion. Check out https://shorturl.at/cwHM4 For Code.")
|
177 |
+
one_day = False
|
178 |
+
days = int(st.number_input('Enter no of Days for Prediction'))
|
179 |
+
st.write("or you can Select one day prediction from below ***IMPORTANT*** After **Checkbox is Clicked** Do Not Press Submit It Will automatically Run")
|
180 |
+
if st.checkbox(label = 'One Day Prediction'):
|
181 |
+
one_day = True
|
182 |
+
if one_day == True:
|
183 |
+
days = 1
|
184 |
+
if st.button('Submit') and days<=10 and days>0:
|
185 |
+
dataframe,values = predict_future(days)
|
186 |
+
data = requests.get("http://worldtimeapi.org/api/timezone/Asia/Kolkata")
|
187 |
+
date = data.json()['datetime'].split('T')[0]
|
188 |
+
st.line_chart(data=dataframe)
|
189 |
+
for i in range(len(values)-1):
|
190 |
+
if values[i+1]>values[i]:
|
191 |
+
st.write(f'Day{i+1}:Positive Growth π’')
|
192 |
+
else:
|
193 |
+
st.write(f'Day{i+1}:Negative Growth π΄')
|
194 |
+
if days == 1:
|
195 |
+
result,ans = forecast_day()
|
196 |
+
st.markdown(f"Tommorow **Bitcoin** Can Show {result} Movement.")
|
197 |
+
st.markdown(f"And Price Can Be Around : $ {ans.reshape(1)[0]}.")
|
198 |
+
elif days>10 or days<0:
|
199 |
+
st.write("Please Renter Days As you have exceeded 10 days limit or the input is too small, If you think everything is correct still it's showing wront output please check if you are entering any spaces while input or send us feedback at info@tusharnautiyal.ml")
|
200 |
+
if __name__ == '__main__':
|
201 |
+
main()
|
build_model.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
from tensorflow import keras
|
4 |
+
from keras import Sequential
|
5 |
+
from keras.layers import Dense,Dropout,LSTM
|
6 |
+
|
7 |
+
|
8 |
+
class model_builder:
|
9 |
+
def __init__(self):
|
10 |
+
self.model = None
|
11 |
+
|
12 |
+
def preprocess_data(self,dataset,time_step):
|
13 |
+
dataX, dataY = [], []
|
14 |
+
for i in range(len(dataset)-time_step-1):
|
15 |
+
a = dataset[i:(i+time_step), 0]
|
16 |
+
dataX.append(a)
|
17 |
+
dataY.append(dataset[i + time_step, 0])
|
18 |
+
return np.array(dataX), np.array(dataY)
|
19 |
+
|
20 |
+
def create_model(self,X_train):
|
21 |
+
model = Sequential()
|
22 |
+
model.add(LSTM(150,return_sequences=True,input_shape=(X_train.shape[1],X_train.shape[2])))
|
23 |
+
model.add(Dropout(0.2))
|
24 |
+
|
25 |
+
model.add(LSTM(150,return_sequences=True))
|
26 |
+
model.add(Dropout(0.2))
|
27 |
+
|
28 |
+
model.add(LSTM(150))
|
29 |
+
model.add(Dropout(0.2))
|
30 |
+
|
31 |
+
model.add(Dense(1))
|
32 |
+
model.compile(loss='mean_squared_error' , metrics = ['mse', 'mae'],optimizer='adam')
|
33 |
+
return model
|
34 |
+
|
35 |
+
def fit(self,X_train,y_train):
|
36 |
+
model = self.create_model(X_train)
|
37 |
+
model.fit(X_train,y_train,epochs=300,batch_size=64,verbose=1)
|
38 |
+
self.model = model
|
39 |
+
return model
|
40 |
+
|
isdone.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Done
|
prevdays.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
2022-10-26
|
started.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
False
|