diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-05-14 22:45:01 -0700 |
---|---|---|
committer | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-05-14 22:45:01 -0700 |
commit | 1988ad5309ad02dffb0d917e7cf7f83477ca3673 (patch) | |
tree | a95e663c57d5ee4f2a11ba98bb0dfb2c20a0ea55 | |
parent | 887204b120949f2f7f09e8fad8f3f1ef4202af19 (diff) |
fred yield curve
6 files changed, 14689 insertions, 177 deletions
diff --git a/openbb_platform/providers/fred/openbb_fred/__init__.py b/openbb_platform/providers/fred/openbb_fred/__init__.py index b6efbd173a6..7546eb79ed3 100644 --- a/openbb_platform/providers/fred/openbb_fred/__init__.py +++ b/openbb_platform/providers/fred/openbb_fred/__init__.py @@ -26,7 +26,10 @@ from openbb_fred.models.sonia_rates import FREDSONIAFetcher from openbb_fred.models.spot import FREDSpotRateFetcher from openbb_fred.models.tbffr import FREDSelectedTreasuryBillFetcher from openbb_fred.models.tmc import FREDTreasuryConstantMaturityFetcher -from openbb_fred.models.us_yield_curve import FREDYieldCurveFetcher +from openbb_fred.models.us_yield_curve import ( + FREDYieldCurveFetcher as FREDUSYieldCurveFetcher, +) +from openbb_fred.models.yield_curve import FREDYieldCurveFetcher fred_provider = Provider( name="fred", @@ -37,7 +40,7 @@ Research division of the Federal Reserve Bank of St. Louis that has more than credentials=["api_key"], fetcher_dict={ "ConsumerPriceIndex": FREDConsumerPriceIndexFetcher, - "USYieldCurve": FREDYieldCurveFetcher, + "USYieldCurve": FREDUSYieldCurveFetcher, "SOFR": FREDSOFRFetcher, "ESTR": FREDESTRFetcher, "SONIA": FREDSONIAFetcher, @@ -58,6 +61,7 @@ Research division of the Federal Reserve Bank of St. Louis that has more than "TreasuryConstantMaturity": FREDTreasuryConstantMaturityFetcher, "SelectedTreasuryConstantMaturity": FREDSelectedTreasuryConstantMaturityFetcher, "SelectedTreasuryBill": FREDSelectedTreasuryBillFetcher, + "YieldCurve": FREDYieldCurveFetcher, }, repr_name="Federal Reserve Economic Data | St. Louis FED (FRED)", v3_credentials=["API_FRED_KEY"], diff --git a/openbb_platform/providers/fred/openbb_fred/models/yield_curve.py b/openbb_platform/providers/fred/openbb_fred/models/yield_curve.py new file mode 100644 index 00000000000..0be0ba37f87 --- /dev/null +++ b/openbb_platform/providers/fred/openbb_fred/models/yield_curve.py @@ -0,0 +1,106 @@ +"""FRED Yield Curve Model.""" + +# pylint: disable=unused-argument + +from typing import Any, Dict, List, Literal, Optional + +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.yield_curve import ( + YieldCurveData, + YieldCurveQueryParams, +) +from openbb_core.provider.utils.errors import EmptyDataError +from openbb_fred.models.series import FredSeriesFetcher +from openbb_fred.utils.fred_helpers import YIELD_CURVES +from pandas import Categorical, DataFrame, DatetimeIndex +from pydantic import Field + + +class FREDYieldCurveQueryParams(YieldCurveQueryParams): + """FRED Yield Curve Query.""" + + __json_schema_extra__ = {"date": {"multiple_items_allowed": True}} + + yield_curve_type: Literal[ + "nominal", "real", "breakeven", "corporate_spot", "corporate_par" + ] = Field( + default="nominal", + description="Yield curve type." + + " Nominal and Real Rates are available daily, others are monthly." + + " The closest date to the requested date will be returned.", + ) + + +class FREDYieldCurveData(YieldCurveData): + """FRED Yield Curve Data.""" + + +class FREDYieldCurveFetcher( + Fetcher[FREDYieldCurveQueryParams, List[FREDYieldCurveData]] +): + """Transform the query, extract and transform the data from the FRED endpoints.""" + + @staticmethod + def transform_query(params: Dict[str, Any]) -> FREDYieldCurveQueryParams: + """Transform query.""" + return FREDYieldCurveQueryParams(**params) + + @staticmethod + async def aextract_data( + query: FREDYieldCurveQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any + ) -> List[Dict]: + """Extract data.""" + api_key = credentials.get("fred_api_key") if credentials else "" + series_ids = ",".join(list(YIELD_CURVES[query.yield_curve_type])) + fetcher = FredSeriesFetcher() + data = await fetcher.fetch_data( + {"symbol": series_ids}, {"fred_api_key": api_key} + ) + if not data: + raise EmptyDataError("The request was returned empty.") + results = [d.model_dump() for d in data.result] + + return results + + @staticmethod + def transform_data( + query: FREDYieldCurveQueryParams, data: List[Dict], **kwargs: Any + ) -> List[FREDYieldCurveData]: + """Transform data.""" + df = DataFrame(data).set_index("date").sort_index() + df.index = df.index.astype(str) + dates = query.date.split(",") if query.date else [df.index.max()] + df.index = DatetimeIndex(df.index) + dates_list = DatetimeIndex(dates) + maturity_dict = YIELD_CURVES[query.yield_curve_type] + df = df.rename(columns=maturity_dict) + df.columns.name = "maturity" + + # Find the nearest date in the DataFrame to each date in dates_list + nearest_dates = [df.index.asof(date) for date in dates_list] + + # Filter for only the nearest dates + df = df[df.index.isin(nearest_dates)] + + df = df.fillna("N/A").replace("N/A", None) + + # Flatten the DataFrame + flattened_data = df.reset_index().melt( + id_vars="date", var_name="maturity", value_name="rate" + ) + flattened_data = flattened_data.sort_values("date") + flattened_data["maturity"] = Categorical( + flattened_data["maturity"], + categories=list(maturity_dict.values()), + ordered=True, + ) + flattened_data["rate"] = flattened_data["rate"].astype(float) / 100 + flattened_data = flattened_data.sort_values( + by=["date", "maturity"] + ).reset_index(drop=True) + flattened_data.loc[:, "date"] = flattened_data["date"].dt.strftime("%Y-%m-%d") + records = flattened_data.to_dict(orient="records") + + return [FREDYieldCurveData.model_validate(d) for d in records] diff --git a/openbb_platform/providers/fred/openbb_fred/utils/fred_helpers.py b/openbb_platform/providers/fred/openbb_fred/utils/fred_helpers.py index b61cc26625e..d604592cbc0 100644 --- a/openbb_platform/providers/fred/openbb_fred/utils/fred_helpers.py +++ b/openbb_platform/providers/fred/openbb_fred/utils/fred_helpers.py @@ -49,6 +49,55 @@ YIELD_CURVE_SERIES_CORPORATE_PAR = { "10Year": "HQMCB10YRP", "30Year": "HQMCB30YRP", } +YIELD_CURVES = { + "nominal": { + "DGS1MO": "month_1", + "DGS3MO": "month_3", + "DGS6MO": "month_6", + "DGS1": "year_1", + "DGS2": "year_2", + "DGS3": "year_3", + "DGS5": "year_5", + "DGS7": "year_7", + "DGS10": "year_10", + "DGS20": "year_20", + "DGS30": "year_30", + }, + "real": { + "DFII5": "year_5", + "DFII7": "year_7", + "DFII10": "year_10", + "DFII20": "year_20", + "DFII30": "year_30", + }, + "breakeven": { + "T5YIEM": "year_5", + "T7YIEM": "year_7", + "T10YIEM": "year_10", + "T20YIEM": "year_20", + "T30YIEM": "year_30", + }, + "corporate_spot": { + "HQMCB6MT": "month_6", + "HQMCB1YR": "year_1", + "HQMCB2YR": "year_2", + "HQMCB3YR": "year_3", + "HQMCB5YR": "year_5", + "HQMCB7YR": "year_7", + "HQMCB10YR": "year_10", + "HQMCB20YR": "year_20", + "HQMCB30YR": "year_30", + "HQMCB50YR": "year_50", + "HQMCB75YR": "year_75", + "HQMCB100YR": "year_100", + }, + "corporate_par": { + "HQMCB2YRP": "year_2", + "HQMCB5YRP": "year_5", + "HQMCB10YRP": "year_10", + "HQMCB30YRP": "year_30", + }, +} def comma_to_float_list(v: str) -> List[float]: diff --git a/openbb_platform/providers/fred/tests/record/http/test_fred_fetchers/test_fred_us_yield_curve_fetcher.yaml b/openbb_platform/providers/fred/tests/record/http/test_fred_fetchers/test_fred_us_yield_curve_fetcher.yaml new file mode 100644 index 00000000000..d89e973ccd7 --- /dev/null +++ b/openbb_platform/providers/fred/tests/record/http/test_fred_fetchers/test_fred_us_yield_curve_fetcher.yaml @@ -0,0 +1,718 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS1MO + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJVM9UzOlWh1qGm+k + pKOEZLwRlY03RjXemMrGm9HWeHPaGm+Bajy1w94S1Xgqh72hAW2Np23KMTRBdT2Vwx5c8NEuWxnS + Nt0boqV7KgeOEW1TjhGoYqBd2BuhlZgm1C3SjJDTvR6VzUZL9KZUNh4t2VA7ZNCKSyqXZ0a0LS6N + 0RI9VetxI0hjCSnRUzVqjXQNaJlyjHQNQO1EJNdTNeUY6RqgFZfUNh4t3VM1YRrpGqCleyq73hCt + uKRyyjFEKy6pHDiGyMWlqZ4pVasqI130ZgK1w5626d4QLeVQO3DQSkxDalYnRrrozQQDKhuPlu6p + HLU0bSYY6RohpxyqNhOMdI3QiksqZ1kjtOKSygWOEVqiN6dyskFN9GbUS5UmugbQQQ9YTUi9eIWY + jVYUUy/gIcajFcXUy1AQ49GaINRrQEGMR85Qpnqm1HY9WqqktvGoqdKUelkWHDi06+tDjKdZUQwx + nrbpHqWvT+Usi97Rp3KyQe/oU9t4tERP7VSJluip7Hr0GpzKrkfp6JvqUTvLGqEVl9Rr+4HzFEr7 + g/rFJXoThNpRi5ZyqBy16H19ahuPVlxS1XiMoQQTS6o1oEx0DYx0DVBLY6obj1qPU9141LaxiQWV + Awe1bWxCvcYrJOxRC2SqBw5qtqK28WhDCVQ3HrX9Su2oRRtKoLrxtE33aA0RqrseOeVQtQ2FMY5A + 7WSDPt1A3QIBrRFCdcejpXkql/Xo1TiVwwa1sKRqd9ZIF30cgcpuR07w1G79GWNMB1C1/WSMMR1A + vZE/E10DY4zpAGoGvTHGbACVTUdLlNQOGtQa3JTKxqNPBlA3bNAqcCoO1oOTDe3mAiDG07JHZQxZ + KwUb+aPqTAbE9WgJh6r9QWNdQ7TyjMrGo88FUDddolfhVM5UaHU4tfMselec2q5H7fFQtZY11kWf + DKByxKImeuq2nox1UZYMULXVChpjQVmgRF2ngzqDtDUerV1J1X6sCXr7g7rdZBP09gfVjUdLlVQd + QzDRNUAtiqnbVTPRRZsLoHbCRGuBUN31aKNPVA57lLkAUz2qBw5qWUx141HbrlQ3Hi3dU7WzaYLe + BKG269Fqcaobj1ZiUjlw0KYDqO56tNEnKmcrtHEEahcKKPW4qR61jUebDqCu8abofX3q1lam6OP1 + 1G29muoaoKZ7qhuPWmJS3XjUEpPqxqOWmFQ3HrWlQG3j0VoKVDceLeUAplQbWwsAFSvsfYw0AAA= + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1139' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:57 GMT + Expires: + - Wed, 15 May 2024 05:36:57 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:13 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '120' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS3MO + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJVM9U3OlWh1qGm+k + pKOEZLwJlY03RjXemMrGm6Eab0Zl481RjTelsvEWqMZTO+wtaWq8oQGq8VSOWkO0lEPlsDc0QXW9 + EXWjFlzwIWUragcOWro3pLLr0dK9AXWNN0JLOVRO90agioF2YW9E2xLTCDnd61E54NESPbUDHjXZ + mFhS2fWoxaUJlWtCI9Ti0oTKBY4xaqKnrvFGkMYSItGbULXAMdI1QE05JlStaI10DUDtRCTXUzXs + jXQNUItLqoc9WrqnarYy0jVAS/dUNt4QtbikbrYy0jVELS6pnXLQmgkm1A4ctHRP5WyF1kyguuvR + Ug6Vc60hWolJ5cBBayZQO3DQmgkmVG0BGumiNROo7nrkEpOqzQQjXSPaFpdGtC0ujdASPZXrEvRm + AvXaxia6BtBBD1hNSL14hZhNs6IYYjxyy9VUz8SCas0/iPFoRTG1jUfOUKZ6VKwGIa5HS5XUaxtD + jEcriqnXNgYbj9bXp2IlDjEerQlCvXoKYjxauqdeiQAxHjnlUDnLGtKsKIY4Ha0opnayQUv01A54 + tERPZePRa3Aqp0qUjr6pHhU7JeCoNUIrLqnXMIYYj5zoTfWo2LyBGI+W7qnterSUQ722H9j16H19 + ahuPVlxS1XjMoQRqG49WGlOv12Cia4A5lEBt19MyYRrpGqAVyNQOHLQCmarZykjXAC1bUdl49KEE + KgcO+lACVasTI120GQcqjtCB0z36UAK1A4e26R5lKIGqbSgjXdqNI4ADHn0cgcqJHr0VQuVUid4K + oWojB3MogaoNTCNd9KEEagcOWnFJbePRikuqGm+MMSVA1ZrQGGNKgKr9cWOMKQGqphxjjCkBahuP + Vo9T23i0hEnVXGusiz4lQOWoRa/HqW08LcehjDHqcWq7Hq1jRW3j0VIOtY1HK9KobDx6VU7lbIVe + lVPb9Wg9HyrnWiO0lENt49FagNQ2Hq3EpHJliD4rQG3XI6d7qrZfQQMKKEuVqDvUAmrCohpP1WaC + ia4BWmlMbePRhrmotxLKRNfABKMVQtVelQnG1D61jUdOlaZ61O1ymuiizwpQNcuaYLRCqG08WmlM + bePRSmNqG49WGlPbeFqWxia6hmitEKqWxia6KKMJ1B5aN8GY2qdykYbeJady1KJPDFA57NFbIVRt + oplgrE2gtuvRSkwqhz36xABVXW+K0eOntvFoJSa1jUdrKVA17E0xevzUNp6WJaYpRkuB2q5HS/dU + jlr0lgJVCwVTXSwj94DF1gIAWHgC4Zc0AAA= + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1166' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:58 GMT + Expires: + - Wed, 15 May 2024 05:36:58 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:15 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '119' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS6MO + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJVM9U0OlWh1qGm+k + pKOEZLwBlY03RjHexJTKxpuhGm9OZePNaWu8BarxZlR2vSVNjTc0oK3xaCnHgrqBY2iC6noqZytw + wYfIVibUNh413RtTO3BQ072xJXXD3ggt5RhT2XhQxYAU9kZUNh61xDShtvHI6V6Pyk5HS/RULo2N + UJMNtQt7I7TiktoBj1pcUjtPGaMmeuoabwRpLCESvTFV85SRrgFayqFqeWakawBqJyK5nqr1uJGu + AS2LSyNdA9R0b0zVetxI1wA13VO3NDbSNUQrLqnaAjTSNUQrLqmccgyRi0tTPWqne7RmgjG1XY+W + 7qmcaw3RUg6VE6YhWolJ1erESBetmUDtqDVCTffUjloj1HRPdeORUw5VmwlGukaoxaURVVuXRrpo + zQQjKqdKtGYC1V2Pmuip6HoTXQPooAesJqRevELMRk2SRiZUa11CjEctio2oVxxAjEdtglDdeOQM + ZapH9cBBLYqpbjxaqqRy1KL19Y2oV0+BoxatCWJEvZY9xHjUdG9IvQIHYjxyyqFyljVELYoNqVcU + Q5yO2nI1ol7bD2I8WqKntvFoiZ56jTOw69FqcGqnSiO04pLarkcrLqmcp4yQE72pniH1hoggYY+W + 7qltPGrKobbr0fr6VDceteVK3UIBYyjBkKr1uJGuAWppTN1shTGUQN1mAsZQAnVrQoyhBKobj1Yg + U7WZYKRrgJqtqNs2xhhKMKLeKJGJroGRLvpQAlVLTCNd2g0lQFyPWiBTtYVmpIvWDqFibxbieOSE + Q9UmFOYwApWjFX0YgdrGo5aWxtQ2HrURQnXjUatxYyqXN2gjCVQcIQKnSrSRBGoneiPkRG+qR9Uc + a4w+IUDdwtIYfULAmKplsTHGhABV2yDGGBMC1DYetVtF3WRvjDEhQNVcZYw+IWBM5cBBmxCgdspB + r8WpnDDRa3GqdsiNIQumYMN/pnpUnCU00TUw1kWfEKBqt8pYF31CgMrGo08IUHUcx1gXvSantvFo + NTmVcy1ah5yKk5DglIM2J0B149FKTGqHPWq/h9rZCqUmp2rzFTQYgrJQiboBD2rmoBpP1VQJSjmo + xlO1kWOC0QqhauvYBKMVQu3AQUuVVK1oTdB749RthZjoos0JUDls0KYEqJtjTdBXJVA7V6Et/6O6 + 69G6VVStZ010DdEKY6q2cUxo2wgxoW0jxEQXbVaAiqtxQMWZLtqsANWNR50VoHKmRWuDUHHVKyRs + UJM9tR2P2h03oXJVhTYnYEJV15uid/ep63pT9EF7Ki56BdWyugaow1DUTTim6N19qrsetbykuutR + mwlUNx4t3VN1HtIUo5lA1Wxlij5oD0r3gMXWAgDnsYdkkjQAAA== + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1234' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:58 GMT + Expires: + - Wed, 15 May 2024 05:36:58 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:16 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '118' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS1 + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJVM9Y3OlWh1qGm+k + pKOEZLwFlY03RjHeyJLKxpuhGG9sTGXjzWlrvAWq8SZUdr0lqvFUDntDA1TjqZxyDFFTDrXTvaEJ + iuuNqBz24IIPka2MqJxrDVHTvRGV070harqnduAYoaYcI1PqpnsjUMWAFPZUjloj1BLTyIzKrkdO + 93pUNhst0VM5VRrRONmgFpdGhlQOHNTi0tCIusYboyZ6Q6omGyNIYwmR6A2omqeMdA1QU46hATUD + x0jXANRORHI9tQMHtbg0oGq6N9I1QE33VA971HRvSNXC3kjXELW4NKRqcWmka4haXFLdeOTi0kTP + ktquR073JnqWVE73KM0EEz1LKudaQ+SUQwPjkUtMEz1LKidMlGaCiZ4FVRuYRroozQQTPQsqpxyU + ZoKJngVVqxMjXSPkEpOqzQQjXSPk4tJEz4La8YpcXJromVO1X2Kka4Sa6Kke8KiJnoquN9E1gA56 + wGpC6sUrxGzkothEz4J6hRnEeNSi2IJ67TOI8ahFsQX1ykqI8cgZiqrFAcR4mqVKiPGoqZKKiR5s + PEpfn6qFGcR45CaIiZ45laMWpQliomdGbeORUw6VsyxKR99Ez5zKWRalo0/9EgGt/UHtAscQLdFT + rwYHp0r0Gpx61SDEeNoWl0ZoxSW1XY+c6E30zKnXY4MEDmoTxJx6bT+I8agph9quR+nrUz9bgWc+ + YG0EEz1zqkYt2lCCiZ4ZVcPeSNcArRVC1WYC2lCCiZ4F9fr6JroGRroGqAmTuhUt2lACVZveENej + tUKonXJQs5UFVQsFtKEE6kctyoyDiZ4l9fol4LBHmXGg6kgFxHjUApmKnXGI8ajp3pLKhQJKVU7V + NpSRLto4giWVSwS0cQRqhwxKK8RUz4B64wjgeDVCboWY6lG1fYk2kmCqZ0Dl8gZtwoHqxiOXltQP + G+TC0lTPgKr1oDHqhAC1ixtj1AkBEz3qpnpj1AkBGrgerTSjao/QGHVCgKoDoya6Bsa6Bsjp0kTP + kqpFgjHqhABVR43BrkfpjVM5VxnrolTi1M9VKJW4qZ4BVbucxpD1UrCWvakeFWeSIEGPnHBM9Qyo + 2j4z1kWpxKlvPEo9Tv2oRanHaWA8areH2gUmynwA1XMVyowA9U1HnRCgbsPbGHVCgNqNEGNdI+R6 + nKpNV9BQBcoqJepmWFD7D9V4qlaDoBIH1Xiqtv5MUJsgVE6UJqgtEGoXxSaodbipngFVOyUmugbI + iZLaad5EF2U+wFTPkKpdZRPUFoipniGVAwetBULFBRWgRIleiRtStZY10UWZEjDVM6RqT9xEF2VK + wFSP6q5HbYJQ3fWo6Z7aKQetM07twEHrjFNxrQw4YaJMCVA/W6E1Qai4Pg/ieuQ+m6ke1Y1HTTlU + 7VOZ6KLMCJjqUXHJK6imQu3sUztsTFGH7KldJpjqGqCOQVFx5SUkcFATDtWNR269mupRtzYxRW8o + UN141GRP7cBBbyhQtSY3Re/tg8pjwGJrATtW/JqQNAAA + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1344' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:59 GMT + Expires: + - Wed, 15 May 2024 05:36:59 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:09 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '117' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS2 + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJRM9S1OlWh1qGm+k + pKOEZLwFlY03RjHewpjKxpuhGG9JbePNUY03pLLrLVCNp7brLZGMN9UzoLLxhgaoxptQN3AMkVOO + qZ6BEZWNN0FyvYmehQGVjQcVfEjZitrGo6Z7amcrQ9R0b0HlQsEIOeWY6FlYUjfsjUAVAyLsLcyo + bDxqiUl11yOnez0qOx010VtSOU8ZoSUbKpcIRqjFpTmVyzMj5OLSRM+Myq43Rk301HW9EaSxhEj0 + plRN9Ea6Bqgph7qBY6RrgFpcmppTM90b6RqgFpdmVC2NjXQNUNO9KVWLSyNdA7R0T9VWiJGuIWpx + aU5t41GLS2qne5RmgomeCZXTvSFqujemcsIE948QudaEqmWOka4hasoxoWqJaaRriFpimlA55aA1 + E4ypHDhozQRjKgeOEWq6N6Z24CCXmFRtJhjpGqEWl0ZUzlNozQQjKpfGaM0EqrseNdEbUS/ZmOga + QAc9YCUC9eIVYjZakqS205FbriZ6VMxQENejFcXUq2UhxiNnKBM9E+qlSojxqEWxMfXyFMR41FRJ + beNR+vomelSsBsGuR2uCUDHLQoxHTfeG1KtIIMYjpxwqZ1lDtKKYej02iNNRW65UrGIhxqMlemoH + PFqip944Atj16DU49dp+EOPRikvqNRAgxqMVl1QOeyPkRG+iZ0Tl0hitCULthInW1zeicspB6+tT + uzQGz3zA2ggmekZUTZgYQwlUbJ+Z6BoY6RqglsbUDRyMoQQqdgghrkctkI2pmnIwhhKo2KWCuB61 + QKZ64KAWyCZULRSMdA1RUw61XY82lEDFMS5w2KMNJVBxhA5iPGqBTHXjUdM91QMHOeVQtQ1lpIs2 + jmBK5SyLNo5A7ZBBa4WYUdv1qK0QMyrXJWj1ONVdj9p+pbbjUUtLqscscpqn6oSDia6BMcaMAFUb + gMYYMwJUbb4aY8wIUNv1qMWZKfVWVUDCHjVdUtt01HRJ3WrWGH1CwJTKMYtWi1NxtgQc9Oi1OLVd + j9qtMqNqE8cYsmAK0bQ3p2p/3xh9QoCKkzGQsEcr0agcODStyI110StyKoc9WkVO3WaIsS5ah9yU + ygUmWkVO3ealsS7anADVXY9aYlI97JHTPVVbr6ChHJSFStQtEUA9B1TjqTbxbqJrACoTUEynbmkJ + sgHVeKrWsybobRDqlpYmGPP6VC0tTXQNkBOliZ45VQsEE120KQFLqra9TdAbIVRc2QlKNuhDCVRc + 4QYxHrUzTnXXo7ZeqR72qK1XqrsetTC2pHK6R1uVQO3AQavGqW48an+ciosXwQnTCLX5SsXFixDj + 0dI9VWc5TdAXJlhS23jUEpPaUYsyK2CqZ0DVAtkUvb9P3cAxRR+2t6BqeW+qa4CW7qnabTNFXwFo + QdW2vSn6CkCqG49aYlpQO+Wgpnuqlsem6A0FaicctP4+YBamSrWxtQAzSaJYkzQAAA== + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1303' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:59 GMT + Expires: + - Wed, 15 May 2024 05:36:59 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:13 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '116' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS3 + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJRM9czOlWh1qGm+k + pKOEZLwFlY03RjHezIjKxpuhGG9ObePNUYw3M6Gy6y1QjTelsvGWKMabm1PXeEMDFOMtDKhsPGrK + obrxJiiuN6VytgIXfIhsZUblbGWImu5NLakc9rRN90aoKYfahYIRqGJACnsqJ0wj1BKT6q5HTvd6 + 1I1XI9REb0blEsEILdlQO+BRi0sTKid6I9Ti0oTKrjdGTfQmVC0RjCCNJUSiNzakZsox0jVATTnU + DRwjXQNQOxHJ9cZUdj1qcWlMbeNR0z3Vwx4t3VO1mWCka4haXJpQtQ1lpGuIWlxS3Xjk4tJEz5DK + 2coQNd0bULXMMYL0jxDp3pDKCdMQNeUYUjvloJaY1DYerZlgQNUmmpEuWjOB6sajpnsDqvYdjHSN + kEtMqjYTjHSNUItLAyonG5RmgrGeJVVbIUa6RqiJ3oDK5RlaM8GAehWtia4BdNADViJQL14hZqMl + SeoVZhDjUYtiA+rFK8R41KLYkHoZCmI8coYy0TOktutRU6UhtZMNalFMxXoKHDhofX1D6rWNIcaj + NkGomGUhxiOne2M9S+qVCBDjkVMOlbMsWkef6iGD2nI1pHbIoCV66jVvIAGPmuip2PYDG4/W0ad2 + gWOEWlwaUq95A3E9WnFJ5cIepf1hokftlIPWBKFi0xISOGgph8rlGVpfn9opBzzzAWsjmOhRsX1m + omuANpRgrGdJ1YRppGuAXBqb6FE3cDCGEoyoWo8b6Rqgto2p7nq0ApnaYY9aIBtRtbw30jVAzVZG + 1Os4gBMm2lAC1Y1HLZBNqNrANNJFG0owpt5IBSRwkFshJnrGVE45aA0RE6pW5Ua6hsgph6ptKCNd + tHEEagc82jgCtUMGrRVCxVFvcLJBa4WYUDnLotXjVBz1hrgetbiktuNRS0tqFwhoIwnUTTjGGDMC + VC3rjdFnBIyp2r40xpgRoLbrUatxY2obj5oujaha1hvrGqAmTOpWhMboMwJGVK1KjNFnBKg4G2Oi + a2Csa4hajRtTtQFojF6Nm1A7cFCrcVOqjhMZ66LNCJhSOd2jVOMmeiZUDnu0mtyEyoGDXpNTOXDQ + anLqttCMUWcETPSoXSCj1eTUbUUZ66JMClC7+WqMPilA1aa9sS5KTU7V1itotAJ1oRJV0zyoEUVb + 41ELY+q2/0zQGyHULYxN0BshplRNNibo1ThVaxIT9M44dYt6E120KQEqri4ERSt6G4TqxqMOQlG1 + njJBn9Y3p2rzz0QXrS9uQdW+uImuIWrjlepBj9p4pbrrkUcSTPQsqFxeolXiVDcetbyk4mpvcK5C + WwBI7YSJNilgQdX+uAn6ugQLKhfHKLW4iR6VMy3anIAFVYscU/TevjlVu+Om6IP25lTNVaa6BqjJ + 3oyqJZop+qA9Fdfxg9oIugaoBSZV63FTjFYCtcMGtbyksuPRWglmVC0RTNH7+oCZmSnVxtYCAD8E + HwuQNAAA + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1317' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:35:59 GMT + Expires: + - Wed, 15 May 2024 05:36:59 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:14 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '115' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS5 + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJRM9M3OlWh1qGm+k + pKOEZLwplY03RjHexJLKxpuhGG9mQGXjzVGMNzWmsvEWqMYbUtl4SxTjzagctYYGtDUeNeWYmVE3 + cAxNUFxvYkRl40EFHyJbmVLbeNR0b0LlhGmImu5NqJxyjFBTjokJdcPeCFQxIMLehMrZygi1xKS6 + 65HTvR6VQwYt0VO5NDZCTTbGFlR2PWpxaURt16MWl0ZUzrLGqInemKqp0gjSWEIkekOq5ikjXQPU + lGNE1QLHSNcAtbikuutRi0tDqkatka4Baro3pHbUoqV7KketIWpxaUTVwt5I1xC1uKR2yjFELi5N + 9Ayo2gI00kVpJhjrWVLbeOR0b6xnSeWUY4iccoz1LKmdcpBLTOobj9JMMNazoGoL0EgXpZlgrGdB + 1Y6VkS5KM4EGxiOnHKo2E4x0jZCLS2M9C6pWtEa6KM0EYz1zqjYTjHSNUBO9BZWrKiPURG9BvTxl + omsAHfSA1ePUi1eI2chFsbGeJfVCBmI8clFM1bISYjxyE8RYz5J6+RViPHKGMtEzoF4bAWI8aqqk + uutRUyW1jUfp6xvrWVKvRAAHDkoThPopB6UJYqxH7SwLHuSkUZY1RC2KLanXOIMEPGrLldqJHqX9 + YaJnQOWy0hA50ZvoGVCvIgEHDkoNbqJnQOXi0gi5uDTRM6Be8wbieuTikgbGoxWX1Gu5QlyPnO6p + n3LQKnFqF5dofX0qdkrAgQOe+YAVOFTtNZjoGqANJRjrWVCvzwMxHq0VQtW6BHMogaq51kjXAC1h + Utt4tAKZqoWCka4BcivERI+KAyGQqEUtkKk4jAM2HqUeN9EzpHLYow0lUHGEDuJ61AKZiuMsEONR + C2QqDl9CjEdN91QcfIUYj5xyqNrtMdJFGUcw0aN2wKOMI5joUTlRojVCjKltPGojxIiqTSi0kQQT + PWqnGpSRBBM9Y6r22dBGEkz0jKhcGKM0QqhtvDHGjABV+8vGGDMCVG0AGmPMCFA13RujV+PUrQiN + 0WcEDKgd9qjVOHW7Dsa6KN1xaverjNFnBAyp2qc11kWrxg2p2r40Rp0RoHaRZgxZMQVr25voUbe8 + N9ZF65EbU7VIM9ZF65FTtwllTNua3Bh1RoD6BTJaVU7VyspY1wit/UflAhNlTsBEj7rNS2PUOQET + PUOqtkOMUecETPSMqFxZodTkVG29gvr7KAuVjKk6hgZqe6MaT9XC2ETXALV9SXXXo/apqJrmTdDb + IFRcz2Kia2CC3hmn4iIuiPHIXSoTPWOqtkFMdFGmBEz0zKiapUzQ2yBUNx55EMpEz5TKuQplSsBE + j4pLL8FRa4jaGTejahPHRBdt+Z8ZVWsqE/Q2iBlVy3oT9DYIFReOgsMerRanuvGoBaYZlYs0I9QC + 04zK6R6tEULlIgetDULthINSi1M/06JNCphTNVeZonf3qRuzproGaAUmVaPWFL2dYELVMsEUvbtP + deNRR+2pbjxqd5+qTTRTXQPUdoIJlWMWrZ1AxZXwoAYaem8fMFOl2thaAPDF8iiRNAAA + headers: + Accept-Ranges: + - bytes + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Length: + - '1362' + Content-Type: + - application/json; charset=UTF-8 + Date: + - Wed, 15 May 2024 05:36:00 GMT + Expires: + - Wed, 15 May 2024 05:37:00 GMT + Last-Modified: + - Tue, 14 May 2024 20:18:16 GMT + Strict-Transport-Security: + - max-age=86400 + Vary: + - Accept-Encoding + x-rate-limit-limit: + - '120' + x-rate-limit-remaining: + - '120' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://api.stlouisfed.org/fred/series/observations?api_key=MOCK_API_KEY&file_type=json&observation_start=2023-11-01&series_id=DGS7 + response: + body: + string: !!binary | + H4sIAAAAAAAEA6pWKkpNzCnJzE2NLy5JLCpRslIyMjAy0TUw1TU0VdJByKbmpaDL5ScVpxaVJZZk + 5uchazbWNTTUNTBU0lFCVgDRb2lpaalraKRrDJIuzcssKVayUsrJzAMpLi0pKC2JL6ksSFWyMtRR + SsvMSYXylLKK88FKilJSi+KTKpWsUIxOSSxJVdJRKs4vKonPBylRslJKLE5W0lFKzi/NK1GyMjS2 + 1FHKT0srTi1RsjLQUcrJzM0ECRuAAIozi5WsoikJErBTwEGICIWyxJzSVCUrJRM9c1OlWh1qGm+k + pKOEMN7MgsrGG6MYb0pt15uhGG9mRmXXm6MYb0rtwLFANd6Eyq63RDGe2lFraEBb41FTjpkldQPH + 0ATF9SZUTpjggg+RrUypnDANUdO9iTmVAwc13VPbeCPUlGNC5cAxAlUMiLA3oXK2MkItManueuR0 + r0fdeDVCTfSmhlQ2Hi3ZGFPZeNTi0pjayQa1uDSicmFvjJrojalqvBGksYRI9EZG1Ax7I10D1JRj + bEBl40HtRCTXU9t41OLSkKopx0jXADXdU9141HRP3YRppGuIWlwaUbUuMdI1RC0ujahaGhvpGiIX |