Skip to content

market

Market data helpers for the refinance calculator interface.

fetch_all_series(api_key)

Retrieve all configured market series from FRED.

Parameters:

Name Type Description Default
api_key str

API key to authenticate with FRED.

required

Returns:

Type Description
tuple[dict[str, list[tuple[str, float]]], list[str]]

Tuple of raw series data and collection of error messages.

Source code in src/refi_calculator/web/market.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def fetch_all_series(api_key: str) -> tuple[dict[str, list[tuple[str, float]]], list[str]]:
    """Retrieve all configured market series from FRED.

    Args:
        api_key: API key to authenticate with FRED.

    Returns:
        Tuple of raw series data and collection of error messages.
    """
    raw_series: dict[str, list[tuple[str, float]]] = {}
    errors: list[str] = []
    for label, series_id in MARKET_SERIES:
        try:
            observations = _fetch_series(series_id, api_key)
        except RuntimeError as exc:
            logger.exception("Failed to fetch %s series", label)
            errors.append(f"{label}: {exc}")
            observations = []
        raw_series[label] = observations
    return raw_series, errors

get_api_key()

Retrieve the FRED API key stored in Streamlit secrets.

Source code in src/refi_calculator/web/market.py
21
22
23
def get_api_key() -> str | None:
    """Retrieve the FRED API key stored in Streamlit secrets."""
    return st.secrets.get("FRED_API_KEY")

render_market_tab()

Render the market data tab with metrics, range selector, chart, and table.

Source code in src/refi_calculator/web/market.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
def render_market_tab() -> None:
    """Render the market data tab with metrics, range selector, chart, and table."""
    st.subheader("Market Data")

    api_key = get_api_key()
    if not api_key:
        st.warning(
            "Add your FRED API key to `st.secrets['FRED_API_KEY']` to view mortgage rate history.",
        )
        return

    raw_series, errors = fetch_all_series(api_key)
    for err in errors:
        st.error(err)

    market_df_all = _build_market_dataframe(raw_series)
    if market_df_all.empty:
        st.info("Market data is not available for the selected range.")
        return

    latest_valid = market_df_all.dropna(how="all")
    if latest_valid.empty:
        st.info("Market data lacks recent observations.")
        return

    latest = latest_valid.iloc[-1].dropna()
    latest_timestamp_raw = latest_valid.index.max()
    if latest_timestamp_raw is pd.NaT:
        st.info("Market data lacks recent observations.")
        return
    latest_date = cast(pd.Timestamp, latest_timestamp_raw).date()
    st.markdown(
        f"**Current rates (latest available as of {latest_date:%Y-%m-%d})**",
    )
    if not latest.empty:
        metric_cols = st.columns(len(latest))
        for col, (label, value) in zip(metric_cols, latest.items()):
            col.metric(label, f"{value:.2f}%")

    options = [label for label, _ in MARKET_PERIOD_OPTIONS]
    option_mapping = {label: value for label, value in MARKET_PERIOD_OPTIONS}
    period_label = st.radio(
        "Range",
        options,
        horizontal=True,
        key="market_period",
    )
    period_months = _segment_months(option_mapping[period_label])

    market_df = _filter_market_dataframe(market_df_all, period_months)
    if market_df.empty:
        st.info("Filtered market data is not available for the selected range.")
        return

    _render_market_chart(market_df)

    table = market_df.sort_index(ascending=False).head(12).reset_index()
    table["Date"] = table["Date"].dt.date
    st.dataframe(table, width="stretch")