Skip to content

fred

FRED API helpers for borrowing-rate data.

fetch_fred_series(series_id, api_key, limit=None)

Fetch a stationary FRED series and return (date, value) pairs.

Parameters:

Name Type Description Default
series_id str

FRED series identifier (e.g., "MORTGAGE30US").

required
api_key str

Your FRED API key.

required
limit int | None

Maximum number of observations to fetch. Defaults to the service limit.

None

Returns:

Type Description
list[tuple[str, float]]

Observations sorted newest-first, (date, float value).

Source code in src/refi_calculator/core/market/fred.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def fetch_fred_series(
    series_id: str,
    api_key: str,
    limit: int | None = None,
) -> list[tuple[str, float]]:
    """Fetch a stationary FRED series and return (date, value) pairs.

    Args:
        series_id: FRED series identifier (e.g., "MORTGAGE30US").
        api_key: Your FRED API key.
        limit: Maximum number of observations to fetch. Defaults to the service limit.

    Returns:
        Observations sorted newest-first, (date, float value).
    """
    params: dict[str, str] = {
        "series_id": series_id,
        "api_key": api_key,
        "file_type": "json",
        "sort_order": "desc",
    }
    if limit:
        params["limit"] = str(limit)

    url = f"https://api.stlouisfed.org/fred/series/observations?{urllib.parse.urlencode(params)}"

    try:
        with urllib.request.urlopen(url, timeout=10) as resp:
            payload = json.load(resp)
    except (urllib.error.URLError, urllib.error.HTTPError, json.JSONDecodeError) as exc:
        raise RuntimeError("Failed to fetch FRED series") from exc

    observations = payload.get("observations", [])
    results: list[tuple[str, float]] = []
    for obs in observations:
        date = obs.get("date")
        value = obs.get("value")
        if date is None or value is None or value == ".":
            continue
        try:
            parsed = float(value)
        except ValueError:
            continue
        results.append((date, parsed))
    return results