diff --git a/app/services/universe_service.py b/app/services/universe_service.py index e07b049..b3aa948 100644 --- a/app/services/universe_service.py +++ b/app/services/universe_service.py @@ -116,6 +116,11 @@ class UniverseService: # Keep only major US exchanges if exchange not in _US_EXCHANGES: continue + # Skip preferred stocks / warrants / rights / units (contain - or end in W/R/U/Z) + if "-" in ticker: + continue + if len(ticker) > 1 and ticker[-1] in ("W", "R", "Z") and ticker[:-1].isalpha(): + continue quotes.append({ "symbol": ticker, "shortName": str(row[name_idx]) if row[name_idx] else None, @@ -343,9 +348,14 @@ class UniverseService: shares = latest_shares if shares is None or close is None: continue + # Sanity checks: skip absurd values (data quality) + if close > 1_000_000 or close <= 0: # max BRK-A ~$600K + continue + if shares < 100_000: # too few shares for a real public co + continue market_cap = shares * close - if math.isnan(market_cap) or market_cap <= 0: + if math.isnan(market_cap) or market_cap <= 0 or market_cap > 5e12: continue # Normalize to first of month @@ -537,7 +547,12 @@ class UniverseService: snapshot_dt = datetime(target.year, target.month, 1, tzinfo=timezone.utc) - conditions = [UniverseSnapshot.snapshot_date == snapshot_dt] + # Always exclude clearly bad data (sanity cap: $5T max, historical record is ~$3.7T) + _MAX_MARKET_CAP = 5e12 + conditions = [ + UniverseSnapshot.snapshot_date == snapshot_dt, + UniverseSnapshot.market_cap <= _MAX_MARKET_CAP, + ] if market_cap_min is not None: conditions.append(UniverseSnapshot.market_cap >= market_cap_min) if market_cap_max is not None: