diff --git a/openbb_sdk/providers/fmp/openbb_fmp/models/forex_eod.py b/openbb_sdk/providers/fmp/openbb_fmp/models/forex_eod.py index 8e73efb66f0..b597dffb5cf 100644 --- a/openbb_sdk/providers/fmp/openbb_fmp/models/forex_eod.py +++ b/openbb_sdk/providers/fmp/openbb_fmp/models/forex_eod.py @@ -4,46 +4,51 @@ from datetime import datetime from typing import Dict, List, Optional -from openbb_provider.abstract.data import Data, QueryParams from openbb_provider.abstract.fetcher import Fetcher from openbb_provider.helpers import data_transformer from openbb_provider.models.forex_eod import ForexEODData, ForexEODQueryParams +from openbb_provider.metadata import DATA_DESCRIPTIONS + +from openbb_fmp.utils.helpers import get_querystring, get_data_many + from pydantic import Field, validator -from openbb_fmp.utils.helpers import get_data_many - -class FMPForexEODQueryParams(QueryParams): - """FMP Forex end of day query. +class FMPForexEODQueryParams(ForexEODQueryParams): + """FMP Forex end of day Query. Source: https://site.financialmodelingprep.com/developer/docs/#Historical-Forex-Price - - Parameter - --------- - symbol : str - The symbol of the company. """ - symbol: str = Field(min_length=1) +class FMPForexEODData(ForexEODData): + """FMP Forex end of day Data.""" -class FMPForexEODData(Data): - date: datetime - open: float - high: float - low: float - close: float - adjClose: float = Field(alias="adj_close") - volume: float - unadjustedVolume: float - change: float - changePercent: float - vwap: Optional[float] - label: str - changeOverTime: float + 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: Optional[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") @@ -61,6 +66,8 @@ class FMPForexEODFetcher( ) -> FMPForexEODQueryParams: return FMPForexEODQueryParams( symbol=query.symbol, + start_date=query.start_date, + end_date=query.end_date, **extra_params or {}, ) @@ -72,7 +79,10 @@ class FMPForexEODFetcher( api_key = credentials.get("fmp_api_key") base_url = "https://financialmodelingprep.com/api/v3" - url = f"{base_url}/historical-price-full/forex/{query.symbol}?&apikey={api_key}" + 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/forex/{query.symbol}?{query_str}&apikey={api_key}" + return get_data_many(url, FMPForexEODData, "historical") @staticmethod diff --git a/openbb_sdk/providers/polygon/openbb_polygon/models/forex_eod.py b/openbb_sdk/providers/polygon/openbb_polygon/models/forex_eod.py index 7954927b500..276c7645ba0 100644 --- a/openbb_sdk/providers/polygon/openbb_polygon/models/forex_eod.py +++ b/openbb_sdk/providers/polygon/openbb_polygon/models/forex_eod.py @@ -1,58 +1,63 @@ """Polygon forex end of day fetcher.""" -from datetime import date, datetime, timedelta -from typing import Dict, List, Literal, Optional, Union +from datetime import datetime, timedelta +from typing import Dict, List, Literal, Optional -from openbb_provider.abstract.data import QueryParams from openbb_provider.abstract.fetcher import Fetcher from openbb_provider.helpers import data_transformer from openbb_provider.models.forex_eod import ForexEODData, ForexEODQueryParams -from pydantic import Field, NonNegativeFloat, PositiveFloat, PositiveInt +from openbb_provider.metadata import QUERY_DESCRIPTIONS from openbb_polygon.utils.helpers import get_data -from openbb_polygon.utils.types import BaseStockData, Timespan + +from pydantic import Field, validator, PositiveFloat, PositiveInt -class PolygonForexEODQueryParams(QueryParams): - """Polygon forex end of day query. +class PolygonForexEODQueryParams(ForexEODQueryParams): + """Polygon forex end of day Query. Source: https://polygon.io/docs/forex/get_v2_aggs_ticker__forexticker__range__multiplier___timespan___from___to - - Parameters - ---------- - stocksTicker : str - The ticker symbol of the stocks to fetch. - start_date : Union[date, datetime], optional - The start date of the query. - end_date : Union[date, datetime], optional - 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 """ - stocksTicker: str = Field(alias="symbol") - start_date: Optional[Union[date, datetime]] - end_date: Optional[Union[date, datetime]] - timespan: Optional[Timespan] = Field(default=Timespan.day) - sort: Optional[Literal["asc", "desc"]] = Field(default="desc") - limit: Optional[PositiveInt] = Field(default=49999) - adjusted: Optional[bool] = Field(default=True) - multiplier: Optional[PositiveInt] = Field(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 PolygonForexEODData(BaseStockData): - v: NonNegativeFloat = Field(alias="volume") - n: PositiveInt - vw: Optional[PositiveFloat] +class PolygonForexEODData(ForexEODData): + """Polygon forex 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 PolygonForexEODFetcher( @@ -80,11 +85,11 @@ class PolygonForexEODFetcher( api_key = credentials.get("polygon_api_key") now = datetime.now() - start_date = query.start_date or (now - timedelta(days=5)).date() + start_date = query.start_date or (now - timedelta(days=7)).date() end_date = query.end_date or now.date() request_url = ( f"https://api.polygon.io/v2/aggs/ticker/" - f"C:{query.stocksTicker.upper()}/range/1/{query.timespan._value_}/" + f"C:{query.symbol}/range/1/{query.timespan}/" f"{start_date}/{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/forex_eod.py b/openbb_sdk/sdk/provider/openbb_provider/models/forex_eod.py index a51aca640a5..29d8cd7d56d 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/models/forex_eod.py +++ b/openbb_sdk/sdk/provider/openbb_provider/models/forex_eod.py @@ -1,48 +1,34 @@ """Forex aggregate end of day price data model.""" -from datetime import datetime +from datetime import date from typing import Optional -from pydantic import NonNegativeFloat, PositiveFloat - from openbb_provider.abstract.data import Data, QueryParams from openbb_provider.models.base import BaseSymbol +from openbb_provider.metadata import QUERY_DESCRIPTIONS, DATA_DESCRIPTIONS + +from pydantic import Field, NonNegativeFloat, PositiveFloat class ForexEODQueryParams(QueryParams, BaseSymbol): - """Forex end of day query. + """Forex end of day Query.""" - Parameter - --------- - symbol : str - The symbol of the forex currency pair. - """ + start_date: Optional[date] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("start_date", ""), + ) + end_date: Optional[date] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("end_date", ""), + ) class ForexEODData(Data): - """Forex end of day price data. + """Forex end of day price Data.""" - Returns - ------- - date : datetime - The date of the forex currency pair. - open : PositiveFloat - The open price of the forex currency pair. - high : PositiveFloat - The high price of the forex currency pair. - low : PositiveFloat - The low price of the forex currency pair. - close : PositiveFloat - The close price of the forex currency pair. - adj_close : Optional[PositiveFloat] - The adjusted close price of the forex currency pair. - """ - - date: datetime - open: PositiveFloat - high: PositiveFloat - low: PositiveFloat - close: PositiveFloat - adj_close: Optional[PositiveFloat] - volume: NonNegativeFloat + 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: NonNegativeFloat = Field(description=DATA_DESCRIPTIONS.get("volume", ""))