In-depth reference
The pro forma, line by line
Every pro-forma line — its exact label, the formula that produces it, what feeds it, and the sign convention — traced from inputs through NOI to the levered return.
The pro forma is not a spreadsheet you type into. It is the computed cash flow — the engine’s output, rendered. Every cell is a function of the inputs you set on the rent roll, the recovery matrix, the expense ledger, the debt terms, and the exit assumptions. This chapter documents each line: the label the workspace shows, the arithmetic behind it, the fields that feed it, and the sign it carries. When a number looks wrong, the fix is upstream — this page tells you exactly which input owns each line so you can find it.
Read this alongside Pro forma & analysis, which covers the tabs, toggles, and the vs-Broker workflow. This chapter is the derivation reference behind that surface.
How to read the ledger
Section titled “How to read the ledger”The annual pro forma is a stack of signed rows. Revenue lines are positive.
Deductions — vacancy, abatements, expenses, leasing costs, debt service — are
carried negative in the ledger even though the underlying engine field is a
positive magnitude. So “General Vacancy Loss” displays as −92,500 while the
engine stores generalVacancy = 92,500. Two rows break that rule:
- Base Rent Abatements is already stored negative by the engine, so it is displayed as-is (a reduction).
- Absorption & Turnover Vacancy is stored as a positive magnitude and shown negated.
Subtotal rows — Scheduled Base Rental Revenue, Potential Gross Revenue,
Effective Gross Revenue, Net Operating Income, Net Cash Flow, Cash Flow After
Debt Service — are rendered bold. Everything between two subtotals foots to the
lower subtotal exactly; there is no rounding slack, because each displayed value
is roundCents-ed off the same monthly series before it is summed to the year.
The engine computes monthly, then rolls up to annual by summing each field across the fiscal year’s months. The monthly and annual pro formas therefore carry the same rows with the same formulas; the monthly grain simply exposes timing — the month a lease commences, an abatement burns off, or a vacancy hits. Where a line behaves differently monthly vs. annually, this chapter says so.
The revenue stack
Section titled “The revenue stack”Revenue builds from the top of the rent roll down to Effective Gross Revenue in a fixed order. The occupied-tenant rent lines resolve first, then the vacant-space market rent, then the two structural haircuts.
Potential Rental Revenue
Section titled “Potential Rental Revenue”Label: Potential Rental Revenue · Sign: positive
This is the engine’s potentialGrossRevenue field — gross scheduled rent for
occupied space plus market rent on vacant space, before free rent is removed:
potentialGrossRevenue = scheduledBaseRental − abatements + absorptionVacancyBecause scheduledBaseRental already includes the (negative) abatement, adding
it back and adding the absorption line means, equivalently:
Potential Rental Revenue = baseRent + stepRent + cpiRent + absorptionVacancyIt is the “everything is leased and paying” line: contract rent on occupied suites, plus what the vacant square footage would earn at market. The two lines directly beneath it strip the two things that keep you from collecting it — the vacant space itself, and any free rent.
Absorption & Turnover Vacancy
Section titled “Absorption & Turnover Vacancy”Label: Absorption & Turnover Vacancy · Sign: negative (shown −absorptionVacancy)
The market rent attributed to space that is not yet leased. For each vacant suite the engine values the empty space at its market rent (from the suite’s Market Leasing Assumption, or the stated total for a ground/pad lease), and — if an absorption schedule is present — ramps that penalty down as the space leases up:
tenantVacancyMarketRent = fullVacancyRent × (1 − absorptionFactor)fullVacancyRent is marketRentPSF × size / 12 per month (or the stated annual
total ÷ 12 for a total-basis lease). The absorptionFactor interpolates from
0 (fully vacant) toward the scheduled target occupancy along the ramp. With no
schedule, the full market rent is booked as vacancy every month until the suite
commences. This line only accrues when absorption vacancy is enabled on the
vacancy config; otherwise vacant space simply contributes zero and this row is
$0.
Base Rent Abatements
Section titled “Base Rent Abatements”Label: Base Rent Abatements · Sign: negative (stored negative, shown as-is)
Free rent — the concession months on a lease or a lease-up suite. The engine
computes it in calcAbatement off the tenant’s abatement schedule against
{ base, step, cpi } for the month, and stores it as a negative number, so
it reduces scheduled rent. Fully-abated months show the full base+step+CPI as a
negative here and a matching positive in the rent components above, netting the
suite to $0 collected while still counting it as occupied.
Scheduled Base Rental Revenue
Section titled “Scheduled Base Rental Revenue”Label: Scheduled Base Rental Revenue · Sign: positive · Subtotal
The contract rent the model expects to bill occupied tenants, net of free rent:
scheduledBaseRental = baseRent + stepRent + cpiRent + abatementsThis foots against the three rows above it — Potential Rental Revenue − Absorption & Turnover Vacancy + Base Rent Abatements = Scheduled Base Rental Revenue — by construction. Its four components come straight off the rent stack:
- baseRent — the in-place contract rent for the month, from
calcBaseRent(lease, state). Converted to a monthly dollar figure from whatever unit the rent roll carried ($/SF/yr, $/SF/mo, or annual total). - stepRent — the increment from contractual step/escalation schedules,
calcStepRent. A step is expressed relative to base, so the sumbaseRent + stepRentis the stepped contract rent in that month. - cpiRent — index-linked escalation,
calcCPIRent, computed offbasePlusStepMonthlyand the prior cumulative CPI. The running CPI level resets to 0 when a lease rolls into a new (blended/option) term so the new term escalates off its own base, not the prior term’s. - abatements — as above, negative.
Retail Sales Percent Revenue
Section titled “Retail Sales Percent Revenue”Label: Retail Sales Percent Revenue · Sign: positive
Overage / percentage rent for retail tenants, retailSalesRent. The engine
computes it in calcRetailSalesRent from the tenant’s projected annual sales
(grown by the 1-based analysis year) against the tenant’s breakpoint. Overage is
recognized in the month it is earned — a reportingLagMonths value on the
lease is captured for reference but not modeled, and the engine emits a warning
when it is set, so you are never silently missing a lag you configured.
Expense Reimbursements
Section titled “Expense Reimbursements”Label: Expense Reimbursements · Sign: positive
Tenant recoveries of operating expenses — reimbursementRevenue, summed across
all tenants for the month. This is the output of the recovery engine: for each
tenant it applies the recovery method (Net, base-year stop, gross-up, pooled),
caps, and exclusions against the grossed-up reimbursable expense pool. The full
mechanics live in Recoveries, end to end; on the
pro forma it arrives as a single per-year total. When a computed management
fee is flagged reimbursable, its marginal recovery is added into this line
after the vacancy/credit-loss haircuts (a contractual pass-through is not
occupancy-adjusted).
Other Income
Section titled “Other Income”Label: Other Income · Sign: positive
Miscellaneous / additional revenue — miscellaneousRevenue — parking, storage,
antenna, late fees, and anything else on the Additional Revenue ledger. Each
source is booked at its stated amount (monthly or annualized ÷ 12), grown by its
own inflation rate (or the general rate), and gated by any start/end month. An
annualOverrides map keyed by fiscal year pins a specific year’s amount. Per
Additional revenue, the sum of the per-source
line items ties exactly to this total because both use the same per-source
function.
Potential Gross Revenue
Section titled “Potential Gross Revenue”Label: Potential Gross Revenue · Sign: positive · Subtotal
The full income base before structural loss — the engine’s potentialGrossIncome:
Potential Gross Revenue = scheduledBaseRental + retailSalesRent + reimbursementRevenue + miscellaneousRevenueGeneral Vacancy Loss
Section titled “General Vacancy Loss”Label: General Vacancy Loss · Sign: negative (shown −generalVacancy)
The structural (as opposed to space-specific) vacancy allowance — the “you will
never be 100% leased 100% of the time” haircut. Computed by calcGeneralVacancy
as base × percent, where the base depends on the vacancy method:
| Method | Base the % applies to |
|---|---|
PercentPGI |
Potential gross income (PGR: scheduled rent + retail + reimbursements + misc) |
PercentSBR |
Scheduled base rental only (base + step + CPI, net of free rent) |
PercentBaseReimb |
Scheduled base rental + reimbursements (the IC-memo commercial convention) |
PercentAllRental |
All rental income (equivalent to PGI here) |
None |
0 — no general vacancy |
Vacancy basis convention. Commercial deals default to a percentage of PGR
(PercentPGI / PercentAllRental) — the haircut lands on the whole income base.
The PercentSBR basis narrows it to scheduled base rent, which is the natural
analog of the residential/multifamily gross potential rent convention where
vacancy is a percentage of gross scheduled rent alone. PercentBaseReimb is the
stricter commercial IC convention — base rent plus recoveries, with percentage
and miscellaneous income left out of the haircut.
Two modifiers refine the raw haircut:
- Excluded tenants. Credit tenants carved out of the general-vacancy haircut have their revenue (base rent and, for a PGI/all-rental basis, their reimbursements) removed from the base before the percentage is applied.
reduceVacancyByDowntime. When enabled, the raw vacancy is reduced by the absorption vacancy already booked above, so the two do not double-count:max(0, rawVacancy − absorptionVacancy).
Per-year overrides (generalVacancyAnnualOverrides) replace the percentage for a
specific fiscal year.
Credit Loss
Section titled “Credit Loss”Label: Credit Loss · Sign: negative (shown −creditCollectionLoss)
Collection / credit loss, calcCreditLoss(base, percent) = max(0, base × percent). It shares the vacancy method’s base: PercentSBR narrows both
the vacancy and the credit-loss base to scheduled base rent, PercentBaseReimb
narrows both to base + reimbursements, and every other method leaves credit loss
on full PGI. Excluded-tenant carve-outs apply here too, via a separate
credit-loss exclusion set, and per-year overrides
(creditLossAnnualOverrides) replace the rate for a given year. When the
credit-loss percentage is 0 (the default), this line is $0.
Effective Gross Revenue
Section titled “Effective Gross Revenue”Label: Effective Gross Revenue · Sign: positive · Subtotal
The revenue the property actually realizes:
effectiveGrossRevenue = potentialGrossIncome − generalVacancy − creditCollectionLossIf a reimbursable management fee is present, its recovery is added to EGR
after this subtraction (see the management-fee note below), so a deal with a
reimbursable fee shows an EGR marginally above the pure PGI − vacancy − credit
figure. EGR is the base for the PercentEGI management fee and the numerator of
economic occupancy.
Operating expenses
Section titled “Operating expenses”Total Operating Expenses
Section titled “Total Operating Expenses”Label: Total Operating Expenses · Sign: negative (shown −totalOperatingExpenses) · Expandable
The sum of every above-line operating expense for the month, expanded into
one child row per expense line (its name from the ledger). Each line is:
inflatedAnnual = annualOverride[fiscalYear] ?? applyInflation(amount, month, method, factors)actual = calcExpenseActual(expense, occupancyPercent, inflatedAnnual)applyInflation grows the stated amount from the base to the current month at
the line’s own inflation rate, a named growth schedule, or per-year growth
overrides (which compound year over year and take precedence). calcExpenseActual
then applies the fixed/variable split: a variable expense scales by
occupancyPercent, a fixed expense does not.
Below-line expenses (position: 'belowLine' — reserves and similar) are
excluded from this total and from NOI; they appear further down in the
capital block. This matters for recoveries: below-line costs are never recovered,
because recovering a cost that never hit NOI would book phantom revenue.
Management fee behavior
Section titled “Management fee behavior”The management fee is special-cased. When managementFeeConfig.method is
anything other than the inert Fixed (an expense-row fee):
-
Any existing Management-category expense line is skipped in the loop above, so the computed fee is not double-counted against a stray management line.
-
The fee is computed on a well-defined, non-circular base:
Method Fee PercentEGIeffectiveGrossRevenue × valuePercentOpExtotalOperatingExpenses × value(the pre-fee, ex-Management total)PerSFvalue × totalRentableArea ÷ 12FixedAmountvalue ÷ 12 -
Inflation is applied only to the dollar-denominated methods (
PerSF,FixedAmount). APercentEGI/PercentOpExfee rides a base that already grows with the model, so inflating it again would compound growth twice. -
The fee is added to
totalOperatingExpensesand appears as a Management Fee child row. -
If the fee is flagged reimbursable, its marginal recovery (a base pass vs. a with-fee pass on a throwaway cap tracker) is added to reimbursement revenue and to EGR — after vacancy and credit loss, since a contractual pass-through is not occupancy-adjusted.
Net Operating Income
Section titled “Net Operating Income”Label: Net Operating Income · Sign: positive · Subtotal
netOperatingIncome = effectiveGrossRevenue − totalOperatingExpensesPer the glossary, NOI is EGR less operating expenses,
before capital costs, leasing costs, below-line reserves, and debt. It is the
single most-scrutinized number in the model and the sole oracle for every
capitalized metric — going-in cap, exit value, debt yield, DSCR. Nothing
re-derives NOI from its parts; every surface reads annuals[].netOperatingIncome
(see Trace any number).
The canonical NOI labels distinguish three period/scope flavors that are easy to conflate:
- Year 1 NOI (EGI − OpEx) —
annuals[0].netOperatingIncome, the in-place / going-in NOI. - Forward NOI @ Exit —
metrics.stabilizedNOI, the forward-12 NOI that capitalizes the reversion (not the last hold-year in-place NOI). - Yr-N NOI (in-place) —
annuals[hold-year].netOperatingIncome, kept for surfaces that genuinely want the final hold-year in-place figure.
Capital & leasing costs
Section titled “Capital & leasing costs”These lines sit below NOI — they reduce cash flow but not NOI. On the overview cash flow they are grouped under Leasing & Capital Costs; the annual and monthly ledgers list them individually.
Tenant Improvements
Section titled “Tenant Improvements”Label: Tenant Improvements · Sign: negative (shown −tenantImprovements)
TI dollars disbursed when a lease commences in the month. For a standard
lease: (leasingCosts.tenantImprovements per SF) × size, booked in the lease’s
in-month (or start month). For a blended roll, the blended lease’s tiPerSF × size. TI is a per-SF cost, so a 0-SF pad lease correctly books $0.
Leasing Commissions
Section titled “Leasing Commissions”Label: Leasing Commissions · Sign: negative (shown −leasingCommissions)
LC dollars at commencement. A commission may be quoted as a flat $/SF or as a
{ percent, basis } rate (a percentage of total lease value); the engine
normalizes it to $/SF at the lease’s rent and term via leasingCommissionToPerSf
before posting lcPerSf × size. A total-basis blended re-lease books its stated
absolute commission (lcTotal) so a ground/pad lease books the real number
rather than $0.
Both TI and LC are rollover/lease-up costs: they hit in the month a suite
(re)commences — a new lease, a renewal at rollover, or a vacant suite absorbed
by its MLA. Years with no rollover carry $0 on both lines. The per-SF versions
(tenantImprovementsPerSF, leasingCommissionsPerSF) are layered onto the
annual summary as debt/operating metrics.
Capital Expenditures
Section titled “Capital Expenditures”Label: Capital Expenditures · Sign: negative (shown −capitalExpenditures)
Non-leasing capital spend from the capital plan, calcCapExForMonth. Each item
books by amountType:
- lumpSum — the full amount in its scheduled month.
- recurring — the amount every
recurringIntervalMonthsfromrecurringStartMonth. - percentRevenue —
amount × currentMonthPGR(a fraction of the month’s potential gross revenue — the top-linepotentialGrossRevenue, not inflated again, since the revenue base already grew). - perUnit —
amount × totalRentableArea.
Nominal amount types (lumpSum / recurring / perUnit) are inflated to the period;
percentRevenue is not. A per-year annualOverrides map pins a specific year.
Debt-funded flagged items also drive loan draws (Good News Funding), but the
spend still appears here.
Capital Reserves / Below-Line Expenses
Section titled “Capital Reserves / Below-Line Expenses”Label: Capital Reserves / Below-Line Expenses · Sign: negative (shown −belowLineExpenses)
The belowLineExpenses total — reserve lines flagged position: 'belowLine'.
Excluded from OpEx and NOI (above), they are subtracted here, between NOI and
Net Cash Flow.
Net Cash Flow (before debt)
Section titled “Net Cash Flow (before debt)”Label: Net Cash Flow · Sign: positive · Subtotal
Unlevered cash flow — the property’s cash generation before financing:
netCashFlowBeforeDebtService = netOperatingIncome − belowLineExpenses − tenantImprovements − leasingCommissions − capitalExpendituresThis is the series the unlevered IRR and equity multiple run on. It is also the “Net Cash Flow” the overview groups the individual capital lines beneath.
Debt service & levered cash flow
Section titled “Debt service & levered cash flow”Debt Service
Section titled “Debt Service”The annual ledger splits debt service into two rows; the overview and monthly ledgers show a single Debt Service line.
- Debt Service (Interest) —
−debtServiceInterest - Debt Service (Principal) —
−debtServicePrincipal
Both come from the debt ledger’s monthly amortization (advanceDebtLedgerMonth)
across every loan. The combined Debt Service on the overview/monthly ledger
is −debtService, which includes financing fees and any maturity balloon; the
interest+principal split on the annual ledger is the recurring service. A
separate debtServiceForDscr (recurring service, excluding origination fees,
balloons, and refi payoffs) is what DSCR divides by. See
Debt & financing, in depth for the ledger mechanics.
Cash Flow After Debt Service
Section titled “Cash Flow After Debt Service”Label: Cash Flow After Debt Service · Sign: positive · Subtotal
Levered cash flow — what reaches equity:
cashFlowAfterDebtService = netCashFlowBeforeDebtService − debtService + loanFundingProceedsloanFundingProceeds picks up draw-mechanic loan fundings in the month they
fund. On the overview cash flow, Year 0 of this row is the levered equity
outflow (−equityInvested), not the full unlevered acquisition cost — so the row
ties to the engine’s levered series that drives the levered IRR. This is the
series the levered IRR, equity multiple, cash-on-cash, and return-on-equity
all consume.
Label: DSCR · Format: ratio · (annual ledger only)
dscr = netOperatingIncome ÷ debtServiceForDscrPer year, using recurring debt service (origination fees, balloons, and refi
payoffs excluded). A year with no debt service has no DSCR and renders --
rather than a misleading 0.00x. The header reports the hold’s average and
minimum DSCR, computed across hold years only (reversion year excluded).
The returns block
Section titled “The returns block”The returns are computed once, on the assembled monthly cash-flow series, in
runCalculation. Every figure below is verified against lib/engine/returns.ts,
exit-settlement.ts, resale.ts, and deal-metrics.ts.
The cash-flow series
Section titled “The cash-flow series”Two dated series are assembled by buildExitSettlement, each ending at the
sale month (the hold end — the reversion year is sliced off so it never leaks
into a return):
Levered (drives levered IRR / EM / NPV):
[ { −equityInvested, at analysisStartDate }, { cashFlowAfterDebtService[m], at month-end } for each held month ]Unlevered (drives unlevered IRR / EM / NPV):
[ { −acquisitionCost, at analysisStartDate }, { netCashFlowBeforeDebtService[m], at month-end } for each held month ]where equityInvested = acquisitionCost − initialLoanProceeds (initial-month
loan fundings only). Each monthly flow is dated at the end of its month
(addMonthsUTC(month.date, 1)); the initial outflow is dated at the analysis
start. The net resale proceeds are folded into the final held month: levered
gets resale.net − loanPayoff − prepaymentPenalty, unlevered gets resale.net.
IRR — unlevered and levered
Section titled “IRR — unlevered and levered”Both IRRs are XIRR on the dated series above: calcXIRR. The solver is
Newton’s method with a bracketing-bisection fallback, discounting each flow by
its actual elapsed time:
XNPV(rate) = Σ amount / (1 + rate) ^ yearsBetween(t0, t)yearsBetween(a, b) = (b − a) in days / 365 // ACT/365So t0 is the analysis start date carrying −equityInvested (levered) or
−acquisitionCost (unlevered), flows are monthly and dated, and the
day-count is ACT/365. XIRR is the annual rate that zeroes XNPV; it reproduces
Excel’s =XIRR (see the XIRR Working report and the
glossary).
Guardrails:
- IRR is only reported when it converges and its magnitude is
≤ 200%(MAX_REPORTABLE_IRR = 2); otherwise the metric is suppressed and a warning is emitted (“Verify leverage, purchase price, and exit assumptions”). - Levered IRR is only computed when equity invested is meaningful — at least 0.1% of acquisition cost. At ≥100% leverage the levered block is suppressed with a warning rather than dividing by a near-zero equity base.
Equity multiple
Section titled “Equity multiple”Label: Equity Multiple · levered and unlevered
equityMultiple = Σ(distributions) / equityInvested = Σ(cashflows[1:]) / (−cashflows[0])calcEquityMultiple treats index 0 as the single equity contribution at close
and every later period as a net distribution (a negative period nets against
distributions rather than being reclassified as a fresh capital call). This keeps
the multiple invariant to intra-hold timing. Levered uses the levered series;
unlevered uses the unlevered series. roi = equityMultiple − 1.
Cap-rate metrics
Section titled “Cap-rate metrics”Going-In Cap Rate — annualized Year-1 NOI over price:
goingInCapRate = (annuals[0].netOperatingIncome × 12/monthsInYear₁) / acquisitionCostThe 12/monthsInYear₁ factor annualizes a stub first year (a mid-year close),
so a 6-month year 1 does not halve the cap rate.
Terminal (Forward) NOI — the reversion year’s NOI. Default method is
ForwardTwelve: the 12 months after the sale month — the buyer’s forward
year — annualized. This is a real modeled year (scheduled steps, rollovers to
market, downtime, reimbursement resets, expense inflation), not the last hold
year grown by a flat rate.
Gross resale value — for a cap-rate exit:
grossResaleValue = terminalNOI / exitCapRatewhere exitCapRate here is the stated assumption (resaleConfig.capRate).
Other exit methods set the value directly: SpecifiedAmount uses the entered
dollar figure; ValuePerUnit uses valuePerUnit × totalArea.
Selling costs & net proceeds:
sellingCosts = grossResaleValue × sellingCostsPercent + sellingCostsFixednet = max(0, gross − sellingCosts − capitalToStabilize)capitalToStabilize (TI + LC + stripped free rent) is netted only on the
Stabilized reversion basis; on the default Actual basis it is $0.
Implied Exit Cap Rate — the engine-realized cap:
exitCapRate (implied) = terminalNOI / grossResaleValueFor a cap-rate exit this equals the assumption; for SpecifiedAmount /
ValuePerUnit it diverges, which is exactly why the two carry distinct labels —
Exit Cap Assumption vs. Implied Exit Cap — and never share one.
Net resale proceeds after debt (into the levered final flow):
netResaleProceedsAfterDebt = resale.net − loanPayoff − prepaymentPenaltyOther headline metrics
Section titled “Other headline metrics”Derived in buildDealMetrics from series already assembled — every ratio guards
its denominator and reports null, never NaN:
- Debt Yield = annualized Year-1 NOI / initial loan principal.
- Loan Constant = annualized Year-1 recurring debt service / initial loan principal.
- Positive Leverage = going-in cap rate > loan constant.
- LTV = initial loan principal / acquisition cost.
- Yield on Cost = stabilized NOI / acquisition cost; Development Spread = yield on cost − exit cap assumption.
- Gross Rent Multiplier = acquisition cost / annualized Year-1 scheduled base rental.
- DCF Value = unlevered NPV + acquisition cost.
- Peak Equity = the trough of the cumulative levered series; Payback Months = the first month the cumulative levered series turns ≥ 0.
- Cash-on-Cash (per year) =
cashFlowAfterDebtService / equityInvested, annualized on stub years. - Return on Equity (per year) = cash flow after debt service ÷ a cost-basis equity roll-forward (initial equity + cumulative principal amortized through the prior year, adjusted for net refinance cash).
- Economic Occupancy (per year) = EGR ÷ gross potential income — read straight off the engine, never re-derived from a rent-only base.
The vs-Broker comparison
Section titled “The vs-Broker comparison”When a broker pro forma was among the sources, the vs Broker tab reconciles
your modeled Year 1 against the broker’s, line by line. Each row carries the
broker figure, your figure, the dollar and percent delta, a severity chip, and
the OM page citation. The reconciliation is built in
broker-reconciliation-view-model.ts:
- Delta =
ours − broker; delta % =delta / |broker|. - Severity is assigned by magnitude — but only to unambiguous component rows and the clean OpEx subtotal. EGI/NOI subtotals are not flagged, because a broker that states vacancy and credit loss separately makes its gross-revenue sum diverge from your post-vacancy EGI/NOI for a benign reason.
- A line is Reconciled when the delta is within tolerance — under $1,000 absolute, or within 2% of the broker figure — or when you accept it.
- Expandable rows show your drivers: the base-rent line decomposes into base, step, CPI, percentage/sales rent, and abatements (which foot to scheduled base rental); expense rows decompose into category line items.
Work it top to bottom after an OM build — this is the fidelity check. See Pro forma & analysis for the Reconcile / Jump / Fix-with-agent actions.
A worked example year
Section titled “A worked example year”One occupied tenant, one vacant suite, a full year — every line tying from inputs to the levered cash flow. Inputs:
- Building: 100,000 SF total.
- Tenant A: 80,000 SF, $20.00/SF/yr base, NNN, no steps/CPI/abatements this year. Annual base rent = 80,000 × $20.00 = $1,600,000.
- Vacant suite: 20,000 SF, market rent $18.00/SF/yr, absorption vacancy enabled, no absorption schedule (fully vacant all year). Vacancy market rent = 20,000 × $18.00 = $360,000.
- Recoveries: Tenant A reimburses $200,000 for the year.
- Other income: parking, $50,000.
- General vacancy:
PercentPGI, 5%. Credit loss: 1% (PGI basis). - Operating expenses (above-line, ex-management): $400,000.
- Management fee:
PercentEGI, 3%, not reimbursable. - Capital: $50,000 reserve capex; no TI/LC (no rollover), no below-line.
- Debt: $10,000,000 interest-only at 5.0% → $500,000 annual interest, $0 principal.
- Acquisition cost: $18,000,000. Equity = 18,000,000 − 10,000,000 = $8,000,000.
-
Revenue stack
Line Amount Note Potential Rental Revenue 1,960,000 1,600,000 base + 360,000 absorption (pre-abatement) less Absorption & Turnover Vacancy (360,000) vacant suite at market less Base Rent Abatements 0 no free rent Scheduled Base Rental Revenue 1,600,000 ties: 1,960,000 − 360,000 − 0 Retail Sales Percent Revenue 0 Expense Reimbursements 200,000 Tenant A recoveries Other Income 50,000 parking Potential Gross Revenue 1,850,000 1,600,000 + 0 + 200,000 + 50,000 -
Structural loss → EGR
Line Amount Note less General Vacancy Loss (92,500) 5% × 1,850,000 less Credit Loss (18,500) 1% × 1,850,000 Effective Gross Revenue 1,739,000 1,850,000 − 92,500 − 18,500 -
Operating expenses
Line Amount Note Operating expenses (ex-mgmt) (400,000) Management Fee (52,170) 3% × 1,739,000 EGR Total Operating Expenses (452,170) -
NOI
NOI = 1,739,000 − 452,170 = 1,286,830 -
Capital → unlevered cash flow
Line Amount Net Operating Income 1,286,830 less Tenant Improvements 0 less Leasing Commissions 0 less Capital Expenditures (50,000) less Capital Reserves / Below-Line 0 Net Cash Flow (before debt) 1,236,830 -
Debt → levered cash flow
Line Amount Net Cash Flow (before debt) 1,236,830 less Debt Service (Interest) (500,000) less Debt Service (Principal) 0 Cash Flow After Debt Service 736,830 -
Ratios off this year
- Going-in cap = 1,286,830 / 18,000,000 = 7.15%
- DSCR = 1,286,830 / 500,000 = 2.57x
- Debt yield = 1,286,830 / 10,000,000 = 12.87%
- Year-1 cash-on-cash = 736,830 / 8,000,000 = 9.21%
Every subtotal foots to the lines above it, and every ratio reads off the same NOI and cash-flow figures the pro forma displays.
Tie-out & rounding rules
Section titled “Tie-out & rounding rules”- Monthly is the source. Each field is computed monthly,
roundCents-ed, then summed to the year. Annual = Σ months. There is no independent annual computation to drift from the monthly grain. - Subtotals foot exactly. Scheduled Base Rental, Potential Gross Revenue, EGR, NOI, Net Cash Flow, and Cash Flow After Debt Service are each the sum of their component rows to the cent.
- Signs are display conventions. The engine stores deductions as positive magnitudes (except abatements, stored negative); the ledger negates them for display. When you read a raw engine field in the inspector, expect the unsigned magnitude.
- The reversion year is not the hold. It appears as a trailing column but is excluded from IRR, equity multiple, average occupancy, and DSCR.
- Guarded ratios. Every derived ratio returns
--(null) rather thanNaN/Infinitywhen its denominator is non-positive.
Troubleshooting: “this line looks wrong”
Section titled “Troubleshooting: “this line looks wrong””-
Potential Rental Revenue looks too high — it includes market rent on vacant space (absorption vacancy). Check the next row: Absorption & Turnover Vacancy strips it back out. If the vacant suite’s market rent is wrong, fix its MLA. Remember this row is pre-abatement gross rent, not what you collect.
-
Scheduled Base Rental is below contract rent — free rent. Look at Base Rent Abatements; a fully-abated month shows the full rent as a negative here. Check the tenant’s abatement schedule on the rent roll.
-
General Vacancy Loss seems double-counted with the vacant suite — the vacant suite is already valued in Absorption & Turnover Vacancy. If you want the structural haircut reduced by that, enable
reduceVacancyByDowntime. Otherwise both apply by design. -
Vacancy or credit loss is haircutting the wrong income — check the vacancy method.
PercentSBRnarrows both to scheduled base rent;PercentBaseReimbto base + reimbursements;PercentPGI/PercentAllRentalapply to full PGR. Credit loss follows the vacancy method’s base. -
Total Operating Expenses jumped and there is a Management Fee line — a computed fee (any method but
Fixed) supersedes a Management-category expense line and is added on top. Confirm you are not also carrying a manual management expense; the engine skips the Management category to avoid double-counting, but only for the computed-fee case. -
NOI won’t tie to your hand calc — NOI is
EGR − Total Operating Expenses, and Total Operating Expenses excludes below-line reserves. If your hand calc subtracted reserves before NOI, that is the gap; reserves come out below NOI, between NOI and Net Cash Flow. -
Levered cash flow / IRR is blank — equity invested may be below 0.1% of acquisition cost (≥100% leverage), or the IRR did not converge / exceeded 200%. The warnings panel names which. Check leverage, price, and exit assumptions.
-
Exit value doesn’t match your cap × NOI — the exit capitalizes the forward-12 terminal NOI (the reversion year), not the last hold-year NOI. The header’s Forward NOI @ Exit is the number being capitalized; Implied Exit Cap = terminal NOI ÷ gross value will equal your assumption for a cap-rate exit and diverge for a specified-amount or per-unit exit.
-
A number is off and you can’t tell why — click the cell. Every value is traceable to its inputs; see Trace any number.
Related
Section titled “Related”- Pro forma & analysis — the tabs, toggles, and vs-Broker workflow this chapter derives.
- Report catalog — the exports, including the XIRR Working report that reproduces the IRR math.
- Trace any number — click any cell for its formula and source proof.
- Recoveries, end to end — the reimbursement line, in full.
- Debt & financing, in depth — the debt ledger behind the debt-service split.