Every number on every WindMayor surface comes from a public, free, cited
source — or it's labeled [ILLUSTRATIVE]. This page is the
paper trail. If you can't reproduce a value from the source we cite,
that's a bug. Tell us.
NULL — we don't smooth, we don't extrapolate, we don't
estimate. Partial real beats fake complete.
DSCR (Debt Service Coverage Ratio) is the single most important number on the site. It answers: does the rent on this property self-fund a typical loan against it? A DSCR ≥ 1.20 is the conventional minimum that lenders underwrite to. The same exact formula is used across military bases, colleges, and cities.
0.0165 constant (1.10% tax + 0.55% blended ins/maint) applied
to every property in every state. That hid the largest geographic lever in
the whole model. v3 deletes the flat constant. Property tax
is now the real per-state effective rate; insurance is the real per-state
landlord rate; the maintenance reserve is broken out and explicitly labeled
an assumption. The pre-v3 value is kept on every record as dscr_v2
so any reviewer can diff the two.
0.0050 maintenance reserve — is now replaced by a
per-ZIP variable maintenance model. The DSCR formula has no
nationwide constants left in its operating cost: tax is per-state, insurance
is per-state, maintenance is per-ZIP. v4 also adds a matched-type DSCR
(dscr_sfr / dscr_condo), a climate-yield
insurance-drag estimate, a forward rent forecast and a corrected FEMA hazard
scale — all documented in the sections below.
Property tax varies far more across states than insurance does, so replacing
the flat 1.10% is what actually moves DSCR. The effective rate runs from
0.28% in Alabama and Hawaii to 1.85% in New
Jersey — a 6.6× spread (Tax Foundation, "Property Taxes by State
and County," property taxes paid as a % of owner-occupied housing value).
Texas (1.49%) is a clear example: moving from the flat 1.10% to the real
Texas rate cuts a typical Texas DSCR by roughly 0.17. Insurance
uses the NAIC 2022 Homeowners Insurance Report (released 2025), Table 4 —
the HO-3 state-average premium divided by the exposure-weighted amount of
insurance, then a labeled ×1.20 uplift to a DP-3
dwelling-fire / landlord proxy, because these are rentals, not owner-occupied
policies. The ×1.20 is an explicit assumption: NAIC does not
publish a clean DP-3 average. The national HO-3 average is
0.40% of insured value, but the state spread is real —
the DP-3 rate runs from 0.26% in Utah and Oregon to
0.98% in Louisiana and 0.92% in Oklahoma.
Every record carries prop_tax_pct_used and
insurance_pct_used so the inputs are auditable per row.
v3 carried a flat 0.50% maintenance reserve on every
property in the country. That is plainly wrong — it costs more to
maintain a 90-year-old house in a high-cost-of-construction metro than a new
build in a cheap one. v4 replaces the constant with a per-ZIP estimate
written to zipdata/data/maintenance_by_zip.csv for all
31,646 ZIPs:
Across all ZIPs the model produces a median maintenance reserve of
0.97% — close to the 1% rule-of-thumb base, with a real
spread from the 0.6% floor to the 1.8% cap.
The BLS construction-cost index is populated for 31,468 of 31,646 ZIPs; where
it is missing the multiplier defaults to 1.00 and the row says so in its
source string.
maintenance_pct row carries a
source string that begins MODEL so no reviewer
mistakes it for observed data.
Zillow ZHVI is now pulled by property type — single-family
(SFR), condo, 2-bedroom, 3-bedroom — not just the all-homes blend.
DSCR can then be priced off the unit an investor would realistically buy in
that ZIP rather than a market-wide average. Colleges carry
dscr_condo (the UI primary), dscr_sfr, and
dscr_2br side by side; each row records the
property_basis it used and falls back down a ladder
(type → sfrcondo blend → all-homes) when a type series is missing.
A DSCR computed from condo rent over single-family value (or vice versa) is
apples-to-oranges. v4 ships a strictly matched-type DSCR in
zipdata/data/dscr_by_type.csv: dscr_sfr uses
single-family rent ÷ single-family value, and dscr_condo
uses condo rent ÷ condo value — never a cross.
dscr_condo takes
the ZIP's blended ZORI and scales it by the metro's multifamily-to-blend rent
ratio. The value leg is true ZIP-level condo ZHVI; the rent leg is a
metro-anchored estimate. Each row's method field states this.
The matched-type comparison settles a question the all-homes blend hid:
across the 2,044 ZIPs with a single-family DSCR and the
1,029 with a condo DSCR, the median
dscr_sfr is 0.74 against a median
dscr_condo of 0.65. Houses pencil better than
condos — condo values have run ahead of condo rents, and an HOA-free
house carries a leaner cost stack. Neither type clears 1.20 at today's rate;
this is a relative ranking, not a green light.
This DSCR is a screen, not an underwrite. It tells you which markets are worth your attention. The actual deal needs property-specific inputs.
| Surface | Field | Source | Status |
|---|---|---|---|
| Military | BAH series (per MHA) | DoD Defense Travel Management Office BAH tables 2013–2026 | live |
| Installation list | Wikipedia + GlobalSecurity.org; 454 records | live | |
| troop_count, years_active, acres | Wikipedia infobox + DoD BSR (partial coverage) | 38% / 26% / 13% | |
| Feeder-city ZIP economics | Zillow ZHVI/ZORI by ZIP, FRED 30yr | live | |
| greater_area_pop, maint_cost_idx | Census ACS B01003 + BLS OEWS / CPI-U (pending) | pending | |
| bah_yield_{1y,5y,13y} | Derived from BAH series — CAGR over window | pending | |
| Colleges | Institution list, enrollment, tuition, admit, grad rate | IPEDS HD/EF/IC/ADM/GR 2023, NCES public domain; 6,086 records | live |
| ZIP economics & DSCR (fill v2 + quality tiers) | Tiered: Zillow ZIP primary → zip_master + HUD FMR rent → Zillow city → ACS. Each row stamps its dscr_source tier |
5,860 / 6,086 (96%) — +113 rows recovered in v5 via all-homes price ladder | |
| housing_capacity, % housed on campus | IPEDS IC2023 ROOM + ROOMCAP fields | 5,947 / 6,086 (98%) | |
| pct_off_campus | Derived: 100 − housing_pct_of_enroll | 98% | |
| endowment_per_student | Derived: endowment / enrollment | 2,732 / 6,086 (45%) | |
| Display outlier clamp | Winsorized; raw values preserved in *_raw fields |
display only | |
| Seattle | ZIP economics | Zillow ZHVI/ZORI + FRED 30yr | 66 / 69 ZIPs (96%) |
| Recapture / Pre-qual tools | Live FRED rate at page load; no fixtures | live | |
| Statewide expansion | All WA ZIPs (~400) — pending Y-SEATTLE.wa-expand | pending | |
| Rate | Historical series (annual) | FRED DGS10 (1962–2026), FRED MORTGAGE30US (1971–2026) | live |
| "Now" values | FRED latest single observation (daily/weekly), date-stamped | live | |
| Short-horizon model (weekly OLS) | Walk-forward; DGS10 momentum + spread deviation. 1mo: real edge. 3mo: no edge | 1mo only — see Rate model | |
| 5-year forward cone | Mean-reversion central path; bands = empirical percentiles of historical rate moves | range, not a forecast | |
| Cities | Institution list (250 US cities), demographics | Census place FIPS; ACS population, median income/age | live |
| ZIP / city economics & DSCR (condo basis) | Zillow ZHVI City condo-tier + ZORI City; FRED 30yr | 246 / 250 (98%) | |
Dual basis — dscr + dscr_condo |
Parallel all-homes & condo-tier ZHVI; flagged via hv_source |
live | |
| ZCTA heatmap | Nationwide ZIP spine — 31,646 ZCTAs | zipdata/data/zip_master.json; Census ACS 2023 + Zillow ZHVI/ZORI + HUD SAFMR |
31,646 ZCTAs (2,155 low-pop dropped) |
| FEMA risk + 18 hazard layers | FEMA National Risk Index, county hazard scores | composite 98.6%; some hazards thin | |
| price_per_sqft, tornado_count_30yr | Realtor.com ZIP market trends; NOAA SPC tornado DB 1950–2023 | $/sqft 90.5%; tornado 99.1% | |
| OSM amenity layer | OpenStreetMap / Overpass — amenity proximity by ZIP | 7,359 ZIPs | |
| Research | BAH regression v1 / v2 | bah-research/ — OLS, DoD BAH + Zillow + ACS/IRS |
research — R²test negative |
| City rent regression | city-rent-research/ — OLS, ZORI CAGR target |
research — R²test +0.28 | |
| AVM v1 (hedonic OLS) | avm/ — OSM footprints + ZHVI label, Seattle MVP |
research preview — degenerate v1 | |
| AI / Chip | Public companies, returns, HQ city | Yahoo Finance chart API; public corporate filings | 53 companies |
| Private AI HQ list | Public record only (city, no valuations, no individuals) | pending |
When you see a blank or — in the UI, that field has no real
source value for that record. We do not estimate, smooth, interpolate, or
fill from a neighbor. Examples:
troop_count = NULLdscr = NULL (a future ticket adds city / county fallback)NULL for display; raw value kept in *_raw field
Listings on TaxFight currently
show illustrative example deals — clearly tagged [Illustrative]
— because the marketplace is pre-launch. Once live inventory ships,
the tag goes away on real listings. Estimates inside an illustrative listing
(rent estimate, DSCR estimate) are bracketed (est) for the same reason.
Every DSCR calculation across all surfaces uses the same FRED MORTGAGE30US rate — pulled live where possible, otherwise the latest observation from the cached rate series. The +0.70% spread above the Treasury is documented OfferMarket pricing for DSCR investor loans, used because investor loans price higher than owner-occupied. The single rate spine means no surface can quietly drift from another.
v3 splits the rate question into two honest pieces — a short-horizon model that we tested and only ship where it has real walk-forward skill, and a 5-year forward cone that is explicitly a range of outcomes, not a forecast. We do not pretend to predict multi-year rates.
The model is OLS at weekly frequency — the cadence of the Freddie Mac PMMS survey. The textbook Treasury-leg + spread-leg decomposition was tested and discarded: forecasting the 10-year Treasury added noise. The signal that actually exists is the weekly lag-catch-up of the PMMS survey rate to Treasury moves that have already happened. Three features: 10-year Treasury 1-week momentum, 10-year 4-week momentum, and the mortgage–Treasury spread's deviation from its 52-week mean. Walk-forward — at each week the model is fit only on pairs whose outcome was observed strictly before that week, no lookahead.
| Horizon | Model MAE | Naive MAE | Model hit-rate | Beats naive? |
|---|---|---|---|---|
| 1 month (4wk), n=2,480 | 0.189 | 0.201 | 63.5% | yes — +6.3% MAE skill |
| 3 month (13wk), n=2,471 | 0.432 | 0.428 | 57.2% | no — −1.0% MAE skill |
The forward cone draws a central path and a fan of bands out to 2031. It is built from 2,878 weekly MORTGAGE30US observations (1971–2026). Read it as a range of plausible outcomes — multi-year rates are not forecastable and the cone does not claim to be a forecast.
That empirical dispersion is wide and worth seeing plainly. The 10th-to-90th percentile spread of historical rate moves is 0.57 pts at 1 month, 2.47 pts at 1 year, and 6.16 pts at 5 years. The 5-year band runs from roughly 3.0% (p10) to 9.2% (p90) by 2031, around a central path near 5.3%. Anyone underwriting a 5-year hold should size against the band, not the central line.
Some IPEDS / Zillow records produce wild values — a college reporting a 29,000% enrollment YoY (probably a coding error), a ZIP with $5M ZHVI and $4k rent (real but breaks the screen). We clamp these for display only:
enrollment_yoy_pct outside [−50, +50]% → NULL in UIhome_value > $3M or rent > $8k/mo → NULL; flag hv_quality / rent_quality = extremeprice_to_rent > 60 or < 5 → NULL; flag p2r_quality = extreme / thin_sample*_raw so nothing is lost
College and city DSCR is computed on Zillow's condo-tier ZHVI
(City_zhvi_uc_condo_tier_…) rather than the all-homes blend. The
reason: the investable unit near a campus or in a dense city core is usually
a condo or small multifamily — not the detached single-family house
that dominates the all-homes index. Pricing DSCR off a $600k median house
when the actual buy is a $300k condo would understate yield and overstate
the loan. Switching the basis flipped the DSCR sign for 1,133
colleges and shifts every city with a condo series.
$76,488 but the condo-tier
ZHVI is $214,676 — nearly 3× higher, and a thin,
downtown-skewed condo sample drives it. Underwriting Detroit off the condo
basis quietly assumes a luxury-loft cost structure for a market whose
detached stock costs a quarter as much. Every record carries an explicit
hv_source field naming exactly which series fed the DSCR
("Zillow ZHVI City condo tier" vs the sfrcondo blend) so a
reviewer can see the basis and discount it where the two diverge.
Several WindMayor surfaces have a research arm — out-of-sample regressions that test whether the patterns we screen on actually predict. We publish these including the failures. A negative R² is reported as a negative R². The point of this page is that a reviewer can trust it; that only works if the losses are as visible as the wins.
We asked: can local economics predict how fast a base's Basic Allowance for
Housing grows? OLS on n=177 military housing areas, target
bah_5y_cagr, 80/20 train/test split.
| Model | Features | R² train | R² test | MAPE test |
|---|---|---|---|---|
| v1 | 7 (Zillow + geo + troops) | 0.240 | −0.272 | 43.6% |
| v2 | 15 (+ ACS income/education/age, HUD FMR, IRS migration) | 0.288 | −0.510 | 46.9% |
The only two features that carried a real signal were
zhvi_5y_cagr (β ≈ +0.009, p < 1e−5)
and zillow_zori_5y_cagr (β ≈ +0.005,
p ≈ 0.005). Plainly: BAH growth tracks local home-value
and rent growth, and nothing else added signal. Troop count, years
active, latitude, distance to coast, education, median age, unemployment,
IRS net migration — every one was statistically indistinguishable from
zero. Worse, adding those eight features in v2 made the test R²
more negative (−0.27 → −0.51): the extra
parameters overfit the 142-row training set. A negative test R² means
the model predicts held-out BAH worse than the training mean. We do
not ship this as a forecast. The honest takeaway is the null result itself:
if you want to anticipate BAH, watch Zillow for that ZIP — the DoD
schedule is already doing roughly that.
Same method, applied to 250-city rent. OLS, n=244, target
zori_5y_cagr. R² train 0.482, R² test
+0.276, MAPE test 16.8%. A genuinely positive out-of-sample
R² — the model does carry real signal — but it is again
dominated by zhvi_5y_cagr (β +0.0071, p ≈ 4e−15):
home-value growth predicts rent growth.
irs_net_migration_2022 entered with a negative
coefficient (β = −0.0030, p = 0.0002):
in this window, cities gaining the most IRS-filed in-migrants had
lower 5-year rent CAGR, not higher. This is almost certainly a
COVID base effect — Sun Belt destinations had already repriced rent
hard in 2020–2021, so their 5-year-trailing CAGR is measured off an
elevated base. The sign is real in the data but it is a window artifact, not
a structural law. Do not underwrite a "migration → rent growth" thesis
on this coefficient.
The AVM research preview is a hedonic OLS home-value model built entirely on free public data — 7,141 OpenStreetMap building footprints for the Seattle metro, ZIP-level ZHVI as the label.
The DSCR stress test reprices every surface at the rate-forecast upper band. Rate now: 6.51% (FRED MORTGAGE30US). Five-year upper band (p90): 7.24% for 2031 — a +73bp shock. Rent and home value are held constant; only the rate moves.
| Surface | Above 1.0 now | Above 1.0 stressed | Dropout |
|---|---|---|---|
| Military bases | 10 | 3 | −70% |
| Colleges | 1,364 | 1,132 | −17% |
| Cities | 71 | 62 | −13% |
| Seattle | 0 | 0 | — |
Military bases are the fragile surface: at +73bp, 7 of the 10 bases that clear DSCR 1.0 today fall below it — a 70% dropout, with the survivors clustered at razor-thin margins. Seattle shows 0% dropout for the worst reason: no Seattle ZIP clears 1.0 even today (median DSCR 0.16), so there is nothing left to lose — it is already underwater, not resilient.
One caveat on vintage: the stress page still reprices against the older
forecast_ensemble p90 band (7.24% for 2031) and the pre-v3 flat
operating-cost constant. The newer empirical 5-year cone above is wider; a
refresh of the stress test onto the v3 cone and the per-state DSCR is a
tracked follow-up.
Every nationwide surface (the ZCTA heatmap, Opportunity Sigma, the zipdata
research) is built on one file: zipdata/data/zip_master.json,
31,646 ZCTAs. It joins ACS 5-year 2023 demographics, Zillow
ZHVI/ZORI, HUD SAFMR FY2026, BLS county unemployment, IRS 2022–2023
migration flows and several new layers shipped in this round:
best_rent field blends ACS
median rent, Zillow ZORI and HUD FMR to reach 100% rent
coverage; the blend mixes market rent and policy rent and is flagged as
such.NULL, never filled from a neighbor. 2,155 very-low-population
ZCTAs were dropped outright rather than carried with thin, unstable stats.
Every FEMA hazard layer on the ZCTA heatmap was wrong, and we shipped it wrong. The fix is worth documenting plainly.
hazard_* fields, fema_risk_score and
fema_eal_score were populated from FEMA NRI's
percentile-normalized score columns. A percentile is uniform by construction
— its national median is ~50 no matter the hazard. So the wildfire map
painted half the country (including the rain-soaked Southeast) warm, and
every hazard map looked equally "blown out." Verified against the live FEMA
service: the score column was byte-identical to the percentile column.
v4 re-pulls the absolute, dollar-denominated NRI Risk Index Values — the genuinely right-skewed measure where most counties sit near zero and only truly hazardous counties are elevated. Those values are cube-root power-transformed (a monotone transform that keeps the right-skew — a log transform would flatten it back toward normal, re-introducing the very bug) and linearly rescaled 0–100 against the 99.5th percentile. The result is a map that tells the truth:
| Hazard layer | Old (percentile) median | v4 (absolute) median | v4 p90 |
|---|---|---|---|
| Wildfire | ~54 | 11.7 | 49.7 |
| Hurricane | ~50 | 8.8 | 42.7 |
| Tornado | ~50 | 32.7 | 68.6 |
| Riverine flood | ~50 | 35.5 | 76.6 |
Composite fema_risk_score | ~50 | 33.8 | 74.7 |
The wildfire median dropping from ~54 to 11.7 is the fix in
one number: most ZIPs do not face meaningful wildfire risk, and the corrected
layer now shows the West hot and the East calm — a right-skewed
distribution with a long warm tail instead of a uniform wash. The composite
fema_risk_score and fema_eal_score were corrected
the same way.
A high gross yield in a hurricane-exposed ZIP is not the same as a high
net yield. The climate-yield layer
(zipdata/data/climate_yield.json, 29,734 ZIPs)
estimates how much of a ZIP's gross yield is eaten by insurance:
Nationally the median insurance drag is 0.48% of value (about $1,268/yr), and the median ZIP loses 9.9% of its gross yield to insurance. But the spread is the story. Florida ZIPs lose a median 20.1% of gross yield to insurance — followed by Texas (16.4%), Louisiana (15.7%), Rhode Island (15.6%) and California (15.3%). A high-yield Florida ZIP can be a "high-yield-but-uninsured-risk" market: the headline number survives only until the carrier quote arrives.
The demand-anchor score asks a reasonable question: does a ZIP's proximity to
big, durable employers — military bases, colleges and semiconductor
fabs — predict its rent growth? For 28,630 ZIPs we
computed a distance-decayed sum (exp(−d/30mi), 90-mile
cutoff) of nearby anchor "mass" across 6,236 anchors —
troop count for bases, enrollment for colleges, market cap for fabs —
weighted up for ZIPs near all three anchor types.
Spot DSCR is a snapshot — today's rent over today's value. The v4 rent
forecast (rate/data/rent_forecast.json) projects where metro
rent is heading so DSCR can be read 1 and 3 years forward. The model is a
pooled AR(1) mean-reversion on year-over-year rent growth:
g(t+h) = a + b·g(t), fit by OLS across all metro-month
pairs (29,770 observations) and clamped to the empirical p1–p99 of
observed growth. Resolution is metro level — ZIP-level monthly rent is
too noisy to forecast honestly.
| Horizon | Model MAE | Naive MAE | Skill vs naive | Beats naive? |
|---|---|---|---|---|
| 1 year, n=91,873 | 3.68 pts | 4.04 pts | +9.1% | yes |
| 3 year, n=204,437 | 4.84 pts | 6.35 pts | +23.8% | yes |
DSCR has two drivers — rent (numerator) and home value (denominator, through the loan). The rent-forecast above makes the rent side forward-looking; the appreciation forecast does the value side. Same model family, same diagnostics, same honesty: pooled AR(1) on YoY home-value growth, clamped to the empirical p1–p99 of observed growth, fit on 72,908 metro-month pairs.
| Horizon | Model MAE | Naive MAE | Skill vs naive | Beats naive? |
|---|---|---|---|---|
| 1 year, n=264,734 | 5.88 pts | 6.17 pts | +4.7% | yes |
| 3 year, n=722,736 | 9.14 pts | 10.06 pts | +9.2% | yes |
The appreciation-forecast skill is real but smaller than rent's (+4.7%/+9.2% vs rent's +9.1%/+23.8%). Home-value growth is highly autocorrelated — sticky momentum means a naive "growth continues at its current pace" baseline is hard to beat. Beating naive by single-digit MAE points at the 1-year horizon, and by ~9% at 3 years, is the honest ceiling on what a pooled AR(1) on a single autocorrelated series will deliver.
dscr_forward_3y = dscr_now × (1+rent_cagr)3 / (1+value_cagr)3
— rising rent lifts it, rising value drags it down (because the loan
on the new value is bigger). Coverage: 244 metros. The
rent-only convention (dscr_forward_3y_rentonly) is preserved
for comparison with the prior surface. Mortgage rate is held at today's
level — a stated assumption, not a forecast. A rate-scenario slider
on the page lets a user swap in their own rate.
WindMayor sells DSCR and Opportunity Sigma as present-tense screens — can a property cash-flow today, and is its yield statistically unusual relative to peers. Whether either has forward predictive value is a separate question. We backtested both, honestly, and report the result as-is.
At each backtest date T we computed DSCR for 242–244 cities
using only data known at T — point-in-time rent and home-value (from
the rent_ts/home_value_ts arrays) and the FRED
MORTGAGE30US rate prevailing at T. Then we measured the forward 5-year
rent CAGR and value CAGR that actually arrived, and regressed
forward growth on DSCR-at-T. Two windows: 2019→2024 (rate ~4.46%) and
2021→2026 (rate ~2.74%).
| Window | fwd RENT CAGR ~ DSCR@T | fwd HV CAGR ~ DSCR@T |
|---|---|---|
| 2019→2024 | r +0.28, R² 0.077 | r +0.26, R² 0.066 |
| 2021→2026 | r +0.29, R² 0.084 | r +0.14, R² 0.020 |
d(DSCR) ~ DSCR@T slope ≈ −0.27, R² 0.66–0.72).
DSCR is a present-tense cash-flow screen, useful chiefly as a downside
filter. We do not market it as predictive of appreciation, and
the R² 0.02–0.08 finding is exactly why.
Same methodology, same windows, same n. Sigma at T is reconstructed by
taking point-in-time gross yield and robust-z-scoring it across the
cross-section at that date — identical formula to
compute_sigma.py, no lookahead.
| Window | fwd RENT CAGR ~ Sigma@T | fwd HV CAGR ~ Sigma@T |
|---|---|---|
| 2019→2024 | r +0.23, R² 0.054 | r +0.24, R² 0.058 |
| 2021→2026 | r +0.29, R² 0.086 | r +0.15, R² 0.023 |
d(DSCR) ~ sigma@T, R² 0.62–0.73) — high
current yield = thin operating margin = most exposed to a rate shock.
Both backtests converge on the same honest answer: yield-type metrics are
good for screening present cash-flow, weak for predicting future returns,
and we do not manufacture predictive power the data does not support.
Opportunity Sigma scores how unusual a ZIP's yield (or DSCR) is relative to
its peers. It is a robust z-score: it uses the
median and 1.4826 × MAD (median absolute
deviation), not the mean and standard deviation. The reason is that
ZIP-level yield has a long fat tail — a handful of $40k-home ZIPs post
90%+ gross yields. A mean/std z-score lets those outliers inflate the spread
and quietly flatten everything else; the median/MAD version is not dragged by
them.
R-SIGMA.normalize-v2. A reviewer caught a ZIP that scored +39.6σ — not a real anomaly but a Zillow ZORI scrape error ($27,865/mo at ZIP 28570) producing an "impossible" yield. v2 fixes the normalization in two ways:
sigma_data.json under artifact_gate —
nothing is silently suppressed.log(yield) rather
than yield itself. After both fixes the maximum national yield σ is
+4.33 (was +39.6), the robust center is
6.19% with a robust log-spread of
0.377, and 91 ZIPs sit above +3σ nationally.
Those 91 are not artifacts — they are the genuine
distressed-market fat tail (Detroit, East St. Louis, Jackson MS, the
Mahoning Valley). The remaining 7 ZIPs above +4σ are inside that
same tail; manual spot-check confirms each is a real low-price /
real-rent observation, not a scrape error.On the national yield base (n=14,956 after gating) the robust center is 6.19%; the log-space robust spread is 0.377. Band thresholds below apply on the log-yield z-score for the national surface; per-surface sigmas (cities, milbase, collegemap, seattle) keep their own robust scales.
| Band | Robust |z| | Reading |
|---|---|---|
| Typical | ≤ 1 | In line with peers |
| Notable | 1 – 2 | Stands out; worth a look |
| Rare | 2 – 3 | Far from the pack |
| Exceptional | > 3 | Extreme — investigate before trusting |
We ran the full 31,646-ZIP spine through a correlation matrix, a yield regression and a k-means clustering. The findings are observational — correlation, not causation; nothing below controls for confounders.
Among the cleaner findings: price-per-sqft correlates −0.16 with gross yield. Per-sqft price captures land scarcity better than total home value, and is one of the strongest single negative predictors of yield.
The most counter-intuitive result: the FEMA composite risk score correlates +0.34 with home value across 29,734 ZCTAs. The market is not discounting hazard — it is paying up for the same coastal and metro places that score risky.
One vintage note: this correlation matrix was computed before the v4 FEMA hazard fix described above. The cube-root rescale is monotone, so the sign and broad direction hold, but the exact coefficients should be re-run on the corrected absolute scale — a tracked follow-up.
k-means (k=6) sorts the spine into six archetypes — from High-yield / Cheap ($78k median home, 15.2% gross yield, 1,683 ZIPs) to Highly-educated / Expensive ($666k home, 4.1% yield, 4,890 ZIPs). Cluster boundaries are fuzzy; the names describe centroids, not every member.
Two interactive surfaces shipped this round; both read the same audited data the rest of the site uses, no separate pipelines.
The Buy-Box Screener filters the full 31,646-ZIP spine against an investor's criteria — yield floor, price ceiling, FEMA risk cap, income, ownership rate and more. It is a pure client-side query over a slim ZIP extract; nothing on it is a recommendation. It is the screen made explicit: set your box, see which ZIPs fall inside it, then do the property-specific diligence.
The AI / Chip Stock Heatmap tracks 53 public companies across the AI and semiconductor supply chain — returns and metadata from the public Yahoo Finance chart API. It pairs with the fab map, which places the physical fabs and offices on a map. It is a context layer for reading where AI capital is concentrating — not a stock screen, and carries no valuations of private companies, only public-record HQ cities.
When a public company's stock rises, the equity wealth lands with its employees — through RSUs, ESPP and options — who live near the company's offices. Stock appreciation is therefore a geographically concentrated injection of housing-demand money. The stock-wealth-geography surface estimates this per office, ZIP and metro across the 2021-01 → 2026-05 window.
DSCR is a levered screen — it asks whether rent covers a real mortgage. The cap-rate page is the unlevered companion: how much yield does the ZIP throw off on the property itself, before financing? Cap rate = NOI / home value, scored on 30,002 ZIPs.
National median cap rate: 2.54% (mean 3.31%; p10 0.69%, p90 6.46%). 898 of 30,002 ZIPs show a negative NOI — modeled operating costs exceed effective rent. These are retained as a real signal that modeled carry is upside-down, not nulled. Cap rate is unlevered by definition; pair with DSCR for the levered picture.
v5 is the biggest round since v3. DSCR's formula constants are unchanged from v4, but v5 adds:
The 78 MB zip_master.json was too large for the heatmap to
fetch on every page load. v5 splits it into two files and key-shortens the
served one:
zip_render.json — 9.3 MB
(~2.6 MB gzipped over the wire), 31 fields for 31,646
ZIPs, key-shortened (each long field name has a 1–3 char alias;
e.g. median_home_value_acs → hv). The
full alias table is included as _keymap at the top of the
file and decoded by the heatmap at runtime — so the served file is
compact, but no fields are renamed in the pipeline. Tracked in git; this
is what the site actually reads.zip_master.json — 78 MB, all
~120 pipeline fields, full long names. Gitignored; regenerated locally by
the pipeline. The canonical intermediate product for data agents; not
served to the browser.
Net effect on cold-load (B-PERF.heatmap-load): heatmap critical path went
from ~49 MB to ~2.6 MB gz. Shape-first paint draws the ZIP
polygons before the data file lands; data layers wash in as
zip_render.json arrives.
The demand-anchor merge wrote anchor_score_raw (the raw distance-weighted
sum) into the demand_anchor_score slot instead of the headline
diversity-weighted value. The correct formula is:
headline = anchor_score_raw × (0.4 + 0.6 × type_diversity / 3)
— where type_diversity (0–3) rewards a ZIP that draws from
all three anchor types rather than a single dominant one. Of 27,535 paired ZIPs,
27,450 carried the wrong value before the fix. The corrected values are now the
source of truth in demand_anchor.json; the pipeline no longer lets a
"never overwrite" guard silently suppress them.
ZIP 28570 (Morehead City NC) carried a Zillow ZORI best_rent of
$27,865/mo — a 24.7× multiple of the HUD FMR ($1,130) and
26× the ACS median rent ($951). The value propagated into zip_render.json
and cap_rate.json, producing a computed DSCR of 13.55 for that ZIP.
In v5 the corrupt ZORI value is removed; best_rent for 28570 falls
back to the ACS value ($951) and is no longer a heatmap outlier.
The fix is generalized at the pipeline level: the rent ladder now guards ZORI
against HUD FMR — any ZORI value exceeding 15× FMR is dropped as a
scrape error; ZIPs where ZORI runs 6–15× FMR are retained but tagged
rent_quality = zori_high_vs_fmr (these are real luxury / vacation-rental
markets such as Aspen CO, the Hamptons NY, and Westhampton Beach NY).
Zillow ZHVI and ZORI data for the 6,086 collegemap institutions were refreshed, but
the stored dscr and dscr_condo values were not recomputed.
A fresh run of the canonical v3 formula against current rent and home-value inputs
found 987 SFR rows and 1,746 condo rows whose stored
DSCR differed from the recomputed value by more than 0.10. All were corrected; a
cross-check confirms 0 stale rows on both bases. The fix also recovered
+113 collegemap DSCR rows (5,747 → 5,860) by recomputing off
the all-homes price ladder, which covers more rural ZIPs than the condo-only basis
the prior pass had narrowed to.
| Field | Source | Coverage |
|---|---|---|
crash_fatal_rate_per_100k |
NHTSA FARS 2021–2023, 3-year average fatal crashes per 100k county population, mapped from county to 31,324 ZIPs. National median 17.2 per 100k. FATAL crashes only — all-severity crash data is fragmented across 50 state DOTs and not uniformly free; no single nationwide all-severity county dataset exists. Labeled in the data as a "directional risk proxy" for overall auto / car-insurance risk, NOT a comprehensive crash count. | 99.0% (3,085 counties) |
pop_density_per_sq_mi |
ACS population / ZIP land area derived from the TopoJSON polygon (d3.geoArea). The heatmap computes this on load from the geometry it already fetches — no separate data pull. | 97.8% |
broadband_pct |
FCC National Broadband Map — % of locations with broadband service. | 99% |
school_score |
NCES EdFacts SY2019–20 state assessment proficiency rates (reading + math).
WA state does not report to EdFacts; rural ZIPs with no K–12 school are
NULL. |
63.4% (20,078 / 31,646 ZIPs) |
traffic_intensity |
FHWA Highway Performance Monitoring System (HPMS) AADT counts, aggregated to ZIP from road segments. Captures vehicle-trip density as a proxy for commute-flow intensity and Uber / short-term-rental demand geography. | live |
crime_proxy |
FBI UCR via County Health Rankings 2022 — violent crime rate per 100k, county-level mapped to ZIP. Labeled a proxy: FBI UCR undercounts (not all agencies report) and measures reported crimes, not actual incidents. | 96% (30,383 / 31,646 ZIPs) |
Two new research surfaces published using the v5 data:
A full characterization of the 1,151 U.S. ZIP codes (4.4% of the 26,177 computable) where rental income covers all operating costs plus a 7.21% DSCR-loan debt service at 80% LTV. The finding: 95% of cash-flowing ZIPs have home values under $200k and are concentrated in Appalachia (WV, KY), the Rust Belt (OH, MI, IL, PA) and the Deep South (AL, MS, LA). A second category — the Hamptons, Fort Myers Beach, Kauai — shows DSCR ≥ 1.0 because ZORI captures vacation-rental pricing, a different investment thesis. Median DSCR among positive ZIPs: 1.28× at a $97k median home value with 12.2% gross yield.
Paste any list of ZIP codes — a portfolio you own, a market you are underwriting, or a comparison set — and receive an aggregate FEMA risk distribution, total annual insurance drag in dollars, yield impact (gross vs. climate-adjusted), and a per-property table. Covers 29,734 ZIPs, fully client-side. Five preset portfolios: Rust Belt cash-flow ZIPs, coastal metros, Sun Belt, high-wildfire exposure, and hurricane alley.
The most consequential claim WindMayor makes is that the numbers on screen come from real public data, traceable to source, with no fabrication. T-DATA.source-spotcheck (re-run 2026-05-22) is the independent audit of that claim. Methodology: pick a random 5-row sample from each surface (deterministic seed=2026), grab one or two cited numeric fields per row, and trace each back to the original public source — fetching the source file fresh during the audit itself for live APIs.
| Surface | Rows | Pass | Fail |
|---|---|---|---|
| seattle (ZHVI + ZORI ZIP) | 10 | 10 | 0 |
| college (ZHVI + ZORI ZIP/city/condo + HUD FMR) | 10 | 10 | 0 |
| cities (ZHVI City + ZORI City) | 10 | 10 | 0 |
| milbase (DoD BAH + ZHVI metro) | 10 | 10 | 0 |
| zip_render (ACS B19013 / B01003 + declared rent_source) | 15 | 15 | 0 |
| crash_by_county (NHTSA FARS formula identity) | 5 | 5 | 0 |
| cap_rate (NOI/HV formula identity) | 5 | 5 | 0 |
| climate_yield (state DP3 × hazard mult identity) | 5 | 5 | 0 |
| demand_anchor (raw × diversity identity) | 5 | 5 | 0 |
| rate_spine (FRED MORTGAGE30US live) | 5 | 5 | 0 |
| insurance (NAIC 2022 HO-3 published values + DP-3 uplift) | 10 | 10 | 0 |
| TOTAL | 90 | 90 | 0 |
Across 11 distinct data surfaces and 7 independent public sources every stored value traced to source to the dollar, with the worst observed delta = 0.19% (a cap-rate row) explained entirely by stored 4-decimal rounding of NOI and home-value before division. Where a ZIP has no Zillow coverage, the row honestly cites a fallback (HUD FMR or Zillow City) instead of fabricating — and the fallback value is also verified.
python3 projects/scripts/source_spotcheck.py (seed=2026,
raw matrix written to /tmp/source_spotcheck.json) and you
should see the same 90 / 90.
WindMayor is a research and underwriting screen, not investment advice, not legal advice, not tax advice. Numbers are screens for further diligence, not closing-grade values. Past data is not prediction. Real deals require property-specific underwriting with current local comparables.