Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| from prophet import Prophet | |
| import yfinance as yf | |
| from sklearn.metrics import mean_absolute_error, mean_squared_error | |
| from prophet.plot import plot_plotly, plot_components_plotly | |
| ticker_symbols = st.secrets["TICKER_SYMBOLS"].split(",") | |
| def fetch_stock_data(ticker_symbol, start_date, end_date): | |
| ticker_symbol = ticker_symbol +st.secrets["TICKER_FLAG"] | |
| stock_data = yf.download(ticker_symbol, start=start_date, end=end_date) | |
| df = stock_data[['Adj Close']].reset_index() | |
| df = df.rename(columns={'Date': 'ds', 'Adj Close': 'y'}) | |
| return df | |
| def train_prophet_model(df): | |
| model = Prophet() | |
| model.fit(df) | |
| return model | |
| def make_forecast(model, periods): | |
| future = model.make_future_dataframe(periods=periods) | |
| forecast = model.predict(future) | |
| return forecast | |
| def calculate_performance_metrics(actual, predicted): | |
| mae = mean_absolute_error(actual, predicted) | |
| mse = mean_squared_error(actual, predicted) | |
| rmse = np.sqrt(mse) | |
| return {'MAE': mae, 'MSE': mse, 'RMSE': rmse} | |
| def determine_sentiment(actual, predicted): | |
| if actual > predicted: | |
| sentiment = 'Negative' | |
| elif actual < predicted: | |
| sentiment = 'Positive' | |
| else: | |
| sentiment = 'Neutral' | |
| return sentiment | |
| def main(): | |
| st.title('Stock Prediction on NSE Stocks') | |
| st.sidebar.header('User Input Parameters') | |
| ticker_symbol = st.sidebar.selectbox('Enter Ticker Symbol', options=ticker_symbols, index=0) | |
| training_period = st.sidebar.selectbox('Select Training Period', | |
| options=['1 week', '1 month', '1 year', '10 years']) | |
| if training_period == '1 week': | |
| start_date = pd.to_datetime('today') - pd.DateOffset(weeks=1) | |
| elif training_period == '1 month': | |
| start_date = pd.to_datetime('today') - pd.DateOffset(months=1) | |
| elif training_period == '1 year': | |
| start_date = pd.to_datetime('today') - pd.DateOffset(years=1) | |
| elif training_period == '10 years': | |
| start_date = pd.to_datetime('today') - pd.DateOffset(years=10) | |
| end_date = pd.to_datetime('today') | |
| df = fetch_stock_data(ticker_symbol, start_date, end_date) | |
| forecast_horizon = st.sidebar.selectbox('Forecast Horizon', | |
| options=['Next day', 'Next week', 'Next month'], | |
| format_func=lambda x: x.capitalize()) | |
| horizon_mapping = {'Next day': 1, 'Next week': 7, 'Next month': 30} | |
| forecast_days = horizon_mapping[forecast_horizon] | |
| if st.sidebar.button('Forecast Stock Prices'): | |
| with st.spinner('Training model...'): | |
| model = train_prophet_model(df) | |
| forecast = make_forecast(model, forecast_days) | |
| forecast_reversed = forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].iloc[-forecast_days:].iloc[::-1] | |
| st.markdown(""" | |
| *The prediction was made using the Prophet forecasting model. The model was trained on historical stock data and used to forecast future prices based on the observed trends and patterns.* | |
| """) | |
| st.subheader(f'Forecast Summary for {ticker_symbol}') | |
| latest_forecast = forecast_reversed.iloc[0] | |
| actual_last_price = df["y"].iloc[-1] | |
| predicted_last_price = latest_forecast['yhat'] | |
| sentiment = determine_sentiment(actual_last_price, predicted_last_price) | |
| st.warning(f'The last available adjusted closing price for {ticker_symbol} on {end_date.strftime("%d %B %Y")} is **₹{actual_last_price:.2f}**.') | |
| if sentiment == 'Positive': | |
| st.success(f"**Prediction: ₹{latest_forecast['yhat']:.2f}/-**      Stoploss: ₹{latest_forecast['yhat_lower']:.2f}      Traget: {latest_forecast['yhat_upper']:.2f}") | |
| st.success(f"...valid for {forecast_horizon.lower()} time frame") | |
| elif sentiment == 'Negative': | |
| st.error(f"**Prediction: ₹{latest_forecast['yhat']:.2f}/-**      Stoploss: ₹{latest_forecast['yhat_lower']:.2f}      Traget: {latest_forecast['yhat_upper']:.2f}") | |
| st.error(f"...valid for {forecast_horizon.lower()} time frame") | |
| else: | |
| st.info(f"**Prediction: ₹{latest_forecast['yhat']:.2f}/-**      Stoploss: ₹{latest_forecast['yhat_lower']:.2f}      Traget: {latest_forecast['yhat_upper']:.2f}") | |
| st.info(f"...valid for {forecast_horizon.lower()} time frame") | |
| st.markdown(f""" | |
| **Find below the prediction Data for the {forecast_horizon.lower()}:** | |
| """) | |
| st.write(forecast_reversed) | |
| def evaluate_performance_metrics(metrics): | |
| evaluation = {} | |
| evaluation['MAE'] = 'Good' if metrics['MAE'] < 0.05 * (df['y'].max() - df['y'].min()) else 'Not Good' | |
| evaluation['MSE'] = 'Good' if metrics['MSE'] < 0.1 * (df['y'].max() - df['y'].min())**2 else 'Not Good' | |
| evaluation['RMSE'] = 'Good' if metrics['RMSE'] < 0.1 * (df['y'].max() - df['y'].min()) else 'Not Good' | |
| return evaluation | |
| actual = df['y'] | |
| predicted = forecast['yhat'][:len(df)] | |
| metrics = calculate_performance_metrics(actual, predicted) | |
| evaluation = evaluate_performance_metrics(metrics) | |
| metrics = calculate_performance_metrics(actual, predicted) | |
| MAE =metrics['MAE'] | |
| MSE = metrics['MSE'] | |
| RMSE = metrics['RMSE'] | |
| st.subheader('Performance Evaluation') | |
| st.write('The metrics below provide a quantitative measure of the model’s accuracy:') | |
| maecolor = "green" if evaluation["MAE"] == "Good" else "red" | |
| msecolor = "green" if evaluation["MSE"] == "Good" else "red" | |
| rmsecolor = "green" if evaluation["RMSE"] == "Good" else "red" | |
| st.markdown(f'- **Mean Absolute Error (MAE):** {MAE:.2f} - :{maecolor}[{"Good" if evaluation["MAE"] == "Good" else "Not good"}] ') | |
| st.markdown("(The average absolute difference between predicted and actual values.)") | |
| st.markdown(f'- **Mean Squared Error (MSE):** {MSE:.2f} - :{msecolor}[{"Good" if evaluation["MSE"] == "Good" else "Not good"}] ') | |
| st.markdown("(The average squared difference between predicted and actual values.)") | |
| st.markdown(f'- **Root Mean Squared Error (RMSE):** {RMSE:.2f} - :{rmsecolor}[{"Good" if evaluation["RMSE"] == "Good" else "Not good"}] ') | |
| st.markdown("(The square root of MSE, which is more interpretable in the same units as the target variable.)") | |
| # Footer | |
| st.markdown(""" | |
| <style> | |
| .footer { | |
| position: fixed; | |
| left: 0; | |
| bottom: 0; | |
| width: 100%; | |
| background-color: #f8f9fa; | |
| color: black; | |
| text-align: center; | |
| padding: 10px 0; | |
| font-size: 14px; | |
| border-top: 1px solid #e7e7e7; | |
| } | |
| .footer .quote { | |
| font-style: italic; | |
| color: #555; | |
| } | |
| .footer .author { | |
| margin-top: 5px; | |
| font-weight: bold; | |
| color: #333; | |
| } | |
| .footer .credit { | |
| margin-top: 5px; | |
| font-size: 12px; | |
| color: #777; | |
| } | |
| </style> | |
| <div class="footer"> | |
| <div class="quote">"The best investment you can make is an investment in yourself." - Warren Buffett</div> | |
| <div class="author">❤️ Made by Mohsin ❤️</div> | |
| <div class="credit">© 2024 Mohsin. All rights reserved.</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Run the main function | |
| if __name__ == "__main__": | |
| main() |