bhuvaneshprasad
commited on
Commit
•
b9f3769
1
Parent(s):
de92895
Uploaded files
Browse files- .gitattributes +1 -0
- app.py +36 -0
- artifacts/data_ingestion/NIFTY 50_Historical.csv +0 -0
- artifacts/data_preprocessing/scaler.pkl +3 -0
- artifacts/model_training/model.keras +3 -0
- forecaster.py +100 -0
- requirements.txt +18 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
artifacts/model_training/model.keras filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import sys
|
3 |
+
from pathlib import Path
|
4 |
+
import plotly.graph_objs as go
|
5 |
+
|
6 |
+
root_dir = Path(__file__).resolve().parents[1]
|
7 |
+
sys.path.append(str(root_dir))
|
8 |
+
|
9 |
+
import forecaster
|
10 |
+
|
11 |
+
def main():
|
12 |
+
st.set_page_config(page_title="Nifty 50 Forecast")
|
13 |
+
st.title("Time Series Forecasting - Nifty 50")
|
14 |
+
|
15 |
+
if st.button("Forecast"):
|
16 |
+
with st.spinner('Forecasting...'):
|
17 |
+
forecast_df = forecaster.main()
|
18 |
+
forecast_df = forecast_df.round(2)
|
19 |
+
|
20 |
+
fig = go.Figure()
|
21 |
+
fig.add_trace(go.Scatter(x=forecast_df.index, y=forecast_df["Close"], mode='lines+markers', name='Forecasted Values'))
|
22 |
+
|
23 |
+
fig.update_layout(
|
24 |
+
title='Nifty 50 Close Forecast',
|
25 |
+
xaxis_title='Date',
|
26 |
+
yaxis_title='Close (Forecasted)',
|
27 |
+
xaxis_tickangle=-90,
|
28 |
+
width=800,
|
29 |
+
height=600
|
30 |
+
)
|
31 |
+
|
32 |
+
st.plotly_chart(fig)
|
33 |
+
st.write(forecast_df)
|
34 |
+
|
35 |
+
if __name__ == "__main__":
|
36 |
+
main()
|
artifacts/data_ingestion/NIFTY 50_Historical.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
artifacts/data_preprocessing/scaler.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1daff063af1b22ef2d61371bd1be3c1e29ec5828ae59a67f9173db4bdbee8454
|
3 |
+
size 1895
|
artifacts/model_training/model.keras
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c70843511ac13463887b37185236931e83f2923017bdca5e356e7d605e0068e3
|
3 |
+
size 2097961
|
forecaster.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import joblib
|
3 |
+
from matplotlib import pyplot as plt
|
4 |
+
import numpy as np
|
5 |
+
import pandas as pd
|
6 |
+
import tensorflow as tf
|
7 |
+
from tsForecaster.components.data_preprocessing import DataPreProcessing
|
8 |
+
from tsForecaster.config.configuration import ConfigurationManager
|
9 |
+
from tsForecaster.constants import CONFIG_FILE_PATH, PARAMS_FILE_PATH
|
10 |
+
from tsForecaster.utils.common import read_yaml
|
11 |
+
|
12 |
+
def create_features(df, pred):
|
13 |
+
|
14 |
+
df = df['Close%']
|
15 |
+
new_date = pd.date_range(df.index[-1] + pd.DateOffset(days=1), periods=1, freq='D')
|
16 |
+
new_close_value = pred
|
17 |
+
|
18 |
+
new_row = pd.DataFrame({'Close%': new_close_value}, index=[pd.to_datetime(new_date.values[0])])
|
19 |
+
df = pd.concat([df, new_row])
|
20 |
+
|
21 |
+
df['Close_1D_ago'] = df['Close%'].shift(1)
|
22 |
+
df['Close_2D_ago'] = df['Close%'].shift(2)
|
23 |
+
df['Close_3D_ago'] = df['Close%'].shift(3)
|
24 |
+
df['Close_1W_ago'] = df['Close%'].shift(7)
|
25 |
+
df['Close_2W_ago'] = df['Close%'].shift(14)
|
26 |
+
df['Close_1M_ago'] = df['Close%'].shift(30)
|
27 |
+
df['Close_2M_ago'] = df['Close%'].shift(60)
|
28 |
+
df['Close_3M_ago'] = df['Close%'].shift(90)
|
29 |
+
df['Close_6M_ago'] = df['Close%'].shift(180)
|
30 |
+
df['Close_1Y_ago'] = df['Close%'].shift(365)
|
31 |
+
df['Close_2Y_ago'] = df['Close%'].shift(930)
|
32 |
+
df['Close_3Y_ago'] = df['Close%'].shift(1095)
|
33 |
+
df['Close_5Y_ago'] = df['Close%'].shift(1825)
|
34 |
+
df['Close_7Y_ago'] = df['Close%'].shift(2555)
|
35 |
+
df['Close_10Y_ago'] = df['Close%'].shift(3650)
|
36 |
+
|
37 |
+
return df
|
38 |
+
|
39 |
+
def forecast(model, df, X, time_steps, scaler, close_df, future_steps=15, fig=False) -> pd.DataFrame:
|
40 |
+
future_predictions = []
|
41 |
+
last_row = X[-1:]
|
42 |
+
df_forecast = df.copy()
|
43 |
+
|
44 |
+
for step in range(future_steps):
|
45 |
+
|
46 |
+
next_close = model.predict(last_row)
|
47 |
+
future_predictions.append(next_close[0, 0])
|
48 |
+
df_forecast = create_features(df_forecast, next_close[0, 0])
|
49 |
+
last_row = df_forecast.iloc[-60:, 1:].values.reshape(1, time_steps, 15)
|
50 |
+
|
51 |
+
predicted_prices = np.array(future_predictions).reshape(-1, 1)
|
52 |
+
predicted_full_features = np.concatenate((predicted_prices, np.zeros((future_steps, 15))), axis=1)
|
53 |
+
predicted_values = scaler.inverse_transform(predicted_full_features)[:, 0]
|
54 |
+
predicted_values_list = predicted_values.flatten().tolist()
|
55 |
+
|
56 |
+
last_close = close_df.values[-1]
|
57 |
+
|
58 |
+
future_closes = []
|
59 |
+
|
60 |
+
for i in range(predicted_values_list.__len__()):
|
61 |
+
next_close = last_close * (1 + (predicted_values_list[i] / 100))
|
62 |
+
future_closes.append(next_close)
|
63 |
+
next_close = last_close
|
64 |
+
|
65 |
+
# Create a DataFrame for future predictions
|
66 |
+
future_dates = pd.date_range(start=df.index[-1] + pd.DateOffset(1), periods=future_steps, freq='D')
|
67 |
+
future_df = pd.DataFrame(future_closes, index=future_dates, columns=['Close'])
|
68 |
+
|
69 |
+
if fig:
|
70 |
+
plt.figure(figsize=(15, 5))
|
71 |
+
plt.plot(future_dates, future_df)
|
72 |
+
plt.show()
|
73 |
+
|
74 |
+
return future_df
|
75 |
+
|
76 |
+
def main() -> pd.DataFrame:
|
77 |
+
config_file = read_yaml(CONFIG_FILE_PATH)
|
78 |
+
params = read_yaml(PARAMS_FILE_PATH)
|
79 |
+
|
80 |
+
config = ConfigurationManager()
|
81 |
+
data_ingestion_config = config.get_data_ingestion_config()
|
82 |
+
data_preprocessing = DataPreProcessing(config=data_ingestion_config)
|
83 |
+
|
84 |
+
df = data_preprocessing.process_csv()
|
85 |
+
close_df = df['Close']
|
86 |
+
df.drop(columns=['Close'], inplace=True)
|
87 |
+
|
88 |
+
scaled_df = data_preprocessing.scaling_data(df)
|
89 |
+
scaler = joblib.load(os.path.join(config_file.data_ingestion.scaler_path, 'scaler.pkl'))
|
90 |
+
|
91 |
+
X, y, dates = data_preprocessing.create_sequences(scaled_df, params.TIME_STEPS)
|
92 |
+
model = tf.keras.models.load_model(config_file.model_training.trained_model_path)
|
93 |
+
|
94 |
+
forecast_df = forecast(model, scaled_df, X, params.TIME_STEPS, scaler, close_df, future_steps=15)
|
95 |
+
|
96 |
+
return forecast_df
|
97 |
+
|
98 |
+
if __name__ == '__main__':
|
99 |
+
forecast = main()
|
100 |
+
print(forecast)
|
requirements.txt
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tensorflow==2.17.0
|
2 |
+
opendatasets==0.1.22
|
3 |
+
yfinance==0.2.40
|
4 |
+
pandas==2.2.2
|
5 |
+
numpy
|
6 |
+
matplotlib==3.9.1
|
7 |
+
seaborn==0.13.2
|
8 |
+
python-box==7.2.0
|
9 |
+
pyYAML==6.0.1
|
10 |
+
tqdm==4.66.4
|
11 |
+
ensure==1.0.4
|
12 |
+
joblib==1.4.2
|
13 |
+
types-PyYAML==6.0.12
|
14 |
+
fastapi==0.111.0
|
15 |
+
streamlit==1.36.0
|
16 |
+
plotly==5.22.0
|
17 |
+
scikit-learn
|
18 |
+
-e .
|