-
Notifications
You must be signed in to change notification settings - Fork 2
/
predictive_analysis.py
210 lines (156 loc) · 8.54 KB
/
predictive_analysis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# -*- coding: utf-8 -*-
"""
#=============================================================================#
#Created on Fri Nov 15 13:28:26 2019 #
# #
#author: Fuad Goloba/Darshan Amin/Alp Ates #
#=============================================================================#
"""
#import Packages
from math import sqrt
import numpy as np
import matplotlib.pyplot as plt
import general_funtions as gen
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from pmdarima.arima import auto_arima
#==============================================================================
# Descriptive Analysis Menu
#==============================================================================
def predictive(comp_data, cmp_tick, cmp_name):
"""Descriptive analysis menu"""
des_flag = 0
while des_flag == 0:
#Clear Screen and display header
gen.clear_screen()
gen.menu_head()
#display option for descriptive
print("Predictive Analysis for {} -> {}".format(cmp_tick, cmp_name))
print("\n")
print("Press 1 to see stock prediction using Linear Regression\n")
print("Press 2 to see stock prediction using ARIMA\n")
print("Press 3 to go back\n")
print("Press any other key to exit\n")
desc_opt = input("Enter your option: ")
if desc_opt == '1':
linear_regression(comp_data, cmp_tick, cmp_name)
elif desc_opt == "2":
arima_prediction(comp_data, cmp_tick, cmp_name)
elif desc_opt == "3":
des_flag = 1
else:
exit()
#==============================================================================
# Linear regression
#==============================================================================
def linear_regression(cmp_data, cmp_tick, cmp_name):
"""Perform Linear regression prediction"""
#Clear the screen and display main header
gen.clear_screen()
gen.menu_head()
print("Stock Price Prediction for {} -> {} using Linear Regression".format(cmp_tick, cmp_name))
#if there was a holiday or weekend then fill the data of the holiday/weekend
#with the data for previous working day as the price wont change during holiday
#and the next working day will open with the closing price of last woking day
cmp_data = cmp_data.resample("D").ffill()
#get from and to dates and filted company data
frm_date, to_date, from_date_s, to_date_s, filter_data = gen.get_dates_data(cmp_data, 1)
#get prediction date from user
predict_date = gen.input_date_validate("prediction date", 0)
predict_dt_s = str(predict_date.strftime("%d/%m/%Y"))
#get the range of dates within training window
filter_date = np.array(filter_data.index)
#get closing price in an n x 1 array
filter_close = np.array(filter_data.Close).reshape(len(filter_data.Close), 1)
#convert dates into index starting from 0 and store it in n x 1 array
filter_days = np.arange(0, len(filter_date)).reshape(len(filter_date), 1)
#divide the training window into 80% test and 20% training window
xdays_train, xdays_test, yclose_train, yclose_test = train_test_split(filter_days, filter_close, test_size = 0.2)
#initiate linear regression
linear_reg = LinearRegression()
#Train the regression training window
linear_reg.fit(xdays_train, yclose_train)
#test the regression model and get the r^2 value (self confidence)
linear_self_conf = linear_reg.score(xdays_test, yclose_test)
print("R Square Value is:", round(linear_self_conf, 2))
#get the root mean square error value
rt_mean_err = sqrt(np.mean((linear_reg.predict(xdays_test) - yclose_test)**2))
print("Root mean square error is: ", round(rt_mean_err, 2))
#predict the prices in the training window
close_predict = linear_reg.predict(filter_days)
#calculate no of days between prediction date and from date of training window
days_dif = np.array((predict_date - frm_date).days).reshape(-1,1)
#get the predicted price for predicted date
predict_lr = linear_reg.predict(days_dif)
print("Predicted price for {} on {} is: {}".format(cmp_tick, predict_dt_s, str(round(predict_lr[0][0], 2))))
#Plot predicted v/s actual closing price for the training period
plt.figure(figsize=(15,6))
plt.title("Actual V/S Predicted Closing Price for {} -> {} from - {} Training Window".format(cmp_tick, cmp_name, from_date_s, to_date_s))
plt.plot(filter_data.index, filter_data.Close, "g", label = "Actual Closing Price")
plt.plot(filter_data.index, close_predict, "r", label = "Predicted Closing Price")
plt.xlabel("Time")
plt.ylabel("Stock Price")
plt.legend(loc = "best")
plt.show()
#display options to go baack or quit
print("\n")
print("Press 1 to go back\n")
print("Press any key to exit\n")
lr_input = input("Enter your option: ")
if lr_input != "1":
exit()
#==============================================================================
# Arima Prediction
#==============================================================================
def arima_prediction(cmp_data, cmp_tick, cmp_name):
"""Arima Model Prediction using Auto arima"""
#Clear the screen and display main header
gen.clear_screen()
gen.menu_head()
print("Stock Price Prediction for {} -> using ARIMA\n".format(cmp_tick, cmp_name))
#if there was a holiday or weekend then fill the data of the holiday/weekend
#with the data for previous working day as the price wont change during holiday
#and the next working day will open with the closing price of last woking day
cmp_data = cmp_data.resample("D").ffill()
#get from and to dates and filted company data
frm_date, to_date, from_date_s, to_date_s, filter_data = gen.get_dates_data(cmp_data, 1)
#get prediction date from user
predict_date = gen.input_date_validate("prediction date", 0)
while predict_date <= to_date:
predict_date = gen.input_date_validate("prediction date", 2)
predict_dt_s = str(predict_date.strftime("%d/%m/%Y"))
#get clsing price for the window
closing_price = filter_data.Close
#set initial 80 % as training and last 20 % as testing
closing_training = closing_price[:int(0.8*(len(closing_price)))]
closing_test = closing_price[int(0.8*(len(closing_price))):]
#Train Arima using Auto arima function
closing_arima = auto_arima(closing_training, error_action = 'ignore', suppress_warnings = True)
closing_arima.fit(closing_training)
#Predict the Test period closing price
close_test_pred = closing_arima.predict(n_periods = len(closing_test))
#get RMSE Value
close_rmse = sqrt(mean_squared_error(closing_test, close_test_pred))
print("Root mean square error is: {}".format(str(round(close_rmse, 2))))
#calculate no of days between prediction date and to date of training window
days_dif = int((predict_date - to_date).days)
#predict Price of prediction date
close_predict = closing_arima.predict(n_periods = days_dif)
print("Predicted price for {} on {} is: {}".format(cmp_tick, predict_dt_s, str(round(close_predict[-1], 2))))
#plot actual vs predicted
plt.figure(figsize=(15,6))
plt.title("Actual V/S Predicted Closing Price for {} -> {} from {} - {} Training Window".format(cmp_tick, cmp_name, from_date_s, to_date_s))
plt.plot(closing_training, "g", label = "Actual Closing Price")
plt.plot(closing_test, "y", label = "Actual Closing period used for test")
plt.plot(closing_test.index, close_test_pred, "r", label = "Predicted Test Closing price")
plt.xlabel("Time")
plt.ylabel("Stock Price")
plt.legend(loc = "best")
plt.show()
#display options to go baack or quit
print("\nPress 1 to go back\n")
print("Press any key to exit\n")
ar_input = input("Enter your option: ")
if ar_input != "1":
exit()