valuation-engine
v1.0.0
Published
ZIP-In Offer Valuation Engine — Cash vs Partner Sale vs Agent Listing modeling
Downloads
119
Maintainers
Readme
@lhbusa/valuation-engine
ZIP-In Offer Valuation Engine v1.0.0
A world-class, production-ready TypeScript package that calculates three-way offer comparisons for residential real estate:
- Guaranteed Cash offers
- Partner Sale (Novation) offers
- Typical Agent Listing benchmark (for comparison)
Used by Local Home Buyers USA to model seller outcomes across different exit strategies.
Installation
npm install @lhbusa/valuation-engineQuick Start
import { valuate } from '@lhbusa/valuation-engine';
const result = valuate({
zip: '55401',
propertyType: 'sf',
yearBuilt: 1995,
beds: 3,
baths: 2,
sqft: 1600,
condition: 'cosmetic',
asIsValue: 320000,
band: 'likely' // 'conservative' | 'likely' | 'stretch'
});
console.log(result.offers);
// {
// cashNet: 288000,
// partnerNet: 312000,
// agentNet: 299000,
// delta: 24000,
// deltaPct: 8.3,
// recommendation: 'partner_sale'
// }API
valuate(input: ValuationInput): ValuationOutput
Main calculation function. Returns a complete valuation analysis.
Input:
interface ValuationInput {
zip: string; // 5-digit ZIP code
propertyType: 'sf' | 'th' | 'condo' | '2to4';
yearBuilt: number;
beds: number;
baths: number;
sqft: number; // Living area
condition: 'turnkey' | 'cosmetic' | 'systems' | 'major';
asIsValue: number; // As-Is market value
band: 'conservative' | 'likely' | 'stretch';
}Output:
interface ValuationOutput {
version: string;
timestamp: string;
input: ValuationInput;
signals: ZipSignals; // Market conditions
offers: OfferComparison; // 3-way comparison
breakdown: CostBreakdown; // Detailed numbers
scoring: ScoringBreakdown; // 7 property scores
impacts: FactorImpacts; // Factor sensitivity
recommendation: {
path: string;
reasoning: string;
};
estimatedDays: number;
}estimateAsIsValue(input: AsIsEstimateInput): number
Estimate As-Is value when the user doesn't know it.
import { estimateAsIsValue } from '@lhbusa/valuation-engine';
const estimated = estimateAsIsValue({
zip: '55401',
propertyType: 'sf',
beds: 3,
baths: 2,
sqft: 1600,
condition: 'cosmetic'
});
// Returns approximately: 325000Scoring & Signals
The engine calculates 6 local indices from the ZIP code:
Local Stability Index (LESI) — Market shock resistance
- Values:
very_stable,stable,mixed,unstable,high_risk
- Values:
Buyer Demand Index (BDI) — 6-month trend + current demand
- Values:
hot,strong,balanced,soft,very_soft - Includes 6-month sparkline series
- Values:
Property Readiness (FOS) — How "sale-ready" the home is
- Values:
high,medium,low - Based on condition, age, size
- Values:
Renovation ROI (RVI) — Uplift potential
- Percentage of As-Is value
- Condition-specific with type/size/age adjustments
Renovation Cost Index (RCI) — Build/repair cost pressure
- Values:
low,medium,high - ZIP-derived
- Values:
Regulatory Friction Index (RFI) — Closing time/complexity
- Values:
low,medium,high - ZIP-derived
- Values:
Scenario Bands
Three conservative-to-aggressive scenarios:
| Band | RVI | Repairs | Carry | Cash Disc. | Partner Coverage | Use Case |
|------|-----|---------|-------|-----------|------------------|----------|
| conservative | 0.88x | 1.10x | 1.12x | +1.5% | +0.8% | Worst case |
| likely | 1.00x | 1.00x | 1.00x | 0% | 0% | Base case |
| stretch | 1.08x | 0.92x | 0.92x | -1.0% | -0.6% | Best case |
Key Formulas
Cash Net
Cash Net = As-Is × (1 - Cash Discount)Where Cash Discount includes:
- Base 10% + Property Readiness factor + Market Stability factor + Buyer Demand factor
- Condition adjustments (turnkey -0.6%, major +3.5%)
- Type adjustments (condo -0.6%, 2-4 unit +1.2%)
- Size & age continuous adjustments
Partner Net (Novation)
ARV = As-Is + RVI Gain
Profit = ARV - (Repairs + Closing Friction + Carry)
Seller Share = 50% of Profit
Partner Service Coverage = 2–5% of As-Is (ZIP-sensitive)
Partner Net = min(As-Is, Seller Share + As-Is - Coverage)Agent Listing (Benchmark Only)
Agent Net = As-Is × (1 - Agent Commission %)Where Agent Commission = ~5.5% + extras (~1.5%) = ~7–12% depending on market.
Use Cases
1. Lead Qualification
const result = valuate(leadData);
if (result.offers.recommendation === 'partner_sale') {
// This is a good novation deal
}2. Offer Presentation
// Show seller the 3 options side-by-side
console.log(`
Cash: ${result.breakdown.cashNet}
Partner: ${result.breakdown.partnerNet}
Agent List: ${result.breakdown.agentNet}
`);3. Analytics
// Track deal sourcing and outcome
analytics.log({
zip: result.input.zip,
recommendation: result.offers.recommendation,
estimatedDays: result.estimatedDays,
margin: result.breakdown.partnerNet - result.breakdown.cashNet,
});Architecture
src/
├── types.ts # All TypeScript interfaces
├── coefficients.ts # Lookup tables, maps, factors
├── indices.ts # ZIP signal derivation, scoring
├── engine.ts # Core calculation logic
└── index.ts # Main exportZero external dependencies — pure TypeScript calculation logic.
Testing
npm test
npm run test:watchBuild
npm run buildProduces:
dist/index.js(CommonJS)dist/index.mjs(ES modules)dist/index.d.ts(TypeScript definitions)
License
MIT
Support
For questions or to report issues, contact Local Home Buyers USA.
