What is GUSPM?
The Gera US Price Momentum (GUSPM) index combines four signals per US state and CBSA metro area, all derived from real FHFA HPI data:
- latestHpi β latest FHFA All-Transactions HPI value (index, base 1980Q1=100)
- pct1yr β 1-year % change (same quarter prior year)
- pct5yr β 5-year % change (same quarter 5 years ago)
- volatility β std dev of 1yr HPI changes over last 10 quarters; band: low / medium / high
GUSPM raw formula: 0.5 Γ pct1yr + 0.3 Γ (pct5yr / 5) + 0.2 Γ max(0, 3 β volatility)
Normalized to 0β100 across all 461 entries. Areas with insufficient FHFA data output βinsufficient dataβ β never a fabricated estimate.
Data source
| Source | FHFA House Price Index (HPI) β All-Transactions, Not Seasonally Adjusted |
| State file | hpi_at_state.txt (All-Transactions, NSA β 51 states + DC) |
| Metro file | hpi_at_metro.txt (All-Transactions, NSA β 410 CBSA metro areas with data) |
| Reference period | 2026 Q1 |
| Last computed | 2026-06-20 |
| Publisher | Federal Housing Finance Agency (FHFA) |
| Licence | US public domain β federal government work |
| Key required? | No β bulk TXT/CSV, no registration |
Step-by-step formula
- 1
Download the FHFA HPI datasets
Fetch hpi_at_state.txt and hpi_at_metro.txt from https://www.fhfa.gov/data/hpi/datasets. No API key required. Files are plain tab-delimited text. State file: columns = state_code, year, quarter, hpi_value. Metro file: columns = metro_name (quoted), cbsa_code, year, quarter, hpi_value (or "-" for no data). Data goes back to 1975 for some states.
- 2
Parse and build time series per area
For states: read each row, skip if hpi_value is not a float. For metros: skip rows where hpi_value is "-". Build a per-area array of {yr, qtr, hpi} objects sorted by (yr, qtr). Metros with fewer than 8 valid data points are excluded from the published dataset.
- 3
Identify the latest quarter
The latest data point for each area is the maximum (yr, qtr) pair with a valid HPI value. As of this computation, the latest available quarter for all 51 states is 2026 Q1.
- 4
Compute pct1yr
Find the data point with yr = latestYr β 1 and qtr = latestQtr (exactly 4 quarters prior). pct1yr = (latestHpi β hpiOneYrAgo) / hpiOneYrAgo Γ 100, rounded to 2 d.p. If no matching point exists, pct1yr = null ("insufficient data").
- 5
Compute pct5yr
Find the data point with yr = latestYr β 5 and qtr = latestQtr. pct5yr = (latestHpi β hpiFiveYrAgo) / hpiFiveYrAgo Γ 100, rounded to 2 d.p. If no matching point, pct5yr = null.
- 6
Compute volatility
For each of the last 10 quarterly periods, compute the 1-year HPI % change (current quarter vs same quarter 1 year prior). Take the population standard deviation of these 10 values (std dev = sqrt(variance)). If fewer than 4 such periods exist, volatility = null. Volatility band: "low" if < 1.0%, "medium" if 1.0β2.5%, "high" if > 2.5%.
- 7
Compute GUSPM raw score
If pct1yr is null: guspm = null. Otherwise: guspm_raw = 0.5 Γ pct1yr + 0.3 Γ (pct5yr ?? 0) / 5 + 0.2 Γ max(0, 3 β (volatility ?? 3)). This blends 1yr momentum (50%), annualized 5yr momentum (30%), and an inverse-volatility stability bonus (20%). Areas with volatility β₯ 3% get zero stability bonus.
- 8
Normalize to 0β100
guspmNorm = (guspm_raw β min_raw) / (max_raw β min_raw) Γ 100, rounded to 1 d.p. Normalization is across all 461 entries (states + metros) in the current dataset so that scores are comparable. The range updates each quarter when new FHFA data is published.
Pseudocode
# Input: hpi_at_state.txt, hpi_at_metro.txt
# Output: GUSPM_ENTRIES array (normalized 0β100)
for each area_file in [state_file, metro_file]:
for each row in area_file:
if hpi_value == "-" or not valid_float(hpi_value): skip
series[area_key].append({ yr, qtr, hpi: float(hpi_value) })
for each area in series:
series[area].sort_by(yr, qtr)
if len(series[area]) < 8: skip # insufficient data
latest = series[area][-1]
oneYrAgo = find(series[area], yr=latest.yr-1, qtr=latest.qtr)
fiveYrAgo = find(series[area], yr=latest.yr-5, qtr=latest.qtr)
pct1yr = oneYrAgo ? (latest.hpi - oneYrAgo.hpi) / oneYrAgo.hpi * 100 : null
pct5yr = fiveYrAgo ? (latest.hpi - fiveYrAgo.hpi) / fiveYrAgo.hpi * 100 : null
changes = [(series[area][i].hpi - series[area][i-4].hpi) / series[area][i-4].hpi * 100
for i in range(4, len(series[area]))][-10:]
volatility = stdev(changes) if len(changes) >= 4 else null
if pct1yr is null: guspm_raw = null
else:
guspm_raw = 0.5 * pct1yr
+ 0.3 * (pct5yr ?? 0) / 5
+ 0.2 * max(0, 3 - (volatility ?? 3))
results.append({ ..., latestHpi: latest.hpi, pct1yr, pct5yr, volatility, guspm_raw })
# Normalize
min_g = min(r.guspm_raw for r in results if r.guspm_raw is not null)
max_g = max(r.guspm_raw for r in results if r.guspm_raw is not null)
for r in results:
r.guspmNorm = (r.guspm_raw - min_g) / (max_g - min_g) * 100 if r.guspm_raw else null
GUSPM_ENTRIES = results.sort_by(guspmNorm, descending=True)Coverage (2026 Q1)
- States covered: 51 (all 50 states + DC)
- Metro areas (CBSAs) covered: 410 (of 410 in FHFA file; those with β₯ 8 valid data points and 1yr data)
- Total pages: 461 entries + 1 hub + 1 methodology
- US state median 1-year change: +3.79%
- Source last published: June 2026
- Update cadence: Quarterly (on each new FHFA HPI release, approx. 2 months after quarter-end)
- Licence: US public domain β federal government work
Limitations & caveats
- Index-based, not price-based: FHFA HPI is a repeat-sales index. It measures % change in prices, not absolute price levels. An index value of 495 means prices have risen 395% since the base period (1980Q1=100 for All-Transactions NSA), not that homes cost $495.
- Enterprise mortgages only: The All-Transactions index covers only mortgages acquired or securitised by Fannie Mae and Freddie Mac, plus FHA/VA appraisals for refinancings. It excludes cash sales and jumbo (above conforming limit) mortgages, which can be significant in high-cost metros.
- GUSPM weights are illustrative: The 50/30/20 split is a judgment call; changing it would reorder areas. The normalized score is for comparison within this dataset, not across datasets with different methodologies.
- Volatility window: The last 10 quarterly periods (β2.5 years) capture recent cyclical variation. Longer windows would smooth structural changes; shorter windows would amplify recent events. Areas with short FHFA series show βinsufficient dataβ for volatility.
- Not investment advice: GUSPM is a statistical summary of FHFA HPI data. It is not a property valuation, mortgage advice, or investment recommendation.
Source data: FHFA House Price Index (HPI), published by the Federal Housing Finance Agency (FHFA). FHFA HPI data is a product of the US federal government and is in the public domain under US law (17 U.S.C. Β§ 105). Downloaded from https://www.fhfa.gov/data/hpi/datasets (2026 Q1). GUSPM computation by Gera Systems β see methodology above.