entropy25's picture
Update app.py
ff6dcea verified
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("""
<style>
.metric-card {
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
padding: 1rem;
border-radius: 10px;
color: white;
text-align: center;
margin: 0.5rem 0;
}
.insight-box {
background: #f8f9fa;
padding: 1rem;
border-left: 4px solid #007bff;
border-radius: 5px;
margin: 1rem 0;
}
.warning-box {
background: #fff3cd;
padding: 1rem;
border-left: 4px solid #ffc107;
border-radius: 5px;
margin: 1rem 0;
}
</style>
""", 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("""
<div class="metric-card">
<h3>💰 Revenue</h3>
<h2>{:.1f}M NOK</h2>
<p>+{:.0f}% 🔥</p>
</div>
""".format(metrics.get('revenue_2024_m', 0), metrics.get('revenue_growth', 0)),
unsafe_allow_html=True)
with col2:
st.markdown("""
<div class="metric-card">
<h3>📈 Net Profit</h3>
<h2>{:.1f}M NOK</h2>
<p>Profitable ✅</p>
</div>
""".format(metrics.get('net_profit_2024_m', 0)), unsafe_allow_html=True)
with col3:
st.markdown("""
<div class="metric-card">
<h3>📊 Gross Margin</h3>
<h2>{:.1f}%</h2>
<p>Healthy 💪</p>
</div>
""".format(metrics.get('gross_margin_2024', 0)), unsafe_allow_html=True)
with col4:
st.markdown("""
<div class="metric-card">
<h3>🎯 Net Margin</h3>
<h2>{:.1f}%</h2>
<p>Strong 📈</p>
</div>
""".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("""
<div class="insight-box">
<h4>🎯 Quick Insights</h4>
<ul>
<li>✅ Revenue growth of {:.0f}% indicates explosive business development</li>
<li>💡 Net profit margin of {:.1f}% shows strong profitability</li>
<li>📈 Gross margin of {:.1f}% demonstrates healthy pricing power</li>
</ul>
</div>
""".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("""
<div class="insight-box">
<h4>🎯 Financial Health Analysis</h4>
<p>Based on your financial data:</p>
<ul>
<li>✅ <strong>Revenue Growth:</strong> {:.0f}% growth shows strong market performance</li>
<li>✅ <strong>Profitability:</strong> {:.1f}% net margin indicates healthy operations</li>
<li>📊 <strong>Overall Rating:</strong> A- (Strong financial position)</li>
</ul>
</div>
""".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()