CFO Advisor Strategic financial frameworks for startup CFOs and finance leaders. Numbers-driven, decisions-focused. This is not a financial analyst skill. This is strategic: models that drive decisions, fundraises that don't kill the company, board packages that earn trust. Keywords CFO, chief financial officer, burn rate, runway, unit economics, LTV, CAC, fundraising, Series A, Series B, term sheet, cap table, dilution, financial model, cash flow, board financials, FP&A, SaaS metrics, ARR, MRR, net dollar retention, gross margin, scenario planning, cash management, treasury, working capital,…

)}\")\n print(f\" New shares issued: {result.new_shares_issued:,.0f}\")\n if result.option_pool_shares_created > 0:\n print(f\" Option pool created: {result.option_pool_shares_created:,.0f} shares\")\n print(f\" ⚠️ Pool created pre-round: dilutes existing shareholders, not new investor\")\n print(f\" Total shares post: {result.total_shares:,.0f}\")\n\n print(f\"\\n {'Shareholder':\u003c22} {'Shares':>12} {'Ownership':>10} {'Invested':>10} {'Δ Ownership':>12}\")\n print(\" \" + \"-\"*68)\n\n prev_map = {e.name: e.pct_ownership for e in prev_cap_table} if prev_cap_table else {}\n\n for entry in result.cap_table:\n delta = \"\"\n if entry.name in prev_map:\n change = (entry.pct_ownership - prev_map[entry.name]) * 100\n delta = f\"{change:+.1f}pp\"\n elif not entry.is_option_pool:\n delta = \"new\"\n\n invested_str = fmt(entry.invested) if entry.invested > 0 else \"-\"\n print(\n f\" {entry.name:\u003c22} {entry.shares:>12,.0f} \"\n f\"{entry.pct_ownership*100:>9.2f}% {invested_str:>10} {delta:>12}\"\n )\n\n\ndef print_exit_analysis(results: list[ExitAnalysis], exit_valuation: float) -> None:\n print(f\"\\n{'='*70}\")\n print(f\" EXIT ANALYSIS @ {fmt(exit_valuation)} (all preferred converts to common)\")\n print(f\"{'='*70}\")\n print(f\"\\n {'Shareholder':\u003c22} {'Ownership':>10} {'Proceeds':>12} {'Invested':>10} {'MOIC':>8}\")\n print(\" \" + \"-\"*65)\n for r in results:\n moic_str = f\"{r.moic:.1f}x\" if r.moic > 0 else \"n/a\"\n invested_str = fmt(r.invested) if r.invested > 0 else \"-\"\n print(\n f\" {r.shareholder:\u003c22} {r.ownership_pct*100:>9.2f}% \"\n f\"{fmt(r.proceeds_common):>12} {invested_str:>10} {moic_str:>8}\"\n )\n print(f\"\\n Note: Does not model liquidation preferences.\")\n print(f\" Participating preferred reduces founder proceeds in most real exits.\")\n print(f\" See references/fundraising_playbook.md for full liquidation waterfall.\")\n\n\ndef print_dilution_summary(rounds: list[RoundResult]) -> None:\n print(f\"\\n{'='*70}\")\n print(f\" DILUTION SUMMARY — FOUNDER PERSPECTIVE\")\n print(f\"{'='*70}\")\n\n # Find all founders (common shareholders who aren't investors or option pool)\n founder_names = []\n for entry in rounds[0].cap_table:\n if entry.share_class == \"common\" and not entry.is_option_pool:\n founder_names.append(entry.name)\n\n if not founder_names:\n print(\" No common shareholders found in initial cap table.\")\n return\n\n header = f\" {'Round':\u003c16}\" + \"\".join(f\" {n:\u003c16}\" for n in founder_names) + f\" {'Total Inv':>12}\"\n print(header)\n print(\" \" + \"-\" * (16 + 18 * len(founder_names) + 14))\n\n for result in rounds:\n cap_map = {e.name: e for e in result.cap_table}\n total_invested = sum(e.invested for e in result.cap_table if not e.is_option_pool)\n row = f\" {result.round_name:\u003c16}\"\n for name in founder_names:\n pct = cap_map[name].pct_ownership * 100 if name in cap_map else 0\n row += f\" {pct:>6.2f}% \"\n row += f\" {fmt(total_invested):>12}\"\n print(row)\n\n\ndef export_csv_rounds(rounds: list[RoundResult]) -> str:\n buf = io.StringIO()\n writer = csv.writer(buf)\n writer.writerow([\"Round\", \"Shareholder\", \"Share Class\", \"Shares\", \"Ownership Pct\",\n \"Invested\", \"Pre Money\", \"Post Money\", \"Price Per Share\"])\n for r in rounds:\n for entry in r.cap_table:\n writer.writerow([\n r.round_name, entry.name, entry.share_class,\n round(entry.shares, 0), round(entry.pct_ownership * 100, 4),\n round(entry.invested, 2), round(r.pre_money_valuation, 0),\n round(r.post_money_valuation, 0), round(r.price_per_share, 4),\n ])\n return buf.getvalue()\n\n\n# ---------------------------------------------------------------------------\n# Sample data: typical two-founder Series A/B/C startup\n# ---------------------------------------------------------------------------\n\ndef build_sample_model() -> tuple[CapTable, list[RoundResult]]:\n \"\"\"\n Sample company:\n - 2 founders, started with 10M shares each\n - 1M shares for early advisor\n - Raises Pre-seed → Seed → Series A → Series B → Series C\n \"\"\"\n cap = CapTable()\n SHARES_PER_FOUNDER = 4_000_000\n SHARES_ADVISOR = 200_000\n\n # Founding state\n cap.add_shareholder(Shareholder(\"Founder A (CEO)\", \"common\", SHARES_PER_FOUNDER))\n cap.add_shareholder(Shareholder(\"Founder B (CTO)\", \"common\", SHARES_PER_FOUNDER))\n cap.add_shareholder(Shareholder(\"Advisor\", \"common\", SHARES_ADVISOR))\n\n rounds: list[RoundResult] = []\n prev_cap = cap.snapshot()\n\n # Round 1: Pre-seed — $500K at $4.5M pre, 10% option pool created\n r1 = cap.execute_round(RoundConfig(\n name=\"Pre-seed\",\n pre_money_valuation=4_500_000,\n investment_amount=500_000,\n new_option_pool_pct=0.10,\n option_pool_pre_round=True,\n lead_investor_name=\"Angel Syndicate\",\n ))\n rounds.append(r1)\n prev_r1 = r1.cap_table[:]\n\n # Round 2: Seed — $2M at $9M pre, expand option pool to 12%\n r2 = cap.execute_round(RoundConfig(\n name=\"Seed\",\n pre_money_valuation=9_000_000,\n investment_amount=2_000_000,\n new_option_pool_pct=0.12,\n option_pool_pre_round=True,\n lead_investor_name=\"Seed Fund\",\n ))\n rounds.append(r2)\n\n # Round 3: Series A — $12M at $38M pre, refresh option pool to 15%\n r3 = cap.execute_round(RoundConfig(\n name=\"Series A\",\n pre_money_valuation=38_000_000,\n investment_amount=12_000_000,\n new_option_pool_pct=0.15,\n option_pool_pre_round=True,\n lead_investor_name=\"Series A Fund\",\n ))\n rounds.append(r3)\n\n # Round 4: Series B — $25M at $95M pre, refresh pool to 12%\n r4 = cap.execute_round(RoundConfig(\n name=\"Series B\",\n pre_money_valuation=95_000_000,\n investment_amount=25_000_000,\n new_option_pool_pct=0.12,\n option_pool_pre_round=True,\n lead_investor_name=\"Series B Fund\",\n ))\n rounds.append(r4)\n\n # Round 5: Series C — $40M at $185M pre, refresh pool to 10%\n r5 = cap.execute_round(RoundConfig(\n name=\"Series C\",\n pre_money_valuation=185_000_000,\n investment_amount=40_000_000,\n new_option_pool_pct=0.10,\n option_pool_pre_round=True,\n lead_investor_name=\"Series C Fund\",\n ))\n rounds.append(r5)\n\n return cap, rounds\n\n\n# ---------------------------------------------------------------------------\n# Entry point\n# ---------------------------------------------------------------------------\n\ndef main() -> None:\n parser = argparse.ArgumentParser(description=\"Fundraising Model — Cap Table & Dilution\")\n parser.add_argument(\"--exit\", type=float, default=250.0,\n help=\"Exit valuation in $M for return analysis (default: 250)\")\n parser.add_argument(\"--csv\", action=\"store_true\", help=\"Export round data as CSV to stdout\")\n args = parser.parse_args()\n\n exit_valuation = args.exit * 1_000_000\n\n print(\"\\n\" + \"=\"*70)\n print(\" FUNDRAISING MODEL — CAP TABLE & DILUTION ANALYSIS\")\n print(\" Sample Company: Two-founder SaaS startup\")\n print(\" Pre-seed → Seed → Series A → Series B → Series C\")\n print(\"=\"*70)\n\n cap, rounds = build_sample_model()\n\n # Print each round\n prev = None\n for r in rounds:\n print_round_result(r, prev)\n prev = r.cap_table\n\n # Dilution summary table\n print_dilution_summary(rounds)\n\n # Exit analysis at specified valuation\n exit_results = cap.analyze_exit(exit_valuation)\n print_exit_analysis(exit_results, exit_valuation)\n\n # Also print at 2x and 5x for sensitivity\n print(\"\\n Exit Sensitivity — Founder A Proceeds:\")\n print(f\" {'Exit Valuation':\u003c20} {'Founder A %':>12} {'Founder A

