ashhadahsan commited on
Commit
e59b179
·
1 Parent(s): fcd701f

commit one

Browse files
app.py ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from pybitget import Client
3
+ import datetime
4
+ import pandas as pd
5
+ from utils.preprocess.preprocess_data import (
6
+ preprocess,
7
+ normalize,
8
+ split_train_test,
9
+ create_dataset,
10
+ build_model,
11
+ train_model,
12
+ )
13
+ import matplotlib.pyplot as plt
14
+ import plotly.graph_objects as go
15
+ from sklearn.metrics import (
16
+ r2_score,
17
+ )
18
+ from utils.preprocess.projections import project
19
+ import numpy as np
20
+
21
+ client = Client(
22
+ st.secrets["apikey"],
23
+ st.secrets["password"],
24
+ passphrase=st.secrets["passphrase"],
25
+ )
26
+ from itertools import cycle
27
+ import plotly.express as px
28
+ from sklearn.model_selection import train_test_split
29
+
30
+
31
+ def get_symbols():
32
+ data = client.spot_get_symbols()
33
+ return [x["symbol"] for x in data["data"]]
34
+
35
+
36
+ def get_data(symbol, period, after, before):
37
+ print(symbol, period, after, end)
38
+ data = client.spot_get_candle_data(
39
+ symbol=symbol,
40
+ period=period,
41
+ after=after,
42
+ before=before,
43
+ limit=1000,
44
+ )["data"]
45
+ return pd.DataFrame(data)
46
+
47
+
48
+ st.set_page_config(page_title="Keras Bitget predictions", page_icon="📈", layout="wide")
49
+ st.title("Crypto price prediction")
50
+
51
+ coin = st.selectbox("Select your symbol", options=get_symbols())
52
+ period = st.selectbox(
53
+ "Select the interval",
54
+ options=[
55
+ "1min",
56
+ "5min",
57
+ "15min",
58
+ "30min",
59
+ "1h",
60
+ "4h",
61
+ "6h",
62
+ "12h",
63
+ "1day",
64
+ "1week",
65
+ ],
66
+ )
67
+ default_time = datetime.time(13, 0)
68
+ start = st.date_input(
69
+ "Start date of the data",
70
+ # value=datetime.datetime.now().date() - datetime.timedelta(days=30),
71
+ value=datetime.date(year=2022, month=1, day=1),
72
+ max_value=datetime.datetime.now().date(),
73
+ )
74
+
75
+ # start = datetime.datetime.timestamp(start)
76
+ end = st.date_input(
77
+ "End date of the data",
78
+ value=datetime.datetime.now().date(),
79
+ max_value=datetime.datetime.now().date(),
80
+ )
81
+ days = st.slider(label="Days to project", min_value=1, max_value=30, step=1, value=20)
82
+ epochs = st.slider(
83
+ label="Training Epochs", min_value=10, max_value=200, step=20, value=20
84
+ )
85
+ # end = datetime.datetime.timestamp(end)
86
+ # end = st.date_input("Start date of the data", datetime.now().date())
87
+ if st.button("Start"):
88
+ data = get_data(
89
+ coin,
90
+ period,
91
+ after=str(
92
+ int(
93
+ datetime.datetime.timestamp(
94
+ datetime.datetime.combine(start, default_time)
95
+ )
96
+ )
97
+ * 1000
98
+ ),
99
+ before=str(
100
+ int(
101
+ datetime.datetime.timestamp(
102
+ datetime.datetime.combine(end, default_time)
103
+ )
104
+ )
105
+ * 1000
106
+ ),
107
+ )
108
+
109
+ closedf = preprocess(data)
110
+ names = cycle(
111
+ ["Stock Open Price", "Stock Close Price", "Stock High Price", "Stock Low Price"]
112
+ )
113
+
114
+ figp = px.line(
115
+ closedf,
116
+ x=closedf.Date,
117
+ y=[closedf["open"], closedf["close"], closedf["high"], closedf["low"]],
118
+ labels={"Date": "Date", "value": "Stock value"},
119
+ )
120
+ figp.update_layout(
121
+ title_text="Stock analysis chart",
122
+ font_size=15,
123
+ font_color="black",
124
+ legend_title_text="Stock Parameters",
125
+ )
126
+ figp.for_each_trace(lambda t: t.update(name=next(names)))
127
+ figp.update_xaxes(showgrid=False)
128
+ figp.update_yaxes(showgrid=False)
129
+
130
+ st.plotly_chart(figp, use_container_width=True)
131
+
132
+ close_stock = closedf.copy()
133
+ close_stock = close_stock[["Date", "close"]]
134
+
135
+ st.write(closedf.shape)
136
+ close_stock_train, close_stock_test = train_test_split(close_stock, train_size=0.60)
137
+ st.write(close_stock_train.shape)
138
+
139
+ closedfsc, scaler = normalize(closedf=closedf)
140
+ training_size = int(len(closedf) * 0.60)
141
+ test_size = len(closedf) - training_size
142
+ train_set, test_set = split_train_test(
143
+ closedfsc=closedfsc, training_size=training_size, test_size=test_size
144
+ )
145
+ st.write(train_set.shape)
146
+ time_step = 15
147
+ X_train, y_train = create_dataset(train_set, time_step)
148
+ X_test, y_test = create_dataset(test_set, time_step)
149
+ X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
150
+ X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)
151
+ model = build_model()
152
+ st.write("Epoch Progress:")
153
+
154
+ progress_bar = st.progress(0)
155
+
156
+ def update_progress(epoch, history):
157
+ progress_percent = (epoch + 1) / epochs * 100
158
+ progress_bar.progress(progress_percent / 100) # Normalize to [0.0, 1.0]
159
+
160
+ # emp.write(
161
+ # f"Epoch {epoch + 1}/{epochs} - Loss: {history.history['loss'][0]} - Val Loss: {history.history['val_loss'][0]}"
162
+ # )
163
+
164
+ trained_model, train_losses, val_loss = train_model(
165
+ model,
166
+ X_train,
167
+ y_train,
168
+ X_test,
169
+ y_test,
170
+ epochs,
171
+ progress_callback=update_progress,
172
+ )
173
+
174
+ st.write("Training Completed!")
175
+
176
+ epochs = [i for i in range(len(train_losses))]
177
+
178
+ trace_train = go.Scatter(
179
+ x=epochs,
180
+ y=train_losses,
181
+ mode="lines",
182
+ name="Training Loss",
183
+ line=dict(color="red"),
184
+ )
185
+
186
+ # Create a trace for validation loss
187
+ trace_val = go.Scatter(
188
+ x=epochs,
189
+ y=val_loss,
190
+ mode="lines",
191
+ name="Validation Loss",
192
+ line=dict(color="blue"),
193
+ )
194
+
195
+ # Create the layout for the plot
196
+ layout = go.Layout(
197
+ title="Training and Validation Loss",
198
+ xaxis=dict(title="Epochs"),
199
+ yaxis=dict(title="Loss"),
200
+ )
201
+
202
+ # Create the figure
203
+ fig = go.Figure(data=[trace_train, trace_val], layout=layout)
204
+
205
+ # Show the plot
206
+ st.plotly_chart(fig, use_container_width=True)
207
+
208
+ train_predict = trained_model.predict(X_train)
209
+ test_predict = trained_model.predict(X_test)
210
+
211
+ train_predict = scaler.inverse_transform(train_predict)
212
+ test_predict = scaler.inverse_transform(test_predict)
213
+ original_ytrain = scaler.inverse_transform(y_train.reshape(-1, 1))
214
+ original_ytest = scaler.inverse_transform(y_test.reshape(-1, 1))
215
+
216
+ st.write(
217
+ "Train data Accuracy score:",
218
+ r2_score(original_ytrain, train_predict),
219
+ )
220
+ st.write(
221
+ "Test data Accuracy score:",
222
+ r2_score(original_ytest, test_predict),
223
+ )
224
+
225
+ plt.figure(figsize=(16, 10))
226
+ plt.plot(original_ytest)
227
+ plt.plot(test_predict)
228
+ plt.ylabel("Price")
229
+ plt.title(coin + " Single Point Price Prediction")
230
+ plt.legend(["Actual", "Predicted"])
231
+ plt.xticks(color="w")
232
+
233
+ st.pyplot(plt.gcf(), use_container_width=True)
234
+ projected_data = project(
235
+ time_step=15, test_data=test_set, model=trained_model, days=days
236
+ )
237
+ last_days = np.arange(1, time_step + 1)
238
+ day_pred = np.arange(time_step + 1, time_step + days + 1)
239
+ temp_mat = np.empty((len(last_days) + days + 1, 1))
240
+
241
+ temp_mat[:] = np.nan
242
+ temp_mat = temp_mat.reshape(1, -1).tolist()[0]
243
+
244
+ last_original_days_value = temp_mat
245
+ next_predicted_days_value = temp_mat
246
+
247
+ last_original_days_value[0 : time_step + 1] = (
248
+ scaler.inverse_transform(
249
+ close_stock[len(close_stock.close) - time_step :].close.values.reshape(
250
+ -1, 1
251
+ )
252
+ )
253
+ .reshape(1, -1)
254
+ .tolist()[0]
255
+ )
256
+ next_predicted_days_value[time_step + 1 :] = (
257
+ scaler.inverse_transform(np.array(projected_data).reshape(-1, 1))
258
+ .reshape(1, -1)
259
+ .tolist()[0]
260
+ )
261
+
262
+ new_pred_plot = pd.DataFrame(
263
+ {
264
+ "last_original_days_value": last_original_days_value,
265
+ "next_predicted_days_value": next_predicted_days_value,
266
+ }
267
+ )
268
+
269
+ names = cycle(["Last 15 days close price", "Predicted next 30 days close price"])
270
+
271
+ fig = px.line(
272
+ new_pred_plot,
273
+ x=new_pred_plot.index,
274
+ y=[
275
+ new_pred_plot["last_original_days_value"],
276
+ new_pred_plot["next_predicted_days_value"],
277
+ ],
278
+ labels={"value": "Stock price", "index": "Timestamp"},
279
+ )
280
+ fig.update_layout(
281
+ title_text="Compare last 15 days vs next 30 days",
282
+ plot_bgcolor="white",
283
+ font_size=15,
284
+ font_color="black",
285
+ legend_title_text="Close Price",
286
+ )
287
+
288
+ fig.for_each_trace(lambda t: t.update(name=next(names)))
289
+ fig.update_xaxes(showgrid=False)
290
+ fig.update_yaxes(showgrid=False)
291
+ st.plotly_chart(fig, use_container_width=True)
292
+
293
+ lstmdf = closedfsc.tolist()
294
+ lstmdf.extend((np.array(projected_data).reshape(-1, 1)).tolist())
295
+ lstmdf = scaler.inverse_transform(lstmdf).reshape(1, -1).tolist()[0]
296
+
297
+ names = cycle(["Close price"])
298
+
299
+ fig = px.line(lstmdf, labels={"value": "Stock price", "index": "Timestamp"})
300
+ fig.update_layout(
301
+ title_text="Plotting whole closing stock price with prediction",
302
+ plot_bgcolor="white",
303
+ font_size=15,
304
+ font_color="black",
305
+ legend_title_text="Stock",
306
+ )
307
+
308
+ fig.for_each_trace(lambda t: t.update(name=next(names)))
309
+
310
+ fig.update_xaxes(showgrid=False)
311
+ fig.update_yaxes(showgrid=False)
312
+ st.plotly_chart(fig, use_container_width=True)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ numpy
4
+ pybitget
5
+ keras
6
+ scikit-learn
7
+ matplotlib
8
+ tqdm
utils/preprocess/__init__.py ADDED
File without changes
utils/preprocess/preprocess_data.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+
4
+ from sklearn.preprocessing import MinMaxScaler
5
+ from keras.models import Sequential
6
+ from keras.layers import Dense
7
+ from keras.layers import LSTM
8
+ from keras.models import Sequential
9
+ from keras.layers import Activation, Dense
10
+ from keras.layers import LSTM
11
+ from keras.layers import Dropout
12
+ from tqdm import tqdm
13
+
14
+ neurons = 512 # number of hidden units in the LSTM layer
15
+ activation_function = "tanh" # activation function for LSTM and Dense layer
16
+ loss = (
17
+ "mse" # loss function for calculating the gradient, in this case Mean Squared Error
18
+ )
19
+ optimizer = "adam" # optimizer for appljying gradient decent
20
+ dropout = 0.25 # dropout ratio used after each LSTM layer to avoid overfitting
21
+ batch_size = 128
22
+
23
+
24
+ def preprocess(df):
25
+ df = df.copy()
26
+ df["ts"] = df["ts"].astype(np.int64)
27
+ df["ts"] = df["ts"] / 1000
28
+ df["timestamp"] = pd.to_datetime(df["ts"], unit="s")
29
+ df = df[["timestamp", "low", "high", "close", "open", "quoteVol"]]
30
+ for col in ["low", "high", "close", "open", "quoteVol"]:
31
+ df[col] = df[col].astype(float)
32
+ df.set_index(df["timestamp"], inplace=True)
33
+ df.drop(["timestamp"], axis=1, inplace=True)
34
+ df["Date"] = pd.to_datetime(df.index.values.tolist()).date
35
+
36
+ return df
37
+
38
+
39
+ def normalize(closedf):
40
+ scaler = MinMaxScaler(feature_range=(0, 1))
41
+ closedfsc = scaler.fit_transform(
42
+ np.array(closedf.drop("Date", axis=1)).reshape(-1, 1)
43
+ )
44
+ return closedfsc, scaler
45
+
46
+
47
+ def split_train_test(closedfsc, training_size, test_size):
48
+ train_data, test_data = (
49
+ closedfsc[0:training_size, :],
50
+ closedfsc[training_size : len(closedfsc), :1],
51
+ )
52
+ return train_data, test_data
53
+
54
+
55
+ def create_dataset(dataset, time_step=1):
56
+ dataX, dataY = [], []
57
+ for i in range(len(dataset) - time_step - 1):
58
+ a = dataset[i : (i + time_step), 0] ###i=0, 0,1,2,3-----99 100
59
+ dataX.append(a)
60
+ dataY.append(dataset[i + time_step, 0])
61
+ return np.array(dataX), np.array(dataY)
62
+
63
+
64
+ # def build_model(inputs):
65
+ # model = Sequential()
66
+ # model.add(
67
+ # LSTM(
68
+ # neurons,
69
+ # return_sequences=True,
70
+ # input_shape=(inputs.shape[1], inputs.shape[2]),
71
+ # activation=activation_function,
72
+ # )
73
+ # )
74
+ # model.add(Dropout(dropout))
75
+ # model.add(LSTM(neurons, return_sequences=True, activation=activation_function))
76
+ # model.add(Dropout(dropout))
77
+ # model.add(LSTM(neurons, activation=activation_function))
78
+ # model.add(Dropout(dropout))
79
+ # model.add(Dense(units=1))
80
+ # model.add(Activation(activation_function))
81
+ # model.compile(loss=loss, optimizer=optimizer, metrics=["mae"])
82
+ # return model
83
+
84
+
85
+ def build_model():
86
+ model = Sequential()
87
+
88
+ model.add(LSTM(256, input_shape=(None, 1), activation="relu"))
89
+
90
+ model.add(Dense(1))
91
+
92
+ model.compile(loss="mean_squared_error", optimizer="adam")
93
+ return model
94
+
95
+
96
+ def train_model(
97
+ model, x_train, y_train, X_test, y_test, epochs, progress_callback=None
98
+ ):
99
+ train_losses = [] # To store training losses
100
+ val_losses = [] # To store validation losses
101
+ for epoch in tqdm(range(epochs)):
102
+ history = model.fit(
103
+ x_train,
104
+ y_train,
105
+ epochs=1,
106
+ verbose=0,
107
+ validation_data=(X_test, y_test),
108
+ batch_size=32,
109
+ )
110
+ train_loss = history.history["loss"][0]
111
+ val_loss = history.history["val_loss"][0]
112
+
113
+ train_losses.append(train_loss)
114
+ val_losses.append(val_loss)
115
+ if progress_callback:
116
+ progress_callback(epoch, history)
117
+ return model, train_losses, val_losses
utils/preprocess/projections.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from numpy import array
2
+
3
+
4
+ def project(time_step: int, test_data, model, days: int = 30):
5
+ x_input = test_data[len(test_data) - time_step :].reshape(1, -1)
6
+ temp_input = list(x_input)
7
+ temp_input = temp_input[0].tolist()
8
+ lst_output = []
9
+ n_steps = time_step
10
+ i = 0
11
+ pred_days = days
12
+ while i < pred_days:
13
+ if len(temp_input) > time_step:
14
+ x_input = array(temp_input[1:])
15
+ # print("{} day input {}".format(i,x_input))
16
+ x_input = x_input.reshape(1, -1)
17
+ x_input = x_input.reshape((1, n_steps, 1))
18
+
19
+ yhat = model.predict(x_input, verbose=0)
20
+ # print("{} day output {}".format(i,yhat))
21
+ temp_input.extend(yhat[0].tolist())
22
+ temp_input = temp_input[1:]
23
+ # print(temp_input)
24
+
25
+ lst_output.extend(yhat.tolist())
26
+ i = i + 1
27
+
28
+ else:
29
+ x_input = x_input.reshape((1, n_steps, 1))
30
+ yhat = model.predict(x_input, verbose=0)
31
+ temp_input.extend(yhat[0].tolist())
32
+
33
+ lst_output.extend(yhat.tolist())
34
+ i = i + 1
35
+ return lst_output