Skip to content

Commit

Permalink
[Feature] Government Yield Curves + Chart (#6417)
Browse files Browse the repository at this point in the history
* stashing

* ecb yield curve

* field_description

* federal reserve yield curve

* econdb yield curve

* countries literal for python 3.9

* list date

* fmp yield curve

* fred yield curve

* integration tests

* chart integration tests

* static assets

* black

* ruff

* pylint

* more pylint

* more pylint

* now black

* country not a standard param

* mypy

* merge branch develop

* add more countries

* econdb date filter

* mypy

* future linting

* make to_chart work

* plot_bgcolor should be 'rbga(255,255,255,0)'

* push deprecation

* push deprecation

---------

Co-authored-by: Igor Radovanovic <[email protected]>
Co-authored-by: hjoaquim <[email protected]>
  • Loading branch information
3 people authored May 21, 2024
1 parent 63b8d60 commit 8baf4d7
Show file tree
Hide file tree
Showing 36 changed files with 139,102 additions and 183 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Yield Curve 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 YieldCurveQueryParams(QueryParams):
"""Yield Curve Query."""

date: Optional[str] = Field(
default=None,
description=QUERY_DESCRIPTIONS.get("date", "")
+ " By default is the current data.",
)


class YieldCurveData(Data):
"""Yield Curve Data."""

date: Optional[dateType] = Field(
default=None,
description=DATA_DESCRIPTIONS.get("date", ""),
)
maturity: str = Field(description="Maturity length of the security.")
rate: float = Field(
description="The yield as a normalized percent (0.05 is 5%)",
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
)
Original file line number Diff line number Diff line change
Expand Up @@ -623,3 +623,46 @@ def test_fixedincome_corporate_bond_prices(params, headers):
result = requests.get(url, headers=headers, timeout=40)
assert isinstance(result, requests.Response)
assert result.status_code == 200


@parametrize(
"params",
[
({"date": "2023-05-01,2024-05-01", "provider": "fmp"}),
(
{
"date": "2023-05-01",
"country": "united_kingdom",
"provider": "econdb",
"use_cache": True,
}
),
(
{
"provider": "ecb",
"yield_curve_type": "par_yield",
"date": None,
"rating": "aaa",
"use_cache": True,
}
),
(
{
"provider": "fred",
"yield_curve_type": "nominal",
"date": "2023-05-01,2024-05-01",
}
),
({"provider": "federal_reserve", "date": "2023-05-01,2024-05-01"}),
],
)
@pytest.mark.integration
def test_fixedincome_government_yield_curve(params, headers):
"""Test the treasury rates 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/government/yield_curve?{query_str}"
result = requests.get(url, headers=headers, timeout=10)
assert isinstance(result, requests.Response)
assert result.status_code == 200
Original file line number Diff line number Diff line change
Expand Up @@ -578,3 +578,45 @@ def test_fixedincome_corporate_bond_prices(params, obb):
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0


@parametrize(
"params",
[
({"date": "2023-05-01,2024-05-01", "provider": "fmp"}),
(
{
"date": "2023-05-01",
"country": "united_kingdom",
"provider": "econdb",
"use_cache": True,
}
),
(
{
"provider": "ecb",
"yield_curve_type": "par_yield",
"date": None,
"rating": "aaa",
"use_cache": True,
}
),
(
{
"provider": "fred",
"yield_curve_type": "nominal",
"date": "2023-05-01,2024-05-01",
}
),
({"provider": "federal_reserve", "date": "2023-05-01,2024-05-01"}),
],
)
@pytest.mark.integration
def test_fixedincome_government_yield_curve(params, obb):
"""Test the government yield curve endpoint."""
params = {p: v for p, v in params.items() if v}

result = obb.fixedincome.government.yield_curve(**params)
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Fixed Income Government Router."""

from openbb_core.app.deprecation import OpenBBDeprecationWarning
from openbb_core.app.model.command_context import CommandContext
from openbb_core.app.model.example import APIEx
from openbb_core.app.model.obbject import OBBject
Expand All @@ -16,8 +17,46 @@
# pylint: disable=unused-argument


@router.command(
model="YieldCurve",
examples=[
APIEx(parameters={"provider": "federal_reserve"}),
APIEx(parameters={"date": "2023-05-01,2024-05-01", "provider": "fmp"}),
APIEx(
parameters={
"date": "2023-05-01",
"country": "united_kingdom",
"provider": "econdb",
}
),
APIEx(parameters={"provider": "ecb", "yield_curve_type": "par_yield"}),
APIEx(
parameters={
"provider": "fred",
"yield_curve_type": "real",
"date": "2023-05-01,2024-05-01",
}
),
],
)
async def yield_curve(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject: # type: ignore
"""Get yield curve data by country and date."""
return await OBBject.from_query(Query(**locals()))


@router.command(
model="USYieldCurve",
deprecated=True,
deprecation=OpenBBDeprecationWarning(
message="This endpoint will be removed in a future version. Use, `/fixedincome/government/yield_curve`, instead.",
since=(4, 2),
expected_removal=(4, 4),
),
examples=[
APIEx(parameters={"provider": "fred"}),
APIEx(parameters={"inflation_adjusted": True, "provider": "fred"}),
Expand All @@ -35,6 +74,12 @@ async def us_yield_curve(

@router.command(
model="EUYieldCurve",
deprecated=True,
deprecation=OpenBBDeprecationWarning(
message="This endpoint will be removed in a future version. Use, `/fixedincome/government/yield_curve`, instead.",
since=(4, 2),
expected_removal=(4, 4),
),
examples=[
APIEx(parameters={"provider": "ecb"}),
APIEx(parameters={"yield_curve_type": "spot_rate", "provider": "ecb"}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,3 +719,42 @@ def test_charting_etf_holdings(params, headers):
assert chart
assert not fig
assert list(chart.keys()) == ["content", "format"]


@parametrize(
"params",
[
(
{
"provider": "econdb",
"country": "united_kingdom",
"date": None,
"chart": True,
}
),
(
{
"provider": "fred",
"date": "2023-05-10,2024-05-10",
"chart": True,
}
),
],
)
@pytest.mark.integration
def test_charting_fixedincome_government_yield_curve(params, headers):
"""Test chart fixedincome government yield curve."""
params = {p: v for p, v in params.items() if v}
body = (json.dumps({"extra_params": {"chart_params": {"title": "test chart"}}}),)
query_str = get_querystring(params, [])
url = f"http://0.0.0.0:8000/api/v1/fixedincome/government/yield_curve?{query_str}"
result = requests.get(url, headers=headers, timeout=10, json=body)
assert isinstance(result, requests.Response)
assert result.status_code == 200

chart = result.json()["chart"]
fig = chart.pop("fig", {})

assert chart
assert not fig
assert list(chart.keys()) == ["content", "format"]
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,34 @@ def test_charting_etf_holdings(params, obb):
assert len(result.results) > 0
assert result.chart.content
assert isinstance(result.chart.fig, OpenBBFigure)


@parametrize(
"params",
[
(
{
"provider": "econdb",
"country": "united_kingdom",
"date": None,
"chart": True,
}
),
(
{
"provider": "fred",
"date": "2023-05-10,2024-05-10",
"chart": True,
}
),
],
)
@pytest.mark.integration
def test_charting_fixedincome_government_yield_curve(params, obb):
"""Test chart fixedincome government yield curve."""
result = obb.fixedincome.government.yield_curve(**params)
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0
assert result.chart.content
assert isinstance(result.chart.fig, OpenBBFigure)
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,9 @@ def to_chart(
)
kwargs["provider"] = self._obbject.provider # pylint: disable=protected-access
kwargs["extra"] = self._obbject.extra # pylint: disable=protected-access
kwargs["extra_params"] = kwargs["extra"]["metadata"].arguments.get(
"extra_params"
)
if "kwargs" in kwargs:
_kwargs = kwargs.pop("kwargs")
kwargs.update(_kwargs.get("chart_params", {}))
Expand Down
Loading

0 comments on commit 8baf4d7

Please sign in to comment.