import torch import torch.nn as nn from torch.utils.tensorboard import SummaryWriter import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error import numpy as np import time, math import yfinance as yf from indicator_MACD import * import os def preproc(df): minmax = MinMaxScaler().fit(df.iloc[:,2:5].astype('float32')) # Close, Volume, and all df_log = minmax.transform(df.iloc[:, 2:5].astype('float32')) # Close, Volume, and all df_log = pd.DataFrame(df_log) df_log.head() input() return df_log,minmax symbol=yf.Ticker(input("Enter the Ticker : ")) data=symbol.history(interval="1d",period="4y") data=data[:-7] real_data = data.iloc[:, 3] real_data = pd.DataFrame(real_data) # real_data = real_data["Close"] print("") print("Real Data ") print(real_data[-7:]) tick_macd = macd_data(real_data) plt.subplot(2, 1, 1) ax = plt.plot(real_data) ax = plt.bar(tick_macd.index, tick_macd['Gap'], width=0.8) plt.subplot(2,1,2) ax = plt.bar(tick_macd.index, tick_macd['Gap'], width=0.8) plt.show() df = pd.DataFrame(data) # df = tick_macd # df.index = pd.to_datetime(df.index) # print((df)) #df = pd.read_csv("./data/AAPL_2020-10-31.csv", header=0, index_col=0) #df = df[-365:] # df = df.iloc[:, 3] # df = df["Close"] print(data.head()) print(df.head()) # input() # print(df) # plt.plot(df) # plt.show() # ktest_size = 300 # ktest_data =df[:-test_size] # ktrain_data = df[-test_size:] # scaler = MinMaxScaler() df_test = df df, scaler = preproc(df) # scaler = scaler.fit(np.expand_dims(df, axis=1)) # df = scaler.transform(np.expand_dims(df, axis=1)) # train_data = scaler.transform(np.expand_dims(train_data, axis=1)) # test_data = scaler.transform(np.expand_dims(test_data, axis=1)) class LSTM(nn.Module): def __init__(self, input_dim, hidden_dim, num_layers, output_dim): super(LSTM, self).__init__() self.hidden_dim = hidden_dim self.num_layers = num_layers self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True) self.fc = nn.Linear(hidden_dim, output_dim) def forward(self, x): h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).requires_grad_() c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).requires_grad_() out, (hnn,cnn) = self.lstm(x, (h0.detach(), c0.detach())) out = self.fc(out[:,-1,:]) return out class GRU(nn.Module): def __init__(self, input_dim, hidden_dim, num_layers, output_dim): super(GRU, self).__init__() self.hidden_dim = hidden_dim self.num_layers = num_layers self.gru = nn.GRU(input_dim, hidden_dim, num_layers, batch_first=True) self.fc = nn.Linear(hidden_dim, output_dim) def forward(self, x): h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).requires_grad_() out, (hn) = self.gru(x, (h0.detach())) out = self.fc(out[:, -1, :]) return out # def window(data, seq_length): # xs = [] # ys = [] # # print(data) # for i in range(len(data)-seq_length-1): # x = data[i:(i+seq_length)] # y = data[i+seq_length] # xs.append(x) # ys.append(y) # #plt.plot(ys) # #plt.plot(ys[0]+xs[0]) # #plt.show() # print((xs[0])) # print((ys[0])) # print("------------") # print(data[29]) # print(data[30]) # input() # return np.array(xs), np.array(ys) def split_window_mod(my_data, lookback): data_raw = my_data.to_numpy() # data_raw = my_data data = [] for index in range(len(data_raw)-lookback): data.append(data_raw[index : index + lookback+1]) # print(data[-1:]) print("Shape : ", len(data[0])) print(data[-3:-1]) input() # data = pd.DataFrame(data) # data = data.iloc[:, 1:5] data = np.array(data) print("Current Data ") print(data) input() # print(data[0]) # print(data[1]) test_set_size = int(np.round(0.3*data.shape[0])); train_set_size = data.shape[0] - (test_set_size); print("TEST:",train_set_size) print("TEST:",test_set_size) x_train = data[:train_set_size, :-1, :] print("") print(" ============== X_train ============== ") print(x_train[-2:]) print("") input() y_train = data[1:train_set_size, -1, :] print("") print(" ============== y_train =====") print(y_train[-2:]) print("") input() print("Current Data Y") # print(x_train[0]) print(y_train[0]) print(y_train[1]) x_test = data[train_set_size:, :-1] print("") print(" ============== X_test ============== ") print(x_test[-2:]) print("") input() y_test = data[-test_set_size:-1, -1, :] # Problematic slicing print("") print(" ============== y_test ============== ") print(y_test[-2:]) print("") input() print("Current Data ") # print(x_test[0]) x_train=x_train[:-1] x_test=x_test[:-1] print(len(x_train)) print(len(y_train)) print(len(x_test)) print(len(y_test)) return [x_train, y_train, x_test, y_test] def split_window(my_data, lookback): # data_raw = my_data.to_numpy() data_raw = my_data.to_numpy() data = [] for index in range(len(data_raw)-lookback): data.append(data_raw[index : index + lookback]) # print(data) data = np.array(data); print("Current Data ") test_set_size = int(np.round(0.1*data.shape[0])); train_set_size = data.shape[0] - (test_set_size); x_train = data[:train_set_size, :-1, :] y_train = data[:train_set_size, -1, :] x_test = data[train_set_size:, :-1] y_test = data[train_set_size:, -1, :] return [x_train, y_train, x_test, y_test] def window(data, seq_length): xs = [] ys = [] # print(data) for i in range(len(data)-seq_length-1): x = data[i:(i+seq_length)] try: y = data[i+7+seq_length] except: break xs.append(x) ys.append(y) #plt.plot(ys) #plt.plot(ys[0]+xs[0]) #plt.show() print((xs[0])) print((ys[0])) print("------------") print(data[29]) print(data[37]) # input() return np.array(xs), np.array(ys) def forecasting(): print("Forecasting . . .") input_dim = 3 hidden_dim = 128 num_layers = 2 output_dim = 3 num_epochs = int(input("Epoch fof training : ")) lookback = 7 # CUDA is_cuda = torch.cuda.is_available() if is_cuda: device = torch.device("cuda") torch.cuda.set_device(0) else: device = torch.device("cpu") # REPLACED # seq_length = 7 # X_train, y_train = window(train_data, seq_length) # X_test, y_test = window(test_data, seq_length) # X_train, y_train, X_test, y_test = split_window(df, lookback) # a, b, c, d = split_window_mod(df_test, lookback) X_train, y_train, X_test, y_test = split_window_mod(df, lookback) print(X_test.shape) #input() # fill Nan for adjusted forecasting # filler_X_train = np.empty_like(X_train) # filler_X_train[:,:] = np.nan # X_train = np.insert(X_train, 0, X_train[7:14], axis=0) print("") print("Fill Attempt X_train ====================================== ") print(X_train[:8]) input() # filler_y_train = np.empty_like(y_train) # filler_y_train[:, :] = np.nan # y_train = np.append(y_train, y_train[-7:], axis=0) print("") print("Fill Attempt y_train ====================================== ") print(y_train[-8:]) input() # print("") # print("Fill Attempt X_test ====================================== ") # print(X_test.shape) # # filler_X_test = X_train[-7:] # # filler_X_test = np.empty_like(X_test) # # filler_X_test[:,:] = np.nan # X_test = np.insert(X_test, 0, X_test[7:14], axis=0) # print(X_test.shape) # print(X_test[:7]) # input() # # filler_y_test = np.empty_like(y_test) # filler_y_test[:, :] = np.nan # y_test = np.append(y_test, filler_y_test[-7:], axis=0) # print("") # print("Fill Attempt y_test ====================================== ") # print(y_test[-7:]) # input() X_train = torch.from_numpy(X_train).type(torch.Tensor) y_train = torch.from_numpy(y_train).type(torch.Tensor) X_test = torch.from_numpy(X_test).type(torch.Tensor) y_test = torch.from_numpy(y_test).type(torch.Tensor) # X_train = torch.from_numpy(X_train).float() # y_train = torch.from_numpy(y_train).float() # X_test = torch.from_numpy(X_test).float() # y_test = torch.from_numpy(y_test).float() # X_test = torch.from_numpy(np.append(X_test, future_days)).float() # y_test = torch.from_numpy(np.append(y_test, future_days)).float() print(X_test.shape) #input() # Tensorboard Setup writer = SummaryWriter() model = GRU(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim, num_layers=num_layers) # model = LSTM(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim, num_layers=num_layers) criterion = torch.nn.MSELoss(reduction='mean') optimiser = torch.optim.Adam(model.parameters(), lr=0.01) hist = np.zeros(num_epochs) start_time = time.time() gru = [] print("X_train : ") print(X_train[-1:]) input() for t in range(num_epochs): y_train_pred = model(X_train) loss = criterion(y_train_pred, y_train) print("Epoch ", t+1, "MSE: ", loss.item()) # y_test_pred = model(X_test) # loss_valid = criterion(y_test_pred, y_test) # print("-------------------- Validation MSE : ", loss_valid.item()) hist[t] = loss.item() optimiser.zero_grad() loss.backward() optimiser.step() writer.add_scalar("Loss/Train", loss.item(), t) # writer.add_scalar("Validation/Train", loss, t) training_time = time.time() - start_time print("Time Spent : {}".format(training_time)) predict = pd.DataFrame(scaler.inverse_transform(y_train_pred.detach().numpy())) original = pd.DataFrame(scaler.inverse_transform(y_train.detach().numpy())) plt.subplot(1, 2, 1) ax = plt.plot(original.index, original[0]) ax = plt.plot(predict.index, predict[0]) plt.subplot(1,2,2) ax = plt.plot(hist) plt.show() # Predict from test data print("================== Test Data Specification ===========") print(X_test[-1:]) print(X_test.shape) for t in range(int(np.round(0.5 * num_epochs))): y_test_pred = model(X_test) loss = criterion(y_test_pred, y_test) print("Epoch ", t+1, "MSE: ", loss.item()) # y_test_pred = model(X_test) # loss_valid = criterion(y_test_pred, y_test) # print("-------------------- Validation MSE : ", loss_valid.item()) hist[t] = loss.item() optimiser.zero_grad() loss.backward() optimiser.step() writer.add_scalar("Loss/Test", loss.item(), t) y_test = scaler.inverse_transform(y_test.detach().numpy()) test_predict = pd.DataFrame(scaler.inverse_transform(y_test_pred.detach().numpy())) # test_original = pd.DataFrame(scaler.inverse_transform(y_test.detach().numpy())) test_original = pd.DataFrame(y_test) print(test_original) print(test_predict[:10]) input() # plt.plot(test_original.index, test_original[0]) # plt.plot(test_original.index, test_original[0], label="Real Data") # plt.plot(test_predict.index, test_predict[0], marker=".", label="Prediction") # Bar plt.bar(test_original.index, test_original[0], label="Real Data") plt.bar(test_predict.index, test_predict[0], label="Prediction") plt.title("Test Result ") plt.show() # Invert prediction results y_train_pred = scaler.inverse_transform(y_train_pred.detach().numpy()) y_train = scaler.inverse_transform(y_train.detach().numpy()) y_test_pred = scaler.inverse_transform(y_test_pred.detach().numpy()) # calculate mean square error # trainScore = math.sqrt(mean_squared_error(y_train[:,0], y_train_pred[:,0])) # testScore = math.sqrt(mean_squared_error(y_test[:,0], y_test_pred[:,0])) # print("Train Score: %.2f " % (trainScore)) # print("Test Score: %.2f " % (trainScore)) # gru.append(trainScore) # gru.append(testScore) # gru.append(training_time) filler_df = np.empty_like(df) filler_df[:, :] = np.nan df = np.append(df, filler_df[-7:], axis=0) trainPredictPlot = np.empty_like(df) trainPredictPlot[:,:] = np.nan print("Train reference:") print("[1]", str(len(y_train_pred)+lookback)) print("[2]", str(len(df)-1)) print ( "[ y_train_pred] ", str(len(y_train_pred)) ) # input() print("") trainPredictPlot[:len(y_train_pred), :] = y_train_pred # trainPredictPlot[lookback:len(y_train_pred)+lookback, :] = y_train_pred print("y_test_pred shape ", y_test_pred.shape) # Stacked prediction rrr_predict = X_test[len(X_test)-1][-(lookback-1):] rrr_predict = np.expand_dims(rrr_predict, axis=0) rrr_predict = torch.from_numpy(rrr_predict).type(torch.Tensor) xxx_predict = model(rrr_predict) vvv_predict = X_test[len(X_test)-1][-(lookback-1):] print() print("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||") print("Real data ") print(X_test[-1:]) print("input data: ") print(vvv_predict) print("Prediction Result: ") print(xxx_predict) zzz_predict = np.append(vvv_predict.detach().numpy(), xxx_predict.detach().numpy(), axis=0) # print("new X_test n+1 ") # print(zzz_predict) # zzz_predict = np.expand_dims(zzz_predict, axis=1) # set axis=1 to get prediction result for 7 days straight print(zzz_predict) # aaa_predict = torch.from_numpy(zzz_predict).type(torch.Tensor) # print("n+1+1 prediction ") aaa_predict = model(aaa_predict) # tmp_future = np.empty_like(aaa_predict) # tmp_future = np.append(tmp_future, aaa_predict.detach().numpy(), axis=0) # print(tmp_future) # print("***************************************************************************************") # for x in range(lookback): # tmp_val = tmp_future[-(lookback-1):] # # aaa_predict = np.expand_dims(aaa_predict.detach().numpy(), axis=0) # aaa_predict = torch.from_numpy(tmp_val).type(torch.Tensor) # # aaa_predict = model(aaa_predict) # print(aaa_predict) # # tmp_future = np.append(tmp_future[0], aaa_predict[0], axis=0) # print("***************************************************************************************") aaa_future = scaler.inverse_transform(aaa_predict.detach().numpy()) y_test_pred = np.append(y_test_pred, aaa_future, axis=0) print(y_test_pred[-2:]) # plt.plot(aaa_future) # plt.show() print() print("|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||") print() input() predict_test = pd.DataFrame(y_train_pred) original_test = pd.DataFrame(y_train) # predict_test = pd.DataFrame(y_train_pred) # original_test = pd.DataFrame(y_train) testPredictPlot = np.empty_like(df) testPredictPlot[:,:] = np.nan print("Our Problem child :") print("[1]", str(len(y_test_pred)+lookback-1)) print("[2]", str(len(df)-1)) print("[3]", str(len(testPredictPlot))) print("[ y_test_pre] ", str(len(y_test_pred))) print(testPredictPlot.shape) print(testPredictPlot[-10:]) print("") # testPredictPlot[len(y_train_pred)+lookback-1:len(df)-3, :] = y_test_pred testPredictPlot[len(y_train_pred):len(df)-16, :] = test_predict fill_tail = np.empty_like(df) fill_tail[:, :] = np.nan z_future_pred = np.append(fill_tail, fill_tail, axis=1) # z_future_pred = np.append(z_future_pred, fill_tail, axis=1) z_future_pred = np.empty_like(z_future_pred) print(fill_tail.shape) print(z_future_pred.shape) # print(z_future_pred[-10:]) X_future = np.empty_like(X_test[:1]) print("========= Future Days =======") X_future[:,:] = np.nan print(" Original shape : ", X_future.shape) print(X_test[-1:]) X_future = np.append(X_test, X_future[lookback:], axis=0) # print(X_future[-10:]) print("Aftern append values : ", X_future.shape) X_future = torch.from_numpy(X_future[:lookback]).type(torch.Tensor) print("========= Future Days =======") print(X_future[-1:]) print(X_future.shape) z_future_pred = model(X_future) z_future_pred = scaler.inverse_transform(z_future_pred.detach().numpy()) # future_predictPlot[len(testPredictPlot)] = original_df = scaler.inverse_transform(df) # AAAAAAAAAAAAAAA bbb_future = np.empty_like(df) bbb_future[:,:] = np.nan bbb_future[-(lookback):, :] = aaa_future predictions = np.append(trainPredictPlot, testPredictPlot, axis=1) predictions = np.append(predictions, original_df, axis=1) predictions = np.append(predictions, bbb_future, axis=1) # predictions = np.append(predictions, z_future_pred, axis=1) result = pd.DataFrame(predictions) print(result[-6:]) print(real_data[-6:]) input() # plt.subplot(2,1,2) for i in range(1): plt.title("Train and Validation") # plt.plot(result.index, result[int(input("Index for Original : "))], label="Original", color="gray", linestyle="--", linewidth=2, alpha=0.3) # plt.plot(result.index, result[int(input("Index for Train : "))], label="Train", color="blue", marker=".", linewidth=1) # plt.plot(result.index, result[int(input("Index for Test : "))], label="Test", color="red", marker=".", linewidth=1) # plt.plot(result.index, result[int(input("Index for Test : "))], label="AAA", color="yellow", marker="o", linewidth=1) # Bar # plt.bar(result.index, result[int(input("Index for Original : "))], label="Original", color="gray", alpha=0.3) # plt.bar(result.index, result[int(input("Index for Train : "))], label="Train", color="blue") # plt.bar(result.index, result[int(input("Index for Test : "))], label="Test", color="red") # plt.bar(result.index, result[int(input("Index for Test : "))], label="AAA", color="cyan") plt.bar(result.index, result[8], label="Original", color="gray", alpha=0.3) plt.bar(result.index, result[2], label="Train", color="blue") plt.bar(result.index, result[5], label="Test", color="red") plt.bar(result.index, result[11], label="Prediction", color="cyan") # plt.plot(real_data.index, real_data[int(input("Index for real data"))], label="aaaaa") # plt.plot(result.index, result[3], color="red", marker=".", linewidth=1) # plt.xticks(range(0,data.shape[0],500),df['Close'][0].loc[::500],rotation=45) plt.legend() plt.show() filler = np.empty_like(y_test_pred[:lookback-2]) # filler[:,:] = np.nan print("====== Simple Forecasting =========") future_all = np.append(filler, y_train_pred, axis=0) future_all = np.append(future_all, y_test_pred, axis=0) future_all = np.append(future_all, z_future_pred, axis=0) future_all = pd.DataFrame(future_all) # plt.plot(original_df) plt.plot(original_df[6], color="gray", linestyle="--", linewidth=2, alpha=0.3) print(future_all.head()) plt.plot(future_all.index, future_all[0], marker=".") plt.title("Original data & Train+Test+Prediction Data") # plt.plot(future_all.index, future_all[1], marker=".") # plt.plot(future_all.index, future_all[2], marker=".") plt.show() print(result.tail()) if not os.path.exists("./models"): os.makedirs("./models") torch.save(model.state_dict(),"./models/my_model") m = torch.jit.script(model) m.save("./models/my_model.pt") # writer.add_graph(model)