|
import streamlit as st |
|
import plotly.express as px |
|
import plotly.graph_objs as go |
|
import pandas as pd |
|
from datetime import date |
|
|
|
|
|
from ..utils.ai_helpers import generate_ai_response |
|
from ..utils.data_processing import calculate_runway |
|
|
|
def render_financial_dashboard(startup_data, cash_flow_df): |
|
""" |
|
Render the AI-powered financial dashboard page. |
|
|
|
This dashboard uses AI to analyze financial data and provide actionable insights |
|
to startup founders, helping them make better decisions about their runway, |
|
spending, and financial health. |
|
|
|
Args: |
|
startup_data (dict): Dictionary containing startup financial profile |
|
cash_flow_df (pd.DataFrame): DataFrame with monthly cash flow details |
|
""" |
|
st.markdown("<h1 class='main-header'>Financial Dashboard</h1>", unsafe_allow_html=True) |
|
st.markdown("<p class='sub-header'>AI-powered financial insights at a glance</p>", unsafe_allow_html=True) |
|
|
|
|
|
if 'insights_cache' not in st.session_state: |
|
st.session_state.insights_cache = {} |
|
|
|
|
|
with st.expander("ℹ️ How AI enhances your financial dashboard"): |
|
st.markdown(""" |
|
### How AI Powers Your Financial Dashboard |
|
|
|
The financial dashboard uses AI to transform raw financial data into actionable intelligence: |
|
|
|
- **Automated Analysis**: Our AI model analyzes your data and highlights critical trends |
|
- **Predictive Forecasting**: AI forecasts your runway using advanced analytics |
|
- **Anomaly Detection**: Identifies unusual spending patterns or concerning financial trends |
|
- **Strategic Recommendations**: Provides tailored recommendations to optimize your runway |
|
- **Benchmark Comparison**: Compares your metrics against industry standards |
|
|
|
This helps founders make data-driven decisions quickly and confidently. |
|
""") |
|
|
|
|
|
insights_key = f"dashboard_{date.today().isoformat()}" |
|
if insights_key not in st.session_state.insights_cache: |
|
try: |
|
insights = generate_ai_response(f""" |
|
You are a financial advisor for startups. Based on this startup's data: |
|
- Current cash: ${startup_data['cash']:,} |
|
- Monthly burn rate: ${startup_data['burn_rate']:,} |
|
- Monthly revenue: ${startup_data['revenue']:,} |
|
- Monthly growth rate: {startup_data['growth_rate'] * 100:.2f}% |
|
|
|
Provide the top 3 most important financial insights that the founder should know today. |
|
Format each insight as a brief, action-oriented bullet point. |
|
""") |
|
st.session_state.insights_cache[insights_key] = insights |
|
except Exception as e: |
|
st.session_state.insights_cache[insights_key] = f"Error generating insights: {str(e)}" |
|
|
|
|
|
with st.expander("📊 AI Financial Insights", expanded=True): |
|
st.markdown("<span class='ai-badge'>AI-Generated Insights</span>", unsafe_allow_html=True) |
|
st.markdown(st.session_state.insights_cache[insights_key]) |
|
|
|
|
|
col1, col2, col3, col4 = st.columns(4) |
|
|
|
|
|
try: |
|
runway_months, runway_df = calculate_runway( |
|
startup_data['cash'], |
|
startup_data['burn_rate'], |
|
startup_data['revenue'], |
|
startup_data['growth_rate'] |
|
) |
|
except Exception as e: |
|
st.error(f"Error calculating runway: {e}") |
|
runway_months = 0 |
|
runway_df = pd.DataFrame() |
|
|
|
|
|
runway_status = ( |
|
"danger-metric" if runway_months < 6 else |
|
"warning-metric" if runway_months < 9 else |
|
"good-metric" |
|
) |
|
burn_status = ( |
|
"danger-metric" if startup_data['burn_rate'] > 100000 else |
|
"warning-metric" if startup_data['burn_rate'] > 80000 else |
|
"good-metric" |
|
) |
|
revenue_status = ( |
|
"good-metric" if startup_data['revenue'] > 20000 else |
|
"warning-metric" if startup_data['revenue'] > 10000 else |
|
"danger-metric" |
|
) |
|
|
|
|
|
metrics_display = [ |
|
("Current Cash", f"${startup_data['cash']:,}", None), |
|
("Monthly Burn", f"${startup_data['burn_rate']:,}", burn_status), |
|
("Monthly Revenue", f"${startup_data['revenue']:,}", revenue_status), |
|
("Runway", f"{runway_months} months", runway_status) |
|
] |
|
|
|
for i, (label, value, status) in enumerate(metrics_display): |
|
with [col1, col2, col3, col4][i]: |
|
status_class = f"metric-value {status}" if status else "metric-value" |
|
st.markdown(f""" |
|
<div class='metric-card'> |
|
<p class='metric-label'>{label}</p> |
|
<p class='{status_class}'>{value}</p> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.subheader("Financial Overview") |
|
tab1, tab2, tab3 = st.tabs([ |
|
"Runway Projection", |
|
"Revenue vs. Expenses", |
|
"Burn Rate Trend" |
|
]) |
|
|
|
with tab1: |
|
|
|
if not runway_df.empty: |
|
fig = px.line( |
|
runway_df.reset_index(), |
|
x='index', |
|
y='Cumulative_Cash', |
|
title="Cash Runway Projection", |
|
labels={'index': 'Month', 'Cumulative_Cash': 'Remaining Cash ($)'}, |
|
color_discrete_sequence=['#0066cc'] |
|
) |
|
fig.add_hline(y=0, line_dash="dash", line_color="red", annotation_text="Out of Cash") |
|
fig.update_layout( |
|
height=400, |
|
plot_bgcolor='rgba(240,247,255,0.8)', |
|
xaxis_title="Month", |
|
yaxis_title="Cash Balance ($)", |
|
font=dict(family="Arial, sans-serif", size=12), |
|
margin=dict(l=20, r=20, t=40, b=20), |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
with st.expander("🔍 AI Runway Analysis", expanded=True): |
|
runway_key = f"runway_{date.today().isoformat()}" |
|
if runway_key not in st.session_state.insights_cache: |
|
try: |
|
runway_analysis = get_runway_analysis(startup_data) |
|
st.session_state.insights_cache[runway_key] = runway_analysis |
|
except Exception as e: |
|
st.session_state.insights_cache[runway_key] = f"Error generating runway analysis: {str(e)}" |
|
|
|
st.markdown("<span class='ai-badge'>AI Financial Analysis</span>", unsafe_allow_html=True) |
|
st.markdown(st.session_state.insights_cache[runway_key]) |
|
|
|
with tab2: |
|
|
|
rev_exp_df = cash_flow_df.copy() |
|
fig = px.bar( |
|
rev_exp_df, |
|
x='Month', |
|
y=['Revenue', 'Total_Expenses'], |
|
title="Revenue vs. Expenses", |
|
barmode='group', |
|
labels={'value': 'Amount ($)', 'variable': 'Category'}, |
|
color_discrete_sequence=['#28a745', '#dc3545'] |
|
) |
|
fig.update_layout( |
|
height=400, |
|
plot_bgcolor='rgba(240,247,255,0.8)', |
|
xaxis_title="Month", |
|
yaxis_title="Amount ($)", |
|
font=dict(family="Arial, sans-serif", size=12), |
|
legend_title="", |
|
margin=dict(l=20, r=20, t=40, b=20), |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
try: |
|
revenue_growth = [ |
|
(cash_flow_df['Revenue'].iloc[i] / cash_flow_df['Revenue'].iloc[i-1] - 1) * 100 |
|
if i > 0 else 0 |
|
for i in range(len(cash_flow_df)) |
|
] |
|
avg_growth = sum(revenue_growth[1:]) / len(revenue_growth[1:]) |
|
|
|
col1, col2 = st.columns(2) |
|
with col1: |
|
st.metric("Average Monthly Revenue Growth", f"{avg_growth:.1f}%") |
|
with col2: |
|
expense_growth = ( |
|
cash_flow_df['Total_Expenses'].iloc[-1] / |
|
cash_flow_df['Total_Expenses'].iloc[0] - 1 |
|
) * 100 |
|
st.metric( |
|
"Total Expense Growth", |
|
f"{expense_growth:.1f}%", |
|
delta=f"{expense_growth - avg_growth:.1f}%", |
|
delta_color="inverse" |
|
) |
|
except Exception as e: |
|
st.error(f"Error calculating growth metrics: {e}") |
|
|
|
with tab3: |
|
|
|
fig = px.line( |
|
cash_flow_df, |
|
x='Month', |
|
y='Net_Burn', |
|
title="Monthly Net Burn Trend", |
|
labels={'Net_Burn': 'Net Burn ($)'}, |
|
color_discrete_sequence=['#dc3545'] |
|
) |
|
fig.update_layout( |
|
height=400, |
|
plot_bgcolor='rgba(240,247,255,0.8)', |
|
xaxis_title="Month", |
|
yaxis_title="Net Burn ($)", |
|
font=dict(family="Arial, sans-serif", size=12), |
|
margin=dict(l=20, r=20, t=40, b=20), |
|
) |
|
|
|
|
|
try: |
|
efficiency_ratio = [ |
|
cash_flow_df['Revenue'].iloc[i] / cash_flow_df['Total_Expenses'].iloc[i] * 100 |
|
for i in range(len(cash_flow_df)) |
|
] |
|
|
|
fig.add_trace(go.Scatter( |
|
x=cash_flow_df['Month'], |
|
y=efficiency_ratio, |
|
name='Efficiency Ratio (%)', |
|
yaxis='y2', |
|
line=dict(color='#0066cc', width=2, dash='dot') |
|
)) |
|
|
|
fig.update_layout( |
|
yaxis2=dict( |
|
title='Efficiency Ratio (%)', |
|
overlaying='y', |
|
side='right', |
|
range=[0, max(efficiency_ratio) * 1.2] |
|
) |
|
) |
|
|
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
with st.expander("🔎 Understanding Efficiency Ratio"): |
|
st.info( |
|
"The efficiency ratio measures how efficiently your startup is generating " |
|
"revenue relative to expenses. A higher percentage means you're getting " |
|
"more revenue per dollar spent. Venture-backed startups typically aim " |
|
"for at least 40% before Series B funding." |
|
) |
|
except Exception as e: |
|
st.error(f"Error calculating efficiency ratio: {e}") |
|
|
|
|
|
st.subheader("Fundraising Readiness") |
|
|
|
|
|
fundraising_key = f"fundraising_{date.today().isoformat()}" |
|
if fundraising_key not in st.session_state.insights_cache: |
|
try: |
|
fundraising_analysis = get_fundraising_readiness_analysis(startup_data, cash_flow_df) |
|
st.session_state.insights_cache[fundraising_key] = fundraising_analysis |
|
except Exception as e: |
|
st.session_state.insights_cache[fundraising_key] = f"Error generating fundraising analysis: {str(e)}" |
|
|
|
st.markdown("<div class='advisor-card'>", unsafe_allow_html=True) |
|
st.markdown("<span class='ai-badge'>AI Fundraising Assessment</span>", unsafe_allow_html=True) |
|
st.markdown( |
|
f"<p class='advice-text'>{st.session_state.insights_cache[fundraising_key]}</p>", |
|
unsafe_allow_html=True |
|
) |
|
st.markdown("</div>", unsafe_allow_html=True) |
|
|
|
|
|
st.info("📅 Need personalized guidance on fundraising? [Book a session](#book-a-session) with our AI financial advisor.") |
|
|
|
def get_runway_analysis(financial_data): |
|
""" |
|
Generate runway analysis using AI |
|
|
|
Args: |
|
financial_data (dict): Startup financial data |
|
|
|
Returns: |
|
str: AI-generated runway analysis |
|
""" |
|
prompt = f""" |
|
You are a financial advisor for startups. Analyze this startup's financial data: |
|
- Current cash: ${financial_data['cash']:,} |
|
- Monthly burn rate: ${financial_data['burn_rate']:,} |
|
- Monthly revenue: ${financial_data['revenue']:,} |
|
- Monthly growth rate: {financial_data['growth_rate'] * 100:.2f}% |
|
|
|
Provide a detailed analysis of their runway and financial health. Include: |
|
1. Exact runway calculation in months |
|
2. Assessment of financial health (critical, concerning, stable, or healthy) |
|
3. Benchmarks compared to similar seed-stage startups |
|
4. Three specific, actionable recommendations to improve runway |
|
5. Key metrics they should focus on |
|
|
|
Format your response in a structured, easy-to-read format with clear sections and bullet points. |
|
""" |
|
|
|
return generate_ai_response(prompt) |
|
|
|
def get_fundraising_readiness_analysis(startup_data, cash_flow_df): |
|
""" |
|
Generate fundraising readiness analysis using AI |
|
|
|
Args: |
|
startup_data (dict): Startup financial profile |
|
cash_flow_df (pd.DataFrame): Monthly cash flow data |
|
|
|
Returns: |
|
str: AI-generated fundraising readiness analysis |
|
""" |
|
|
|
try: |
|
mrr_growth = ( |
|
cash_flow_df['Revenue'].iloc[-1] / |
|
cash_flow_df['Revenue'].iloc[-2] - 1 |
|
) * 100 |
|
except Exception: |
|
mrr_growth = 0 |
|
|
|
try: |
|
gross_margin = ( |
|
cash_flow_df['Revenue'].iloc[-1] - |
|
cash_flow_df['Total_Expenses'].iloc[-1] / 2 |
|
) / cash_flow_df['Revenue'].iloc[-1] * 100 |
|
except Exception: |
|
gross_margin = 0 |
|
|
|
|
|
metrics = { |
|
"MRR Growth": f"{mrr_growth:.1f}%", |
|
"Gross Margin": f"{gross_margin:.1f}%", |
|
"CAC": "$950", |
|
"LTV": "$4,500", |
|
"Churn": "3.2%", |
|
} |
|
|
|
|
|
metrics_text = "\n".join([f"- {k}: {v}" for k, v in metrics.items()]) |
|
|
|
|
|
try: |
|
runway = startup_data['cash'] / (startup_data['burn_rate'] - startup_data['revenue']) |
|
except Exception: |
|
runway = 0 |
|
|
|
|
|
prompt = f""" |
|
You are a startup fundraising advisor. Analyze this startup's readiness for their next funding round: |
|
|
|
Company Profile: |
|
- Stage: {startup_data['stage']} |
|
- Last Funding: {startup_data.get('last_funding', 'N/A')} |
|
- Current Cash: ${startup_data['cash']:,} |
|
- Monthly Burn: ${startup_data['burn_rate']:,} |
|
- Runway: {runway:.1f} months |
|
|
|
Key Metrics: |
|
{metrics_text} |
|
|
|
Provide a comprehensive fundraising readiness assessment: |
|
1. Overall fundraising readiness score (0-10) |
|
2. Assessment of current metrics compared to investor expectations for next round |
|
3. Identify the 3 most critical metrics to improve before fundraising |
|
4. Recommend specific targets for each key metric |
|
5. Suggest timeline and specific milestones for fundraising preparation |
|
6. Estimate reasonable valuation range based on metrics and market conditions |
|
|
|
Be specific with numbers, timelines, and actionable targets. |
|
""" |
|
|
|
return generate_ai_response(prompt) |