import streamlit as st import yfinance as yf import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from fpdf import FPDF from io import BytesIO # Set Seaborn theme for visuals sns.set_theme(style="whitegrid") # App title st.set_page_config(page_title="Stock Analyzer with Monthly Report", layout="wide") st.title("📈 Stock Analyzer with Monthly Report") st.markdown("Analyze and visualize stock data using Yahoo Finance and generate monthly reports.") # Sidebar for user inputs st.sidebar.header("Stock Selection") ticker = st.sidebar.text_input("Enter Stock Ticker", value="AAPL", help="Enter the stock ticker symbol, e.g., AAPL, MSFT") start_date = st.sidebar.date_input("Start Date", value=pd.to_datetime("2020-01-01")) end_date = st.sidebar.date_input("End Date", value=pd.to_datetime("today")) show_stats = st.sidebar.checkbox("Show Summary Statistics", value=True) show_plot = st.sidebar.checkbox("Show Stock Chart", value=True) # Monthly Report Section st.sidebar.header("Generate Monthly Report") report_month = st.sidebar.date_input("Select Month for Report", value=pd.to_datetime("2024-10")) show_monthly_report = st.sidebar.checkbox("Generate Monthly Report", value=True) # Fetch stock data try: stock_data = yf.download(ticker, start=start_date, end=end_date) if not stock_data.empty: st.success(f"Data for **{ticker}** loaded successfully!") # Display stock data st.subheader("Stock Data") st.dataframe(stock_data, width=900) # Show summary statistics if show_stats: st.subheader("Summary Statistics") st.table(stock_data.describe()) # Plot stock price data if show_plot: st.subheader("Stock Price Chart") fig, ax = plt.subplots(figsize=(12, 6)) stock_data["Close"].plot(ax=ax, label="Closing Price") ax.set_title(f"{ticker} Closing Price ({start_date} to {end_date})") ax.set_xlabel("Date") ax.set_ylabel("Price (USD)") ax.legend() st.pyplot(fig) # Monthly Report if show_monthly_report: # Extract data for the selected month stock_data["Month"] = stock_data.index.to_period("M") selected_month = report_month.strftime("%Y-%m") monthly_data = stock_data[stock_data["Month"] == selected_month] if not monthly_data.empty: # Generate monthly statistics avg_price = monthly_data["Close"].mean() max_price = monthly_data["Close"].max() min_price = monthly_data["Close"].min() monthly_return = ((monthly_data["Close"].iloc[-1] - monthly_data["Close"].iloc[0]) / monthly_data["Close"].iloc[0]) * 100 # Display monthly statistics st.subheader(f"Monthly Report for {ticker} - {selected_month}") st.markdown(f""" - **Average Closing Price**: ${avg_price:.2f} - **Highest Closing Price**: ${max_price:.2f} - **Lowest Closing Price**: ${min_price:.2f} - **Monthly Return**: {monthly_return:.2f}% """) # Insights (simple) st.markdown("### Key Insights") if monthly_return > 0: st.markdown("- The stock showed positive growth this month.") else: st.markdown("- The stock showed a decline this month.") st.markdown(f"- The highest price was observed at **${max_price:.2f}**.") # Chart for monthly performance st.subheader("Monthly Closing Price Trend") fig, ax = plt.subplots(figsize=(12, 6)) monthly_data["Close"].plot(ax=ax, label="Closing Price", color="dodgerblue") ax.set_title(f"{ticker} - Closing Prices for {selected_month}", fontsize=16) ax.set_xlabel("Date") ax.set_ylabel("Price (USD)") ax.legend() st.pyplot(fig) # Generate a natural language report using a simple template st.subheader("Generated Monthly Report") st.markdown(f""" ### {ticker} - {selected_month} Report During the month of {selected_month}, {ticker} performed as follows: - The average closing price was **${avg_price:.2f}**. - The stock reached its highest price of **${max_price:.2f}** during the month. - The monthly return was **{monthly_return:.2f}%**, indicating {'positive growth' if monthly_return > 0 else 'a decline'}. Key observations: - The highest price was observed on **{monthly_data['Close'].idxmax().strftime('%Y-%m-%d')}**. - Overall, the stock {'maintained an upward trend' if monthly_return > 0 else 'experienced downward pressure'}. """) # Save the chart image chart_image = BytesIO() fig.savefig(chart_image, format='png') chart_image.seek(0) # Create PDF report def create_pdf(): pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) # Title pdf.set_font("Arial", 'B', 16) pdf.cell(200, 10, txt=f"Monthly Report for {ticker} - {selected_month}", ln=True, align="C") pdf.ln(10) # Summary Stats pdf.set_font("Arial", size=12) pdf.multi_cell(0, 10, txt=f""" During the month of {selected_month}, {ticker} performed as follows: - Average Closing Price: ${avg_price:.2f} - Highest Closing Price: ${max_price:.2f} - Lowest Closing Price: ${min_price:.2f} - Monthly Return: {monthly_return:.2f}% Key Observations: - The highest price was observed on {monthly_data['Close'].idxmax().strftime('%Y-%m-%d')}. - Overall, the stock {'maintained an upward trend' if monthly_return > 0 else 'experienced downward pressure'}. """) pdf.ln(10) # Add the chart image to PDF pdf.image(chart_image, x=10, y=pdf.get_y(), w=180) pdf.ln(100) # Space after the image # Add Footer pdf.set_font("Arial", 'I', 8) pdf.cell(200, 10, txt="Generated by Stock Analyzer", ln=True, align="C") # Save PDF to BytesIO for Streamlit download pdf_output = BytesIO() pdf.output(pdf_output) pdf_output.seek(0) return pdf_output # Add download button for PDF report pdf_data = create_pdf() st.download_button( label="Download PDF Report", data=pdf_data, file_name=f"{ticker}_monthly_report_{selected_month}.pdf", mime="application/pdf" ) else: st.warning(f"No data available for {selected_month}. Please try a different month.") else: st.warning(f"No data found for ticker **{ticker}** within the selected date range.") except Exception as e: st.error(f"An error occurred: {str(e)}") # Footer st.markdown("---") st.markdown("Designed By [Novizant](https://novizant.com/). ❤️")