One engine, ported from the app
The app's calculation code (its Swift "Domain" layer) works through five steps in a fixed order. The website runs a line-for-line TypeScript port of that code: same steps, same order, same formulas and the same validation messages.
- Validate every input. If anything fails, nothing is calculated.
- Size the loan against each lending limit and the financed project cost.
- Allocate the proposed loan between the rehab holdback and the acquisition advance.
- Measure the actual As-Is LTV, LTC and LTARV of the proposed loan.
- Price it: points, fee, interest, minimum interest, cash to close and gross lender revenue.
Worked examples on this page use the calculator's default deal unless noted: a $300,000 purchase, $400,000 as-is value, $100,000 rehab and $550,000 ARV, with illustrative limits of 70% As-Is LTV, 90% LTC and 70% LTARV, 100% rehab funding, 12% interest and 2 points over 12 months. These are not a standard program.
Arithmetic and rounding
The engine does no math in binary floating point. Every amount is a base-10 decimal: Foundation's Decimal in the app (38 significant digits) and big.js in the browser (division carried to 40 decimal places). Values are rounded only at these points:
| Value | Rule |
|---|---|
| Each limit's dollar cap | Kept at full precision; shown, and compared for ties, rounded down to the whole dollar |
| Maximum loan | Lowest applicable cap at full precision, then rounded down to the whole dollar |
| Rehab holdback, points, monthly and scheduled interest, funded-balance total, minimum interest, cash to close | Rounded to the cent, half away from zero ($0.005 becomes $0.01), once, at the end of each formula |
| Funded-balance interest for each period | Not rounded. Shown to the cent for reading only; the total is calculated separately |
| Actual leverage ratios | Not rounded; shown as a percentage to two decimals (half up), trailing zeros dropped |
| Rates, points and limits you enter | Shown exactly as entered: 12.375% stays 12.375% |
Sums and differences of amounts that are already whole cents (acquisition advance, borrower equity, net proceeds, gross revenue) need no further rounding.
Loan sizing caps
- Total project cost is purchase price plus rehab budget. Closing costs, lender fees, interest and reserves are not added. Some lenders include them in loan-to-cost; this engine does not.
- Every limit applies to the total loan, including the rehab holdback. Some lenders apply an as-is limit only to the initial advance. The engine doesn't model that convention; the LTV vs LTC vs LTARV guide shows the difference.
- The financed cap always applies. The loan can never exceed the purchase price plus the share of the rehab the lender funds, however high the ratio limits are. This is the financed project cost; at 100% rehab funding it equals total project cost.
Binding constraint and ties
The binding constraint is every policy limit (As-Is LTV, LTC or LTARV) whose whole-dollar cap equals the maximum loan. Ties are judged at whole-dollar precision, the same precision the caps are shown in, so the display and the "binding" label always agree, and every tied limit is reported. If no policy limit equals the maximum, the financed project cost is what limits the loan.
| Limits equal to the maximum | Result headline |
|---|---|
| None (the financed cap is lowest) | Limited by financed project cost |
| One | Binding Constraint: LTC |
| Two or more | Binding Constraints: As-Is LTV + LTARV |
Example: change the default deal's as-is value to $400,000.57 and its ARV to $400,001. The two caps are less than a dollar apart, but both round down to the same whole dollar, so both bind.
| Limit | Exact cap | Whole-dollar cap |
|---|---|---|
| As-Is LTV: 70% × $400,000.57 | $280,000.399 | $280,000 |
| LTARV: 70% × $400,001 | $280,000.70 | $280,000 |
| LTC: 90% × $400,000 | $360,000 | $360,000 |
Maximum loan: $280,000. Headline: "Binding Constraints: As-Is LTV + LTARV".
Requested loan
A requested loan is optional. On the default deal, a $300,000 request is cut back to $280,000, and the result shows the $20,000 excess. Everything after this step (holdback, ratios and pricing) uses the proposed loan.
Holdback, advance and equity
The rehab holdback is the funded rehab, held back at closing for draws. The acquisition advance is the rest of the loan, funded toward the purchase and capped at the purchase price. Unallocated is a safeguard: any part of the loan that fits neither the purchase nor the holdback is reported there rather than added to the advance. Borrower purchase equity covers the purchase only, before points, fees or a reserve.
Default deal: $100,000 holdback, $180,000 advance and $120,000 borrower equity.
Leverage ratios
Ratios use the total proposed loan, so they show where the deal sits against each limit. On the default deal, the actual LTARV is $280,000 ÷ $550,000 = 50.9090…%, shown as 50.91%.
Points and lender fee
Points are charged on the gross loan, including the rehab holdback: 2% of $280,000 is $5,600.00. A blank lender fee or points field counts as zero.
Full-balance interest
Scheduled interest is calculated at full precision, not as the rounded monthly figure times the term. The two can differ by a few cents:
| Exact monthly interest | $1,421.875 |
|---|---|
| Monthly interest, rounded to the cent | $1,421.88 |
| Rounded monthly × 12 (not used) | $17,062.56 |
| Scheduled interest, full precision | $17,062.50 |
Scheduled interest is an estimate for the full stated term. Actual interest depends on the payoff date and the loan documents. On the default deal it is $33,600.00, or $2,800.00 a month.
Funded-balance interest
Interest accrues on the acquisition advance from the closing date and on each draw from its draw date, until maturity. This is often called non-Dutch interest. The day count is Actual/365 or Actual/360.
- Periods. Draws are sorted by date, and draws on the same date are combined. Each draw date ends one period and starts the next at a higher balance. A draw on the closing date adds to the opening balance, and a draw on the maturity date accrues no interest.
- Completeness. A total, and therefore gross lender revenue, is produced only when the scheduled draws add up exactly to the rehab holdback. Otherwise the engine shows the undrawn amount and no total, rather than guessing when the rest will be drawn.
- Draw checks. A closing date is required. Each draw must be more than $0 with no more than two decimal places, dated no earlier than closing and no later than maturity, and all draws together can't exceed the holdback.
| Closing date | Term | Maturity |
|---|---|---|
| Jan 31, 2026 | 1 month | Feb 28, 2026 |
| Aug 31, 2026 | 6 months | Feb 28, 2027 |
| Aug 31, 2027 | 6 months | Feb 29, 2028 |
Worked example, an illustrative fix-and-flip deal: a $229,500 loan with a $70,000 holdback and a $159,500 acquisition advance, at 11% Actual/360, closing Nov 2, 2026 with a 9-month term (maturity Aug 2, 2027) and 3 draws.
| Period | Days | Outstanding | Interest |
|---|---|---|---|
| Nov 2, 2026 to Dec 15, 2026 | 43 | $159,500 | $2,095.65 |
| Dec 15, 2026 to Feb 1, 2027 | 48 | $184,500 | $2,706.00 |
| Feb 1, 2027 to Mar 15, 2027 | 42 | $209,500 | $2,688.58 |
| Mar 15, 2027 to Aug 2, 2027 | 140 | $229,500 | $9,817.50 |
| Total interest | $17,307.74 | ||
Σ(principal × days) is 56,643,500 dollar-days; × 11% ÷ 360 = $17,307.74. Adding the rounded period amounts gives $17,307.73; the total differs because it is rounded once, at the end. The same schedule under Actual/365 comes to $17,070.64.
Minimum interest
Minimum interest is shown on its own line. It is never added to scheduled interest, cash to close or gross lender revenue, and it is not a payoff calculation: it doesn't subtract interest already paid. Three months on the default deal is $8,400.00.
Reserve, net proceeds and cash to close
- The interest reserve is a dollar amount you enter; the engine doesn't size it. It is withheld from the loan proceeds at closing, so it lowers net proceeds and raises cash to close dollar for dollar. It is not added to interest and not counted as lender revenue.
- If points, the fee and the reserve add up to more than the advance, net proceeds are shown as $0 and the shortfall stays in cash to close, so borrower cash is never understated.
Default deal: $300,000 − ($180,000 − $5,600.00 − $0 − $0) = $125,600.00 cash to close.
Gross lender revenue
Gross lender revenue leaves out the interest reserve (counting it would double-count interest) and minimum interest. It is gross, not profit: cost of funds, servicing, defaults, taxes and overhead are not deducted. Default deal: $5,600.00 + $0 + $33,600.00 = $39,200.00.
Validation limits
The engine checks every input before it calculates. If any check fails, it lists the problems and calculates nothing; it never substitutes a value silently.
| Input | Accepted | If blank |
|---|---|---|
| Purchase price | More than $0 | Required |
| As-is value | $0 or more; more than $0 when As-Is LTV is on | Allowed only with As-Is LTV off |
| Rehab budget | $0 or more | $0 |
| ARV | $0 or more; more than $0 when LTARV is on | Allowed only with LTARV off |
| Requested loan | More than $0 | Sizes the maximum loan |
| Term | Whole months, 1 to 360 | Required |
| Lending limits | At least one turned on; each one that is on more than 0% and no more than 100% | Required when on |
| Rehab funding | 0% to 100% | Required (starts at 100%) |
| Interest rate | 0% to 100% | Required |
| Points | 0 to 100 | 0 |
| Lender fee, interest reserve | $0 or more | $0 |
| Minimum interest | Whole months, at least 1 and no more than the term | None |
| Closing date and draws | Required for funded-balance interest; draw rules above | Not used for full-balance interest |
Every currency input must be under $1 trillion with no more than two decimal places; fractional cents are rejected, not rounded. Number fields accept "$", "%", spaces and correctly placed thousands separators, up to 15 digits before the decimal point.
How parity with the app is tested
Two layers of tests check that the website calculates exactly what the app calculates.
Unit tests. The app's Swift test suites for its calculation code were ported to Vitest. 93 tests pass. Nine are skipped because they cover things the website doesn't have: four app-only suites (saved-deal form state, quote PDF content, review prompts, and saved-data persistence and purchases) and five single tests (German-locale number entry, non-Gregorian device calendars, deal name and address trimming, and two saved-program checks).
Differential test. A harness compiles the app's unchanged Swift calculation code, then runs the same generated scenarios through it and through the website's engine and compares every field. The scenarios come from a fixed seed, so every run tests the same set. They deliberately include invalid and awkward inputs: blank, zero, negative and over-limit values, fractional cents, limits such as 72.3456789%, leap-day and month-end closing dates, draws on the closing or maturity date, draws outside the term, same-day draws, and draw schedules that fall short of or exceed the holdback.
| Scenarios generated | 25,000 |
|---|---|
| Calculated | 13,055 |
| Rejected by validation (messages compared word for word) | 11,945 |
| With funded-balance interest | 3,745 |
| Fields compared | 903,332 |
| Mismatches | 0 |
All money amounts, dates, day counts, labels and US display strings must match exactly. Full-precision quotients (leverage ratios and per-period interest) are compared to 24 decimal places, because the app's decimals keep 38 significant digits and the web engine's divisions keep 40 decimal places. Both are display-only values, and 24 places is far deeper than any digit that reaches a displayed figure.
Intentional differences
- US English and US dollars only. The website formats every amount for the United States. The app formats numbers, dates and currency for your iPhone's region. The calculations are identical.
- Nothing is saved on the website. Saved lending programs, saved deals, deal names and addresses, and preliminary quote PDFs are app features.
- Web-only helpers. These fill in inputs or display figures derived from the engine's results. None of them changes a calculation.
- Shareable links. Copy link puts the inputs in the page address so the form refills when the link is opened (see the Privacy Policy).
- Loan-amount entry. The interest, Dutch interest and points calculators start from a loan rather than a whole deal. They give the engine the amount funded at closing as the purchase price and the holdback as the rehab budget, with 100% rehab funding and a single 100% LTC limit, so the engine sizes the loan to exactly the amount entered. These amounts are entered in whole dollars.
- Split holdback into monthly draws. Fills the draw schedule with equal draws (3 on the deal calculators; 3 or 6 on the interest and Dutch interest calculators): the holdback ÷ the number of draws, rounded down to the cent, with any leftover cents on the last draw, dated one month apart starting one month after closing. The draws then go through the same checks and interest math as draws you type.
- Day-count Dutch comparison on the Dutch interest calculator: the funded-balance math run again with the whole holdback drawn on the closing date, which gives full-balance interest on your day count, and the difference from your draw schedule. The app reports full-balance interest monthly (loan × rate × months ÷ 12, no day count); the calculator shows that figure too.
- Per-diem display on the interest calculator.
- Two-quote points comparison on the points calculator.