#!/usr/bin/env python3
"""
Interactive Financial Stress-Testing Dashboard
Single-file web app that models:
- Net worth projections with BTC scenarios + h-clock cycle trade
- Cashflow and break-even analysis
- Stress tests + Monte Carlo BTC outcomes
- Cycle trade simulator
- BTC-denominated scoreboard
Run:
python /home/ben/ava/fund-model/app.py
CLI:
--host 0.0.0.0
--port 8235
--log-level info
"""
from __future__ import annotations
import argparse
import json
import logging
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse
LOGGER = logging.getLogger("fund-model")
DEFAULTS = {
# Core portfolio defaults from current plan
"btcCagr": 25,
"btcStack": 22.19,
"btcPrice": 97_000,
"strdPosition": 500_000,
"strdYield": 14.66,
"cash": 100_000,
# Income / expenses
"salaryGross": 240_000,
"salaryNet": 170_000,
"expensesNeeds": 75_000,
"expensesWants": 58_000,
"monthlyDca": 500,
# Projection controls
"horizonYears": 7,
"quitJob": False,
# h-clock cycle trade assumptions
"cycleBottomMin": 25_000,
"cycleBottomMax": 60_000,
"cycleTopMin": 150_000,
"cycleTopMax": 400_000,
"cycleCapital": 500_000,
"tradeDurationMonths": 18,
"taxRate": 33,
# Monte Carlo controls
"mcVolatility": 65,
"mcPaths": 1000,
}
HTML_TEMPLATE = r"""
Fund Model — Stress Dashboard
Base NW (horizon)
Pessimistic NW
Optimistic NW
Base BTC Stack (horizon)
Net Worth Path with BTC Price Scenarios + h-clock Trade
Band = pessimistic to optimistic. Base uses your slider CAGR. Model applies STRD → IBIT cycle trade (sell Aug 2026, buy bottom window, sell late 2027 with LTCG tax).
Monthly Surplus
Annual Surplus
BTC Buy Capacity / Year
Passive Coverage (expenses)
Cashflow Breakdown
NW if BTC -50%
NW if BTC -70%
NW if BTC -80%
Runway if job loss
Cashflow if STRD = 0
Worst case (all 3)
Monte Carlo (N paths, 5 years)
Geometric Brownian Motion with drift from BTC CAGR and volatility input. Shows distribution of year-5 net worth.