diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-06-10 10:00:08 -0700 |
---|---|---|
committer | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-06-10 10:00:08 -0700 |
commit | b18f544710e3b2e9f4d8c490fa3a14191b137080 (patch) | |
tree | 3e3b019a5a4cfa96fe4e54c2c3823e1db0c9841b | |
parent | ebd07afdd62716576bfd0d0a3716bcfcc5cc5b97 (diff) |
update ameribor
12 files changed, 545 insertions, 667 deletions
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/ameribor_rates.py b/openbb_platform/core/openbb_core/provider/standard_models/ameribor.py index 4dad428a6a1..2edf6f66b67 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/ameribor_rates.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/ameribor.py @@ -13,7 +13,7 @@ from openbb_core.provider.utils.descriptions import ( ) -class AMERIBORQueryParams(QueryParams): +class AmeriborQueryParams(QueryParams): """AMERIBOR Query.""" start_date: Optional[dateType] = Field( @@ -26,8 +26,19 @@ class AMERIBORQueryParams(QueryParams): ) -class AMERIBORData(Data): +class AmeriborData(Data): """AMERIBOR Data.""" date: dateType = Field(description=DATA_DESCRIPTIONS.get("date", "")) - rate: Optional[float] = Field(description="AMERIBOR rate.") + symbol: Optional[str] = Field( + default=None, description=DATA_DESCRIPTIONS.get("symbol", "") + ) + maturity: str = Field(description="Maturity length of the item.") + rate: float = Field( + description="Interest rate.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + title: Optional[str] = Field( + default=None, + description="Title of the series.", + ) diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py index a24f4147a33..fec1db5ba7e 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py @@ -180,13 +180,15 @@ def test_fixedincome_rate_sonia(params, headers): @parametrize( "params", [ - ({"start_date": "2023-01-01", "end_date": "2023-06-06"}), ( { - "parameter": "overnight", + "maturity": "overnight", "provider": "fred", "start_date": "2023-01-01", "end_date": "2023-06-06", + "transform": None, + "aggregation_method": None, + "frequency": None, } ), ], diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py index 4376652a20a..ce61157def8 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py @@ -159,13 +159,15 @@ def test_fixedincome_rate_sonia(params, obb): @parametrize( "params", [ - ({"start_date": "2023-01-01", "end_date": "2023-06-06"}), ( { - "parameter": "overnight", + "maturity": "overnight", "provider": "fred", "start_date": "2023-01-01", "end_date": "2023-06-06", + "transform": None, + "aggregation_method": None, + "frequency": None, } ), ], 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 e86119d5f84..bc521a30f71 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py @@ -17,10 +17,13 @@ router = Router(prefix="/rate") @router.command( - model="AMERIBOR", + model="Ameribor", examples=[ APIEx(parameters={"provider": "fred"}), - APIEx(parameters={"parameter": "30_day_ma", "provider": "fred"}), + APIEx( + description="The change from one year ago is applied with the transform parameter.", + parameters={"maturity": "all", "transform": "pc1", "provider": "fred"}, + ), ], ) async def ameribor( @@ -29,9 +32,9 @@ async def ameribor( standard_params: StandardParams, extra_params: ExtraParams, ) -> OBBject: # type: ignore - """Ameribor. + """AMERIBOR. - Ameribor (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of + AMERIBOR (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of short-term interbank borrowing. This rate is based on transactions in overnight unsecured loans conducted on the American Financial Exchange (AFX). """ diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json index e6c85cdb235..906b2d8f50a 100644 --- a/openbb_platform/openbb/assets/reference.json +++ b/openbb_platform/openbb/assets/reference.json @@ -29878,8 +29878,8 @@ "flag": null, "message": null }, - "description": "Ameribor.\n\nAmeribor (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of\nshort-term interbank borrowing. This rate is based on transactions in overnight unsecured loans conducted on the\nAmerican Financial Exchange (AFX).", - "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.fixedincome.rate.ameribor(provider='fred')\nobb.fixedincome.rate.ameribor(parameter=30_day_ma, provider='fred')\n```\n\n", + "description": "AMERIBOR.\n\nAMERIBOR (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of\nshort-term interbank borrowing. This rate is based on transactions in overnight unsecured loans conducted on the\nAmerican Financial Exchange (AFX).", + "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.fixedincome.rate.ameribor(provider='fred')\n# The change from one year ago is applied with the transform parameter.\nobb.fixedincome.rate.ameribor(maturity=all, transform=pc1, provider='fred')\n```\n\n", "parameters": { "standard": [ { @@ -29908,12 +29908,70 @@ ], "fred": [ { - "name": "parameter", - "type": "Literal['overnight', 'term_30', 'term_90', '1_week_term_structure', '1_month_term_structure', '3_month_term_structure', '6_month_term_structure', '1_year_term_structure', '2_year_term_structure', '30_day_ma', '90_day_ma']", - "description": "Period of AMERIBOR rate.", - "default": "overnight", + "name": "maturity", + "type": "Union[Union[Literal['all', 'overnight', 'average_30d', 'average_90d', 'term_30d', 'term_90d'], str], List[Union[Literal['all', 'overnight', 'average_30d', 'average_90d', 'term_30d', 'term_90d'], str]]]", + "description": "Period of AMERIBOR rate. Multiple items allowed for provider(s): fred.", + "default": "all", "optional": true, - "choices": null + "choices": [ + "all", + "overnight", + "average_30d", + "average_90d", + "term_30d", + "term_90d" + ] + }, + { + "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" + ] } ] }, @@ -29921,7 +29979,7 @@ "OBBject": [ { "name": "results", - "type": "List[AMERIBOR]", + "type": "List[Ameribor]", "description": "Serializable results." }, { @@ -29957,17 +30015,41 @@ "choices": null }, { + "name": "symbol", + "type": "str", + "description": "Symbol representing the entity requested in the data.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "maturity", + "type": "str", + "description": "Maturity length of the item.", + "default": "", + "optional": false, + "choices": null + }, + { "name": "rate", "type": "float", - "description": "AMERIBOR rate.", + "description": "Interest rate.", "default": "", "optional": false, "choices": null + }, + { + "name": "title", + "type": "str", + "description": "Title of the series.", + "default": null, + "optional": true, + "choices": null } ], "fred": [] }, - "model": "AMERIBOR" + "model": "Ameribor" }, "/fixedincome/rate/sonia": { "deprecated": { diff --git a/openbb_platform/openbb/package/fixedincome_rate.py b/openbb_platform/openbb/package/fixedincome_rate.py index 2e2508bc588..68f87788b60 100644 --- a/openbb_platform/openbb/package/fixedincome_rate.py +++ b/openbb_platform/openbb/package/fixedincome_rate.py @@ -47,9 +47,9 @@ class ROUTER_fixedincome_rate(Container): ] = None, **kwargs ) -> OBBject: - """Ameribor. + """AMERIBOR. - Ameribor (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of + AMERIBOR (short for the American interbank offered rate) is a benchmark interest rate that reflects the true cost of short-term interbank borrowing. This rate is based on transactions in overnight unsecured loans conducted on the American Financial Exchange (AFX). @@ -62,13 +62,50 @@ class ROUTER_fixedincome_rate(Container): 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. - parameter : Literal['overnight', 'term_30', 'term_90', '1_week_term_structure', '1_month_term_structure', '3_month_term_structure', '6_month_term_structure', '1_year_term_structure', '2_year_term_structure', '30_day_ma', '90_day_ma'] - Period of AMERIBOR rate. (provider: fred) + maturity : Union[Literal['all', 'overnight', 'average_30d', 'average_90d', 'term_30d', 'term_90d'], str] + Period of AMERIBOR rate. Multiple comma separated items allowed. (provider: 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[AMERIBOR] + results : List[Ameribor] Serializable results. provider : Optional[Literal['fred']] Provider name. @@ -79,18 +116,25 @@ class ROUTER_fixedincome_rate(Container): extra : Dict[str, Any] Extra info. - AMERIBOR + Ameribor -------- date : date The date of the data. - rate : Optional[float] - AMERIBOR rate. + symbol : Optional[str] + Symbol representing the entity requested in the data. + maturity : str + Maturity length of the item. + rate : float + Interest rate. + title : Optional[str] + Title of the series. Examples -------- >>> from openbb import obb >>> obb.fixedincome.rate.ameribor(provider='fred') - >>> obb.fixedincome.rate.ameribor(parameter='30_day_ma', provider='fred') + >>> # The change from one year ago is applied with the transform parameter. + >>> obb.fixedincome.rate.ameribor(maturity='all', transform='pc1', provider='fred') """ # noqa: E501 return self._run( @@ -108,6 +152,7 @@ class ROUTER_fixedincome_rate(Container): "end_date": end_date, }, extra_params=kwargs, + info={"maturity": {"fred": {"multiple_items_allowed": True}}}, ) ) diff --git a/openbb_platform/providers/fred/openbb_fred/__init__.py b/openbb_platform/providers/fred/openbb_fred/__init__.py index 7633383120c..0dfda4b40a7 100644 --- a/openbb_platform/providers/fred/openbb_fred/__init__.py +++ b/openbb_platform/providers/fred/openbb_fred/__init__.py @@ -1,7 +1,7 @@ """FRED provider module.""" from openbb_core.provider.abstract.provider import Provider -from openbb_fred.models.ameribor_rates import FREDAMERIBORFetcher +from openbb_fred.models.ameribor import FredAmeriborFetcher from openbb_fred.models.balance_of_payments import FredBalanceOfPaymentsFetcher from openbb_fred.models.bond_indices import FredBondIndicesFetcher from openbb_fred.models.commercial_paper import FREDCommercialPaperFetcher @@ -49,7 +49,7 @@ Research division of the Federal Reserve Bank of St. Louis that has more than "SOFR": FREDSOFRFetcher, "ESTR": FREDESTRFetcher, "SONIA": FREDSONIAFetcher, - "AMERIBOR": FREDAMERIBORFetcher, + "Ameribor": FredAmeriborFetcher, "FederalFundsRate": FredFederalFundsRateFetcher, "PROJECTIONS": FREDPROJECTIONFetcher, "IORB": FREDIORBFetcher, diff --git a/openbb_platform/providers/fred/openbb_fred/models/ameribor.py b/openbb_platform/providers/fred/openbb_fred/models/ameribor.py new file mode 100644 index 00000000000..a92c71fbecb --- /dev/null +++ b/openbb_platform/providers/fred/openbb_fred/models/ameribor.py @@ -0,0 +1,229 @@ +"""FRED AMERIBOR Model.""" + +# pylint: disable=unused-argument + +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.ameribor import ( + AmeriborData, + AmeriborQueryParams, +) +from openbb_core.provider.utils.errors import EmptyDataError +from openbb_fred.models.series import FredSeriesFetcher +from pandas import Categorical, DataFrame +from pydantic import Field + +MATURITY_TO_FRED_ID = { + "all": "AMERIBOR,AMBOR30,AMBOR90,AMBOR30T,AMBOR90T", + "overnight": "AMERIBOR", + "average_30d": "AMBOR30", + "average_90d": "AMBOR90", + "term_30d": "AMBOR30T", + "term_90d": "AMBOR90T", +} + + +class FredAmeriborQueryParams(AmeriborQueryParams): + """FRED AMERIBOR Query.""" + + __json_schema_extra__ = {"maturity": {"multiple_items_allowed": True}} + + maturity: Union[ + Literal[ + "all", + "overnight", + "average_30d", + "average_90d", + "term_30d", + "term_90d", + ], + str, + ] = Field( + default="all", + description="Period of AMERIBOR rate.", + json_schema_extra={ + "choices": [ + "all", + "overnight", + "average_30d", + "average_90d", + "term_30d", + "term_90d", + ] + }, + ) + 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 FredAmeriborData(AmeriborData): + """FRED AMERIBOR Data.""" + + +class FredAmeriborFetcher(Fetcher[FredAmeriborQueryParams, List[FredAmeriborData]]): + """FRED Ameribor Fetcher.""" + + data_type = FredAmeriborData + + @staticmethod + def transform_query(params: Dict[str, Any]) -> FredAmeriborQueryParams: + """Transform query.""" + return FredAmeriborQueryParams(**params) + + @staticmethod + async def aextract_data( + query: FredAmeriborQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any, + ) -> Dict: + """Extract data.""" + maturities = query.maturity.split(",") + ids = "" + if len(maturities) == 1 or "all" in maturities: + ids = MATURITY_TO_FRED_ID[query.maturity] + else: + ids = ",".join([MATURITY_TO_FRED_ID[m] for m in maturities]) + + try: + response = await FredSeriesFetcher.fetch_data( + dict( + symbol=ids, + start_date=query.start_date, + end_date=query.end_date, + frequency=query.frequency, + aggregation_method=query.aggregation_method, + transform=query.transform, + ), + credentials, + ) + except Exception as e: + raise e from e + + return { + "metadata": response.metadata, + "data": [d.model_dump() for d in response.result], + } + + @staticmethod + def transform_data( + query: FredAmeriborQueryParams, + data: Dict, + **kwargs: Any, + ) -> AnnotatedResult[List[FredAmeriborData]]: + """Transform data.""" + if not data["data"]: + raise EmptyDataError("The request was returned with no data.") + metadata = data.get("metadata", {}) + maturity_dict = { + "AMERIBOR": "overnight", + "AMBOR30": "month_1", + "AMBOR90": "month_3", + "AMBOR30T": "month_1", + "AMBOR90T": "month_3", + } + + df = DataFrame(data.get("data", [])) + # Flatten data + df = df.melt(id_vars="date", var_name="symbol", value_name="value").query( + "value.notnull()" + ) + df = df.rename(columns={"value": "rate"}).sort_values(by="date") + # Normalize percent values + df["rate"] = df["rate"].astype(float) / 100 + + df["maturity"] = df["symbol"].apply(lambda x: maturity_dict.get(x, x)) + df["title"] = df["symbol"].apply(lambda x: metadata.get(x, {}).get("title", x)) + maturity_categories = ["overnight", "month_1", "month_3"] + df["maturity"] = Categorical( + df["maturity"], categories=maturity_categories, ordered=True + ) + df.sort_values(by=["date", "maturity"], inplace=True) + records = df.to_dict(orient="records") + + return AnnotatedResult( + result=[FredAmeriborData.model_validate(d) for d in records], + metadata=metadata, + ) diff --git a/openbb_platform/providers/fred/openbb_fred/models/ameribor_rates.py b/openbb_platform/providers/fred/openbb_fred/models/ameribor_rates.py deleted file mode 100644 index e96a2b67a94..00000000000 --- a/openbb_platform/providers/fred/openbb_fred/models/ameribor_rates.py +++ /dev/null @@ -1,92 +0,0 @@ -"""FRED AMERIBOR Model.""" - -from typing import Any, Dict, List, Literal, Optional - -from op |