import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots import numpy as np from datetime import datetime import io # Page configuration st.set_page_config( page_title="πŸ“Š FinanceGPT Analyzer", page_icon="πŸ“Š", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for better styling st.markdown(""" """, unsafe_allow_html=True) class FinanceAnalyzer: def __init__(self): self.data = None self.processed_data = {} def load_sample_data(self): """Load sample financial data""" sample_data = { 'Year': [2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023], 'Statement_Type': ['Income Statement'] * 10 + ['Income Statement'] * 10, 'Account_Name_Norwegian': ['Salgsinntekt', 'Varekostnad', 'Bruttoresultat', 'LΓΈnnskostnad', 'Andre driftskostnader', 'Driftsresultat', 'Finansinntekter', 'Finanskostnader', 'OrdinΓ¦rt resultat fΓΈr skatt', 'Γ…rsresultat'] * 2, 'Account_Name_English': ['Sales Revenue', 'Cost of Goods Sold', 'Gross Profit', 'Salary Costs', 'Other Operating Expenses', 'Operating Result', 'Financial Income', 'Financial Expenses', 'Profit Before Tax', 'Net Profit'] * 2, '2024_Amount_NOK': [25107008, -15064205, 10042803, -3521456, -1987234, 4534113, 123456, -234567, 4422002, 3537602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], '2023_Amount_NOK': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4891891, -2934535, 1957356, -1234567, -654321, 68468, 45678, -123456, -9310, -7448] } return pd.DataFrame(sample_data) def process_financial_data(self, df): """Process uploaded financial data""" self.data = df # Create pivot tables for easier analysis income_2024 = df[df['Year'] == 2024]['2024_Amount_NOK'].values income_2023 = df[df['Year'] == 2023]['2023_Amount_NOK'].values accounts = df[df['Year'] == 2024]['Account_Name_English'].values self.processed_data = { 'revenue_2024': income_2024[0] if len(income_2024) > 0 else 0, 'revenue_2023': income_2023[0] if len(income_2023) > 0 else 0, 'net_profit_2024': income_2024[9] if len(income_2024) > 9 else 0, 'net_profit_2023': income_2023[9] if len(income_2023) > 9 else 0, 'cogs_2024': abs(income_2024[1]) if len(income_2024) > 1 else 0, 'cogs_2023': abs(income_2023[1]) if len(income_2023) > 1 else 0, 'operating_profit_2024': income_2024[5] if len(income_2024) > 5 else 0, 'operating_profit_2023': income_2023[5] if len(income_2023) > 5 else 0, } def calculate_metrics(self): """Calculate key financial metrics""" if not self.processed_data: return {} data = self.processed_data # Growth rates revenue_growth = ((data['revenue_2024'] - data['revenue_2023']) / abs(data['revenue_2023']) * 100) if data['revenue_2023'] != 0 else 0 # Profitability ratios gross_margin_2024 = ((data['revenue_2024'] - data['cogs_2024']) / data['revenue_2024'] * 100) if data['revenue_2024'] != 0 else 0 net_margin_2024 = (data['net_profit_2024'] / data['revenue_2024'] * 100) if data['revenue_2024'] != 0 else 0 return { 'revenue_growth': revenue_growth, 'gross_margin_2024': gross_margin_2024, 'net_margin_2024': net_margin_2024, 'revenue_2024_m': data['revenue_2024'] / 1000000, 'net_profit_2024_m': data['net_profit_2024'] / 1000000, } def create_revenue_trend_chart(self): """Create revenue trend visualization""" if not self.processed_data: return go.Figure() fig = go.Figure() years = [2023, 2024] revenues = [self.processed_data['revenue_2023']/1000000, self.processed_data['revenue_2024']/1000000] net_profits = [self.processed_data['net_profit_2023']/1000000, self.processed_data['net_profit_2024']/1000000] fig.add_trace(go.Scatter(x=years, y=revenues, mode='lines+markers', name='Revenue (M NOK)', line=dict(color='#1f77b4', width=3))) fig.add_trace(go.Scatter(x=years, y=net_profits, mode='lines+markers', name='Net Profit (M NOK)', line=dict(color='#ff7f0e', width=3))) fig.update_layout(title='Revenue vs Profit Trend', xaxis_title='Year', yaxis_title='Amount (M NOK)', height=400) return fig def create_financial_health_radar(self): """Create financial health radar chart""" metrics = self.calculate_metrics() categories = ['Revenue Growth', 'Gross Margin', 'Net Margin', 'Profitability', 'Efficiency'] values = [ min(metrics.get('revenue_growth', 0) / 5, 100), # Scale revenue growth metrics.get('gross_margin_2024', 0), max(metrics.get('net_margin_2024', 0), 0), 70, # Sample value 65 # Sample value ] fig = go.Figure() fig.add_trace(go.Scatterpolar( r=values, theta=categories, fill='toself', name='Financial Health' )) fig.update_layout( polar=dict( radialaxis=dict(visible=True, range=[0, 100]) ), title="Financial Health Score", height=400 ) return fig def main(): st.title("πŸ“Š FinanceGPT Analyzer") st.markdown("### Professional Financial Analysis Dashboard") analyzer = FinanceAnalyzer() # Sidebar navigation with st.sidebar: st.header("Navigation") page = st.selectbox("Choose Analysis Page", [ "🏠 Dashboard", "πŸ’° Income Analysis", "πŸ›οΈ Balance Sheet Analysis", "πŸ’Έ Cash Flow Analysis", "πŸ“Š Financial Ratios Hub", "πŸ€– AI Finance Assistant" ]) st.header("Data Upload") uploaded_file = st.file_uploader("Upload CSV file", type=['csv']) if st.button("Use Sample Data"): analyzer.data = analyzer.load_sample_data() analyzer.process_financial_data(analyzer.data) st.success("Sample data loaded!") if uploaded_file: try: df = pd.read_csv(uploaded_file) analyzer.data = df analyzer.process_financial_data(df) st.success("Data uploaded successfully!") except Exception as e: st.error(f"Error loading file: {e}") # Main content based on selected page if page == "🏠 Dashboard": dashboard_page(analyzer) elif page == "πŸ’° Income Analysis": income_analysis_page(analyzer) elif page == "πŸ›οΈ Balance Sheet Analysis": balance_sheet_page(analyzer) elif page == "πŸ’Έ Cash Flow Analysis": cash_flow_page(analyzer) elif page == "πŸ“Š Financial Ratios Hub": ratios_page(analyzer) elif page == "πŸ€– AI Finance Assistant": ai_assistant_page(analyzer) def dashboard_page(analyzer): """Main dashboard page""" st.header("πŸ“Š Financial Dashboard") if analyzer.data is None: st.warning("Please upload data or use sample data to begin analysis.") return metrics = analyzer.calculate_metrics() # Key metrics cards col1, col2, col3, col4 = st.columns(4) with col1: st.markdown("""

