diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-02-22 00:45:09 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-22 08:45:09 +0000 |
commit | 11df8e1b054589091242cf10784d56863474c152 (patch) | |
tree | f603f2ef720fdde92343f0419dc9c3e425bfe5b8 | |
parent | 3cc6025ab4c7cf4195a04e8ad6b2fa2d03abe97d (diff) |
[BugFix] Fix ECB Yield Curve (#6108)
* fix ecb yield curve
* standard model update
6 files changed, 111897 insertions, 68572 deletions
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/eu_yield_curve.py b/openbb_platform/core/openbb_core/provider/standard_models/eu_yield_curve.py index f1de1e00b77..81d01c278b8 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/eu_yield_curve.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/eu_yield_curve.py @@ -1,7 +1,7 @@ """Euro Area Yield Curve Standard Model.""" from datetime import date as dateType -from typing import Literal, Optional +from typing import Optional from pydantic import Field @@ -16,16 +16,14 @@ class EUYieldCurveQueryParams(QueryParams): date: Optional[dateType] = Field( default=None, description=QUERY_DESCRIPTIONS.get("date", "") ) - yield_curve_type: Literal["spot_rate", "instantaneous_forward", "par_yield"] = ( - Field( - default="spot_rate", - description="The yield curve type.", - ) - ) class EUYieldCurveData(Data): """Euro Area Yield Curve Data.""" - maturity: str = Field(description="Yield curve rate maturity.") - rate: Optional[float] = Field(description="Yield curve rate.", default=None) + maturity: Optional[float] = Field(description="Maturity, in years.", default=None) + rate: Optional[float] = Field( + description="Yield curve rate, as a normalized percent.", + default=None, + json_schema_extra={"unit_measurement": "percent.", "frontend_multiply": 100}, + ) diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py index e5863accef6..87539ad0eef 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_api.py @@ -439,10 +439,9 @@ def test_fixedincome_spreads_treasury_effr(params, headers): @parametrize( "params", [ - ({"date": "2023-01-01", "yield_curve_type": "spot_rate"}), ( { - "rating": "A", + "rating": "aaa", "provider": "ecb", "date": "2023-01-01", "yield_curve_type": "spot_rate", diff --git a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py index 69af98d72d5..df53341fb85 100644 --- a/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py +++ b/openbb_platform/extensions/fixedincome/integration/test_fixedincome_python.py @@ -405,10 +405,9 @@ def test_fixedincome_spreads_treasury_effr(params, obb): @parametrize( "params", [ - ({"date": "2023-01-01", "yield_curve_type": "spot_rate"}), ( { - "rating": "A", + "rating": "aaa", "provider": "ecb", "date": "2023-01-01", "yield_curve_type": "spot_rate", diff --git a/openbb_platform/providers/ecb/openbb_ecb/models/eu_yield_curve.py b/openbb_platform/providers/ecb/openbb_ecb/models/eu_yield_curve.py index f891bb1321e..357f8972083 100644 --- a/openbb_platform/providers/ecb/openbb_ecb/models/eu_yield_curve.py +++ b/openbb_platform/providers/ecb/openbb_ecb/models/eu_yield_curve.py @@ -1,6 +1,10 @@ """Euro Area Yield Curve Model.""" -from datetime import datetime, timedelta +# pylint: disable=unused-argument + +import asyncio +import warnings +from datetime import datetime from typing import Any, Dict, List, Literal, Optional from openbb_core.provider.abstract.fetcher import Fetcher @@ -8,34 +12,38 @@ from openbb_core.provider.standard_models.eu_yield_curve import ( EUYieldCurveData, EUYieldCurveQueryParams, ) -from openbb_ecb.utils.ecb_helpers import get_series_data +from openbb_core.provider.utils.errors import EmptyDataError +from openbb_core.provider.utils.helpers import amake_request +from openbb_ecb.utils.yield_curve_series import get_yield_curve_ids +from pandas import DataFrame, to_datetime from pydantic import Field, field_validator +_warn = warnings.warn + class ECBEUYieldCurveQueryParams(EUYieldCurveQueryParams): - """Euro Area Yield Curve Query.""" + """ECB Yield Curve Query Params.""" - rating: Literal["A", "C"] = Field( - default="A", - description="The rating type.", + rating: Literal["aaa", "all_ratings"] = Field( + default="aaa", + description="The rating type, either 'aaa' or 'all_ratings'.", + ) + yield_curve_type: Literal["spot_rate", "instantaneous_forward", "par_yield"] = ( + Field( + default="spot_rate", + description="The yield curve type.", + ) ) class ECBEUYieldCurveData(EUYieldCurveData): - """Euro Area Yield Curve Data.""" + """ECB Yield Curve Data.""" - __alias_dict__ = { - "rate": "OBS", - } - - @field_validator("OBS", mode="before", check_fields=False) + @field_validator("rate", mode="before", check_fields=False) @classmethod - def value_validate(cls, v): - """Validate rate.""" - try: - return float(v) - except ValueError: - return None + def normalize_percent(cls, v): + """Normalize percent.""" + return float(v) / 100 if v else None class ECBEUYieldCurveFetcher( @@ -44,62 +52,88 @@ class ECBEUYieldCurveFetcher( List[ECBEUYieldCurveData], ] ): - """Transform the query, extract and transform the data from the ECB endpoints.""" - - data_type = ECBEUYieldCurveData + """ECB Yield Curve Fetcher.""" @staticmethod def transform_query(params: Dict[str, Any]) -> ECBEUYieldCurveQueryParams: """Transform query.""" + if params.get("date") is None: + params["date"] = datetime.now().date() return ECBEUYieldCurveQueryParams(**params) # pylint: disable=unused-argument @staticmethod - def extract_data( + async def aextract_data( query: ECBEUYieldCurveQueryParams, credentials: Optional[Dict[str, str]], **kwargs: Any, - ) -> list: + ) -> List[Dict]: """Extract data.""" - # Check that the date is in the past - today = datetime.today().date() - if query.date and query.date >= today: - raise ValueError("Date must be in the past") - - if not query.date: - date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") - else: - date = query.date.strftime("%Y-%m-%d") - - yield_suffixes = { - "spot_rate": "SR_", - "instantaneous_forward": "IF_", - "par_yield": "PY", - } - yield_type = f"YC.B.U2.EUR.4F.G_N_{query.rating}.SV_C_YM." + yield_suffixes.get( - query.yield_curve_type, "" + + results = [] + + IDS = get_yield_curve_ids( + rating=query.rating, + yield_curve_type=query.yield_curve_type, ) - # Add the maturities - series_id = [f"{yield_type}{m}M" for m in [3, 6]] - series_id += [f"{yield_type}{y}Y" for y in [1, 2, 3, 5, 7, 10, 20, 30]] + YIELD_CURVE = IDS["SERIES_IDS"] + MATURITIES = IDS["MATURITIES"] - data = [] + maturities = list(MATURITIES.keys()) - for id_ in series_id: - d = get_series_data(id_, date) - maturity = id_.split("_")[-1] + BASE_URL = "https://data.ecb.europa.eu/data-detail-api" - for item in d: - item["maturity"] = maturity + async def get_one(maturity): + """Each maturity is a separate download.""" + url = f"{BASE_URL}/{YIELD_CURVE[maturity]}" + response = await amake_request(url=url, timeout=10) + if isinstance(response, List): + for item in response: + d = { + "date": item.get("PERIOD"), + "maturity": MATURITIES[maturity], + "rate": item.get("OBS_VALUE_AS_IS"), + } - data.extend(d) + results.append(d) - return data + tasks = [get_one(maturity) for maturity in maturities] + + await asyncio.gather(*tasks) + + return results # pylint: disable=unused-argument @staticmethod def transform_data( - query: ECBEUYieldCurveQueryParams, data: list, **kwargs: Any + query: ECBEUYieldCurveQueryParams, + data: List[Dict], + **kwargs: Any, ) -> List[ECBEUYieldCurveData]: """Transform data.""" - return [ECBEUYieldCurveData.model_validate(d) for d in data] + + if not data: + raise EmptyDataError() + + # Find the nearest date to the requested one. + df = DataFrame(data).set_index("date").query("`rate`.notnull()") + df.index = to_datetime(df.index) + dates = df.index.unique().tolist() + date = to_datetime(query.date) + nearest_date = min(dates, key=lambda d: abs(d - date)).strftime("%Y-%m-%d") + df.index = df.index.astype(str) + + if nearest_date != date.strftime("%Y-%m-%d"): + _warn(f"Using nearest date: {nearest_date}") + + df.index = df.index.astype(str) + results = ( + df.filter(like=nearest_date, axis=0) + .sort_values("maturity") + .reset_index(drop=True) + ) + + return [ + ECBEUYieldCurveData.model_validate(d) + for d in results.to_dict(orient="records") + ] diff --git a/openbb_platform/providers/ecb/openbb_ecb/utils/yield_curve_series.py b/openbb_platform/providers/ecb/openbb_ecb/utils/yield_curve_series.py new file mode 100644 index 00000000000..881a8ac0889 --- /dev/null +++ b/openbb_platform/providers/ecb/openbb_ecb/utils/yield_curve_series.py @@ -0,0 +1,92 @@ +"""ECB Yield Curve Series IDs""" + +from typing import Dict, Literal + +RATING_DICT = {"aaa": "A", "all_ratings": "C"} + +YIELD_TYPE_DICT = { + "spot_rate": "SR", + "instantaneous_forward": "IF", + "par_yield": "PY", +} + + +def get_yield_curve_ids( + rating: Literal["aaa", "all_ratings"] = "aaa", + yield_curve_type: Literal[ + "spot_rate", "instantaneous_forward", "par_yield" + ] = "spot_rate", +) -> Dict: + """Get Yield Curve Series IDs""" + + YIELD_CURVE = { + "month_3": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_3M", + "month_6": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_6M", + "year_1": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_1Y", + "year_2": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_2Y", + "year_3": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_3Y", + "year_4": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_4Y", + "year_5": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_5Y", + "year_6": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_6Y", + "year_7": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_7Y", + "year_8": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_8Y", + "year_9": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_9Y", + "year_10": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_10Y", + "year_11": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_11Y", + "year_12": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_12Y", + "year_13": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_13Y", + "year_14": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_14Y", + "year_15": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_15Y", + "year_16": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_16Y", + "year_17": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_17Y", + "year_18": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_18Y", + "year_19": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_19Y", + "year_20": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_20Y", + "year_21": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_21Y", + "year_22": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_22Y", + "year_23": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_23Y", + "year_24": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_24Y", + "year_25": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_25Y", + "year_26": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_26Y", + "year_27": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_27Y", + "year_28": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_28Y", + "year_29": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_29Y", + "year_30": f"YC.B.U2.EUR.4F.G_N_{RATING_DICT[rating]}.SV_C_YM.{YIELD_TYPE_DICT[yield_curve_type]}_30Y", + } + + MATURITY_VALUES = { + "month_3": 0.25, + "month_6": 0.5, + "year_1": 1, + "year_2": 2, + "year_3": 3, + "year_4": 4, + "year_5": 5, + "year_6": 6, + "year_7": 7, + "year_8": 8, + "year_9": 9, + "year_10": 10, + "year_11": 11, + "year_12": 12, + "year_13": 13, + "year_14": 14, + "year_15": 15, + "year_16": 16, + "year_17": 17, + "year_18": 18, + "year_19": 19, + "year_20": 20, + "year_21": 21, + "year_22": 22, + "year_23": 23, + "year_24": 24, + "year_25": 25, + "year_26": 26, + "year_27": 27, + "year_28": 28, + "year_29": 29, + "year_30": 30, + } + + return dict(SERIES_IDS=YIELD_CURVE, MATURITIES=MATURITY_VALUES) diff --git a/openbb_platform/providers/ecb/tests/record/http/test_ecb_fetchers/test_ecbeu_yield_curve_fetcher.yaml b/openbb_platform/providers/ecb/tests/record/http/test_ecb_fetchers/test_ecbeu_yield_curve_fetcher.yaml index 28425638988..46baf949061 100644 --- a/openbb_platform/providers/ecb/tests/record/http/test_ecb_fetchers/test_ecbeu_yield_curve_fetcher.yaml +++ b/openbb_platform/providers/ecb/tests/record/http/test_ecb_fetchers/test_ecbeu_yield_curve_fetcher.yaml @@ -3,3417 +3,3491 @@ interactions: body: null headers: Accept: - - '*/*' + - application/json Accept-Encoding: - gzip, deflate Connection: - keep-alive method: GET - uri: https://data.ecb.europa.eu/data-detail-api/YC.B.U2.EUR.4F.G_N_A.SV_C_YM.SR_3M?startPeriod=20230101 + uri: https://data.ecb.europa.eu/data-detail-api/YC.B.U2.EUR.4F.G_N_A.SV_C_YM.SR_6Y response: body: string: !!binary | - H4sIAAAAAAAAA8y9W681uXEs+Fcaeh27kRde+60ttQ7kOWr56HIAYx4EHY/gF40seCwPjMH89yFZ - i7WXepGLu5jxoatbl1ZLldpZsZOVwQwG/4//9ye/+off/OSbn+jXiZyk+JO/+8lvvvv1L76rf++f - f/r1P3z9O/n6u9/9+mv386//2++///23X//mf/7+p7//519+/Ztf/15/Wf7X5fHf/89v//vvvvv9 - d9//9he//ee/jfW773/x2/J3/umn//Rt+U//VCL/6me//8XPyt9yzovSI8A//eoX39f/3Z/+8H// - x8/+8B9/fPztn/7qlz/55s9//dOf/u4nv/31d9+XJ7//2S9++u1vf/Xr8r/9P//t//nzR8zvv/3l - d+Vvknz1/b/951dCouW/++/f/bfyVPnb3//bv/9ff/jTV//5hz/9tcf+zW+//e3vapbf/k0S3/7m - 9794eh8hJ+Xz/6X8/Rr575n/nqT83Z//+rv/8bvvvv9pTfofzp/5+5+X//jzjx/tZ9/+9tuayj/9 - 8PHy//iLn/3+57+uWX78N/pbpm98+ob810T0vxF9Q+dr+vV3v/+HX3/37f9+vJX/7++e0GPSJCD0 - eqz36EmGo8c49FoOEnMeosc29HiKnnT05BJ6QhwyCL0ea4FeMqD317+8YKf81a/+5T8w2LUMKEV5 - xY7+Xi3YPR4fY8cdO76CXUzRicNgd8ZaYBfB2BEMuyMDiuyH2JENOxpjV1Ft2OVvOHwGu79NX/Jz - +s9pHu+wIX385TWM/xbFAeKjd9SW1dE7WoE9SCzdKrFkSOystugdKajaeqxFtTlstUnEVVvLQEMY - fOXKC4+mamuPj6uNHislX1spowvCKOwesRbYqQG7YY8iAYhezUFp1GGW1x9s6IUZehJ/S7miJ3rt - O0ecCfWde8RaoCdw9DzwS0ecsp/Vnreh56fohQd6n/vSfaAn6kD84Iy1QI/B66YDYlcyYM8chtg5 - G3Zuip3v2OVL2DlHDsTMz1gL7CzMfISd4rBrGXAKQ3bQ4huw0yl27oGdfoqX/yB9uVUjNtu72Ogw - +VaJzajhpQ5Tg6YAqrYe6321MZjPCZDP1Qy8j2lcbTY+J1M+J/qoNqJLKyWnlFFcvMdaYBew2HHG - YVczUF8Y+Qg7nvHMz2HXHh9jRw278o9L7CDkEBnUX56xFth5MHYJht2RAWuMQ+xmVPqT2KUZdpwf - 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 - |