revenue-model-builder¶
A bottom-up revenue forecasting framework — turn a driver tree
(market_base × penetration × share × price) into an auditable revenue
model that aligns to reported totals via a structural residual line. Core
engine has zero third-party dependencies (pure Python stdlib), including
the Monte Carlo + sensitivity layer.
:material-github: Source on GitHub
· :material-package-variant: pip install revenue-model-builder
Why¶
Most open-source finance tooling covers trading / backtesting
(zipline, backtrader, QuantLib) or DCF valuation. Driver-based revenue
forecasting — decomposing revenue into base × penetration × share × price,
what sell-side analysts and PE associates actually do — has almost no
open-source presence. This project is a minimal, runnable encoding of that
workflow, with the math enforced in code rather than left to a prompt.
Core idea¶
segment_revenue = market_base × penetration × share × price
total_revenue = Σ(segments) + residual # residual absorbs un-modeled biz
The design encodes five hard-won modeling rules — a structural residual that absorbs un-modeled business, A/B/C data grading for traceability, incremental (not growth-rate) penetration forecasts, a certainty pyramid for prioritizing forecast inputs, and a history-first workflow.
Quick start¶
from revenue_model import Driver, Segment, RevenueModel, BASE, PENETRATION, SHARE, PRICE
seg = Segment(
name="cockpit-domestic",
base=Driver("China passenger car sales", BASE, {2022: 22.0, 2023: 23.0},
level="A", unit="million units", source="CAAM"),
penetration=Driver("DMS penetration", PENETRATION, {2022: 0.04, 2023: 0.06},
level="B", unit="fraction", source="research institute"),
share=Driver("market share", SHARE, {2022: 0.10, 2023: 0.12},
level="C", unit="fraction", source="estimate"),
price=Driver("ASP", PRICE, {2022: 600, 2023: 620},
level="C", unit="yuan", source="benchmark"),
)
model = RevenueModel("DemoCo", [seg], total_revenue={2022: 110.0, 2023: 215.0})
for r in model.validate_all():
print(r.year, f"segments={r.segment_sum:.1f}", f"residual={r.residual:.1f}", r.warnings)
CLI
Once installed: python -m revenue_model {build, simulate, excel, extract}.
Documentation¶
- :material-scale-balance: Design Principles — the five hard-won modeling rules (residual, ABC grading, incremental penetration, certainty pyramid, history-first)
- :material-file-document-outline: Segment Extraction Proposal — annual-report → segment skeleton pipeline
- :material-chart-line: Stochastic Revenue Design — v0.2→v0.3 roadmap (Monte Carlo → financial stochastic processes)
Uncertainty¶
Turn point forecasts into distributions and find out which assumption matters most — pure stdlib, no numpy:
from revenue_model import simulate_model, tornado
mc = simulate_model(model, 2024, {"market share": (0.10, 0.18)}, n=20000, seed=0)
print(mc.median, mc.percentiles["p5"], mc.percentiles["p95"])
Backtesting¶
How accurate is the forecast, really? The backtest extra runs honest
out-of-sample evaluation — five methods (Naive / Linear / CAGR / Holt /
ARIMA), pure-stdlib metrics (sMAPE as the headline, robust across scales),
and real A-share data via the data extra (akshare, CSV-cached). Across ten
companies spanning six growth regimes, adaptive methods (Holt / ARIMA) win all
ten at ~14% sMAPE.
The finding sharpens the framework's positioning: on revenue totals,
statistics wins — but the driver decomposition uniquely locates structure
(which segment rides a trend vs a one-off event like Luxun's 2025 Leoni
acquisition, invisible to any aggregate method). See
examples/backtest_demo/.
Research / education tool, not investment advice. See DISCLAIMER.