diff --git a/openbb_sdk/providers/fmp/openbb_fmp/models/stock_eod.py b/openbb_sdk/providers/fmp/openbb_fmp/models/stock_eod.py index add57ce8114..f2feee1ade0 100644 --- a/openbb_sdk/providers/fmp/openbb_fmp/models/stock_eod.py +++ b/openbb_sdk/providers/fmp/openbb_fmp/models/stock_eod.py @@ -1,54 +1,55 @@ """FMP Stocks end of day fetcher.""" -from datetime import datetime, timedelta -from typing import Dict, List, Literal, Optional +from datetime import datetime +from typing import Dict, List, Optional from openbb_provider.abstract.fetcher import Fetcher from openbb_provider.helpers import data_transformer, get_querystring +from openbb_provider.metadata import DATA_DESCRIPTIONS from openbb_provider.models.stock_eod import StockEODData, StockEODQueryParams -from pydantic import Field, NonNegativeInt, validator - from openbb_fmp.utils.helpers import get_data_many +from pydantic import Field, NonNegativeInt, validator + class FMPStockEODQueryParams(StockEODQueryParams): - """FMP Stock end of day query. + """FMP Stock end of day Query. Source: https://financialmodelingprep.com/developer/docs/#Stock-Historical-Price - - Parameter - --------- - symbol : str - The symbol of the company. - start_date : date - The start date of the stock data from which to retrieve the data. - end_date : date - The end date of the stock data up to which to retrieve the data. - timeseries : Optional[int] - The number of days to look back. - series_type : Optional[Literal["line"]] - The type of the series. Only "line" is supported. """ - # symbol: str = Field(min_length=1) - series_type: Optional[Literal["line"]] - # start_date: date - # end_date: date - timeseries: Optional[NonNegativeInt] # Number of days to looks back + timeseries: Optional[NonNegativeInt] = Field( + default=None, description="Number of days to look back." + ) class FMPStockEODData(StockEODData): - adjClose: float = Field(alias="adj_close") - unadjustedVolume: float - change: float - changePercent: float - vwap: float - label: str - changeOverTime: float + """FMP Stock end of day Data.""" + + date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", "")) + adjClose: float = Field( + description="Adjusted Close Price of the symbol.", alias="adj_close" + ) + unadjustedVolume: float = Field( + description="Unadjusted volume of the symbol.", alias="unadjusted_volume" + ) + change: float = Field( + description="Change in the price of the symbol from the previous day.", + alias="change", + ) + changePercent: float = Field( + description=r"Change \% in the price of the symbol.", alias="change_percent" + ) + vwap: float = Field(description="Volume Weighted Average Price of the symbol.") + label: str = Field(description="Human readable format of the date.") + changeOverTime: float = Field( + description=r"Change \% in the price of the symbol over a period of time.", + alias="change_over_time", + ) @validator("date", pre=True) - def time_validate(cls, v): # pylint: disable=E0213 + def date_validate(cls, v): # pylint: disable=E0213 return datetime.strptime(v, "%Y-%m-%d") @@ -64,13 +65,10 @@ class FMPStockEODFetcher( def transform_query( query: StockEODQueryParams, extra_params: Optional[Dict] = None ) -> FMPStockEODQueryParams: - now = datetime.now() - start_date = query.start_date or (now - timedelta(days=5)) - end_date = query.end_date or now return FMPStockEODQueryParams( symbol=query.symbol, - start_date=start_date, - end_date=end_date, + start_date=query.start_date, + end_date=query.end_date, **extra_params or {}, ) @@ -85,6 +83,7 @@ class FMPStockEODFetcher( query_str = get_querystring(query.dict(), ["symbol"]) query_str = query_str.replace("start_date", "from").replace("end_date", "to") url = f"{base_url}/historical-price-full/{query.symbol}?{query_str}&apikey={api_key}" + return get_data_many(url, FMPStockEODData, "historical") @staticmethod diff --git a/openbb_sdk/providers/polygon/openbb_polygon/models/stock_eod.py b/openbb_sdk/providers/polygon/openbb_polygon/models/stock_eod.py index 9fae5c614d4..845ccd6c99d 100644 --- a/openbb_sdk/providers/polygon/openbb_polygon/models/stock_eod.py +++ b/openbb_sdk/providers/polygon/openbb_polygon/models/stock_eod.py @@ -2,47 +2,61 @@ from datetime import datetime, timedelta -from typing import Dict, List, Optional +from typing import Dict, List, Literal, Optional from openbb_provider.abstract.fetcher import Fetcher from openbb_provider.helpers import data_transformer +from openbb_provider.metadata import QUERY_DESCRIPTIONS from openbb_provider.models.stock_eod import StockEODData, StockEODQueryParams -from pydantic import Field, NonNegativeFloat, PositiveFloat, PositiveInt - from openbb_polygon.utils.helpers import get_data -from openbb_polygon.utils.types import BaseStockData, BaseStockQueryParams + +from pydantic import Field, PositiveFloat, PositiveInt, validator -class PolygonStockEODQueryParams(BaseStockQueryParams): - """Polygon stocks end of day query. +class PolygonStockEODQueryParams(StockEODQueryParams): + """Polygon stocks end of day Query. Source: https://polygon.io/docs/stocks/getting-started - - Parameters - ---------- - symbol : str - The symbol of the stocks to fetch. - start_date : Union[date, datetime] - The start date of the query. - end_date : Union[date, datetime] - The end date of the query. - timespan : Timespan, optional - The timespan of the query, by default Timespan.day - sort : Literal["asc", "desc"], optional - The sort order of the query, by default "desc" - limit : PositiveInt, optional - The limit of the query, by default 49999 - adjusted : bool, optional - Whether the query is adjusted, by default True - multiplier : PositiveInt, optional - The multiplier of the query, by default 1 """ + timespan: Literal[ + "minute", "hour", "day", "week", "month", "quarter", "year" + ] = Field(default="day", description="The timespan of the data.") + sort: Literal["asc", "desc"] = Field( + default="desc", description="Sort order of the data." + ) + limit: PositiveInt = Field( + default=49999, description=QUERY_DESCRIPTIONS.get("limit", "") + ) + adjusted: bool = Field(default=True, description="Whether the data is adjusted.") + multiplier: PositiveInt = Field( + default=1, description="The multiplier of the timespan." + ) -class PolygonStockEODData(BaseStockData): - v: NonNegativeFloat = Field(alias="volume") - n: PositiveInt - vw: Optional[PositiveFloat] + +class PolygonStockEODData(StockEODData): + """Polygon stocks end of day Data.""" + + class Config: + fields = { + "open": "o", + "high": "h", + "low": "l", + "close": "c", + "volume": "v", + } + + t: datetime = Field(description="The timestamp of the data.") + n: PositiveInt = Field( + description="The number of transactions for the symbol in the time period." + ) + vw: PositiveFloat = Field( + description="The volume weighted average price of the symbol." + ) + + @validator("t", pre=True, check_fields=False) + def time_validate(cls, v): # pylint: disable=E0213 + return datetime.fromtimestamp(v / 1000) class PolygonStockEODFetcher( @@ -57,9 +71,9 @@ class PolygonStockEODFetcher( def transform_query( query: StockEODQueryParams, extra_params: Optional[Dict] = None ) -> PolygonStockEODQueryParams: - now = datetime.now() - start_date = query.start_date or (now - timedelta(days=5)).date() - end_date = query.end_date or now.date() + now = datetime.now().date() + start_date = query.start_date or (now - timedelta(days=7)) + end_date = query.end_date or now return PolygonStockEODQueryParams( symbol=query.symbol, start_date=start_date, @@ -76,7 +90,7 @@ class PolygonStockEODFetcher( request_url = ( f"https://api.polygon.io/v2/aggs/ticker/" - f"{query.stocksTicker.upper()}/range/1/{str(query.timespan.value)}/" + f"{query.symbol}/range/1/{str(query.timespan)}/" f"{query.start_date}/{query.end_date}?adjusted={query.adjusted}" f"&sort={query.sort}&limit={query.limit}&multiplier={query.multiplier}" f"&apiKey={api_key}" diff --git a/openbb_sdk/sdk/provider/openbb_provider/models/stock_eod.py b/openbb_sdk/sdk/provider/openbb_provider/models/stock_eod.py index 4c7d6b5936b..42ced8db233 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/models/stock_eod.py +++ b/openbb_sdk/sdk/provider/openbb_provider/models/stock_eod.py @@ -1,61 +1,34 @@ """Stock aggregate end of day price data model.""" -from datetime import date, datetime +from datetime import date from typing import Optional from pydantic import Field, PositiveFloat from openbb_provider.abstract.data import Data, QueryParams -from openbb_provider.metadata import QUERY_DESCRIPTIONS +from openbb_provider.metadata import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS from openbb_provider.models.base import BaseSymbol class StockEODQueryParams(QueryParams, BaseSymbol): - """Stock end of day query. - Parameter - --------- - symbol : str - The symbol of the company. - start_date : Optional[date] - The start date of the stock data from which to retrieve the data. - end_date : Optional[date] - The end date of the stock data up to which to retrieve the data. - """ + """Stock end of day Query.""" start_date: Optional[date] = Field( - description=QUERY_DESCRIPTIONS.get("start_date", ""), default=None, + description=QUERY_DESCRIPTIONS.get("start_date", ""), ) end_date: Optional[date] = Field( - description=QUERY_DESCRIPTIONS.get("end_date", ""), default=None + default=None, + description=QUERY_DESCRIPTIONS.get("end_date", ""), ) class StockEODData(Data): - """Stock end of day price data. + """Stock end of day price Data.""" - Returns - ------- - date : datetime - The date of the stock. - open : PositiveFloat - The open price of the stock. - high : PositiveFloat - The high price of the stock. - low : PositiveFloat - The low price of the stock. - close : PositiveFloat - The close price of the stock. - adj_close : Optional[PositiveFloat] - The adjusted close price of the stock. - volume : PositiveFloat - The volume of the stock. - """ - - date: datetime - open: PositiveFloat - high: PositiveFloat - low: PositiveFloat - close: PositiveFloat - volume: PositiveFloat + open: PositiveFloat = Field(description=DATA_DESCRIPTIONS.get("open", "")) + high: PositiveFloat = Field(description=DATA_DESCRIPTIONS.get("high", "")) + low: PositiveFloat = Field(description=DATA_DESCRIPTIONS.get("low", "")) + close: PositiveFloat = Field(description=DATA_DESCRIPTIONS.get("close", "")) + volume: PositiveFloat = Field(description=DATA_DESCRIPTIONS.get("volume", ""))