πŸ’° Revenue

{:.1f}M NOK

+{:.0f}% πŸ”₯

""".format(metrics.get('revenue_2024_m', 0), metrics.get('revenue_growth', 0)), unsafe_allow_html=True) with col2: st.markdown("""

πŸ“ˆ Net Profit

{:.1f}M NOK

Profitable βœ…

""".format(metrics.get('net_profit_2024_m', 0)), unsafe_allow_html=True) with col3: st.markdown("""

πŸ“Š Gross Margin

{:.1f}%

Healthy πŸ’ͺ

""".format(metrics.get('gross_margin_2024', 0)), unsafe_allow_html=True) with col4: st.markdown("""

🎯 Net Margin

{:.1f}%

Strong πŸ“ˆ

""".format(metrics.get('net_margin_2024', 0)), unsafe_allow_html=True) # Charts section col1, col2 = st.columns(2) with col1: st.plotly_chart(analyzer.create_revenue_trend_chart(), use_container_width=True) with col2: st.plotly_chart(analyzer.create_financial_health_radar(), use_container_width=True) # Quick insights st.markdown("""

🎯 Quick Insights

""".format( metrics.get('revenue_growth', 0), metrics.get('net_margin_2024', 0), metrics.get('gross_margin_2024', 0) ), unsafe_allow_html=True) def income_analysis_page(analyzer): """Income statement analysis page""" st.header("πŸ’° Income Analysis") if analyzer.data is None: st.warning("Please upload data to begin analysis.") return # Revenue analysis st.subheader("πŸ“ˆ Revenue Trend Analysis") st.plotly_chart(analyzer.create_revenue_trend_chart(), use_container_width=True) # Cost structure st.subheader("πŸ₯§ Cost Structure Analysis") if analyzer.processed_data: data = analyzer.processed_data costs = ['Cost of Goods Sold', 'Operating Expenses', 'Financial Expenses'] values = [data['cogs_2024'], 2000000, 234567] # Sample values fig = px.pie(values=values, names=costs, title="Cost Breakdown 2024") st.plotly_chart(fig, use_container_width=True) # Profitability metrics st.subheader("πŸ“Š Profitability Indicators") metrics = analyzer.calculate_metrics() col1, col2, col3 = st.columns(3) with col1: st.metric("Gross Margin", f"{metrics.get('gross_margin_2024', 0):.1f}%") with col2: st.metric("Net Margin", f"{metrics.get('net_margin_2024', 0):.1f}%") with col3: st.metric("Revenue Growth", f"{metrics.get('revenue_growth', 0):.1f}%") def balance_sheet_page(analyzer): """Balance sheet analysis page""" st.header("πŸ›οΈ Balance Sheet Analysis") if analyzer.data is None: st.warning("Please upload balance sheet data to begin analysis.") return st.info("Balance sheet analysis requires additional data. Please upload complete financial statements.") # Sample asset structure chart assets = ['Current Assets', 'Fixed Assets', 'Intangible Assets'] values = [45, 35, 20] fig = px.pie(values=values, names=assets, title="Asset Structure") st.plotly_chart(fig, use_container_width=True) def cash_flow_page(analyzer): """Cash flow analysis page""" st.header("πŸ’Έ Cash Flow Analysis") if analyzer.data is None: st.warning("Please upload cash flow data to begin analysis.") return st.info("Cash flow analysis requires additional data. Please upload complete cash flow statements.") # Sample cash flow chart categories = ['Operating CF', 'Investing CF', 'Financing CF'] values = [5000000, -2000000, -1000000] fig = go.Figure(go.Waterfall( name="Cash Flow", orientation="v", measure=["relative", "relative", "relative"], x=categories, y=values, text=[f"{v/1000000:.1f}M" for v in values] )) fig.update_layout(title="Cash Flow Waterfall") st.plotly_chart(fig, use_container_width=True) def ratios_page(analyzer): """Financial ratios analysis page""" st.header("πŸ“Š Financial Ratios Hub") if analyzer.data is None: st.warning("Please upload data to calculate ratios.") return # Ratio categories col1, col2, col3, col4 = st.columns(4) with col1: if st.button("Profitability"): st.session_state.ratio_category = "profitability" with col2: if st.button("Liquidity"): st.session_state.ratio_category = "liquidity" with col3: if st.button("Efficiency"): st.session_state.ratio_category = "efficiency" with col4: if st.button("Growth"): st.session_state.ratio_category = "growth" # Display ratios based on selection metrics = analyzer.calculate_metrics() st.subheader("Key Financial Ratios") col1, col2, col3 = st.columns(3) with col1: st.metric("Gross Profit Margin", f"{metrics.get('gross_margin_2024', 0):.1f}%", "A+") with col2: st.metric("Net Profit Margin", f"{metrics.get('net_margin_2024', 0):.1f}%", "A") with col3: st.metric("Revenue Growth", f"{metrics.get('revenue_growth', 0):.1f}%", "A+") def ai_assistant_page(analyzer): """AI finance assistant page""" st.header("πŸ€– AI Finance Assistant") if analyzer.data is None: st.warning("Please upload data to enable AI analysis.") return # Chat interface st.subheader("πŸ’¬ Ask Your Financial Questions") # Predefined questions col1, col2 = st.columns(2) with col1: if st.button("Analyze my financial health"): st.session_state.ai_query = "financial_health" if st.button("Find the biggest risks"): st.session_state.ai_query = "risks" with col2: if st.button("Give investment advice"): st.session_state.ai_query = "investment" if st.button("Create improvement plan"): st.session_state.ai_query = "improvement" # Text input for custom questions user_question = st.text_input("Or ask your own question:") if user_question or 'ai_query' in st.session_state: metrics = analyzer.calculate_metrics() # Simple AI-like responses based on data if user_question or st.session_state.get('ai_query') == 'financial_health': st.markdown("""

🎯 Financial Health Analysis

Based on your financial data:

""".format( metrics.get('revenue_growth', 0), metrics.get('net_margin_2024', 0) ), unsafe_allow_html=True) # Clear the session state if 'ai_query' in st.session_state: del st.session_state.ai_query if __name__ == "__main__": main()