Files
openbb-invest-api/routes_macro.py
Yaojia Wang ad45cb429c feat: OpenBB Investment Analysis API
REST API wrapping OpenBB SDK for stock data, sentiment analysis,
technical indicators, macro data, and rule-based portfolio analysis.

- Stock data via yfinance (quote, profile, metrics, financials, historical, news)
- News sentiment via Alpha Vantage (per-article, per-ticker scores)
- Analyst data via Finnhub (recommendations, insider trades, upgrades)
- Macro data via FRED (Fed rate, CPI, GDP, unemployment, treasury yields)
- Technical indicators via openbb-technical (RSI, MACD, SMA, EMA, Bollinger)
- Rule-based portfolio analysis engine (BUY_MORE/HOLD/SELL)
- Stock discovery (gainers, losers, active, undervalued, growth)
- 102 tests, all passing
2026-03-09 00:20:10 +01:00

54 lines
1.5 KiB
Python

"""Routes for macroeconomic data (FRED-powered)."""
import functools
import logging
from collections.abc import Awaitable, Callable
from typing import ParamSpec, TypeVar
from fastapi import APIRouter, HTTPException, Query
from models import ApiResponse
import macro_service
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1")
P = ParamSpec("P")
R = TypeVar("R")
def _safe(fn: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]:
@functools.wraps(fn)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
try:
return await fn(*args, **kwargs)
except HTTPException:
raise
except Exception:
logger.exception("Upstream data error")
raise HTTPException(
status_code=502,
detail="Data provider error. Check server logs.",
)
return wrapper # type: ignore[return-value]
@router.get("/macro/overview", response_model=ApiResponse)
@_safe
async def macro_overview():
"""Get key macro indicators: Fed rate, treasury yields, CPI, unemployment, GDP, VIX."""
data = await macro_service.get_macro_overview()
return ApiResponse(data=data)
@router.get("/macro/series/{series_id}", response_model=ApiResponse)
@_safe
async def macro_series(
series_id: str,
limit: int = Query(default=30, ge=1, le=1000),
):
"""Get a specific FRED time series by ID."""
data = await macro_service.get_series(series_id, limit=limit)
return ApiResponse(data=data)