Spaces:
Sleeping
Sleeping
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() |