File size: 5,677 Bytes
4aabfcc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import pandas as pd
import numpy as np
import yfinance as yf
from datetime import date, timedelta
import matplotlib.pyplot as plt
from pmdarima.arima import auto_arima

# Custom CSS for professional look
st.markdown("""

    <style>

        .main {

            background-color: #f5f5f5;

            padding: 20px;

        }

        .sidebar .sidebar-content {

            background-color: #fafafa;

        }

        .stButton>button {

            background-color: #2e7d32;

            color: white;

            border-radius: 5px;

            font-weight: bold;

        }

        .stButton>button:hover {

            background-color: #388e3c;

        }

        h1, h2, h3 {

            color: #333;

        }

        .stDataFrame {

            background-color: #ffffff;

        }

        .stTable {

            color: #333;

        }

        .stPlotlyChart {

            background-color: #ffffff;

        }

    </style>

""", unsafe_allow_html=True)

# App Title
st.title("πŸ“ˆ Stock Market Forecasting")

# Sidebar Inputs
st.sidebar.header("User Input")

# Inputs for stock ticker, date range, and forecast days
ticker = st.sidebar.text_input("Enter stock ticker:", value="GOOGL")
end_date = st.sidebar.date_input("End Date", value=date.today())
start_date = st.sidebar.date_input("Start Date", value=date.today() - timedelta(days=365))
forecast_days = st.sidebar.slider("Forecast days", min_value=10, max_value=30, value=15)

# Ensure start_date is not later than end_date
if start_date > end_date:
    st.sidebar.error("❌ Start date cannot be later than end date.")
    st.stop()

# Feature selection for stock attributes (e.g., Close, High, Low, Open)
feature_select = st.sidebar.multiselect(
    label="Select Stock Features to Forecast",
    options=["Close", "High", "Low", "Open"],
    default=["Close"]
)

# Feature descriptions (explanation for each stock feature)
feature_descriptions = {
    "Close": "The closing price of the stock at the end of the trading day.",
    "High": "The highest price at which the stock traded during the day.",
    "Low": "The lowest price at which the stock traded during the day.",
    "Open": "The price at which the stock opened at the beginning of the trading day."
}

# Fetch Stock Data based on user input
if st.sidebar.button("Fetch Data"):
    st.subheader(f"Stock Data for {ticker.upper()} ({start_date} to {end_date})")

    try:
        # Download stock data from Yahoo Finance
        df = yf.download(ticker, start=start_date, end=end_date, progress=False)

        # Check if data is available
        if df.empty:
            st.error("❌ No data found for the selected ticker or date range.")
            st.stop()

        st.success("βœ… Data fetched successfully!")

        # Reset index and insert 'Date' column for better readability
        df.insert(0, "Date", df.index)
        df.reset_index(drop=True, inplace=True)

        st.dataframe(df.head())  # Display first few rows of the stock data

        # Initialize an empty DataFrame to store forecasted data for all features
        combined_forecast_df = pd.DataFrame()

        # Iterate over each selected feature and generate forecasts
        for feature in feature_select:
            st.write(f"### πŸ” Forecasting: {feature}")
            st.write(feature_descriptions[feature])

            # Prepare the time series for forecasting (drop NaN values)
            series = df[feature].dropna()

            # Fit the ARIMA model using the selected feature's time series
            model = auto_arima(series,
                               start_p=1, start_q=1,
                               max_p=2, max_q=2,
                               m=12,  # Monthly seasonal cycle
                               start_P=0,
                               seasonal=True,
                               d=1, D=1,
                               trace=True,  # Display fitting progress
                               error_action='ignore',
                               suppress_warnings=True)

            # Forecast future values for the specified number of days
            forecast = model.predict(n_periods=forecast_days)
            future_dates = pd.date_range(start=df["Date"].iloc[-1] + timedelta(days=1), periods=forecast_days)

            # Create a DataFrame to hold the forecasted values
            forecast_df = pd.DataFrame({
                "Date": future_dates,
                feature: forecast
            })

            # Combine the forecasted data for each feature into a single DataFrame
            combined_forecast_df = pd.merge(combined_forecast_df, forecast_df, on="Date", how="outer") if not combined_forecast_df.empty else forecast_df

            # Plot historical data and forecasted data
            fig, ax = plt.subplots(figsize=(10, 4))
            ax.plot(df["Date"], series, label="Historical", color='blue')  # Historical data
            ax.plot(forecast_df["Date"], forecast_df[feature], label="Forecast", color='orange')  # Forecasted data
            ax.set_title(f"{feature} Forecast for {ticker.upper()}")
            ax.set_xlabel("Date")
            ax.set_ylabel(feature)
            ax.legend()

            # Display the plot
            st.pyplot(fig)

        # Display the combined forecasted data for all selected features
        st.subheader("Combined Forecasted Data")
        st.dataframe(combined_forecast_df.head())

    except Exception as e:
        st.error(f"❌ An error occurred: {str(e)}")
        st.stop()