Skip to content

Commit

Permalink
[Feature] Add Intrinio to equity.historical_market_cap (#6932)
Browse files Browse the repository at this point in the history
* add intrinio to historical market cap

* no-else-return
  • Loading branch information
deeleeramone authored Nov 6, 2024
1 parent 64e0a23 commit e444a5d
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 15 deletions.
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

0 comments on commit e444a5d

Please sign in to comment.