Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add Intrinio to equity.historical_market_cap #6932

Merged
merged 2 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion openbb_platform/extensions/equity/integration/test_equity_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2082,7 +2082,16 @@ def test_equity_compare_company_facts(params, headers):
"end_date": None,
"provider": "fmp",
}
)
),
(
{
"symbol": "AAPL,MSFT",
"start_date": None,
"end_date": None,
"provider": "intrinio",
"interval": "week",
}
),
],
)
@pytest.mark.integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1945,7 +1945,16 @@ def test_equity_compare_company_facts(params, obb):
"end_date": None,
"provider": "fmp",
}
)
),
(
{
"symbol": "AAPL,MSFT",
"start_date": None,
"end_date": None,
"provider": "intrinio",
"interval": "week",
}
),
],
)
@pytest.mark.integration
Expand Down
24 changes: 20 additions & 4 deletions openbb_platform/openbb/assets/reference.json
Original file line number Diff line number Diff line change
Expand Up @@ -29944,7 +29944,7 @@
{
"name": "symbol",
"type": "Union[str, List[str]]",
"description": "Symbol to get data for. Multiple items allowed for provider(s): fmp.",
"description": "Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio.",
"default": "",
"optional": false,
"choices": null
Expand All @@ -29966,7 +29966,22 @@
"choices": null
}
],
"fmp": []
"fmp": [],
"intrinio": [
{
"name": "interval",
"type": "Literal['week', 'month', 'quarter', 'year']",
"description": "None",
"default": "week",
"optional": true,
"choices": [
"week",
"month",
"quarter",
"year"
]
}
]
},
"returns": {
"OBBject": [
Expand All @@ -29977,7 +29992,7 @@
},
{
"name": "provider",
"type": "Optional[Literal['fmp']]",
"type": "Optional[Literal['fmp', 'intrinio']]",
"description": "Provider name."
},
{
Expand Down Expand Up @@ -30024,7 +30039,8 @@
"choices": null
}
],
"fmp": []
"fmp": [],
"intrinio": []
},
"model": "HistoricalMarketCap"
},
Expand Down
29 changes: 20 additions & 9 deletions openbb_platform/openbb/package/equity.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def historical_market_cap(
symbol: Annotated[
Union[str, List[str]],
OpenBBField(
description="Symbol to get data for. Multiple comma separated items allowed for provider(s): fmp."
description="Symbol to get data for. Multiple comma separated items allowed for provider(s): fmp, intrinio."
),
],
start_date: Annotated[
Expand All @@ -93,9 +93,9 @@ def historical_market_cap(
OpenBBField(description="End date of the data, in YYYY-MM-DD format."),
] = None,
provider: Annotated[
Optional[Literal["fmp"]],
Optional[Literal["fmp", "intrinio"]],
OpenBBField(
description="The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp."
description="The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp, intrinio."
),
] = None,
**kwargs
Expand All @@ -105,20 +105,22 @@ def historical_market_cap(
Parameters
----------
symbol : Union[str, List[str]]
Symbol to get data for. Multiple comma separated items allowed for provider(s): fmp.
Symbol to get data for. Multiple comma separated items allowed for provider(s): fmp, intrinio.
start_date : Union[date, None, str]
Start date of the data, in YYYY-MM-DD format.
end_date : Union[date, None, str]
End date of the data, in YYYY-MM-DD format.
provider : Optional[Literal['fmp']]
The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp.
provider : Optional[Literal['fmp', 'intrinio']]
The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp, intrinio.
interval : Literal['week', 'month', 'quarter', 'year']
None

Returns
-------
OBBject
results : List[HistoricalMarketCap]
Serializable results.
provider : Optional[Literal['fmp']]
provider : Optional[Literal['fmp', 'intrinio']]
Provider name.
warnings : Optional[List[Warning_]]
List of warnings.
Expand Down Expand Up @@ -149,7 +151,7 @@ def historical_market_cap(
"provider": self._get_provider(
provider,
"equity.historical_market_cap",
("fmp",),
("fmp", "intrinio"),
)
},
standard_params={
Expand All @@ -159,7 +161,16 @@ def historical_market_cap(
},
extra_params=kwargs,
info={
"symbol": {"fmp": {"multiple_items_allowed": True, "choices": None}}
"symbol": {
"fmp": {"multiple_items_allowed": True, "choices": None},
"intrinio": {"multiple_items_allowed": True, "choices": None},
},
"interval": {
"intrinio": {
"multiple_items_allowed": False,
"choices": ["week", "month", "quarter", "year"],
}
},
},
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
from openbb_intrinio.models.historical_dividends import (
IntrinioHistoricalDividendsFetcher,
)
from openbb_intrinio.models.historical_market_cap import (
IntrinioHistoricalMarketCapFetcher,
)
from openbb_intrinio.models.income_statement import IntrinioIncomeStatementFetcher
from openbb_intrinio.models.index_historical import IntrinioIndexHistoricalFetcher
from openbb_intrinio.models.insider_trading import IntrinioInsiderTradingFetcher
Expand Down Expand Up @@ -90,6 +93,7 @@
"FredSeries": IntrinioFredSeriesFetcher,
"HistoricalAttributes": IntrinioHistoricalAttributesFetcher,
"HistoricalDividends": IntrinioHistoricalDividendsFetcher,
"HistoricalMarketCap": IntrinioHistoricalMarketCapFetcher,
"IncomeStatement": IntrinioIncomeStatementFetcher,
"IndexHistorical": IntrinioIndexHistoricalFetcher,
"InsiderTrading": IntrinioInsiderTradingFetcher,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"""Intrinio Historical Market Cap Model."""

# pylint: disable=unused-argument
from datetime import datetime
from typing import Any, Literal, Optional

from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.historical_market_cap import (
HistoricalMarketCapData,
HistoricalMarketCapQueryParams,
)
from openbb_core.provider.utils.errors import EmptyDataError
from pydantic import Field


class IntrinioHistoricalMarketCapQueryParams(HistoricalMarketCapQueryParams):
"""Intrinio Historical MarketCap Query.

Source: https://docs.intrinio.com/documentation/web_api/get_historical_data_v2
"""

__json_schema_extra__ = {
"symbol": {"multiple_items_allowed": True},
"interval": {
"multiple_items_allowed": False,
"choices": ["week", "month", "quarter", "year"],
},
}

interval: Literal["week", "month", "quarter", "year"] = Field(
default="week",
)


class IntrinioHistoricalMarketCapData(HistoricalMarketCapData):
"""Intrinio Historical MarketCap Data."""

__alias_dict__ = {
"market_cap": "value",
}


class IntrinioHistoricalMarketCapFetcher(
Fetcher[
IntrinioHistoricalMarketCapQueryParams,
list[IntrinioHistoricalMarketCapData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""

@staticmethod
def transform_query(
params: dict[str, Any]
) -> IntrinioHistoricalMarketCapQueryParams:
"""Transform the query params."""
transformed_params = params

now = datetime.now().date()
if params.get("start_date") is None:
transformed_params["start_date"] = datetime(
2000,
1,
1,
).date()
if params.get("end_date") is None:
transformed_params["end_date"] = now

return IntrinioHistoricalMarketCapQueryParams(**transformed_params)

@staticmethod
async def aextract_data(
query: IntrinioHistoricalMarketCapQueryParams,
credentials: Optional[dict[str, str]],
**kwargs: Any,
) -> list[dict]:
"""Return the raw data from the Intrinio endpoint."""
# pylint: disable=import-outside-toplevel
import asyncio # noqa
from openbb_core.provider.utils.helpers import amake_request
from openbb_intrinio.utils.helpers import response_callback
from warnings import warn

api_key = credentials.get("intrinio_api_key") if credentials else ""
base_url = "https://api-v2.intrinio.com/historical_data/"
frequency = query.interval + "ly"
start_date = query.start_date
end_date = query.end_date
results: list = []
messages: list = []
symbols = query.symbol.split(",")

async def get_one(symbol):
"""Get data for one symbol."""
url_params = (
f"{symbol}/marketcap?frequency={frequency}&start_date={start_date}"
f"&end_date={end_date}&page_size=10000"
f"&api_key={api_key}"
)
url = f"{base_url}{url_params}"
try:
response = await amake_request(url, response_callback=response_callback)
except OpenBBError as e:
if "Cannot look up this item/identifier combination" in str(e):
msg = f"Symbol not found: {symbol}"
messages.append(msg)
return
raise e from e

if not isinstance(response, dict):
raise OpenBBError(
f"Unexpected response format, expected a dictionary, got {response.__class__.__name__}"
)

if not response:
msg = f"No data found for symbol: {symbol}"
messages.append(msg)

if response.get("historical_data"):
data = response.get("historical_data", {})
result = [
{"symbol": symbol, **item} for item in data if item.get("value")
]
results.extend(result)

return

await asyncio.gather(*[get_one(symbol) for symbol in symbols])

if messages and not results:
raise OpenBBError(messages)

if messages and results:
for message in messages:
warn(message)

if not results:
raise EmptyDataError("The response was returned empty.")

return results

@staticmethod
def transform_data(
query: IntrinioHistoricalMarketCapQueryParams, data: list[dict], **kwargs: Any
) -> list[IntrinioHistoricalMarketCapData]:
"""Return the transformed data."""
return [
IntrinioHistoricalMarketCapData.model_validate(d)
for d in sorted(data, key=lambda x: x["date"])
]
Loading
Loading