Inspiration
A new U.S. small business can win a profitable contract and still go broke before the client pays. Materials and payroll go out now; the invoice lands in 30 or 45 days. The problem is not profit — it is the time between spending and collecting.
Banks underwrite credit scores. Spreadsheets assume a straight line. We wanted a copilot that answers one question before the owner signs:
Will this deal strengthen the company, or leave it illiquid before payday?
That question is a first-passage problem. Once we saw it that way, Brownian motion and the Inverse Gaussian stopped being theory and became the product.
What it does
La Necia by Capital Juan is a Growth Deal Simulator for early-stage U.S. SMEs.
The owner logs in with a demo key, sees real cash (balance, inflows, outflows, open contracts), and simulates a new deal. The engine returns Yes / No / Conditional, the probability of running out of cash before collection, the causes, and — when risk is high — a specific loan amount that would keep the business alive until the client pays.
Six fictional SMEs (Austin taco truck, Phoenix HVAC, Miami boutique, and others) show all three verdicts live.
How we built it
Cash follows a Brownian motion with drift:
$$X(t) = X_0 + \mu t + \sigma W(t)$$
$X_0$ is available cash (balance minus capital trapped in delivered-but-unpaid work). $\mu$ and $\sigma$ are estimated from the company's real daily net flow.
Ruin is the first time cash hits the liquidity floor $L$:
$$\tau = \inf{ t : X(t) \le L }$$
When $\mu < 0$, that hitting time is Inverse Gaussian:
$$\tau \sim \mathrm{IG}!\left(\frac{a}{|\mu|},\; \frac{a^2}{\sigma^2}\right),\qquad a = X_0 - L$$
When $\mu \ge 0$ the IG is defective, so we use the closed-form first-passage formula for Brownian motion with drift. Both branches are the same model — not a heuristic wearing a math costume.
A new deal shifts the starting point:
$$X_0' = X_{\text{available}} - \text{upfront cost} + \text{deposit}$$
We evaluate $P(\tau \le T)$ with and without the deal. Then we bisect for the smallest loan $L$ that brings that probability down to 20%, and split it into a trend gap plus a volatility buffer:
$$\text{recommended loan} = \text{liquidity gap} + \text{volatility buffer}$$
A realistic cap (80% of receivables + free cash) stops us from “pre-approving” credit a 8-month-old shop could never get.
Stack: FastAPI + SciPy on the backend, React + Vite + Tailwind on the frontend. Auth is a demo API key on purpose — no real bank, no OAuth.
What we learned
- Profitability and solvency are different questions. A deal can have a fat margin and still kill you on the way to payday.
- $\mu$ is only the daily grind. Lumpy contract costs (
cost_to_complete) are not inside the drift; if you fold future collections into $X_0$, the model pretends the check already arrived. - Runway is a time. Burn rate is a speed. Mixing them in the UI is how a pitch loses the judges.
- The loan has to come out of the same $P(\tau \le T)$ that produces the verdict. Anything else is a made-up number with a formula taped on.
Challenges
The first-passage law changes shape when drift turns positive. We had to keep both branches honest and still return one number the owner can act on.
Estimating $\mu$ and $\sigma$ from ~12 days of transactions is noisy by design — that is a real early-stage ledger. We floored $\sigma$ so a flat week does not blow up the IG.
The hardest product decision was the credit cap. Without it the model happily “approves” a loan ten times the company’s cash. With it, some deals become a clean No, which is the honest answer.
We also had to extend the original DayZero / Ignition dashboard (Centro de Mando, Proyecto, Ledger, Bóveda) without throwing away the team’s pitch. Login, the deal simulator, and the loan alert sit on top of that architecture — we did not rebuild the house the night before the demo.
Log in or sign up for Devpost to join the conversation.