feat: ticker validation + SLV/USO/WEAT/CORN/TUR added to ETFs watchlist
Backend:
- GET /api/market/validate?symbol= — validates ticker against yfinance,
returns {valid, name, price} or {valid: false, reason: 'helpful message'}
- Added SLV, USO, WEAT, CORN, TUR to ETFs WATCHLIST category
Frontend:
- validateTicker() async helper exported from useApi.ts
- InstrumentPicker (PatternLab): custom ticker field now validates before selecting
Shows spinner while checking, red error message if not found on yfinance
- InstrumentLens (PatternExplorer): same validation on Go button + Enter key
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,24 @@ def watchlist():
|
||||
return WATCHLIST
|
||||
|
||||
|
||||
@router.get("/validate")
|
||||
def validate_ticker(symbol: str = Query(..., description="Ticker to validate against yfinance")):
|
||||
"""Check if a ticker is fetchable. Returns valid=True + live price/name, or valid=False + reason."""
|
||||
from services.data_fetcher import get_quote
|
||||
import yfinance as yf
|
||||
symbol = symbol.strip().upper()
|
||||
q = get_quote(symbol)
|
||||
if q and q.get("price"):
|
||||
# Try to get a display name
|
||||
try:
|
||||
info = yf.Ticker(symbol).fast_info
|
||||
name = getattr(info, "long_name", None) or getattr(info, "short_name", None) or symbol
|
||||
except Exception:
|
||||
name = symbol
|
||||
return {"valid": True, "symbol": symbol, "name": name, "price": q["price"], "change_pct": q.get("change_pct")}
|
||||
return {"valid": False, "symbol": symbol, "reason": f"Ticker '{symbol}' not found on yfinance — check the symbol (e.g. GC=F for Gold, ^GSPC for S&P 500)"}
|
||||
|
||||
|
||||
@router.get("/macro-regime")
|
||||
def macro_regime(force: bool = False):
|
||||
"""Macro gauge values + 5-scenario scoring. Cached 15 min."""
|
||||
|
||||
Reference in New Issue
Block a user