import gradio as gr import pandas as pd import numpy as np import json import chromadb from chromadb.config import Settings from datetime import datetime class FastFinancialAnalyzer: def __init__(self): # Initialize ChromaDB self.client = chromadb.Client(Settings(anonymized_telemetry=False)) # Create financial metrics collection self.collection = self.client.create_collection( name="financial_metrics_" + datetime.now().strftime("%Y%m%d_%H%M%S") ) # Initialize ratio benchmarks self.initialize_ratio_benchmarks() def initialize_ratio_benchmarks(self): """Initialize benchmark ratios for comparison""" self.benchmarks = { "liquidity_ratios": { "current_ratio": {"good": 2.0, "warning": 1.0}, "quick_ratio": {"good": 1.0, "warning": 0.5} }, "profitability_ratios": { "gross_margin": {"good": 0.4, "warning": 0.2}, "net_margin": {"good": 0.1, "warning": 0.05} }, "efficiency_ratios": { "inventory_turnover": {"good": 4, "warning": 2}, "asset_turnover": {"good": 0.5, "warning": 0.25} } } def calculate_ratios(self, balance_sheet_df, income_stmt_df): """Calculate key financial ratios""" try: ratios = {} # Clean numeric data for df in [balance_sheet_df, income_stmt_df]: for col in df.select_dtypes(include=['object']).columns: df[col] = pd.to_numeric(df[col].astype(str).str.replace(r'[^\d.-]', ''), errors='coerce') # Calculate ratios for each year years = [col for col in balance_sheet_df.columns if str(col).isdigit()] for year in years: ratios[year] = { "liquidity": { "current_ratio": balance_sheet_df.loc[balance_sheet_df['Account'] == 'Total_Current_Assets', year].values[0] / balance_sheet_df.loc[balance_sheet_df['Account'] == 'Total_Current_Liabilities', year].values[0], "quick_ratio": (balance_sheet_df.loc[balance_sheet_df['Account'] == 'Total_Current_Assets', year].values[0] - balance_sheet_df.loc[balance_sheet_df['Account'] == 'Inventory', year].values[0]) / balance_sheet_df.loc[balance_sheet_df['Account'] == 'Total_Current_Liabilities', year].values[0] }, "profitability": { "gross_margin": income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Gross Profit', year].values[0] / income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Total Net Revenue', year].values[0], "net_margin": income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Net Earnings', year].values[0] / income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Total Net Revenue', year].values[0] }, "growth": { "revenue_growth": None if year == years[0] else (income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Total Net Revenue', year].values[0] - income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Total Net Revenue', str(int(year)-1)].values[0]) / income_stmt_df.loc[income_stmt_df['Revenue Items'] == 'Total Net Revenue', str(int(year)-1)].values[0] * 100 } } return ratios except Exception as e: return f"Error calculating ratios: {str(e)}" def analyze_trends(self, ratios): """Analyze financial trends""" trends = { "liquidity": self.analyze_ratio_trend("current_ratio", ratios), "profitability": self.analyze_ratio_trend("net_margin", ratios), "growth": self.analyze_revenue_growth(ratios) } return trends def analyze_ratio_trend(self, ratio_name, ratios): """Analyze trend for a specific ratio""" values = [] years = sorted(ratios.keys()) for year in years: if ratio_name in ratios[year].get("liquidity", {}): values.append(ratios[year]["liquidity"][ratio_name]) elif ratio_name in ratios[year].get("profitability", {}): values.append(ratios[year]["profitability"][ratio_name]) if not values: return "No data available" trend = np.polyfit(range(len(values)), values, 1)[0] if trend > 0.05: return "Strong upward trend" elif trend > 0: return "Slight upward trend" elif trend > -0.05: return "Stable" else: return "Downward trend" def analyze_revenue_growth(self, ratios): """Analyze revenue growth trend""" growth_rates = [] years = sorted(ratios.keys())[1:] # Skip first year as it won't have growth rate for year in years: if ratios[year]["growth"]["revenue_growth"] is not None: growth_rates.append(ratios[year]["growth"]["revenue_growth"]) if not growth_rates: return "No growth data available" avg_growth = np.mean(growth_rates) if avg_growth > 10: return f"Strong growth (avg {avg_growth:.1f}%)" elif avg_growth > 0: return f"Moderate growth (avg {avg_growth:.1f}%)" else: return f"Declining growth (avg {avg_growth:.1f}%)" def generate_insights(self, ratios, trends): """Generate actionable insights""" insights = [] # Liquidity insights current_ratio = ratios[max(ratios.keys())]["liquidity"]["current_ratio"] if current_ratio < self.benchmarks["liquidity_ratios"]["current_ratio"]["warning"]: insights.append("ALERT: Liquidity needs immediate attention") elif current_ratio < self.benchmarks["liquidity_ratios"]["current_ratio"]["good"]: insights.append("WATCH: Liquidity is below ideal levels") # Profitability insights net_margin = ratios[max(ratios.keys())]["profitability"]["net_margin"] if net_margin > self.benchmarks["profitability_ratios"]["net_margin"]["good"]: insights.append("STRONG: Excellent profit margins") elif net_margin < self.benchmarks["profitability_ratios"]["net_margin"]["warning"]: insights.append("ALERT: Profit margins need improvement") # Growth insights if "growth" in trends: if "Strong" in trends["growth"]: insights.append("POSITIVE: Strong revenue growth trend") elif "Declining" in trends["growth"]: insights.append("WATCH: Revenue growth is slowing") return insights def analyze_financials(self, balance_sheet_file, income_stmt_file): """Main analysis function""" try: # Read files balance_sheet_df = pd.read_csv(balance_sheet_file) income_stmt_df = pd.read_csv(income_stmt_file) # Calculate ratios ratios = self.calculate_ratios(balance_sheet_df, income_stmt_df) # Analyze trends trends = self.analyze_trends(ratios) # Generate insights insights = self.generate_insights(ratios, trends) # Prepare comprehensive analysis analysis = { "Financial Ratios": ratios, "Trend Analysis": trends, "Key Insights": insights, "Summary": { "Latest Year Analysis": { "Current Ratio": f"{ratios[max(ratios.keys())]['liquidity']['current_ratio']:.2f}", "Net Margin": f"{ratios[max(ratios.keys())]['profitability']['net_margin']:.2%}", "Revenue Growth": f"{ratios[max(ratios.keys())]['growth']['revenue_growth']:.2f}%" if ratios[max(ratios.keys())]['growth']['revenue_growth'] else "N/A" } } } return json.dumps(analysis, indent=2) except Exception as e: return f"Error in analysis: {str(e)}" def create_interface(): analyzer = FastFinancialAnalyzer() iface = gr.Interface( fn=analyzer.analyze_financials, inputs=[ gr.File(label="Balance Sheet (CSV)", type="filepath"), gr.File(label="Income Statement (CSV)", type="filepath") ], outputs=gr.Textbox(label="Analysis Results", lines=20), title="Fast Financial Statement Analyzer", description="Upload financial statements for instant analysis with ratio calculations and trend detection." ) return iface if __name__ == "__main__": iface = create_interface() iface.launch()