| import streamlit as st |
| import yfinance as yf |
| import plotly.graph_objects as go |
| from prophet import Prophet |
| import pandas as pd |
| import matplotlib.pyplot as plt |
| from statsmodels.tsa.seasonal import seasonal_decompose |
|
|
| from statsmodels.graphics.gofplots import qqplot |
|
|
| |
| st.set_page_config(layout="wide") |
| st.set_option('deprecation.showPyplotGlobalUse', False) |
|
|
|
|
| |
| def display_header(): |
| st.sidebar.title("Navigation") |
| st.sidebar.info(""" |
| This application is designed to provide users with financial insights and predictive analysis |
| on various stocks using real-time data from Yahoo Finance. Created by Gokul Palanisamy. |
| """) |
| st.sidebar.title("About Us") |
| st.sidebar.info(""" |
| Developed by Gokul Palanisamy, this tool helps users make informed investment decisions by |
| analyzing historical data and predicting future stock trends. |
| """) |
| st.sidebar.title("Contact Us") |
| st.sidebar.info(""" |
| Email: [gokulp@bu.edu](mailto:gokulp@bu.edu) |
| Phone: +1 (857) 832-0441 |
| More Information: [Gokul Palanisamy](https://www.linkedin.com/in/gokulp/) |
| """) |
|
|
|
|
| display_header() |
|
|
| |
| st.markdown("## StocX AI") |
| col1, col2, col3 = st.columns(3) |
| with col1: |
| stock1 = st.text_input('Enter Stock Ticker Symbol 1', value='', key='stock1_input') |
| with col2: |
| stock2 = st.text_input('Enter Stock Ticker Symbol 2', value='', key='stock2_input') |
| with col3: |
| daysago = st.text_input('Select Time Frame in Days (write "max" for maximum time)', value='1y', key='daysago_input') |
| forecast_out = st.slider('Predicted Days Ahead', 1, 180, 30) |
|
|
|
|
| |
| def fetch_data(ticker, period): |
| return yf.Ticker(ticker).history(period=period) |
|
|
|
|
| data1, data2 = None, None |
| if stock1: |
| data1 = fetch_data(stock1, daysago) |
| st.write(f'### {stock1} Stock Data') |
| st.write(data1) |
|
|
| if stock2: |
| data2 = fetch_data(stock2, daysago) |
| st.write(f'### {stock2} Stock Data') |
| st.write(data2) |
|
|
|
|
| |
| def compare_stocks(stock1, data1, stock2, data2): |
| if data1 is not None and data2 is not None: |
| |
| pct_change1 = (data1['Close'].iloc[-1] - data1['Close'].iloc[0]) / data1['Close'].iloc[0] * 100 |
| pct_change2 = (data2['Close'].iloc[-1] - data2['Close'].iloc[0]) / data2['Close'].iloc[0] * 100 |
|
|
| better_stock = stock1 if pct_change1 > pct_change2 else stock2 |
| reason = f"{better_stock} had a higher percentage change ({max(pct_change1, pct_change2):.2f}%) over the period." |
|
|
| st.write("## Stock Performance Comparison") |
| st.write(f"**{stock1}** percentage change: {pct_change1:.2f}%") |
| st.write(f"**{stock2}** percentage change: {pct_change2:.2f}%") |
| st.write(f"**Better Performing Stock:** {better_stock}") |
| st.write(f"**Reason:** {reason}") |
|
|
|
|
| if stock1 and stock2 and data1 is not None and data2 is not None: |
| compare_stocks(stock1, data1, stock2, data2) |
|
|
|
|
| |
| def perform_analysis(stock, data): |
| if data is not None and not data.empty: |
| st.write(f"### {stock} Detailed Analysis") |
|
|
| |
| st.write(f"#### Time Series Decomposition") |
| decomposition = seasonal_decompose(data['Close'], period=30, model='additive') |
| fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, figsize=(10, 8)) |
| decomposition.observed.plot(ax=ax1, title='Observed') |
| decomposition.trend.plot(ax=ax2, title='Trend') |
| decomposition.seasonal.plot(ax=ax3, title='Seasonal') |
| decomposition.resid.plot(ax=ax4, title='Residual') |
| plt.tight_layout() |
| st.pyplot() |
|
|
| |
| st.write(f"#### Prophet Forecast") |
| df_prophet = pd.DataFrame(data={'ds': data.index, 'y': data['Close']}) |
| df_prophet['ds'] = pd.to_datetime(df_prophet['ds']).dt.tz_localize(None) |
| model = Prophet() |
| model.fit(df_prophet) |
| future = model.make_future_dataframe(periods=forecast_out) |
| forecast = model.predict(future) |
| fig = plot_prophet_forecast(model, forecast) |
| st.plotly_chart(fig) |
|
|
|
|
| |
| def plot_prophet_forecast(model, forecast): |
| fig = go.Figure() |
| fig.add_trace(go.Scatter(x=model.history['ds'], y=model.history['y'], mode='lines', name='Actual')) |
| fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat'], mode='lines+markers', name='Forecast')) |
| fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill=None, mode='lines', |
| line=dict(color='gray', dash='dash'), name='Upper Confidence Interval')) |
| fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='lines', |
| line=dict(color='gray', dash='dash'), name='Lower Confidence Interval')) |
| fig.update_layout(title='Prophet Forecast and Confidence Intervals', xaxis_title='Date', yaxis_title='Values', |
| hovermode='x') |
| return fig |
|
|
|
|
| |
| if stock1 and data1 is not None: |
| perform_analysis(stock1, data1) |
| if stock2 and data2 is not None: |
| perform_analysis(stock2, data2) |
|
|