Skip to content

Commit

Permalink
[Feature] Add Forward PE Estimates (#6398)
Browse files Browse the repository at this point in the history
* forward_pe

* ruff

* merge branch develop

* mypy

* typo

---------

Co-authored-by: Igor Radovanovic <[email protected]>
Co-authored-by: montezdesousa <[email protected]>
  • Loading branch information
3 people committed May 14, 2024
1 parent 17a7e7d commit 0eee602
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Forward PE Estimates Standard Model."""

from typing import Optional

from pydantic import Field, field_validator

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 ForwardPeEstimatesQueryParams(QueryParams):
"""Forward PE Estimates Query Parameters."""

symbol: Optional[str] = Field(
default=None,
description=QUERY_DESCRIPTIONS["symbol"],
)

@field_validator("symbol", mode="before", check_fields=False)
@classmethod
def to_upper(cls, v):
"""Convert field to uppercase."""
return v.upper() if v else None


class ForwardPeEstimatesData(Data):
"""Forward PE Estimates Data."""

symbol: str = Field(description=DATA_DESCRIPTIONS.get("symbol", ""))
name: Optional[str] = Field(default=None, description="Name of the entity.")
year1: Optional[float] = Field(
default=None,
description="Estimated PE ratio for the next fiscal year.",
)
year2: Optional[float] = Field(
default=None,
description="Estimated PE ratio two fiscal years from now.",
)
year3: Optional[float] = Field(
default=None,
description="Estimated PE ratio three fiscal years from now.",
)
year4: Optional[float] = Field(
default=None,
description="Estimated PE ratio four fiscal years from now.",
)
year5: Optional[float] = Field(
default=None,
description="Estimated PE ratio five fiscal years from now.",
)
29 changes: 29 additions & 0 deletions openbb_platform/extensions/equity/integration/test_equity_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1953,3 +1953,32 @@ def test_equity_ownership_form_13f(params, headers):
result = requests.get(url, headers=headers, timeout=10)
assert isinstance(result, requests.Response)
assert result.status_code == 200


@parametrize(
"params",
[
(
{
"symbol": "NVDA,MSFT",
"provider": "intrinio",
}
),
(
{
"symbol": None,
"provider": "intrinio",
}
),
],
)
@pytest.mark.integration
def test_equity_estimates_forward_pe(params, headers):
"""Test the equity estimates forward_pe 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/equity/estimates/forward_pe?{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 @@ -1819,3 +1819,31 @@ def test_equity_ownership_form_13f(params, obb):
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0


@parametrize(
"params",
[
(
{
"symbol": "NVDA,MSFT",
"provider": "intrinio",
}
),
(
{
"symbol": None,
"provider": "intrinio",
}
),
],
)
@pytest.mark.integration
def test_equity_estimates_forward_pe(params, obb):
"""Test the equity estimates forward_pe endpoint."""
params = {p: v for p, v in params.items() if v}

result = obb.equity.estimates.forward_pe(**params)
assert result
assert isinstance(result, OBBject)
assert len(result.results) > 0
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,25 @@ async def forward_eps(
) -> OBBject:
"""Get forward EPS estimates."""
return await OBBject.from_query(Query(**locals()))


@router.command(
model="ForwardPeEstimates",
examples=[
APIEx(parameters={"provider": "intrinio"}),
APIEx(
parameters={
"symbol": "AAPL,MSFT,GOOG",
"provider": "intrinio",
}
),
],
)
async def forward_pe(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject:
"""Get forward PE estimates."""
return await OBBject.from_query(Query(**locals()))
133 changes: 133 additions & 0 deletions openbb_platform/openbb/assets/reference.json
Original file line number Diff line number Diff line change
Expand Up @@ -6750,6 +6750,139 @@
},
"model": "ForwardEpsEstimates"
},
"/equity/estimates/forward_pe": {
"deprecated": {
"flag": null,
"message": null
},
"description": "Get forward PE estimates.",
"examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.equity.estimates.forward_pe(provider='intrinio')\nobb.equity.estimates.forward_pe(symbol='AAPL,MSFT,GOOG', provider='intrinio')\n```\n\n",
"parameters": {
"standard": [
{
"name": "symbol",
"type": "Union[str, List[str]]",
"description": "Symbol to get data for. Multiple items allowed for provider(s): intrinio.",
"default": null,
"optional": true
},
{
"name": "provider",
"type": "Literal['intrinio']",
"description": "The provider to use for the query, by default None. If None, the provider specified in defaults is selected or 'intrinio' if there is no default.",
"default": "intrinio",
"optional": true
}
],
"intrinio": []
},
"returns": {
"OBBject": [
{
"name": "results",
"type": "List[ForwardPeEstimates]",
"description": "Serializable results."
},
{
"name": "provider",
"type": "Optional[Literal['intrinio']]",
"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": "symbol",
"type": "str",
"description": "Symbol representing the entity requested in the data.",
"default": "",
"optional": false
},
{
"name": "name",
"type": "str",
"description": "Name of the entity.",
"default": null,
"optional": true
},
{
"name": "year1",
"type": "float",
"description": "Estimated PE ratio for the next fiscal year.",
"default": null,
"optional": true
},
{
"name": "year2",
"type": "float",
"description": "Estimated PE ratio two fiscal years from now.",
"default": null,
"optional": true
},
{
"name": "year3",
"type": "float",
"description": "Estimated PE ratio three fiscal years from now.",
"default": null,
"optional": true
},
{
"name": "year4",
"type": "float",
"description": "Estimated PE ratio four fiscal years from now.",
"default": null,
"optional": true
},
{
"name": "year5",
"type": "float",
"description": "Estimated PE ratio five fiscal years from now.",
"default": null,
"optional": true
}
],
"intrinio": [
{
"name": "peg_ratio_year1",
"type": "float",
"description": "Estimated Forward PEG ratio for the next fiscal year.",
"default": null,
"optional": true
},
{
"name": "eps_ttm",
"type": "float",
"description": "The latest trailing twelve months earnings per share.",
"default": null,
"optional": true
},
{
"name": "last_udpated",
"type": "date",
"description": "The date the data was last updated.",
"default": null,
"optional": true
}
]
},
"model": "ForwardPeEstimates"
},
"/equity/discovery/gainers": {
"deprecated": {
"flag": null,
Expand Down
92 changes: 92 additions & 0 deletions openbb_platform/openbb/package/equity_estimates.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ROUTER_equity_estimates(Container):
analyst_search
consensus
forward_eps
forward_pe
forward_sales
historical
price_target
Expand Down Expand Up @@ -468,6 +469,97 @@ def forward_eps(
)
)

@exception_handler
@validate
def forward_pe(
self,
symbol: Annotated[
Union[str, None, List[Optional[str]]],
OpenBBField(
description="Symbol to get data for. Multiple comma separated items allowed for provider(s): intrinio."
),
] = None,
provider: Annotated[
Optional[Literal["intrinio"]],
OpenBBField(
description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default."
),
] = None,
**kwargs
) -> OBBject:
"""Get forward PE estimates.
Parameters
----------
symbol : Union[str, None, List[Optional[str]]]
Symbol to get data for. Multiple comma separated items allowed for provider(s): intrinio.
provider : Optional[Literal['intrinio']]
The provider to use for the query, by default None.
If None, the provider specified in defaults is selected or 'intrinio' if there is
no default.
Returns
-------
OBBject
results : List[ForwardPeEstimates]
Serializable results.
provider : Optional[Literal['intrinio']]
Provider name.
warnings : Optional[List[Warning_]]
List of warnings.
chart : Optional[Chart]
Chart object.
extra : Dict[str, Any]
Extra info.
ForwardPeEstimates
------------------
symbol : str
Symbol representing the entity requested in the data.
name : Optional[str]
Name of the entity.
year1 : Optional[float]
Estimated PE ratio for the next fiscal year.
year2 : Optional[float]
Estimated PE ratio two fiscal years from now.
year3 : Optional[float]
Estimated PE ratio three fiscal years from now.
year4 : Optional[float]
Estimated PE ratio four fiscal years from now.
year5 : Optional[float]
Estimated PE ratio five fiscal years from now.
peg_ratio_year1 : Optional[float]
Estimated Forward PEG ratio for the next fiscal year. (provider: intrinio)
eps_ttm : Optional[float]
The latest trailing twelve months earnings per share. (provider: intrinio)
last_udpated : Optional[date]
The date the data was last updated. (provider: intrinio)
Examples
--------
>>> from openbb import obb
>>> obb.equity.estimates.forward_pe(provider='intrinio')
>>> obb.equity.estimates.forward_pe(symbol='AAPL,MSFT,GOOG', provider='intrinio')
""" # noqa: E501

return self._run(
"/equity/estimates/forward_pe",
**filter_inputs(
provider_choices={
"provider": self._get_provider(
provider,
"/equity/estimates/forward_pe",
("intrinio",),
)
},
standard_params={
"symbol": symbol,
},
extra_params=kwargs,
info={"symbol": {"intrinio": {"multiple_items_allowed": True}}},
)
)

@exception_handler
@validate
def forward_sales(
Expand Down
Loading

0 comments on commit 0eee602

Please sign in to comment.