| ★ ▲ | Address ▲ | Zone ▲ | Lot ▲ | Price ▲ | Lot Size ▲ | Lot W ▲ | Exit $/SF ▲ | Sell Value ▲ | Land Cost ▲ | Profit ▲ | ROC ▲ | Slope ▲ | Days Listed ▲ | New ▲ | Link |
|---|
The sliders below are the SFR pro forma. Every parcel reprices live as you drag — pins re-color, the deal card refreshes, Market Data aggregates re-tally. Move the ROC chip to widen or narrow the visible pool.
Default filter posture on load: Status = Active · ROC ≥ 20% · Lot ≥ 5K SF · Lot W ≥ 40 ft · Lot D ≥ 100 ft · Acquisition ≤ $2M · Exit ≥ $1,200/SF · Land basis ≤ $500/SF · Slope ≤ 20%. Click Reset all in the header chip bar to return to this posture.
PIN COLORS (Return on Cost)
DEAL STATUS DOTS
OTHER MARKERS
Switch to the Assumptions tab above to tune the SFR pro forma — every parcel reprices live as you drag. The map opens on viable deals only (ROC ≥ 0% at asking price); use the ROC filter to widen.
We identify single-family-zoned LA County parcels — teardown or vacant — where the spread between land cost and a new-construction $/SF exit is large enough to pencil. We acquire, build one modern modular SFR per lot, and sell it. Baseline economics: $500/SF all-in ($425 hard + $75 soft, configurable) against a $1,000/SF+ target exit. Build-to-sell only. One home per lot for v1.
This app covers LA County only (City + all incorporated cities). All listings, comps, and zoning data are LA-specific. Vacant Land + Single Family Residential are both admitted to the acquisition layer; vacant lots are the preferred build-to-sell target and run the pro forma off defaultHomeSf with demoCost = 0.
VHFHSZ: Very High Fire Hazard Severity Zone is an informational flag only in the SFR app, NOT a knockout. The Jan-2025 Palisades burn footprint is a priority target — post-fire vacant lots are surfaced via the burn-zone overlay (toggle in the filter bar) and the 🔥 badge on deal cards. Insurance + WUI code surcharge belong in the per-deal pro forma, not the eligibility gate.
Listing status: Captured at scrape time and refreshed on every rebuild. Redfin's STATUS field maps to a user-facing label: Active → “Active” (no pill), Contingent → “In Contract” (amber pill), Pre On-Market → “Coming Soon” (gray pill). Filter via the Listing Status segmented control under Filters; pill renders on the deal card header for non-Active deals.
Zoning coverage: 4-endpoint cascade (City of LA / Santa Monica / Malibu / LA County DRP) confirms zone for ~80% of slice parcels. Parcels in uncovered cities (Beverly Hills, WeHo, Culver City, Inglewood, Pasadena, Glendale, Burbank, Long Beach) fall back to the Redfin property-type mapping with a zoningUnconfirmed flag on the card.
Every parcel runs through the SFR pro forma (see src/models/proforma.js):
The acquisition decision always turns on “max land price.” The model exposes both forms:
maxLand = netSales − buildCost − financingCost − (netSales × targetGrossReturnPct)maxLand = ((sellValue − sellingCosts) − allInBuildPsf×homeSf×(1 + roc×holdMonths÷12)) / (1 + roc×holdMonths÷12)Deal signal = maxLand vs. asking. The gap is the opportunity.
Land $X + Build $Y ($/SF × homeSf) + Demo $Z + Financing $F = $T all-in → Sell $S − Txn cost $C → $P profit. Demo is broken out of Build so the equation foots to Total cost. Financing now includes the loan origination fee (P1-6 fix: computeCostStack rolls loanAmount × loanFeePct into financingCost so totalCost foots).homeSf ≤ FAR × lotSf; amber “⚠ Home SF exceeds max buildable” otherwise. FAR resolves through a small helper (resolveFar) so the future per-jurisdiction far_rules.json source can be swapped in. For now the value is the constant FAR_DEFAULT = 0.50 labeled “assumed · <city> = verify”. The strip omits cleanly when lotSf is missing..dcp3-tv line-height (smaller-font values use .dcp3-tv-sm, same line-height). Land $/SF = asking ÷ lot SF (broker frame). Missing data renders as “—”. Home SF is a plain static tile by default; only in edit mode does it flip to the reddish editable input (bounds 400–12,000).SENSITIVITY_DELTA_PSF ($100) below the base exit $/SF. Each row re-runs calculateProForma (P1-5 fix: resolved as window.calculateProForma || window.Models?.ProForma?.calculateProForma so the lookup never fails on load order). Viable badge green when ROC ≥ 0.resolveExportInputs if needed — only the card render is stripped.)_editInput('homeSf', ...) which routes to _onEditInput, writes _editMode.values.homeSf, and persists to _overrideHomeSf on Done. Drives both build cost (hard+soft $/SF × homeSf) AND sale (homeSf × exitPsf); re-renders tiles, math line, FAR cap pill, all sensitivity rows, and the expanded ledger from the single-source pro forma.sfr_overrides_<AIN>). An “Edited” badge appears on cards with saved overrides. Internally they write _overrideHardPsf / _overrideSoftPsf / _overrideHomeSf — the same keys resolveDealInputs consumes, so card edits actually apply.Page-load defaults: ROC ≥ 0%, Lot Width ≥ 50 ft, Lot Depth — any, Exit $/SF ≥ $1200, Slope ≤ 20%, Asking ≤ $2M, Land Basis ≤ $500/SF, Zoning = R1 + LAND + R2/R3 vacant.
l.ld.fetch_slopes.py; drag the slider to widen. Lots with slope ≥15% show a cost-uplift warning.l.isVacantLand. Persists across page reloads. Vacant lots carry $0 demo cost; teardowns add demo cost from the Assumptions slider.l.status from Redfin (Active, Contingent → “In Contract”, Pre On-Market → “Coming Soon”). Captured at scrape time; refreshed on every rebuild. Persists across page reloads.newSinceLast=true by the snapshot diff (i.e. absent from the prior pipeline run). Persists per browser. See New & Changed Listings for the underlying detection.l.burnZone = "Palisades". Displayed as 🔥 BURN-ZONE TARGET. Surfaced, never suppressed.l.coastal = true for parcels inside the CA Coastal Commission boundary. Displayed as 🌊 Coastal Zone — CDP required on the deal card. Informational only — never excludes. The Coastal Development Permit (CDP) adds 3–6+ months to entitlement. Toggle the coastal zone overlay in the filter panel to visualize the CCC boundary on the map._editMode.values.homeSf live, drives the FAR cap pill + pro forma, and persists to _overrideHomeSf on Done. Overrides the global Home Size slider for that one deal.Rescaled to the realized SFR exit-$/SF distribution observed in the SM+Palisades slice (~$840 P5 → $3,540 P95). The band discriminates inside the $1.5K–$2.5K/SF meat of the market.
Listing data is a dated snapshot from the most recent pipeline run. Individual listings may have gone under contract, been withdrawn, or had price changes since the snapshot was taken. Always verify a listing is still active on Redfin before acting. Use the Redfin ↗ link in the card footer to confirm live status.
A footnote at the bottom of each deal card shows “Listing data as of [date]”. The text turns amber when the snapshot is more than 3 days old.
Every pipeline run compares today’s Redfin pull against a committed rolling snapshot (data/listings_snapshot.json, keyed by Redfin URL) and stamps three fields on each listing:
firstSeen — ISO date the listing was first observed by the pipeline. Carries forward on every run.newSinceLast — true when the listing key was absent from the previous snapshot. Surfaces in the card header as a green “New” badge and is filterable via the New since last refresh toggle in Filters.statusChanged — {from, to} when Redfin status moved between runs (e.g. Active → Contingent). Surfaces as an amber “→ In Contract” micro-tag in the badges row.priceChanged — signed integer dollar delta vs. the prior snapshot. Negative values surface as a green “Price ↓ $X” micro-tag; positive as a red “Price ↑ $X”.listings.js naturally and are written to data/new_gone_<YYYY-MM-DD>.json for the (future) Build B2 email pass.First-run guard: on the very first pipeline run after this feature ships there is no prior snapshot — the run establishes the baseline and newSinceLast=false for every listing. Real diffs start on run 2. Legacy listings missing these fields render as if all three were unset (no badges, no filter hits).
Colored dots in the header bar show when each dataset was last refreshed:
Datasets tracked: Listings, Comps, Parcels.
Invite-only access. Contact matt@lucidresi.com.
Exit $/SF is the estimated sale price per square foot for a completed new-construction single-family home on this parcel. The comp universe is restricted to detached single-family residences only (no condos, no townhomes, no multi-family) and to sales within the last 24 months. Comps are classified into three condition tiers, and the exit price prefers the truest comp pool (T1-New) and falls back gracefully when that pool is thin.
prefer T1-New regression → T1-Reno regression → T1-New median → T1-Reno median → T2 regression × (1 + uplift) → T2 median × (1 + uplift)
uplift = 18% (condition adjustment for older / unrenovated comps)
No floor. No ceiling. The model output is the number. Each cluster reports its exitSrc (which tier the price came from) so confidence can be judged at a glance.
Comps are spatially clustered (0.005° ≈ 0.35 mi grid cells) and bucketed into one of three tiers:
A cluster needs at least 3 comps in a tier to fit a weighted size-regression. Below that, the tier median is used. T1-Reno requires no premium — recently renovated SFR finishes are comparable to new construction in $/SF terms; the gap shows up only in T2.
The Sale $/SF grid layer and comp popup colors use a 14-bucket cold-to-hot gradient:
Within each cluster and each tier (with ≥3 comps), the pipeline fits a recency-weighted linear regression of price = intercept + slope × sqft across comp sale price and square footage, then predicts the price at the 3,500 SF target home size. Output is converted back to $/SF for display. Comps outside 1,200–6,000 SF are excluded from the curve fit; comps with extreme slopes (<$200 or >$1,500/SF) are rejected as bad fits.
The 3,500 SF anchor matches our default new-build SFR home size. Larger or smaller targets are interpolated from the same curve via the KEY-panel home-size override.
The model requires at least 5 comps. If fewer qualify, the search radius expands (up to 3.0 miles) and lower product tiers are added until 5 are found. Confidence is scored 0–100 based on comp count and method quality:
The pipeline rejects regression slopes outside [$200, $1,500]/SF as bad curve fits, and excludes comps whose $/SF falls outside this same band. Comps outside 1,200–6,000 SF are excluded from the size-curve fit. Trimming is performed at the curve-fit stage, not as a post-hoc IQR pass.
When a cluster lacks enough T1-New or T1-Reno prints to anchor an exit, the model falls back to the T2 (older / unrenovated) pool with a +18% condition uplift. This adjusts for the empirical gap between an existing-condition resale and what a new SFR build in the same submarket trades for.
The uplift is applied only when exitSrc is existing+uplift or existing-median+uplift. T1-Reno prints (recently renovated) are treated as comparable to new construction in finish level and require no premium.
Each cluster exposes the path the exit number was derived from, so confidence can be judged at a glance:
new — Strongest: ≥3 T1-New comps in the cluster supported a size-regression fitreno — Strong: ≥3 T1-Reno comps anchored the regression (recent renovation ≈ new finish)new-median / reno-median — Moderate: ≥3 T1 prints exist but the regression did not pass sanity checks; tier median usedexisting+uplift / existing-median+uplift — Limited: no T1 prints in the cluster; T2 baseline used with +18% condition upliftblended+uplift — Weakest: insufficient comps in any tier; blended cluster median used with half uplift. Treat exit with caution.Hiding comps filters the comp table for inspection; exit $/SF stays at the pipeline value (full re-pricing on the remaining pool is a future enhancement). Excluded comps remain visible at reduced opacity and are flagged (EXCLUDED: TRUE) in CSV exports.
Exclusions are per-deal and per-session — they reset on page reload. To override exit $/SF, use edit mode on the deal card.
Eligible parcels are single-family-zoned and buildable. In-scope zones: A, RA, RE, RS, R1, RU, RZ, RW1, and LAND (vacant residential).
R2 / R3 vacant land is also admitted when isVacantLand === true — these are buildable single-SFR lots within a multi-family zone. Improved or teardown R2/R3 (existing multi-family buildings) remains excluded due to RSO / tenant risk. In the current dataset this adds ~73 R2 and ~52 R3 vacant lots to the eligible pool.
Two automatic disqualifiers — no override:
LA County build-to-sell single-family
Your account is signed in, but it doesn't have access to this app.
Access to SFR Acquisition is by invitation only. Contact your admin at matt@lucidresi.com to request access.
Choose a password for your account