mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
1788 lines
60 KiB
Python
1788 lines
60 KiB
Python
"""FRED provider module integration tests."""
|
|
|
|
from datetime import date, datetime
|
|
from math import inf, isfinite
|
|
from statistics import median
|
|
|
|
import pytest
|
|
from openbb_core.app.model.obbject import OBBject
|
|
|
|
from openbb_fred.models.ameribor import MATURITY_TO_FRED_ID, FredAmeriborData
|
|
from openbb_fred.models.balance_of_payments import FredBalanceOfPaymentsData
|
|
from openbb_fred.models.bond_indices import BAML_CATEGORIES, FredBondIndicesData
|
|
from openbb_fred.models.commercial_paper import CP_SERIES_IDS, FREDCommercialPaperData
|
|
from openbb_fred.models.commodity_spot_prices import (
|
|
SERIES_MAP,
|
|
FredCommoditySpotPricesData,
|
|
)
|
|
from openbb_fred.models.consumer_price_index import FREDConsumerPriceIndexData
|
|
from openbb_fred.models.dwpcr_rates import FREDDiscountWindowPrimaryCreditRateData
|
|
from openbb_fred.models.ecb_interest_rates import (
|
|
FREDEuropeanCentralBankInterestRatesData,
|
|
)
|
|
from openbb_fred.models.economic_calendar import FredEconomicCalendarData
|
|
from openbb_fred.models.euro_short_term_rate import FredEuroShortTermRateData
|
|
from openbb_fred.models.fed_projections import FREDPROJECTIONData
|
|
from openbb_fred.models.federal_funds_rate import FredFederalFundsRateData
|
|
from openbb_fred.models.ffrmc import FREDSelectedTreasuryConstantMaturityData
|
|
from openbb_fred.models.high_quality_market import (
|
|
FredHighQualityMarketCorporateBondData,
|
|
)
|
|
from openbb_fred.models.iorb_rates import FREDIORBData
|
|
from openbb_fred.models.manufacturing_outlook_ny import FredManufacturingOutlookNYData
|
|
from openbb_fred.models.manufacturing_outlook_texas import (
|
|
FredManufacturingOutlookTexasData,
|
|
)
|
|
from openbb_fred.models.mortgage_indices import (
|
|
MORTGAGE_CHOICES_TO_ID,
|
|
FredMortgageIndicesData,
|
|
)
|
|
from openbb_fred.models.non_farm_payrolls import FredNonFarmPayrollsData
|
|
from openbb_fred.models.overnight_bank_funding_rate import (
|
|
FredOvernightBankFundingRateData,
|
|
)
|
|
from openbb_fred.models.personal_consumption_expenditures import (
|
|
FredPersonalConsumptionExpendituresData,
|
|
)
|
|
from openbb_fred.models.regional import FredRegionalData
|
|
from openbb_fred.models.release_table import FredReleaseTableData
|
|
from openbb_fred.models.retail_prices import FredRetailPricesData
|
|
from openbb_fred.models.search import FredSearchData
|
|
from openbb_fred.models.senior_loan_officer_survey import (
|
|
SLOOS_CATEGORIES,
|
|
FredSeniorLoanOfficerSurveyData,
|
|
)
|
|
from openbb_fred.models.series import FredSeriesData
|
|
from openbb_fred.models.sofr import FREDSOFRData
|
|
from openbb_fred.models.sonia_rates import FREDSONIAData
|
|
from openbb_fred.models.spot import FREDSpotRateData
|
|
from openbb_fred.models.survey_of_economic_conditions_chicago import (
|
|
FredSurveyOfEconomicConditionsChicagoData,
|
|
)
|
|
from openbb_fred.models.tbffr import FREDSelectedTreasuryBillData
|
|
from openbb_fred.models.tips_yields import FredTipsYieldsData
|
|
from openbb_fred.models.tmc import FREDTreasuryConstantMaturityData
|
|
from openbb_fred.models.university_of_michigan import FredUofMichiganData
|
|
from openbb_fred.models.yield_curve import FREDYieldCurveData
|
|
from openbb_fred.utils.api import observation_dates
|
|
from openbb_fred.utils.fred_helpers import YIELD_CURVES
|
|
|
|
PERCENT_BAND = (-100.0, 100.0)
|
|
POSITIVE_BAND = (0.0, 1.0e6)
|
|
INDEX_BAND = (0.0, 1.0e5)
|
|
COUNT_BAND = (0.0, 1.0e12)
|
|
WIDE_BAND = (-1.0e15, 1.0e15)
|
|
TRANSFORMS = ("chg", "ch1", "pch", "pc1", "pca", "cch", "cca", "log")
|
|
|
|
|
|
def results_of(result, data_class, minimum=1):
|
|
"""Return the rows an OBBject carries, asserting the model it validated as.
|
|
|
|
Parameters
|
|
----------
|
|
result : OBBject
|
|
The command output.
|
|
data_class : type
|
|
The provider Data model the rows are expected to validate as.
|
|
minimum : int
|
|
The fewest rows the parameters can legitimately return.
|
|
|
|
Returns
|
|
-------
|
|
list
|
|
The validated rows.
|
|
"""
|
|
assert isinstance(result, OBBject)
|
|
assert isinstance(result.results, list)
|
|
assert len(result.results) >= minimum
|
|
assert isinstance(result.results[0], data_class)
|
|
assert set(data_class.model_fields) <= set(result.results[0].model_dump())
|
|
|
|
return result.results
|
|
|
|
|
|
def dates_of(rows, field="date"):
|
|
"""Return one date per row, asserting every one of them is a real date."""
|
|
dates = [getattr(row, field) for row in rows]
|
|
assert dates
|
|
assert all(isinstance(value, date) for value in dates)
|
|
|
|
return dates
|
|
|
|
|
|
def assert_oldest_first(dates):
|
|
"""Assert the observations are ordered oldest first."""
|
|
assert list(dates) == sorted(dates)
|
|
|
|
|
|
def assert_newest_first(dates):
|
|
"""Assert the observations are ordered newest first."""
|
|
assert list(dates) == sorted(dates, reverse=True)
|
|
|
|
|
|
def assert_inside_window(dates, params):
|
|
"""Assert every observation falls inside the window the query asked for."""
|
|
start = params.get("start_date")
|
|
end = params.get("end_date")
|
|
|
|
if start:
|
|
assert min(dates) >= date.fromisoformat(start)
|
|
|
|
if end:
|
|
assert max(dates) <= date.fromisoformat(end)
|
|
|
|
|
|
def assert_finite(values, low, high):
|
|
"""Assert the published numbers are finite and inside a plausible band.
|
|
|
|
Parameters
|
|
----------
|
|
values : list
|
|
The values read off the rows, nulls included.
|
|
low : float
|
|
The lowest value the field can plausibly carry.
|
|
high : float
|
|
The highest value the field can plausibly carry.
|
|
|
|
Returns
|
|
-------
|
|
list
|
|
The values that were actually published.
|
|
"""
|
|
seen = [value for value in values if value is not None]
|
|
assert all(isinstance(value, (int, float)) for value in seen)
|
|
assert all(isfinite(value) for value in seen)
|
|
assert all(low <= value <= high for value in seen)
|
|
|
|
return seen
|
|
|
|
|
|
def assert_months(dates, requested):
|
|
"""Assert every observation falls in one of the months the query asked for."""
|
|
months = {tuple(entry[:7].split("-")) for entry in observation_dates(requested)}
|
|
assert {(f"{value.year:04d}", f"{value.month:02d}") for value in dates} <= months
|
|
|
|
|
|
def median_gap(dates):
|
|
"""Return the median number of days between consecutive observations."""
|
|
ordered = sorted(set(dates))
|
|
assert len(ordered) > 1
|
|
|
|
return median(
|
|
(later - earlier).days for earlier, later in zip(ordered, ordered[1:])
|
|
)
|
|
|
|
|
|
def band_for(params, tight):
|
|
"""Return the band a field sits in, widened when the query transforms it."""
|
|
return WIDE_BAND if params.get("transform") in TRANSFORMS else tight
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def obb(pytestconfig):
|
|
"""Fixture to setup obb."""
|
|
if pytestconfig.getoption("markexpr") != "not integration":
|
|
import openbb
|
|
|
|
return openbb.obb
|
|
return None
|
|
|
|
|
|
class TestCommodityPrice:
|
|
"""Test the commodity price commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"commodity": "all",
|
|
"start_date": None,
|
|
"end_date": None,
|
|
"frequency": None,
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"commodity": "wti",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "avg",
|
|
"transform": "pc1",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_commodity_spot_prices_are_returned(self, params, obb):
|
|
"""Test the commodity price spot command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.commodity.price.spot(**params)
|
|
commodity = params.get("commodity", "all")
|
|
rows = results_of(result, FredCommoditySpotPricesData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.symbol for row in rows} <= set(SERIES_MAP[commodity].split(","))
|
|
assert all(row.commodity for row in rows)
|
|
assert assert_finite(
|
|
[row.price for row in rows], *band_for(params, POSITIVE_BAND)
|
|
)
|
|
|
|
if params.get("frequency") == "m":
|
|
assert len(rows) <= 13
|
|
else:
|
|
assert len(rows) > 100
|
|
|
|
|
|
class TestEconomy:
|
|
"""Test the economy commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"country": "united_states",
|
|
"start_date": None,
|
|
"end_date": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"country": "japan",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2023-12-31",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_balance_of_payments_is_returned(self, params, obb):
|
|
"""Test the economy balance_of_payments command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.balance_of_payments(**params)
|
|
rows = results_of(result, FredBalanceOfPaymentsData)
|
|
periods = dates_of(rows, "period")
|
|
|
|
assert_newest_first(periods)
|
|
assert_inside_window(periods, params)
|
|
assert median_gap(periods) >= 80
|
|
assert assert_finite(
|
|
[row.balance_total for row in rows]
|
|
+ [row.credits_total for row in rows]
|
|
+ [row.debits_total for row in rows],
|
|
*WIDE_BAND,
|
|
)
|
|
assert_finite(
|
|
[row.balance_percent_of_gdp for row in rows],
|
|
-200.0,
|
|
200.0,
|
|
)
|
|
|
|
if params.get("start_date"):
|
|
assert len(rows) <= 24
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2025-07-01",
|
|
"end_date": "2025-07-02",
|
|
"release_id": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2024-01-02",
|
|
"end_date": "2024-01-09",
|
|
"release_id": 10,
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_calendar_is_returned(self, params, obb):
|
|
"""Test the economy calendar command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.calendar(**params)
|
|
rows = results_of(result, FredEconomicCalendarData)
|
|
stamps = [row.date for row in rows]
|
|
|
|
assert all(isinstance(stamp, datetime) for stamp in stamps)
|
|
assert_inside_window([stamp.date() for stamp in stamps], params)
|
|
assert all(row.event for row in rows)
|
|
assert all(isinstance(row.release_id, int) for row in rows)
|
|
|
|
if params.get("release_id"):
|
|
assert {row.release_id for row in rows} == {params["release_id"]}
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"country": "united_states", "provider": "fred"},
|
|
{
|
|
"country": "spain",
|
|
"transform": "yoy",
|
|
"frequency": "annual",
|
|
"harmonized": False,
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2023-06-06",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"country": "portugal,spain",
|
|
"transform": "period",
|
|
"frequency": "monthly",
|
|
"harmonized": True,
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_cpi_is_returned(self, params, obb):
|
|
"""Test the economy cpi command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.cpi(**params)
|
|
rows = results_of(result, FREDConsumerPriceIndexData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.country for row in rows} <= set(params["country"].split(","))
|
|
assert assert_finite([row.value for row in rows], *PERCENT_BAND)
|
|
|
|
if params.get("frequency") == "annual":
|
|
assert len(rows) <= 8
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"symbol": "NYUR", "provider": "fred"},
|
|
{
|
|
"symbol": "CAICLAIMS",
|
|
"is_series_group": False,
|
|
"start_date": "1990-01-01",
|
|
"end_date": "2010-01-01",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"symbol": "156241",
|
|
"is_series_group": True,
|
|
"start_date": "2000-01-01",
|
|
"end_date": None,
|
|
"frequency": "w",
|
|
"units": "Number",
|
|
"region_type": "state",
|
|
"season": "nsa",
|
|
"aggregation_method": "eop",
|
|
"transform": "ch1",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_fred_regional_is_returned(self, params, obb):
|
|
"""Test the economy fred_regional command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.fred_regional(**params)
|
|
rows = results_of(result, FredRegionalData)
|
|
dates = dates_of(rows)
|
|
|
|
assert all(isinstance(row.region, str) and row.region for row in rows)
|
|
assert all(isinstance(row.series_id, str) and row.series_id for row in rows)
|
|
assert all(row.code not in (None, "") for row in rows)
|
|
assert assert_finite([row.value for row in rows], *WIDE_BAND)
|
|
|
|
if params.get("end_date"):
|
|
assert max(dates) <= date.fromisoformat(params["end_date"])
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"release_id": "50", "provider": "fred"},
|
|
{"release_id": "14", "element_id": "7930", "provider": "fred"},
|
|
{
|
|
"release_id": "53",
|
|
"element_id": "12883",
|
|
"date": "2023-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_fred_release_table_is_returned(self, params, obb):
|
|
"""Test the economy fred_release_table command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.fred_release_table(**params)
|
|
rows = results_of(result, FredReleaseTableData)
|
|
keys = [
|
|
(str(row.date or ""), inf if row.line is None else row.line) for row in rows
|
|
]
|
|
|
|
assert keys == sorted(keys)
|
|
assert all(row.element_id for row in rows)
|
|
assert all(row.name for row in rows)
|
|
assert_finite([row.value for row in rows], *WIDE_BAND)
|
|
|
|
observed = [row for row in rows if row.symbol]
|
|
|
|
if observed:
|
|
assert all(isinstance(row.date, date) for row in observed)
|
|
assert all(row.value is not None for row in observed)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{"query": "gdp", "provider": "fred"},
|
|
{
|
|
"query": "GDP*",
|
|
"search_type": "series_id",
|
|
"release_id": None,
|
|
"offset": 0,
|
|
"limit": 10,
|
|
"order_by": "observation_end",
|
|
"sort_order": "desc",
|
|
"filter_variable": None,
|
|
"filter_value": None,
|
|
"tag_names": None,
|
|
"exclude_tag_names": None,
|
|
"series_id": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"query": None,
|
|
"search_type": "release",
|
|
"release_id": 10,
|
|
"limit": 10,
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
{"series_id": "NYICLAIMS", "provider": "fred"},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_fred_search_is_returned(self, params, obb):
|
|
"""Test the economy fred_search command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.fred_search(**params)
|
|
rows = results_of(result, FredSearchData)
|
|
ends = [row.observation_end for row in rows]
|
|
|
|
if params.get("limit"):
|
|
assert len(rows) <= params["limit"]
|
|
|
|
if all(end is not None for end in ends):
|
|
assert ends == sorted(ends, reverse=True)
|
|
|
|
if params.get("series_id"):
|
|
assert {row.series_id for row in rows} == {params["series_id"]}
|
|
assert all(row.series_group for row in rows)
|
|
elif params.get("release_id"):
|
|
assert all(row.series_id for row in rows)
|
|
elif params.get("query"):
|
|
assert all(row.series_id for row in rows)
|
|
|
|
if params.get("search_type") != "series_id":
|
|
term = params["query"].lower()
|
|
assert all(
|
|
term in " ".join(str(v) for v in row.model_dump().values()).lower()
|
|
for row in rows
|
|
)
|
|
else:
|
|
assert all(row.release_id for row in rows)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"symbol": "GDP", "provider": "fred"},
|
|
{
|
|
"symbol": "SP500",
|
|
"start_date": None,
|
|
"end_date": None,
|
|
"limit": 10000,
|
|
"frequency": "q",
|
|
"aggregation_method": "eop",
|
|
"transform": "chg",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"symbol": "GDP,UNRATE",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_fred_series_is_returned(self, params, obb):
|
|
"""Test the economy fred_series command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.fred_series(**params)
|
|
rows = results_of(result, FredSeriesData)
|
|
dates = dates_of(rows)
|
|
symbols = params["symbol"].split(",")
|
|
carried = {key.lower().replace("_", "") for key in rows[0].model_dump()}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {symbol.lower().replace("_", "") for symbol in symbols} <= carried
|
|
assert assert_finite(
|
|
[
|
|
value
|
|
for row in rows
|
|
for key, value in row.model_dump().items()
|
|
if key != "date"
|
|
],
|
|
*WIDE_BAND,
|
|
)
|
|
|
|
if params.get("limit"):
|
|
assert len(rows) <= params["limit"]
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"date": "2024-05-01,2024-04-01,2023-05-01",
|
|
"category": "pce_price_index",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"date": "2024-06-01",
|
|
"category": "real_pce_percent_change",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_pce_is_returned(self, params, obb):
|
|
"""Test the economy pce command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.pce(**params)
|
|
rows = results_of(result, FredPersonalConsumptionExpendituresData)
|
|
dates = dates_of(rows)
|
|
keys = [(row.date, row.line) for row in rows]
|
|
|
|
assert keys == sorted(keys)
|
|
assert all(row.symbol and row.name and row.units for row in rows)
|
|
assert all(row.element_id and row.parent_id for row in rows)
|
|
assert all(isinstance(row.level, int) for row in rows)
|
|
assert assert_finite([row.value for row in rows], *WIDE_BAND)
|
|
|
|
if params.get("date"):
|
|
assert_months(dates, params["date"])
|
|
assert len(set(dates)) <= len(observation_dates(params["date"]))
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{},
|
|
{"release_id": "9", "element_id": "201241"},
|
|
{
|
|
"release_id": "9",
|
|
"element_id": "201241",
|
|
"frequency": "monthly",
|
|
"limit": 4,
|
|
"use_cache": False,
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_release_table_is_returned(self, params, obb):
|
|
"""Test the economy release_table command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.release_table(**params)
|
|
fixed = {"series", "symbol", "units", "trend"}
|
|
|
|
assert isinstance(result, list)
|
|
assert len(result) > 0
|
|
assert all(isinstance(row, dict) for row in result)
|
|
assert all(fixed <= set(row) for row in result)
|
|
assert all(row["series"] for row in result)
|
|
|
|
periods = [key for key in result[0] if key not in fixed]
|
|
|
|
assert periods
|
|
assert len(periods) <= params.get("limit", 8)
|
|
assert all(date.fromisoformat(period) for period in periods)
|
|
assert all(set(row) - fixed == set(periods) for row in result)
|
|
|
|
observed = [row for row in result if row["symbol"]]
|
|
|
|
assert observed
|
|
assert all(isinstance(row["trend"], list) and row["trend"] for row in observed)
|
|
assert assert_finite(
|
|
[value for row in observed for value in row["trend"]], *WIDE_BAND
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"country": "united_states",
|
|
"item": "meats",
|
|
"region": "all_city",
|
|
"frequency": "annual",
|
|
"start_date": "2022-01-01",
|
|
"end_date": "2024-04-01",
|
|
"transform": "pc1",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"item": "eggs",
|
|
"region": "northeast",
|
|
"frequency": "monthly",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_retail_prices_are_returned(self, params, obb):
|
|
"""Test the economy retail_prices command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.retail_prices(**params)
|
|
rows = results_of(result, FredRetailPricesData)
|
|
dates = dates_of(rows)
|
|
keys = [(row.date, row.description) for row in rows]
|
|
|
|
assert keys == sorted(keys)
|
|
assert_inside_window(dates, params)
|
|
assert {row.country for row in rows} == {"united_states"}
|
|
assert all(row.symbol and row.description for row in rows)
|
|
assert assert_finite(
|
|
[row.value for row in rows], *band_for(params, POSITIVE_BAND)
|
|
)
|
|
|
|
|
|
class TestEconomySurvey:
|
|
"""Test the economy survey commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2024-01-01",
|
|
"end_date": "2024-04-01",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "quarter",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_economic_conditions_chicago_is_returned(self, params, obb):
|
|
"""Test the economy survey economic_conditions_chicago command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.economic_conditions_chicago(**params)
|
|
rows = results_of(result, FredSurveyOfEconomicConditionsChicagoData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite(
|
|
[row.activity_index for row in rows]
|
|
+ [row.one_year_outlook for row in rows]
|
|
+ [row.current_hiring for row in rows],
|
|
*band_for(params, PERCENT_BAND),
|
|
)
|
|
|
|
if params.get("frequency") == "quarter":
|
|
assert len(rows) <= 20
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"topic": "new_orders",
|
|
"start_date": "2024-01-01",
|
|
"end_date": "2024-04-01",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"topic": "business_outlook,employment",
|
|
"seasonally_adjusted": True,
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "quarter",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_manufacturing_outlook_ny_is_returned(self, params, obb):
|
|
"""Test the economy survey manufacturing_outlook_ny command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.manufacturing_outlook_ny(**params)
|
|
rows = results_of(result, FredManufacturingOutlookNYData)
|
|
dates = dates_of(rows)
|
|
topics = params.get("topic", "new_orders").split(",")
|
|
expected = {
|
|
f"{side}_{topic}" for topic in topics for side in ("current", "future")
|
|
}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.topic for row in rows} <= expected
|
|
assert assert_finite(
|
|
[row.diffusion_index for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
assert_finite(
|
|
[row.percent_reporting_increase for row in rows]
|
|
+ [row.percent_reporting_decrease for row in rows]
|
|
+ [row.percent_reporting_no_change for row in rows],
|
|
*band_for(params, (0.0, 100.0)),
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"topic": "new_orders",
|
|
"start_date": "2024-01-01",
|
|
"end_date": "2024-04-01",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"topic": "business_activity,production",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "annual",
|
|
"aggregation_method": "eop",
|
|
"transform": "ch1",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_manufacturing_outlook_texas_is_returned(self, params, obb):
|
|
"""Test the economy survey manufacturing_outlook_texas command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.manufacturing_outlook_texas(**params)
|
|
rows = results_of(result, FredManufacturingOutlookTexasData)
|
|
dates = dates_of(rows)
|
|
topics = params.get("topic", "new_orders_growth").split(",")
|
|
expected = {
|
|
f"{side}_{topic}" for topic in topics for side in ("current", "future")
|
|
}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.topic for row in rows} <= expected
|
|
assert assert_finite(
|
|
[row.diffusion_index for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
if params.get("frequency") == "annual":
|
|
assert len(rows) <= 5 * len(expected)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"date": "2024-06-01,2023-06-01",
|
|
"category": "avg_earnings_hourly",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"date": "2024-06-01",
|
|
"category": "employees_sa",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_nonfarm_payrolls_are_returned(self, params, obb):
|
|
"""Test the economy survey nonfarm_payrolls command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.nonfarm_payrolls(**params)
|
|
rows = results_of(result, FredNonFarmPayrollsData)
|
|
dates = dates_of(rows)
|
|
category = params.get("category", "employees_nsa")
|
|
|
|
assert_oldest_first(dates)
|
|
assert all(row.symbol and row.name for row in rows)
|
|
assert all(row.element_id and row.parent_id for row in rows)
|
|
assert all(isinstance(row.level, int) for row in rows)
|
|
|
|
if category.startswith("employees") and not category.endswith("percent"):
|
|
assert assert_finite([row.value for row in rows], *COUNT_BAND)
|
|
else:
|
|
assert assert_finite([row.value for row in rows], *WIDE_BAND)
|
|
|
|
if params.get("date"):
|
|
assert_months(dates, params["date"])
|
|
assert len(set(dates)) <= len(observation_dates(params["date"]))
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"category": "auto",
|
|
"start_date": "2022-01-01",
|
|
"end_date": "2024-04-01",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"category": "credit_card",
|
|
"transform": "pch",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_sloos_is_returned(self, params, obb):
|
|
"""Test the economy survey sloos command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.sloos(**params)
|
|
rows = results_of(result, FredSeniorLoanOfficerSurveyData)
|
|
dates = dates_of(rows)
|
|
wanted = SLOOS_CATEGORIES[params.get("category", "spreads")].split(",")
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.symbol for row in rows} <= set(wanted)
|
|
assert all(row.title for row in rows)
|
|
assert assert_finite(
|
|
[row.value for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"frequency": None,
|
|
"start_date": "2022-01-01",
|
|
"end_date": "2024-04-01",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"frequency": "quarter",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_university_of_michigan_is_returned(self, params, obb):
|
|
"""Test the economy survey university_of_michigan command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.economy.survey.university_of_michigan(**params)
|
|
rows = results_of(result, FredUofMichiganData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite(
|
|
[row.consumer_sentiment for row in rows], *band_for(params, (0.0, 200.0))
|
|
)
|
|
assert assert_finite(
|
|
[row.inflation_expectation for row in rows],
|
|
*band_for(params, PERCENT_BAND),
|
|
)
|
|
|
|
if params.get("frequency") == "quarter":
|
|
assert len(rows) <= 20
|
|
|
|
|
|
class TestFixedIncome:
|
|
"""Test the top-level fixed income commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"category": "high_yield",
|
|
"index": "us,europe,emerging",
|
|
"index_type": "total_return",
|
|
"start_date": "2023-05-31",
|
|
"end_date": "2024-06-01",
|
|
"transform": None,
|
|
"frequency": None,
|
|
"aggregation_method": "avg",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"category": "us",
|
|
"index": "corporate",
|
|
"index_type": "oas",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "eop",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_bond_indices_are_returned(self, params, obb):
|
|
"""Test the fixedincome bond_indices command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.bond_indices(**params)
|
|
rows = results_of(result, FredBondIndicesData)
|
|
dates = dates_of(rows)
|
|
index = params.get("index", "yield_curve")
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert all(row.title for row in rows)
|
|
|
|
if index == "yield_curve":
|
|
maturities = set(BAML_CATEGORIES[params.get("category", "us")][index])
|
|
assert {row.maturity for row in rows} <= maturities
|
|
else:
|
|
assert {row.maturity for row in rows} == {None}
|
|
|
|
if params.get("index_type") == "total_return":
|
|
assert assert_finite([row.value for row in rows], *INDEX_BAND)
|
|
else:
|
|
assert assert_finite([row.value for row in rows], *PERCENT_BAND)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"index": "usda_30y,fha_30y",
|
|
"start_date": "2023-05-31",
|
|
"end_date": "2024-06-01",
|
|
"transform": None,
|
|
"frequency": None,
|
|
"aggregation_method": "avg",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"index": "conforming_30y",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "eop",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_mortgage_indices_are_returned(self, params, obb):
|
|
"""Test the fixedincome mortgage_indices command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.mortgage_indices(**params)
|
|
rows = results_of(result, FredMortgageIndicesData)
|
|
dates = dates_of(rows)
|
|
wanted = {
|
|
symbol
|
|
for index in params.get("index", "primary").split(",")
|
|
for symbol in MORTGAGE_CHOICES_TO_ID[index].split(",")
|
|
}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.symbol for row in rows} <= wanted
|
|
assert all(row.name for row in rows)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
|
|
class TestFixedIncomeCorporate:
|
|
"""Test the corporate bond commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"maturity": "overnight",
|
|
"category": "financial",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"maturity": "30d",
|
|
"category": "asset_backed",
|
|
"frequency": "m",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_commercial_paper_is_returned(self, params, obb):
|
|
"""Test the fixedincome corporate commercial_paper command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.corporate.commercial_paper(**params)
|
|
rows = results_of(result, FREDCommercialPaperData)
|
|
dates = dates_of(rows)
|
|
maturity = params.get("maturity", "all")
|
|
category = params.get("category", "all")
|
|
published = {
|
|
(entry["maturity"], entry["asset"]) for entry in CP_SERIES_IDS.values()
|
|
}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {(row.maturity, row.asset_type) for row in rows} <= published
|
|
assert all(row.title for row in rows)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
if category != "all":
|
|
assert {row.asset_type for row in rows} == set(category.split(","))
|
|
|
|
if maturity != "all":
|
|
assert {row.maturity for row in rows} == {
|
|
entry if entry == "overnight" else f"day_{entry.rstrip('d')}"
|
|
for entry in maturity.split(",")
|
|
}
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{"date": "2023-01-01", "yield_curve": "spot", "provider": "fred"},
|
|
{
|
|
"date": "2023-01-01,2024-01-01",
|
|
"yield_curve": "par",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_hqm_is_returned(self, params, obb):
|
|
"""Test the fixedincome corporate hqm command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.corporate.hqm(**params)
|
|
rows = results_of(result, FredHighQualityMarketCorporateBondData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert all(row.maturity.startswith("year_") for row in rows)
|
|
assert all(float(row.maturity[len("year_") :]) > 0 for row in rows)
|
|
assert assert_finite([row.rate for row in rows], *PERCENT_BAND)
|
|
assert 1 <= len(set(dates)) <= len(observation_dates(params.get("date")))
|
|
|
|
if params.get("date"):
|
|
assert_months(dates, params["date"])
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"maturity": "10",
|
|
"category": "spot_rate",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": None,
|
|
"end_date": None,
|
|
"maturity": "1,5.5,10",
|
|
"category": "spot_rate,par_yield",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_spot_rates_are_returned(self, params, obb):
|
|
"""Test the fixedincome corporate spot_rates command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.corporate.spot_rates(**params)
|
|
rows = results_of(result, FREDSpotRateData)
|
|
dates = dates_of(rows)
|
|
labels = {"spot_rate": "Spot Rate", "par_yield": "Par Yield"}
|
|
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite([row.rate for row in rows], *PERCENT_BAND)
|
|
assert all("High Quality Market (HQM)" in row.title for row in rows)
|
|
|
|
if params.get("maturity"):
|
|
heads = tuple(
|
|
f"{entry}-Year" for entry in str(params["maturity"]).split(",")
|
|
)
|
|
assert all(row.title.startswith(heads) for row in rows)
|
|
|
|
if params.get("category"):
|
|
wanted = {labels[entry] for entry in str(params["category"]).split(",")}
|
|
assert {row.title.rsplit("Bond ", 1)[-1] for row in rows} == wanted
|
|
|
|
|
|
class TestFixedIncomeGovernment:
|
|
"""Test the government bond commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"maturity": None,
|
|
"start_date": None,
|
|
"end_date": None,
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"maturity": "10",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "eop",
|
|
"transform": "pc1",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_tips_yields_are_returned(self, params, obb):
|
|
"""Test the fixedincome government tips_yields command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.government.tips_yields(**params)
|
|
rows = results_of(result, FredTipsYieldsData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert all(row.symbol.startswith("DTP") for row in rows)
|
|
assert all(isinstance(row.due, date) for row in rows)
|
|
assert all(row.name for row in rows)
|
|
assert assert_finite(
|
|
[row.value for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
if params.get("maturity"):
|
|
assert all(
|
|
row.symbol.rsplit("DTP", 1)[-1].startswith(params["maturity"])
|
|
for row in rows
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"yield_curve_type": "nominal",
|
|
"date": "2023-05-01,2024-05-01",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"yield_curve_type": "real",
|
|
"date": None,
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_yield_curve_is_returned(self, params, obb):
|
|
"""Test the fixedincome government yield_curve command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.government.yield_curve(**params)
|
|
rows = results_of(result, FREDYieldCurveData)
|
|
dates = dates_of(rows)
|
|
curve = params.get("yield_curve_type", "nominal")
|
|
maturities = set(YIELD_CURVES[curve].values())
|
|
wanted = len(str(params["date"]).split(",")) if params.get("date") else 1
|
|
published = [
|
|
value
|
|
for value in (row.model_dump()["rate"] for row in rows)
|
|
if value is not None and isfinite(value)
|
|
]
|
|
|
|
assert_oldest_first(dates)
|
|
assert {row.maturity for row in rows} <= maturities
|
|
assert len(set(dates)) == wanted
|
|
assert len(rows) == wanted * len({row.maturity for row in rows})
|
|
assert published
|
|
assert all(PERCENT_BAND[0] <= value <= PERCENT_BAND[1] for value in published)
|
|
|
|
|
|
class TestFixedIncomeRate:
|
|
"""Test the reference rate commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"maturity": "overnight",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"maturity": "average_30d,term_90d",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_ameribor_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate ameribor command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.ameribor(**params)
|
|
rows = results_of(result, FredAmeriborData)
|
|
dates = dates_of(rows)
|
|
wanted = {
|
|
symbol
|
|
for entry in params.get("maturity", "all").split(",")
|
|
for symbol in MATURITY_TO_FRED_ID[entry].split(",")
|
|
}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert {row.symbol for row in rows} <= wanted
|
|
assert {row.maturity for row in rows} <= {"overnight", "day_30", "day_90"}
|
|
assert all(row.title for row in rows)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"parameter": "daily_excl_weekend",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"parameter": "weekly",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_dpcredit_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate dpcredit command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.dpcredit(**params)
|
|
rows = results_of(result, FREDDiscountWindowPrimaryCreditRateData)
|
|
dates = dates_of(rows)
|
|
cadence = {"daily_excl_weekend": (1, 4), "weekly": (6, 8)}
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], 0.0, 25.0)
|
|
|
|
low, high = cadence[params.get("parameter", "daily_excl_weekend")]
|
|
assert low <= median_gap(dates) <= high
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"interest_rate_type": "lending",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"interest_rate_type": "deposit",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_ecb_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate ecb command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.ecb(**params)
|
|
rows = results_of(result, FREDEuropeanCentralBankInterestRatesData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], -5.0, 25.0)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"frequency": "w",
|
|
"transform": None,
|
|
"aggregation_method": "avg",
|
|
"effr_only": False,
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"effr_only": True,
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_effr_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate effr command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.effr(**params)
|
|
rows = results_of(result, FredFederalFundsRateData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite([row.rate for row in rows], *PERCENT_BAND)
|
|
|
|
if params.get("effr_only"):
|
|
assert {row.target_range_upper for row in rows} == {None}
|
|
assert {row.volume for row in rows} == {None}
|
|
else:
|
|
assert assert_finite(
|
|
[row.target_range_upper for row in rows]
|
|
+ [row.target_range_lower for row in rows],
|
|
*PERCENT_BAND,
|
|
)
|
|
assert assert_finite(
|
|
[row.volume for row in rows], *band_for(params, COUNT_BAND)
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{"long_run": False, "provider": "fred"},
|
|
{"long_run": True, "use_cache": False, "provider": "fred"},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_effr_forecast_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate effr_forecast command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.effr_forecast(**params)
|
|
rows = results_of(result, FREDPROJECTIONData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert assert_finite(
|
|
[row.median for row in rows]
|
|
+ [row.range_high for row in rows]
|
|
+ [row.range_low for row in rows],
|
|
-5.0,
|
|
25.0,
|
|
)
|
|
assert all(
|
|
row.range_low <= row.median <= row.range_high
|
|
for row in rows
|
|
if None not in (row.range_low, row.median, row.range_high)
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_estr_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate estr command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.estr(**params)
|
|
rows = results_of(result, FredEuroShortTermRateData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
assert_finite(
|
|
[row.number_of_banks for row in rows], *band_for(params, (0.0, 1000.0))
|
|
)
|
|
assert_finite([row.transactions for row in rows], *band_for(params, COUNT_BAND))
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{"start_date": "2023-01-01", "end_date": "2023-06-06", "provider": "fred"},
|
|
{
|
|
"start_date": "2021-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_iorb_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate iorb command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.iorb(**params)
|
|
rows = results_of(result, FREDIORBData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], 0.0, 25.0)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"frequency": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "eop",
|
|
"transform": "chg",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_overnight_bank_funding_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate overnight_bank_funding command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.overnight_bank_funding(**params)
|
|
rows = results_of(result, FredOvernightBankFundingRateData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
assert_finite(
|
|
[row.percentile_1 for row in rows] + [row.percentile_99 for row in rows],
|
|
*band_for(params, PERCENT_BAND),
|
|
)
|
|
assert_finite([row.volume for row in rows], *band_for(params, COUNT_BAND))
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"frequency": None,
|
|
"transform": None,
|
|
"aggregation_method": None,
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2024-01-01",
|
|
"frequency": "m",
|
|
"aggregation_method": "avg",
|
|
"transform": "pch",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_sofr_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate sofr command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.sofr(**params)
|
|
rows = results_of(result, FREDSOFRData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert assert_finite(
|
|
[row.rate for row in rows], *band_for(params, PERCENT_BAND)
|
|
)
|
|
assert_finite(
|
|
[row.average_30d for row in rows] + [row.average_180d for row in rows],
|
|
*band_for(params, PERCENT_BAND),
|
|
)
|
|
assert_finite([row.volume for row in rows], *band_for(params, COUNT_BAND))
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"parameter": "rate",
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"parameter": "index",
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_sonia_is_returned(self, params, obb):
|
|
"""Test the fixedincome rate sonia command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.rate.sonia(**params)
|
|
rows = results_of(result, FREDSONIAData)
|
|
dates = dates_of(rows)
|
|
rates = [row.rate for row in rows]
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
|
|
if params.get("parameter") == "index":
|
|
assert assert_finite(rates, 0.0, 1.0e6)
|
|
else:
|
|
assert assert_finite(rates, -5.0, 25.0)
|
|
|
|
|
|
class TestFixedIncomeSpreads:
|
|
"""Test the rate spread commands the FRED router serves."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"maturity": "3m",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"maturity": "2y",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_tcm_is_returned(self, params, obb):
|
|
"""Test the fixedincome spreads tcm command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.spreads.tcm(**params)
|
|
rows = results_of(result, FREDTreasuryConstantMaturityData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], -25.0, 25.0)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"maturity": "10y",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"maturity": "6m",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_tcm_effr_is_returned(self, params, obb):
|
|
"""Test the fixedincome spreads tcm_effr command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.spreads.tcm_effr(**params)
|
|
rows = results_of(result, FREDSelectedTreasuryConstantMaturityData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], -25.0, 25.0)
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
[
|
|
{"provider": "fred"},
|
|
{
|
|
"start_date": "2023-01-01",
|
|
"end_date": "2023-06-06",
|
|
"maturity": "3m",
|
|
"provider": "fred",
|
|
},
|
|
{
|
|
"start_date": "2020-01-01",
|
|
"end_date": "2024-01-01",
|
|
"maturity": "6m",
|
|
"use_cache": False,
|
|
"provider": "fred",
|
|
},
|
|
],
|
|
)
|
|
@pytest.mark.integration
|
|
def test_treasury_effr_is_returned(self, params, obb):
|
|
"""Test the fixedincome spreads treasury_effr command."""
|
|
params = {p: v for p, v in params.items() if v is not None}
|
|
|
|
result = obb.fred.fixedincome.spreads.treasury_effr(**params)
|
|
rows = results_of(result, FREDSelectedTreasuryBillData)
|
|
dates = dates_of(rows)
|
|
|
|
assert_oldest_first(dates)
|
|
assert_inside_window(dates, params)
|
|
assert len(set(dates)) == len(dates)
|
|
assert assert_finite([row.rate for row in rows], -25.0, 25.0)
|