diff --git a/openbb_sdk/extensions/economy/openbb_economy/economy_router.py b/openbb_sdk/extensions/economy/openbb_economy/economy_router.py index 7d06ab38885..e0483e96053 100644 --- a/openbb_sdk/extensions/economy/openbb_economy/economy_router.py +++ b/openbb_sdk/extensions/economy/openbb_economy/economy_router.py @@ -26,6 +26,17 @@ def corecpi( return CommandOutput(results=Empty()) +@router.command(model="MajorIndicesConstituents") +def const( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> CommandOutput[BaseModel]: + """""" + return CommandOutput(results=Query(**locals()).execute()) + + # pylint: disable=too-many-arguments @router.command(model="CPI") def cpi( diff --git a/openbb_sdk/providers/fmp/openbb_fmp/major_indices_constituents.py b/openbb_sdk/providers/fmp/openbb_fmp/major_indices_constituents.py new file mode 100644 index 00000000000..7ec3aa013c2 --- /dev/null +++ b/openbb_sdk/providers/fmp/openbb_fmp/major_indices_constituents.py @@ -0,0 +1,84 @@ +"""FMP Major Indices end of day fetcher.""" + +# IMPORT STANDARD +from datetime import datetime +from typing import Dict, List, Optional + +# IMPORT INTERNAL +from openbb_provider.abstract.fetcher import Fetcher +from openbb_provider.helpers import data_transformer +from openbb_provider.models.major_indices_constituents import ( + MajorIndicesConstituentsQueryParams, + MajorIndicesConstituentsData, +) + +# IMPORT THIRD-PARTY +from pydantic import validator + +from .helpers import get_data_many + + +class FMPMajorIndicesConstituentsQueryParams(MajorIndicesConstituentsQueryParams): + """FMP Major Indices Constituents query. + + Source: https://site.financialmodelingprep.com/developer/docs/list-of-dow-companies-api/ + https://site.financialmodelingprep.com/developer/docs/list-of-sp-500-companies-api/ + https://site.financialmodelingprep.com/developer/docs/list-of-nasdaq-companies-api/ + + Parameter + --------- + index : Literal['nasdaq', 'sp500', 'dowjones'] + The index for which we want to fetch the constituents. Default is 'dowjones'. + """ + + +class FMPMajorIndicesConstituentsData(MajorIndicesConstituentsData): + """FMP Major Indices Constituents data.""" + + @validator("dateFirstAdded", pre=True) + def date_first_added_validate(cls, v): # pylint: disable=E0213 + try: + return datetime.strptime(v, "%Y-%m-%d") if v else None + except Exception: + # For returning string in case of mismatched dates + return v + + @validator("founded", pre=True) + def founded_validate(cls, v): # pylint: disable=E0213 + try: + return datetime.strptime(v, "%Y-%m-%d") if v else None + except Exception: + # For returning string in case of mismatched dates + return v + + +class FMPMajorIndicesConstituentsFetcher( + Fetcher[ + MajorIndicesConstituentsQueryParams, + MajorIndicesConstituentsData, + FMPMajorIndicesConstituentsQueryParams, + FMPMajorIndicesConstituentsData, + ] +): + @staticmethod + def transform_query( + query: MajorIndicesConstituentsQueryParams, extra_params: Optional[Dict] = None + ) -> FMPMajorIndicesConstituentsQueryParams: + return FMPMajorIndicesConstituentsQueryParams( + index=query.index, + **extra_params or {}, + ) + + @staticmethod + def extract_data( + query: FMPMajorIndicesConstituentsQueryParams, api_key: str + ) -> List[FMPMajorIndicesConstituentsData]: + base_url = "https://financialmodelingprep.com/api/v3" + url = f"{base_url}/{query.index}_constituent/?apikey={api_key}" + return get_data_many(url, FMPMajorIndicesConstituentsData) + + @staticmethod + def transform_data( + data: List[FMPMajorIndicesConstituentsData], + ) -> List[MajorIndicesConstituentsData]: + return data_transformer(data, MajorIndicesConstituentsData) diff --git a/openbb_sdk/providers/fmp/openbb_fmp/provider.py b/openbb_sdk/providers/fmp/openbb_fmp/provider.py index ae2753aded3..e3fec6954a7 100644 --- a/openbb_sdk/providers/fmp/openbb_fmp/provider.py +++ b/openbb_sdk/providers/fmp/openbb_fmp/provider.py @@ -31,6 +31,7 @@ from .historical_stock_splits import FMPHistoricalStockSplitsFetcher from .income_statement import FMPIncomeStatementFetcher from .institutional_ownership import FMPInstitutionalOwnershipFetcher from .key_metrics import FMPKeyMetricsFetcher +from .major_indices_constituents import FMPMajorIndicesConstituentsFetcher from .major_indices_eod import FMPMajorIndicesEODFetcher from .major_indices_price import FMPMajorIndicesPriceFetcher from .price_target import FMPPriceTargetFetcher @@ -98,5 +99,6 @@ fmp_provider = Provider( FMPHistoricalEmployeesFetcher, FMPAvailableIndicesFetcher, FMPRiskPremiumFetcher, + FMPMajorIndicesConstituentsFetcher, ], ) diff --git a/openbb_sdk/sdk/provider/openbb_provider/models/major_indices_constituents.py b/openbb_sdk/sdk/provider/openbb_provider/models/major_indices_constituents.py new file mode 100644 index 00000000000..a494cb4a2ff --- /dev/null +++ b/openbb_sdk/sdk/provider/openbb_provider/models/major_indices_constituents.py @@ -0,0 +1,57 @@ +"""Major Indices Constituents data model.""" + + +from datetime import date +from typing import Optional, Literal, Union + +from pydantic import Field + +from openbb_provider.abstract.data import Data, QueryParams +from openbb_provider.metadata import DESCRIPTIONS + + +class MajorIndicesConstituentsQueryParams(QueryParams): + """Major Indices Constituents query. + + Parameter + --------- + index : Literal['nasdaq', 'sp500', 'dowjones'] + The index for which we want to fetch the constituents. Default is 'dowjones'. + """ + + index: Literal["nasdaq", "sp500", "dowjones"] = Field( + description=DESCRIPTIONS.get("index", ""), + default="dowjones", + ) + + +class MajorIndicesConstituentsData(Data): + """Major Indices Constituents price data. + + Returns + ------- + symbol : str + The symbol of the constituent company in the index. + name : str + The name of the constituent company in the index. + sector : str + The sector the constituent company in the index belongs to. + subSector : str + The sub-sector the constituent company in the index belongs to. + headQuarter : str + The location of the headquarter of the constituent company in the index. + dateFirstAdded : date + The date the constituent company was added to the index. + cik : int + The Central Index Key of the constituent company in the index. + founded : date + The founding year of the constituent company in the index. + """ + + name: str + sector: str + subSector: Optional[str] = Field(alias="sub_sector") + headQuarter: Optional[str] = Field(alias="headquarter") + dateFirstAdded: Optional[Union[date, str]] = Field(alias="date_first_added") + cik: int + founded: Union[date, str]