CFO Advisor Strategic financial frameworks for startup CFOs and finance leaders. Numbers-driven, decisions-focused. This is not a financial analyst skill. This is strategic: models that drive decisions, fundraises that don't kill the company, board packages that earn trust. Keywords CFO, chief financial officer, burn rate, runway, unit economics, LTV, CAC, fundraising, Series A, Series B, term sheet, cap table, dilution, financial model, cash flow, board financials, FP&A, SaaS metrics, ARR, MRR, net dollar retention, gross margin, scenario planning, cash management, treasury, working capital,…

:>14} {'MOIC':>8}\")\n print(\" \" + \"-\"*56)\n for mult in [0.5, 1.0, 1.5, 2.0, 3.0, 5.0]:\n val = rounds[-1].post_money_valuation * mult\n ex = cap.analyze_exit(val)\n founder_a = next((r for r in ex if r.shareholder == \"Founder A (CEO)\"), None)\n if founder_a:\n print(f\" {fmt(val):\u003c20} {founder_a.ownership_pct*100:>11.2f}% \"\n f\"{fmt(founder_a.proceeds_common):>14} {'n/a':>8}\")\n\n print(\"\\n Key Takeaways:\")\n final = rounds[-1].cap_table\n total = sum(e.shares for e in final)\n founder_a_final = next((e for e in final if e.name == \"Founder A (CEO)\"), None)\n if founder_a_final:\n print(f\" Founder A final ownership: {founder_a_final.pct_ownership*100:.2f}%\")\n total_raised = sum(e.invested for e in final)\n print(f\" Total capital raised: {fmt(total_raised)}\")\n print(f\" Total shares outstanding: {total:,.0f}\")\n print(f\" Final post-money: {fmt(rounds[-1].post_money_valuation)}\")\n print(\"\\n Run with --exit \u003c$M> to model proceeds at different exit valuations.\")\n print(\" Example: python fundraising_model.py --exit 500\")\n\n if args.csv:\n print(\"\\n\\n--- CSV EXPORT ---\\n\")\n sys.stdout.write(export_csv_rounds(rounds))\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":18627,"content_sha256":"646d2ff1260187092651432ad198ac8922afe0574c2d30b9008324f143a8b11e"},{"filename":"scripts/unit_economics_analyzer.py","content":"#!/usr/bin/env python3\n\"\"\"\nUnit Economics Analyzer\n========================\nPer-cohort LTV, per-channel CAC, payback periods, and LTV:CAC ratios.\nNever blended averages — those hide what's actually happening.\n\nUsage:\n python unit_economics_analyzer.py\n python unit_economics_analyzer.py --csv\n\nStdlib only. No dependencies.\n\"\"\"\n\nimport argparse\nimport csv\nimport io\nimport sys\nfrom dataclasses import dataclass, field\nfrom typing import Optional\n\n\n# ---------------------------------------------------------------------------\n# Data structures\n# ---------------------------------------------------------------------------\n\n@dataclass\nclass CohortData:\n \"\"\"\n Revenue data for a group of customers acquired in the same period.\n Revenue is tracked monthly: revenue[0] = month 1, revenue[1] = month 2, etc.\n \"\"\"\n label: str # e.g. \"Q1 2024\"\n acquisition_period: str # human-readable label\n customers_acquired: int\n total_cac_spend: float # total S&M spend to acquire this cohort\n monthly_revenue: list[float] # revenue per month from this cohort\n gross_margin_pct: float = 0.70 # blended gross margin for this cohort\n\n\n@dataclass\nclass ChannelData:\n \"\"\"Acquisition cost and customer data for a single channel.\"\"\"\n channel: str\n spend: float\n customers_acquired: int\n avg_arpa: float # average revenue per account (monthly)\n gross_margin_pct: float = 0.70\n avg_monthly_churn: float = 0.02 # monthly churn rate for customers from this channel\n\n\n@dataclass\nclass UnitEconomicsResult:\n \"\"\"Computed unit economics for a cohort or channel.\"\"\"\n label: str\n customers: int\n cac: float\n arpa: float # average revenue per account per month\n gross_margin_pct: float\n monthly_churn: float\n ltv: float\n ltv_cac_ratio: float\n payback_months: float\n # Cohort-specific\n m1_revenue: Optional[float] = None\n m6_revenue: Optional[float] = None\n m12_revenue: Optional[float] = None\n m24_revenue: Optional[float] = None\n m12_ltv: Optional[float] = None # realized LTV through month 12\n retention_m6: Optional[float] = None # % of M1 revenue retained at M6\n retention_m12: Optional[float] = None\n\n\n# ---------------------------------------------------------------------------\n# Calculators\n# ---------------------------------------------------------------------------\n\ndef calc_ltv(arpa: float, gross_margin_pct: float, monthly_churn: float) -> float:\n \"\"\"\n LTV = (ARPA × Gross Margin) / Monthly Churn Rate\n Assumes constant churn (simplified; cohort method is more accurate).\n \"\"\"\n if monthly_churn \u003c= 0:\n return float(\"inf\")\n return (arpa * gross_margin_pct) / monthly_churn\n\n\ndef calc_payback(cac: float, arpa: float, gross_margin_pct: float) -> float:\n \"\"\"\n CAC Payback (months) = CAC / (ARPA × Gross Margin)\n \"\"\"\n denominator = arpa * gross_margin_pct\n if denominator \u003c= 0:\n return float(\"inf\")\n return cac / denominator\n\n\ndef analyze_cohort(cohort: CohortData) -> UnitEconomicsResult:\n \"\"\"Compute full unit economics for a cohort.\"\"\"\n n = cohort.customers_acquired\n if n == 0:\n raise ValueError(f\"Cohort {cohort.label}: customers_acquired cannot be 0\")\n\n cac = cohort.total_cac_spend / n\n\n # ARPA from month 1 revenue\n m1_rev = cohort.monthly_revenue[0] if cohort.monthly_revenue else 0\n arpa = m1_rev / n if n > 0 else 0\n\n # Observed monthly churn from cohort data\n # Use revenue decline from M1 to M12 to estimate churn\n months_available = len(cohort.monthly_revenue)\n if months_available >= 12:\n m12_rev = cohort.monthly_revenue[11]\n # Revenue retention over 12 months: (M12/M1)^(1/11) per month on average\n # Implied monthly retention rate\n if m1_rev > 0 and m12_rev > 0:\n monthly_retention = (m12_rev / m1_rev) ** (1 / 11)\n monthly_churn = 1 - monthly_retention\n else:\n monthly_churn = 0.02 # default\n elif months_available >= 6:\n m6_rev = cohort.monthly_revenue[5]\n if m1_rev > 0 and m6_rev > 0:\n monthly_retention = (m6_rev / m1_rev) ** (1 / 5)\n monthly_churn = 1 - monthly_retention\n else:\n monthly_churn = 0.02\n else:\n monthly_churn = 0.02 # default if \u003c 6 months data\n\n # Clamp to reasonable range\n monthly_churn = max(0.001, min(monthly_churn, 0.30))\n\n ltv = calc_ltv(arpa, cohort.gross_margin_pct, monthly_churn)\n payback = calc_payback(cac, arpa, cohort.gross_margin_pct)\n ltv_cac = ltv / cac if cac > 0 else float(\"inf\")\n\n # Snapshot revenues\n def rev_at(month_idx: int) -> Optional[float]:\n if months_available > month_idx:\n return cohort.monthly_revenue[month_idx]\n return None\n\n m6 = rev_at(5)\n m12 = rev_at(11)\n m24 = rev_at(23)\n\n # Realized LTV through observed months (actual gross profit)\n m12_ltv = sum(cohort.monthly_revenue[:12]) * cohort.gross_margin_pct if months_available >= 12 else None\n\n # Retention rates\n ret_m6 = (m6 / m1_rev) if (m6 is not None and m1_rev > 0) else None\n ret_m12 = (m12 / m1_rev) if (m12 is not None and m1_rev > 0) else None\n\n return UnitEconomicsResult(\n label=cohort.label,\n customers=n,\n cac=cac,\n arpa=arpa,\n gross_margin_pct=cohort.gross_margin_pct,\n monthly_churn=monthly_churn,\n ltv=ltv,\n ltv_cac_ratio=ltv_cac,\n payback_months=payback,\n m1_revenue=m1_rev,\n m6_revenue=m6,\n m12_revenue=m12,\n m24_revenue=m24,\n m12_ltv=m12_ltv,\n retention_m6=ret_m6,\n retention_m12=ret_m12,\n )\n\n\ndef analyze_channel(ch: ChannelData) -> UnitEconomicsResult:\n \"\"\"Compute unit economics for an acquisition channel.\"\"\"\n if ch.customers_acquired == 0:\n raise ValueError(f\"Channel {ch.channel}: customers_acquired cannot be 0\")\n\n cac = ch.spend / ch.customers_acquired\n ltv = calc_ltv(ch.avg_arpa, ch.gross_margin_pct, ch.avg_monthly_churn)\n payback = calc_payback(cac, ch.avg_arpa, ch.gross_margin_pct)\n ltv_cac = ltv / cac if cac > 0 else float(\"inf\")\n\n return UnitEconomicsResult(\n label=ch.channel,\n customers=ch.customers_acquired,\n cac=cac,\n arpa=ch.avg_arpa,\n gross_margin_pct=ch.gross_margin_pct,\n monthly_churn=ch.avg_monthly_churn,\n ltv=ltv,\n ltv_cac_ratio=ltv_cac,\n payback_months=payback,\n )\n\n\n# ---------------------------------------------------------------------------\n# Blended metrics (for comparison)\n# ---------------------------------------------------------------------------\n\ndef blended_cac(channels: list[ChannelData]) -> float:\n total_spend = sum(c.spend for c in channels)\n total_customers = sum(c.customers_acquired for c in channels)\n return total_spend / total_customers if total_customers > 0 else 0\n\n\ndef blended_ltv(channels: list[ChannelData]) -> float:\n \"\"\"Weighted average LTV by customers acquired.\"\"\"\n total_customers = sum(c.customers_acquired for c in channels)\n if total_customers == 0:\n return 0\n weighted = sum(\n calc_ltv(c.avg_arpa, c.gross_margin_pct, c.avg_monthly_churn) * c.customers_acquired\n for c in channels\n )\n return weighted / total_customers\n\n\n# ---------------------------------------------------------------------------\n# Reporting\n# ---------------------------------------------------------------------------\n\ndef fmt(value: float, prefix: str = \"$\", decimals: int = 0) -> str:\n if value == float(\"inf\"):\n return \"∞\"\n if abs(value) >= 1_000_000:\n return f\"{prefix}{value/1_000_000:.2f}M\"\n if abs(value) >= 1_000:\n return f\"{prefix}{value/1_000:.1f}K\"\n return f\"{prefix}{value:.{decimals}f}\"\n\n\ndef pct(value: Optional[float]) -> str:\n if value is None:\n return \"n/a\"\n return f\"{value*100:.1f}%\"\n\n\ndef rating(ltv_cac: float, payback: float) -> str:\n if ltv_cac == float(\"inf\"):\n return \"∞\"\n if ltv_cac >= 5 and payback \u003c= 12:\n return \"🟢 Excellent\"\n if ltv_cac >= 3 and payback \u003c= 18:\n return \"🟡 Good\"\n if ltv_cac >= 2 and payback \u003c= 24:\n return \"🟠 Marginal\"\n return \"🔴 Poor\"\n\n\ndef print_cohort_analysis(results: list[UnitEconomicsResult]) -> None:\n print(\"\\n\" + \"=\"*80)\n print(\" COHORT ANALYSIS\")\n print(\"=\"*80)\n print(f\" {'Cohort':\u003c12} {'Cust':>5} {'CAC':>8} {'ARPA/mo':>9} {'Churn/mo':>10} \"\n f\"{'LTV':>10} {'LTV:CAC':>8} {'Payback':>9} {'Ret@M12':>8}\")\n print(\" \" + \"-\"*88)\n for r in results:\n payback_str = f\"{r.payback_months:.1f}mo\" if r.payback_months != float(\"inf\") else \"∞\"\n ltv_str = fmt(r.ltv) if r.ltv != float(\"inf\") else \"∞\"\n ltv_cac_str = f\"{r.ltv_cac_ratio:.1f}x\" if r.ltv_cac_ratio != float(\"inf\") else \"∞\"\n print(\n f\" {r.label:\u003c12} {r.customers:>5} {fmt(r.cac):>8} {fmt(r.arpa):>9} \"\n f\"{pct(r.monthly_churn):>10} {ltv_str:>10} {ltv_cac_str:>8} \"\n f\"{payback_str:>9} {pct(r.retention_m12):>8}\"\n )\n\n # Trend analysis\n print(\"\\n Cohort Trend (is the business getting better or worse?):\")\n if len(results) >= 3:\n ltv_cac_values = [r.ltv_cac_ratio for r in results if r.ltv_cac_ratio != float(\"inf\")]\n cac_values = [r.cac for r in results]\n churn_values = [r.monthly_churn for r in results]\n\n if len(ltv_cac_values) >= 2:\n ltv_cac_trend = \"↑ Improving\" if ltv_cac_values[-1] > ltv_cac_values[0] else \"↓ Deteriorating\"\n else:\n ltv_cac_trend = \"n/a\"\n\n cac_trend = \"↓ Decreasing (good)\" if cac_values[-1] \u003c cac_values[0] else \"↑ Increasing\"\n churn_trend = \"↓ Improving\" if churn_values[-1] \u003c churn_values[0] else \"↑ Worsening\"\n\n print(f\" LTV:CAC: {ltv_cac_trend}\")\n print(f\" CAC: {cac_trend}\")\n print(f\" Churn rate: {churn_trend}\")\n\n\ndef print_channel_analysis(results: list[UnitEconomicsResult], channels: list[ChannelData]) -> None:\n print(\"\\n\" + \"=\"*80)\n print(\" CHANNEL ANALYSIS (Per-Channel vs Blended)\")\n print(\"=\"*80)\n print(f\" {'Channel':\u003c22} {'Spend':>9} {'Cust':>5} {'CAC':>8} {'LTV':>10} {'LTV:CAC':>8} {'Payback':>9} {'Rating'}\")\n print(\" \" + \"-\"*90)\n for r, ch in zip(results, channels):\n payback_str = f\"{r.payback_months:.1f}mo\" if r.payback_months != float(\"inf\") else \"∞\"\n ltv_str = fmt(r.ltv) if r.ltv != float(\"inf\") else \"∞\"\n ltv_cac_str = f\"{r.ltv_cac_ratio:.1f}x\" if r.ltv_cac_ratio != float(\"inf\") else \"∞\"\n print(\n f\" {r.label:\u003c22} {fmt(ch.spend):>9} {r.customers:>5} {fmt(r.cac):>8} \"\n f\"{ltv_str:>10} {ltv_cac_str:>8} {payback_str:>9} {rating(r.ltv_cac_ratio, r.payback_months)}\"\n )\n\n # Blended comparison\n b_cac = blended_cac(channels)\n b_ltv = blended_ltv(channels)\n b_ltv_cac = b_ltv / b_cac if b_cac > 0 else 0\n total_spend = sum(c.spend for c in channels)\n total_customers = sum(c.customers_acquired for c in channels)\n avg_payback = sum(\n calc_payback(b_cac, c.avg_arpa, c.gross_margin_pct) * c.customers_acquired\n for c in channels\n ) / total_customers\n\n print(\" \" + \"-\"*90)\n print(\n f\" {'BLENDED (dangerous)':\u003c22} {fmt(total_spend):>9} {total_customers:>5} \"\n f\"{fmt(b_cac):>8} {fmt(b_ltv):>10} {b_ltv_cac:.1f}x{'':\u003c7} \"\n f\"{avg_payback:.1f}mo{'':\u003c4} {rating(b_ltv_cac, avg_payback)}\"\n )\n print(\"\\n ⚠️ Blended numbers hide channel-level problems. Manage channels individually.\")\n\n # Budget reallocation\n print(\"\\n Recommended Budget Reallocation:\")\n sorted_results = sorted(zip(results, channels), key=lambda x: x[0].ltv_cac_ratio, reverse=True)\n for r, ch in sorted_results:\n if r.ltv_cac_ratio >= 3:\n action = \"✅ Scale\"\n elif r.ltv_cac_ratio >= 2:\n action = \"🔄 Optimize\"\n else:\n action = \"❌ Cut / pause\"\n print(f\" {ch.channel:\u003c22} LTV:CAC = {r.ltv_cac_ratio:.1f}x → {action}\")\n\n\ndef export_csv_results(cohort_results: list[UnitEconomicsResult], channel_results: list[UnitEconomicsResult]) -> str:\n buf = io.StringIO()\n writer = csv.writer(buf)\n writer.writerow([\"Type\", \"Label\", \"Customers\", \"CAC\", \"ARPA_Monthly\", \"Gross_Margin_Pct\",\n \"Monthly_Churn\", \"LTV\", \"LTV_CAC_Ratio\", \"Payback_Months\",\n \"Retention_M6\", \"Retention_M12\"])\n for r in cohort_results:\n writer.writerow([\"cohort\", r.label, r.customers, round(r.cac, 2), round(r.arpa, 2),\n r.gross_margin_pct, round(r.monthly_churn, 4),\n round(r.ltv, 2) if r.ltv != float(\"inf\") else \"inf\",\n round(r.ltv_cac_ratio, 2) if r.ltv_cac_ratio != float(\"inf\") else \"inf\",\n round(r.payback_months, 2) if r.payback_months != float(\"inf\") else \"inf\",\n round(r.retention_m6, 3) if r.retention_m6 else \"\",\n round(r.retention_m12, 3) if r.retention_m12 else \"\"])\n for r in channel_results:\n writer.writerow([\"channel\", r.label, r.customers, round(r.cac, 2), round(r.arpa, 2),\n r.gross_margin_pct, round(r.monthly_churn, 4),\n round(r.ltv, 2) if r.ltv != float(\"inf\") else \"inf\",\n round(r.ltv_cac_ratio, 2) if r.ltv_cac_ratio != float(\"inf\") else \"inf\",\n round(r.payback_months, 2) if r.payback_months != float(\"inf\") else \"inf\",\n \"\", \"\"])\n return buf.getvalue()\n\n\n# ---------------------------------------------------------------------------\n# Sample data\n# ---------------------------------------------------------------------------\n\ndef make_sample_cohorts() -> list[CohortData]:\n \"\"\"\n Series A SaaS company, 8 quarters of cohort data.\n Shows a business improving on all dimensions over time.\n \"\"\"\n return [\n CohortData(\n label=\"Q1 2023\", acquisition_period=\"Jan-Mar 2023\",\n customers_acquired=12, total_cac_spend=54_000,\n gross_margin_pct=0.68,\n monthly_revenue=[\n 10_200, 9_600, 9_100, 8_700, 8_300, 8_000, # M1-M6\n 7_800, 7_600, 7_400, 7_200, 7_000, 6_800, # M7-M12\n 6_700, 6_600, 6_500, 6_400, 6_300, 6_200, # M13-M18\n 6_100, 6_000, 5_900, 5_800, 5_700, 5_600, # M19-M24\n ],\n ),\n CohortData(\n label=\"Q2 2023\", acquisition_period=\"Apr-Jun 2023\",\n customers_acquired=15, total_cac_spend=60_000,\n gross_margin_pct=0.69,\n monthly_revenue=[\n 13_500, 12_900, 12_500, 12_100, 11_800, 11_500,\n 11_300, 11_100, 10_900, 10_700, 10_500, 10_300,\n 10_200, 10_100, 10_000, 9_900, 9_800, 9_700,\n ],\n ),\n CohortData(\n label=\"Q3 2023\", acquisition_period=\"Jul-Sep 2023\",\n customers_acquired=18, total_cac_spend=63_000,\n gross_margin_pct=0.70,\n monthly_revenue=[\n 16_200, 15_800, 15_400, 15_100, 14_800, 14_600,\n 14_400, 14_200, 14_000, 13_900, 13_800, 13_700,\n 13_600, 13_500, 13_400, 13_300,\n ],\n ),\n CohortData(\n label=\"Q4 2023\", acquisition_period=\"Oct-Dec 2023\",\n customers_acquired=22, total_cac_spend=70_400,\n gross_margin_pct=0.71,\n monthly_revenue=[\n 20_900, 20_500, 20_200, 19_900, 19_700, 19_500,\n 19_300, 19_100, 19_000, 18_900, 18_800, 18_700,\n ],\n ),\n CohortData(\n label=\"Q1 2024\", acquisition_period=\"Jan-Mar 2024\",\n customers_acquired=28, total_cac_spend=81_200,\n gross_margin_pct=0.72,\n monthly_revenue=[\n 27_200, 26_900, 26_600, 26_400, 26_200, 26_000,\n 25_800, 25_700, 25_600, 25_500,\n ],\n ),\n CohortData(\n label=\"Q2 2024\", acquisition_period=\"Apr-Jun 2024\",\n customers_acquired=34, total_cac_spend=91_800,\n gross_margin_pct=0.72,\n monthly_revenue=[\n 33_300, 33_000, 32_800, 32_600, 32_400, 32_200,\n ],\n ),\n CohortData(\n label=\"Q3 2024\", acquisition_period=\"Jul-Sep 2024\",\n customers_acquired=40, total_cac_spend=100_000,\n gross_margin_pct=0.73,\n monthly_revenue=[\n 39_600, 39_400, 39_200,\n ],\n ),\n CohortData(\n label=\"Q4 2024\", acquisition_period=\"Oct-Dec 2024\",\n customers_acquired=47, total_cac_spend=112_800,\n gross_margin_pct=0.73,\n monthly_revenue=[\n 47_000,\n ],\n ),\n ]\n\n\ndef make_sample_channels() -> list[ChannelData]:\n \"\"\"\n Q4 2024 channel breakdown. Blended looks fine; per-channel reveals problems.\n \"\"\"\n return [\n ChannelData(\"Organic / SEO\", spend=9_500, customers_acquired=14, avg_arpa=950, gross_margin_pct=0.73, avg_monthly_churn=0.015),\n ChannelData(\"Paid Search (SEM)\", spend=48_000, customers_acquired=18, avg_arpa=980, gross_margin_pct=0.73, avg_monthly_churn=0.020),\n ChannelData(\"Paid Social\", spend=32_000, customers_acquired=8, avg_arpa=900, gross_margin_pct=0.72, avg_monthly_churn=0.025),\n ChannelData(\"Content / Inbound\", spend=11_000, customers_acquired=6, avg_arpa=1100, gross_margin_pct=0.74, avg_monthly_churn=0.012),\n ChannelData(\"Outbound SDR\", spend=22_000, customers_acquired=4, avg_arpa=1200, gross_margin_pct=0.73, avg_monthly_churn=0.022),\n ChannelData(\"Events / Webinars\", spend=18_500, customers_acquired=3, avg_arpa=1050, gross_margin_pct=0.72, avg_monthly_churn=0.028),\n ChannelData(\"Partner / Referral\", spend=7_800, customers_acquired=7, avg_arpa=1000, gross_margin_pct=0.73, avg_monthly_churn=0.013),\n ]\n\n\n# ---------------------------------------------------------------------------\n# Entry point\n# ---------------------------------------------------------------------------\n\ndef main() -> None:\n parser = argparse.ArgumentParser(description=\"Unit Economics Analyzer\")\n parser.add_argument(\"--csv\", action=\"store_true\", help=\"Export results as CSV to stdout\")\n args = parser.parse_args()\n\n cohorts = make_sample_cohorts()\n channels = make_sample_channels()\n\n print(\"\\n\" + \"=\"*80)\n print(\" UNIT ECONOMICS ANALYZER\")\n print(\" Sample Company: Series A SaaS | Q4 2024 Snapshot\")\n print(\" Gross Margin: ~72% | Monthly Churn: derived from cohort data\")\n print(\"=\"*80)\n\n cohort_results = [analyze_cohort(c) for c in cohorts]\n channel_results = [analyze_channel(c) for c in channels]\n\n print_cohort_analysis(cohort_results)\n print_channel_analysis(channel_results, channels)\n\n # Health summary\n print(\"\\n\" + \"=\"*80)\n print(\" HEALTH SUMMARY\")\n print(\"=\"*80)\n latest = cohort_results[-1]\n prev = cohort_results[-4] if len(cohort_results) >= 4 else cohort_results[0]\n\n print(f\"\\n Latest Cohort ({latest.label}):\")\n print(f\" CAC: {fmt(latest.cac)}\")\n ltv_str = fmt(latest.ltv) if latest.ltv != float(\"inf\") else \"∞\"\n ltv_cac_str = f\"{latest.ltv_cac_ratio:.1f}x\" if latest.ltv_cac_ratio != float(\"inf\") else \"∞\"\n payback_str = f\"{latest.payback_months:.1f} months\" if latest.payback_months != float(\"inf\") else \"∞\"\n print(f\" LTV: {ltv_str}\")\n print(f\" LTV:CAC: {ltv_cac_str} (target: > 3x)\")\n print(f\" CAC Payback: {payback_str} (target: \u003c 18mo)\")\n print(f\" Rating: {rating(latest.ltv_cac_ratio, latest.payback_months)}\")\n\n # Trend vs 4 quarters ago\n print(f\"\\n Trend vs {prev.label}:\")\n cac_delta = (latest.cac - prev.cac) / prev.cac * 100\n ltv_delta_str = \"n/a\"\n if latest.ltv != float(\"inf\") and prev.ltv != float(\"inf\"):\n ltv_delta = (latest.ltv - prev.ltv) / prev.ltv * 100\n ltv_delta_str = f\"{ltv_delta:+.1f}%\"\n cac_str = \"↓ Better\" if cac_delta \u003c 0 else \"↑ Worse\"\n print(f\" CAC: {cac_delta:+.1f}% ({cac_str})\")\n print(f\" LTV: {ltv_delta_str}\")\n\n print(\"\\n Benchmark Reference:\")\n print(\" LTV:CAC > 5x → Scale aggressively\")\n print(\" LTV:CAC 3-5x → Healthy; grow at current pace\")\n print(\" LTV:CAC 2-3x → Marginal; optimize before scaling\")\n print(\" LTV:CAC \u003c 2x → Acquiring unprofitably; stop and fix\")\n print(\" Payback \u003c 12mo → Outstanding capital efficiency\")\n print(\" Payback 12-18mo → Good for B2B SaaS\")\n print(\" Payback > 24mo → Requires long-dated capital to scale\")\n\n if args.csv:\n print(\"\\n\\n--- CSV EXPORT ---\\n\")\n sys.stdout.write(export_csv_results(cohort_results, channel_results))\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":21030,"content_sha256":"625315195f8ba7265223b87107df20b81b769055077d427f54cefbb625ec4336"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"CFO Advisor","type":"text"}]},{"type":"paragraph","content":[{"text":"Strategic financial frameworks for startup CFOs and finance leaders. Numbers-driven, decisions-focused.","type":"text"}]},{"type":"paragraph","content":[{"text":"This is ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" a financial analyst skill. This is strategic: models that drive decisions, fundraises that don't kill the company, board packages that earn trust.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Keywords","type":"text"}]},{"type":"paragraph","content":[{"text":"CFO, chief financial officer, burn rate, runway, unit economics, LTV, CAC, fundraising, Series A, Series B, term sheet, cap table, dilution, financial model, cash flow, board financials, FP&A, SaaS metrics, ARR, MRR, net dollar retention, gross margin, scenario planning, cash management, treasury, working capital, burn multiple, rule of 40","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Burn rate & runway scenarios (base/bull/bear)\npython scripts/burn_rate_calculator.py\n\n# Per-cohort LTV, per-channel CAC, payback periods\npython scripts/unit_economics_analyzer.py\n\n# Dilution modeling, cap table projections, round scenarios\npython scripts/fundraising_model.py","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Key Questions (ask these first)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What's your burn multiple?","type":"text","marks":[{"type":"strong"}]},{"text":" (Net burn ÷ Net new ARR. > 2x is a problem.)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If fundraising takes 6 months instead of 3, do you survive?","type":"text","marks":[{"type":"strong"}]},{"text":" (If not, you're already behind.)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Show me unit economics per cohort, not blended.","type":"text","marks":[{"type":"strong"}]},{"text":" (Blended hides deterioration.)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What's your NDR?","type":"text","marks":[{"type":"strong"}]},{"text":" (> 100% means you grow without signing a single new customer.)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What are your decision triggers?","type":"text","marks":[{"type":"strong"}]},{"text":" (At what runway do you start cutting? Define now, not in a crisis.)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Responsibilities","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Area","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"What It Covers","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Financial Modeling","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bottoms-up P&L, three-statement model, headcount cost model","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/financial_planning.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unit Economics","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LTV by cohort, CAC by channel, payback periods","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/financial_planning.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Burn & Runway","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Gross/net burn, burn multiple, scenario planning, decision triggers","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/cash_management.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fundraising","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Timing, valuation, dilution, term sheets, data room","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/fundraising_playbook.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Board Financials","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"What boards want, board pack structure, BvA","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/financial_planning.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cash Management","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Treasury, AR/AP optimization, runway extension tactics","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/cash_management.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Budget Process","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Driver-based budgeting, allocation frameworks","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/financial_planning.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"CFO Metrics Dashboard","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Category","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Metric","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Frequency","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Efficiency","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Burn Multiple","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 1.5x","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Efficiency","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rule of 40","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 40","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quarterly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Efficiency","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Revenue per FTE","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Track trend","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quarterly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Revenue","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ARR growth (YoY)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 2x at Series A/B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Revenue","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Net Dollar Retention","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 110%","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Revenue","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Gross Margin","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 65%","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Economics","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LTV:CAC","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 3x","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Economics","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CAC Payback","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 18 mo","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cash","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Runway","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 12 mo","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cash","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AR > 60 days","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 5% of AR","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Monthly","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Red Flags","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Burn multiple rising while growth slows (worst combination)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Gross margin declining month-over-month","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Net Dollar Retention \u003c 100% (revenue shrinks even without new churn)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cash runway \u003c 9 months with no fundraise in process","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"LTV:CAC declining across successive cohorts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Any single customer > 20% of ARR (concentration risk)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CFO doesn't know cash balance on any given day","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration with Other C-Suite Roles","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"When...","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CFO works with...","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"To...","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Headcount plan changes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CEO + COO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model full loaded cost impact of every new hire","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Revenue targets shift","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CRO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Recalibrate budget, CAC targets, quota capacity","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Roadmap scope changes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CTO + CPO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Assess R&D spend vs. revenue impact","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fundraising","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CEO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Lead financial narrative, model, data room","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Board prep","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CEO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Own financial section of board pack","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Compensation design","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CHRO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model total comp cost, equity grants, burn impact","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pricing changes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CPO + CRO","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model ARR impact, LTV change, margin impact","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Resources","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/financial_planning.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Modeling, SaaS metrics, FP&A, BvA frameworks","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/fundraising_playbook.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Valuation, term sheets, cap table, data room","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/cash_management.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Treasury, AR/AP, runway extension, cut vs invest decisions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/burn_rate_calculator.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Runway modeling with hiring plan + scenarios","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/unit_economics_analyzer.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Per-cohort LTV, per-channel CAC","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/fundraising_model.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Dilution, cap table, multi-round projections","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Proactive Triggers","type":"text"}]},{"type":"paragraph","content":[{"text":"Surface these without being asked when you detect them in company context:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Runway \u003c 18 months with no fundraising plan → raise the alarm early","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Burn multiple > 2x for 2+ consecutive months → spending outpacing growth","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unit economics deteriorating by cohort → acquisition strategy needs review","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No scenario planning done → build base/bull/bear before you need them","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Budget vs actual variance > 20% in any category → investigate immediately","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Artifacts","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Request","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"You Produce","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"How much runway do we have?\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Runway model with base/bull/bear scenarios","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Prep for fundraising\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fundraising readiness package (metrics, deck financials, cap table)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Analyze our unit economics\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Per-cohort LTV, per-channel CAC, payback, with trends","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Build the budget\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Zero-based or incremental budget with allocation framework","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Board financial section\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"P&L summary, cash position, burn, forecast, asks","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reasoning Technique: Chain of Thought","type":"text"}]},{"type":"paragraph","content":[{"text":"Work through financial logic step by step. Show all math. Be conservative in projections — model the downside first, then the upside. Never round in your favor.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Communication","type":"text"}]},{"type":"paragraph","content":[{"text":"All output passes the Internal Quality Loop before reaching the founder (see ","type":"text"},{"text":"agent-protocol/SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Self-verify: source attribution, assumption audit, confidence scoring","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Peer-verify: cross-functional claims validated by the owning role","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Critic pre-screen: high-stakes decisions reviewed by Executive Mentor","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Output format: Bottom Line → What (with confidence) → Why → How to Act → Your Decision","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Results only. Every finding tagged: 🟢 verified, 🟡 medium, 🔴 assumed.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Context Integration","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Always","type":"text","marks":[{"type":"strong"}]},{"text":" read ","type":"text"},{"text":"company-context.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" before responding (if it exists)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"During board meetings:","type":"text","marks":[{"type":"strong"}]},{"text":" Use only your own analysis in Phase 2 (no cross-pollination)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Invocation:","type":"text","marks":[{"type":"strong"}]},{"text":" You can request input from other roles: ","type":"text"},{"text":"[INVOKE:role|question]","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"cfo-advisor","author":"@skillopedia","source":{"stars":16818,"repo_name":"claude-skills","origin_url":"https://github.com/alirezarezvani/claude-skills/blob/HEAD/c-level-advisor/skills/cfo-advisor/SKILL.md","repo_owner":"alirezarezvani","body_sha256":"1be9157a7b88ffb9d421606ac263408e6327313b1ca414ce77582fc435d9f76a","cluster_key":"1cad75ddeace09d605e02961ce12c4354cd5caf41bfc247841e067dc2e70bb85","clean_bundle":{"format":"clean-skill-bundle-v1","source":"alirezarezvani/claude-skills/c-level-advisor/skills/cfo-advisor/SKILL.md","attachments":[{"id":"f8747d9b-258e-590f-8d1b-404a292bc1fe","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f8747d9b-258e-590f-8d1b-404a292bc1fe/attachment.md","path":"references/cash_management.md","size":12836,"sha256":"a59cd6e86181d5cccd317cf42cca4a98652a71cdf090c1806c5d6fadf95c1ce9","contentType":"text/markdown; charset=utf-8"},{"id":"5aeb5b1d-b597-5498-b60a-e7f1ac1ca676","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5aeb5b1d-b597-5498-b60a-e7f1ac1ca676/attachment.md","path":"references/financial_planning.md","size":16269,"sha256":"add005ec25556262a740c6870216a0a99ec6ae13138b95d20c1948b73c1327f6","contentType":"text/markdown; charset=utf-8"},{"id":"65428cc5-2828-5145-aa22-ac457775eb74","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/65428cc5-2828-5145-aa22-ac457775eb74/attachment.md","path":"references/fundraising_playbook.md","size":13928,"sha256":"6b6bae2764394bb88ecd71676b9ab8748f621b1585e84da76852e700522338d1","contentType":"text/markdown; charset=utf-8"},{"id":"ea885f31-b110-5f62-a01b-51c67e661841","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ea885f31-b110-5f62-a01b-51c67e661841/attachment.py","path":"scripts/burn_rate_calculator.py","size":15952,"sha256":"c1c8b1b648f53934925c1cd8583550d1ac6990f229d2d664fafd0cf1f23b5051","contentType":"text/x-python; charset=utf-8"},{"id":"6251886f-5166-5b10-b04f-7465f75e1e7d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6251886f-5166-5b10-b04f-7465f75e1e7d/attachment.py","path":"scripts/fundraising_model.py","size":18627,"sha256":"646d2ff1260187092651432ad198ac8922afe0574c2d30b9008324f143a8b11e","contentType":"text/x-python; charset=utf-8"},{"id":"7c8eccac-0cbf-546f-85e7-d2c0107db927","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7c8eccac-0cbf-546f-85e7-d2c0107db927/attachment.py","path":"scripts/unit_economics_analyzer.py","size":21030,"sha256":"625315195f8ba7265223b87107df20b81b769055077d427f54cefbb625ec4336","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"988c67b4acfbe5b467193931abbcacf4c813b8c7a7c83f28b635e88d6ea02a83","attachment_count":6,"text_attachments":6,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":4,"skill_md_path":"c-level-advisor/skills/cfo-advisor/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":3},"license":"MIT","version":"v1","category":"web-development","metadata":{"author":"Alireza Rezvani","domain":"cfo-leadership","updated":"2026-03-05T00:00:00.000Z","version":"1.0.0","category":"c-level","frameworks":"financial-planning, fundraising-playbook, cash-management","python-tools":"burn_rate_calculator.py, unit_economics_analyzer.py, fundraising_model.py"},"import_tag":"clean-skills-v1","description":"Financial leadership for startups and scaling companies. Financial modeling, unit economics, fundraising strategy, cash management, and board financial packages. Use when building financial models, analyzing unit economics, planning fundraising, managing cash runway, preparing board materials, or when user mentions CFO, burn rate, runway, fundraising, unit economics, LTV, CAC, term sheets, or financial strategy."}},"renderedAt":1782980368713}

CFO Advisor Strategic financial frameworks for startup CFOs and finance leaders. Numbers-driven, decisions-focused. This is not a financial analyst skill. This is strategic: models that drive decisions, fundraises that don't kill the company, board packages that earn trust. Keywords CFO, chief financial officer, burn rate, runway, unit economics, LTV, CAC, fundraising, Series A, Series B, term sheet, cap table, dilution, financial model, cash flow, board financials, FP&A, SaaS metrics, ARR, MRR, net dollar retention, gross margin, scenario planning, cash management, treasury, working capital,…