refactored StockEOD for stocks.load

This commit is contained in:
Pratyush Shukla
2023-07-28 02:57:42 +05:30
parent 90db0babd0
commit 7640ffbe57
3 changed files with 94 additions and 108 deletions

View File

@@ -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

View File

@@ -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}"

View File

@@ -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", ""))