diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-06-10 11:24:52 -0700 |
---|---|---|
committer | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-06-10 11:24:52 -0700 |
commit | 8fca1ba3d5c743c54b4d37dffb326ab936d7201d (patch) | |
tree | d31e3aadbd877265b3baf65acb157f60fa442890 | |
parent | 81e6ed7bc7e3ba47981667d488e9cc08bef45739 (diff) |
add overnight bank funding rate
10 files changed, 1343 insertions, 0 deletions
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/overnight_bank_funding_rate.py b/openbb_platform/core/openbb_core/provider/standard_models/overnight_bank_funding_rate.py new file mode 100644 index 00000000000..51afa516840 --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/overnight_bank_funding_rate.py @@ -0,0 +1,65 @@ +"""Overnight Bank Funding Rate Standard Model.""" + +from datetime import date as dateType +from typing import Optional + +from pydantic import Field + +from openbb_core.provider.abstract.data import Data +from openbb_core.provider.abstract.query_params import QueryParams +from openbb_core.provider.utils.descriptions import ( + DATA_DESCRIPTIONS, + QUERY_DESCRIPTIONS, +) + + +class OvernightBankFundingRateQueryParams(QueryParams): + """Overnight Bank Funding Rate Query.""" + + start_date: Optional[dateType] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("start_date", ""), + ) + end_date: Optional[dateType] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("end_date", ""), + ) + + +class OvernightBankFundingRateData(Data): + """Overnight Bank Funding Rate Data.""" + + date: dateType = Field(description=DATA_DESCRIPTIONS.get("date", "")) + rate: float = Field( + description="Overnight Bank Funding Rate.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + percentile_1: Optional[float] = Field( + default=None, + description="1st percentile of the distribution.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + percentile_25: Optional[float] = Field( + default=None, + description="25th percentile of the distribution.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + percentile_75: Optional[float] = Field( + default=None, + description="75th percentile of the distribution.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + percentile_99: Optional[float] = Field( + default=None, + description="99th percentile of the distribution.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + volume: Optional[float] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("volume", "") + + "The notional volume of transactions (Billions of $).", + json_schema_extra={ + "x-unit_measurement": "currency", + "x-frontend_multiply": 1e9, + }, + ) diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py index fec1db5ba7e..89819f95093 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py @@ -743,3 +743,30 @@ def test_fixedincome_bond_indices(params, headers): result = requests.get(url, headers=headers, timeout=10) assert isinstance(result, requests.Response) assert result.status_code == 200 + + +@parametrize( + "params", + [ + ( + { + "start_date": "2023-01-01", + "end_date": "2023-06-06", + "transform": None, + "aggregation_method": None, + "frequency": None, + "provider": "fred", + } + ), + ], +) +@pytest.mark.integration +def test_fixedincome_rate_overnight_bank_funding(params, headers): + """Test the Overnight Bank Funding Rate endpoint.""" + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://0.0.0.0:8000/api/v1/fixedincome/rate/overnight_bank_funding?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py index ce61157def8..9a3b01721ff 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py @@ -693,3 +693,27 @@ def test_fixedincome_bond_indices(params, obb): assert result assert isinstance(result, OBBject) assert len(result.results) > 0 + + +@parametrize( + "params", + [ + ( + { + "start_date": "2023-01-01", + "end_date": "2023-06-06", + "transform": None, + "aggregation_method": None, + "frequency": None, + "provider": "fred", + } + ), + ], +) +@pytest.mark.integration +def test_fixedincome_rate_overnight_bank_funding(params, obb): + """Test the Overnight Bank Funding Rate endpoint.""" + result = obb.fixedincome.rate.overnight_bank_funding(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py index bc521a30f71..adca399dd24 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py @@ -221,3 +221,22 @@ async def dpcredit( also known as the discount rate. """ return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="OvernightBankFundingRate", + examples=[APIEx(parameters={"provider": "fred"})], +) +async def overnight_bank_funding( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: # type: ignore + """Overnight Bank Funding. + + For the United States, the overnight bank funding rate (OBFR) is calculated as a volume-weighted median of + overnight federal funds transactions and Eurodollar transactions reported in the + FR 2420 Report of Selected Money Market Rates. + """ + return await OBBject.from_query(Query(**locals())) diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json index 906b2d8f50a..87258a2a9dc 100644 --- a/openbb_platform/openbb/assets/reference.json +++ b/openbb_platform/openbb/assets/reference.json @@ -31101,6 +31101,185 @@ }, "model": "DiscountWindowPrimaryCreditRate" }, + "/fixedincome/rate/overnight_bank_funding": { + "deprecated": { + "flag": null, + "message": null + }, + "description": "Overnight Bank Funding.\n\nFor the United States, the overnight bank funding rate (OBFR) is calculated as a volume-weighted median of\novernight federal funds transactions and Eurodollar transactions reported in the\nFR 2420 Report of Selected Money Market Rates.", + "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.fixedincome.rate.overnight_bank_funding(provider='fred')\n```\n\n", + "parameters": { + "standard": [ + { + "name": "start_date", + "type": "Union[date, str]", + "description": "Start date of the data, in YYYY-MM-DD format.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "end_date", + "type": "Union[date, str]", + "description": "End date of the data, in YYYY-MM-DD format.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "provider", + "type": "Literal['fred']", + "description": "The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: f, r, e, d.", + "default": null, + "optional": true + } + ], + "fred": [ + { + "name": "frequency", + "type": "Literal['a', 'q', 'm', 'w', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem']", + "description": "Frequency aggregation to convert daily data to lower frequency. a = Annual q = Quarterly m = Monthly w = Weekly wef = Weekly, Ending Friday weth = Weekly, Ending Thursday wew = Weekly, Ending Wednesday wetu = Weekly, Ending Tuesday wem = Weekly, Ending Monday wesu = Weekly, Ending Sunday wesa = Weekly, Ending Saturday bwew = Biweekly, Ending Wednesday bwem = Biweekly, Ending Monday", + "default": null, + "optional": true, + "choices": [ + "a", + "q", + "m", + "w", + "wef", + "weth", + "wew", + "wetu", + "wem", + "wesu", + "wesa", + "bwew", + "bwem" + ] + }, + { + "name": "aggregation_method", + "type": "Literal['avg', 'sum', 'eop']", + "description": "A key that indicates the aggregation method used for frequency aggregation. avg = Average sum = Sum eop = End of Period", + "default": null, + "optional": true, + "choices": [ + "avg", + "sum", + "eop" + ] + }, + { + "name": "transform", + "type": "Literal['chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log']", + "description": "Transformation type None = No transformation chg = Change ch1 = Change from Year Ago pch = Percent Change pc1 = Percent Change from Year Ago pca = Compounded Annual Rate of Change cch = Continuously Compounded Rate of Change cca = Continuously Compounded Annual Rate of Change log = Natural Log", + "default": null, + "optional": true, + "choices": [ + "chg", + "ch1", + "pch", + "pc1", + "pca", + "cch", + "cca", + "log" + ] + } + ] + }, + "returns": { + "OBBject": [ + { + "name": "results", + "type": "List[OvernightBankFundingRate]", + "description": "Serializable results." + }, + { + "name": "provider", + "type": "Optional[Literal['fred']]", + "description": "Provider name." + }, + { + "name": "warnings", + "type": "Optional[List[Warning_]]", + "description": "List of warnings." + }, + { + "name": "chart", + "type": "Optional[Chart]", + "description": "Chart object." + }, + { + "name": "extra", + "type": "Dict[str, Any]", + "description": "Extra info." + } + ] + }, + "data": { + "standard": [ + { + "name": "date", + "type": "date", + "description": "The date of the data.", + "default": "", + "optional": false, + "choices": null + }, + { + "name": "rate", + "type": "float", + "description": "Overnight Bank Funding Rate.", + "default": "", + "optional": false, + "choices": null + }, + { + "name": "percentile_1", + "type": "float", + "description": "1st percentile of the distribution.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "percentile_25", + "type": "float", + "description": "25th percentile of the distribution.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "percentile_75", + "type": "float", + "description": "75th percentile of the distribution.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "percentile_99", + "type": "float", + "description": "99th percentile of the distribution.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "volume", + "type": "float", + "description": "The trading volume.The notional volume of transactions (Billions of $).", + "default": null, + "optional": true, + "choices": null + } + ], + "fred": [] + }, + "model": "OvernightBankFundingRate" + }, "/fixedincome/spreads/tcm": { "deprecated": { "flag": null, diff --git a/openbb_platform/openbb/package/fixedincome_rate.py b/openbb_platform/openbb/package/fixedincome_rate.py index 68f87788b60..e53f135de18 100644 --- a/openbb_platform/openbb/package/fixedincome_rate.py +++ b/openbb_platform/openbb/package/fixedincome_rate.py @@ -20,6 +20,7 @@ class ROUTER_fixedincome_rate(Container): effr_forecast estr iorb + overnight_bank_funding sofr sonia """ @@ -725,6 +726,134 @@ class ROUTER_fixedincome_rate(Container): @exception_handler @validate + def overnight_bank_funding( + self, + start_date: Annotated[ + Union[datetime.date, None, str], + OpenBBField(description="Start date of the data, in YYYY-MM-DD format."), + ] = None, + end_date: Annotated[ + Union[datetime.date, None, str], + OpenBBField(description="End date of the data, in YYYY-MM-DD format."), + ] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBField( + description="The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fred." + ), + ] = None, + **kwargs + ) -> OBBject: + """Overnight Bank Funding. + + For the United States, the overnight bank funding rate (OBFR) is calculated as a volume-weighted median of + overnight federal funds transactions and Eurodollar transactions reported in the + FR 2420 Report of Selected Money Market Rates. + + + Parameters + ---------- + start_date : Union[datetime.date, None, str] + Start date of the data, in YYYY-MM-DD format. + end_date : Union[datetime.date, None, str] + End date of the data, in YYYY-MM-DD format. + provider : Optional[Literal['fred']] + The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fred. + frequency : Optional[Literal['a', 'q', 'm', 'w', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem']] + + Frequency aggregation to convert daily data to lower frequency. + a = Annual + q = Quarterly + m = Monthly + w = Weekly + wef = Weekly, Ending Friday + weth = Weekly, Ending Thursday + wew = Weekly, Ending Wednesday + wetu = Weekly, Ending Tuesday + wem = Weekly, Ending Monday + wesu = Weekly, Ending Sunday + wesa = Weekly, Ending Saturday + bwew = Biweekly, Ending Wednesday + bwem = Biweekly, Ending Monday + (provider: fred) + aggregation_method : Optional[Literal['avg', 'sum', 'eop']] + + A key that indicates the aggregation method used for frequency aggregation. + avg = Average + sum = Sum + eop = End of Period + (provider: fred) + transform : Optional[Literal['chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log']] + + Transformation type + None = No transformation + chg = Change + ch1 = Change from Year Ago + pch = Percent Change + pc1 = Percent Change from Year Ago + pca = Compounded Annual Rate of Change + cch = Continuously Compounded Rate of Change + cca = Continuously Compounded Annual Rate of Change + log = Natural Log + (provider: fred) + + Returns + ------- + OBBject + results : List[OvernightBankFundingRate] + Serializable results. + provider : Optional[Literal['fred']] + Provider name. + warnings : Optional[List[Warning_]] + List of warnings. + chart : Optional[Chart] + Chart object. + extra : Dict[str, Any] + Extra info. + + OvernightBankFundingRate + ------------------------ + date : date + The date of the data. + rate : float + Overnight Bank Funding Rate. + percentile_1 : Optional[float] + 1st percentile of the distribution. + percentile_25 : Optional[float] + 25th percentile of the distribution. + percentile_75 : Optional[float] + 75th percentile of the distribution. + percentile_99 : Optional[float] + 99th percentile of the distribution. + volume : Optional[float] + The trading volume.The notional volume of transactions (Billions of $). + + Examples + -------- + >>> from openbb import obb + >>> obb.fixedincome.rate.overnight_bank_funding(provider='fred') + """ # noqa: E501 + + return self._run( + "/fixedincome/rate/overnight_bank_funding", + **filter_inputs( + provider_choices={ + "provider": self._get_provider( + provider, + "fixedincome.rate.overnight_bank_funding", + ("fred",), + ) + }, + standard_params={ + "start_date": start_date, + "end_date": end_date, + }, + extra_params=kwargs, + ) + ) + + @exception_handler + @validate def sofr( self, start_date: Annotated[ diff --git a/openbb_platform/providers/fred/openbb_fred/__init__.py b/openbb_platform/providers/fred/openbb_fred/__init__.py index 0dfda4b40a7..bdce029bbe5 100644 --- a/openbb_platform/providers/fred/openbb_fred/__init__.py +++ b/openbb_platform/providers/fred/openbb_fred/__init__.py @@ -18,6 +18,9 @@ from openbb_fred.models.hqm import FREDHighQualityMarketCorporateBondFetcher from openbb_fred.models.ice_bofa import FREDICEBofAFetcher from openbb_fred.models.iorb_rates import FREDIORBFetcher from openbb_fred.models.moody import FREDMoodyCorporateBondIndexFetcher +from openbb_fred.models.overnight_bank_funding_rate import ( + FredOvernightBankFundingRateFetcher, +) from openbb_fred.models.regional import FredRegionalDataFetcher from openbb_fred.models.retail_prices import FredRetailPricesFetcher from openbb_fred.models.search import ( @@ -57,6 +60,7 @@ Research division of the Federal Reserve Bank of St. Louis that has more than "EuropeanCentralBankInterestRates": FREDEuropeanCentralBankInterestRatesFetcher, "ICEBofA": FREDICEBofAFetcher, "MoodyCorporateBondIndex": FREDMoodyCorporateBondIndexFetcher, + "OvernightBankFundingRate": FredOvernightBankFundingRateFetcher, "CommercialPaper": FREDCommercialPaperFetcher, "FredSearch": FredSearchFetcher, "FredSeries": FredSeriesFetcher, diff --git a/openbb_platform/providers/fred/openbb_fred/models/overnight_bank_funding_rate.py b/openbb_platform/providers/fred/openbb_fred/models/overnight_bank_funding_rate.py new file mode 100644 index 00000000000..78b6145ab5d --- /dev/null +++ b/openbb_platform/providers/fred/openbb_fred/models/overnight_bank_funding_rate.py @@ -0,0 +1,196 @@ +"""FRED Overnight Bank Funding Rate Model.""" + +from typing import Any, Dict, List, Literal, Optional, Union + +from openbb_core.provider.abstract.annotated_result import AnnotatedResult +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.overnight_bank_funding_rate import ( + OvernightBankFundingRateData, + OvernightBankFundingRateQueryParams, +) +from openbb_core.provider.utils.errors import EmptyDataError +from openbb_fred.models.series import FredSeriesFetcher +from pydantic import Field, field_validator + +OBFR_ID_TO_FIELD = { + "OBFR": "rate", + "OBFR1": "percentile_1", + "OBFR25": "percentile_25", + "OBFR75": "percentile_75", + "OBFR99": "percentile_99", + "OBFRVOL": "volume", +} +ALL_IDS = list(OBFR_ID_TO_FIELD) + + +class FredOvernightBankFundingRateQueryParams(OvernightBankFundingRateQueryParams): + """FRED Overnight Bank Funding Rate Query Params.""" + + frequency: Union[ + None, + Literal[ + "a", + "q", + "m", + "w", + "wef", + "weth", + "wew", + "wetu", + "wem", + "wesu", + "wesa", + "bwew", + "bwem", + ], + ] = Field( + default=None, + description=""" + Frequency aggregation to convert daily data to lower frequency. + a = Annual + q = Quarterly + m = Monthly + w = Weekly + wef = Weekly, Ending Friday + weth = Weekly, Ending Thursday + wew = Weekly, Ending Wednesday + wetu = Weekly, Ending Tuesday + wem = Weekly, Ending Monday + wesu = Weekly, Ending Sunday + wesa = Weekly, Ending Saturday + bwew = Biweekly, Ending Wednesday + bwem = Biweekly, Ending Monday + """, + json_schema_extra={ + "choices": [ + "a", + "q", + "m", + "w", + "wef", + "weth", + "wew", + "wetu", + "wem", + "wesu", + "wesa", + "bwew", + "bwem", + ] + }, + ) + aggregation_method: Union[None, Literal["avg", "sum", "eop"]] = Field( + default=None, + description=""" + A key that indicates the aggregation method used for frequency aggregation. + avg = Average + sum = Sum + eop = End of Period + """, + json_schema_extra={"choices": ["avg", "sum", "eop"]}, + ) + transform: Union[ + None, Literal["chg", "ch1", "pch", "pc1", "pca", "cch", "cca", "log"] + ] = Field( + default=None, + description=""" + Transformation type + None = No transformation + chg = Change + ch1 = Change from Year Ago + pch = Percent Change + pc1 = Percent Change from Year Ago + pca = Compounded Annual Rate of Change + cch = Continuously Compounded Rate of Change + cca = Continuously Compounded Annual Rate of Change + log = Natural Log + """, + json_schema_extra={ + "choices": ["chg", "ch1", "pch", "pc1", "pca", "cch", "cca", "log"] + }, + ) + + +class FredOvernightBankFundingRateData(OvernightBankFundingRateData): + """Fred Overnight Bank Funding Rate Data.""" + + __alias_dict__ = { + "rate": "OBFR", + "percentile_1": "OBFR1", + "percentile_25": "OBFR25", + "percentile_75": "OBFR75", + "percentile_99": "OBFR99", + "volume": "OBFRVOL", + } + + @field_validator( + "rate", + "percentile_1", + "percentile_25", + "percentile_75", + "percentile_99", + mode="before", + check_fields=False, + ) + @classmethod + def normalize_percent(cls, v): + """Normalize percent.""" + return float(v) / 100 if v else None |