mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
removed eod redundant files
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
"""CBOE Stock EOD fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.stock_eod import StockEODData, StockEODQueryParams
|
||||
from pydantic import validator
|
||||
|
||||
from openbb_cboe.utils.helpers import get_eod_prices
|
||||
|
||||
|
||||
class CboeStockEODQueryParams(StockEODQueryParams):
|
||||
"""CBOE Stock end of day query.
|
||||
|
||||
Source: https://www.cboe.com/
|
||||
"""
|
||||
|
||||
|
||||
class CboeStockEODData(StockEODData):
|
||||
"""CBOE Stocks End of Day Data."""
|
||||
|
||||
@validator("date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return the datetime object from the date string"""
|
||||
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class CboeStockEODFetcher(
|
||||
Fetcher[
|
||||
CboeStockEODQueryParams,
|
||||
List[CboeStockEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the CBOE endpoints"""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> CboeStockEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
|
||||
return CboeStockEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: CboeStockEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the CBOE endpoint"""
|
||||
return get_eod_prices(query.symbol, query.start_date, query.end_date).to_dict(
|
||||
"records"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: dict) -> List[CboeStockEODData]:
|
||||
"""Transform the data to the standard format"""
|
||||
return [CboeStockEODData.parse_obj(d) for d in data]
|
||||
@@ -1,100 +0,0 @@
|
||||
"""FMP Cryptos end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.crypto_eod import (
|
||||
CryptoEODData,
|
||||
CryptoEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.helpers import get_querystring
|
||||
from pydantic import Field, NonNegativeInt, validator
|
||||
|
||||
from openbb_fmp.utils.helpers import get_data_many
|
||||
|
||||
|
||||
class FMPCryptoEODQueryParams(CryptoEODQueryParams):
|
||||
# noqa: E501
|
||||
"""FMP Crypto end of day Query.
|
||||
|
||||
Source:
|
||||
https://site.financialmodelingprep.com/developer/docs/cryptocurrency-historical-data-api/#Historical-Daily-Prices
|
||||
"""
|
||||
|
||||
timeseries: Optional[NonNegativeInt] = Field(
|
||||
default=None, description="Number of days to look back."
|
||||
)
|
||||
|
||||
|
||||
class FMPCryptoEODData(CryptoEODData):
|
||||
"""FMP Crypto end of day Data."""
|
||||
|
||||
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"
|
||||
)
|
||||
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 date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return the date as a datetime object."""
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class FMPCryptoEODFetcher(
|
||||
Fetcher[
|
||||
FMPCryptoEODQueryParams,
|
||||
List[FMPCryptoEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the FMP endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> FMPCryptoEODQueryParams:
|
||||
"""Transform the query params. Start and end dates are set to 1 year interval."""
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return FMPCryptoEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: FMPCryptoEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the FMP endpoint."""
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
|
||||
base_url = "https://financialmodelingprep.com/api/v3/"
|
||||
query_str = get_querystring(query.dict(by_alias=True), ["symbol"])
|
||||
query_str = query_str.replace("start_date", "from").replace("end_date", "to")
|
||||
url = f"{base_url}historical-price-full/crypto/{query.symbol}?{query_str}&apikey={api_key}"
|
||||
|
||||
return get_data_many(url, "historical", **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: List[Dict]) -> List[FMPCryptoEODData]:
|
||||
"""Return the transformed data."""
|
||||
return [FMPCryptoEODData(**d) for d in data]
|
||||
@@ -1,91 +0,0 @@
|
||||
"""FMP Forex end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.forex_eod import ForexEODData, ForexEODQueryParams
|
||||
from pydantic import Field, validator
|
||||
|
||||
from openbb_fmp.utils.helpers import get_data_many, get_querystring
|
||||
|
||||
|
||||
class FMPForexEODQueryParams(ForexEODQueryParams):
|
||||
"""FMP Forex end of day Query.
|
||||
|
||||
Source: https://site.financialmodelingprep.com/developer/docs/#Historical-Forex-Price
|
||||
"""
|
||||
|
||||
|
||||
class FMPForexEODData(ForexEODData):
|
||||
"""FMP Forex end of day Data."""
|
||||
|
||||
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"
|
||||
)
|
||||
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 date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return the date as a datetime object."""
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class FMPForexEODFetcher(
|
||||
Fetcher[
|
||||
FMPForexEODQueryParams,
|
||||
List[FMPForexEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the FMP endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> FMPForexEODQueryParams:
|
||||
"""Transform the query params. Start and end dates are set to a 1 year interval."""
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
|
||||
return FMPForexEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: FMPForexEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the FMP endpoint."""
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
|
||||
base_url = "https://financialmodelingprep.com/api/v3"
|
||||
query_str = get_querystring(query.dict(by_alias=True), ["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, "historical", **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: List[Dict]) -> List[FMPForexEODData]:
|
||||
"""Return the transformed data."""
|
||||
return [FMPForexEODData(**d) for d in data]
|
||||
@@ -1,108 +0,0 @@
|
||||
"""FMP Major Indices end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.major_indices_eod import (
|
||||
MajorIndicesEODData,
|
||||
MajorIndicesEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.helpers import get_querystring
|
||||
from pydantic import Field, NonNegativeInt, validator
|
||||
|
||||
from openbb_fmp.utils.helpers import get_data_many
|
||||
|
||||
|
||||
class FMPMajorIndicesEODQueryParams(MajorIndicesEODQueryParams):
|
||||
"""FMP Major Indices end of day Query.
|
||||
|
||||
Source: https://site.financialmodelingprep.com/developer/docs/historical-index-price-api/
|
||||
"""
|
||||
|
||||
timeseries: Optional[NonNegativeInt] = Field(
|
||||
default=None, description="Number of days to look back."
|
||||
)
|
||||
interval: Literal[
|
||||
"1min", "5min", "15min", "30min", "1hour", "4hour", "1day"
|
||||
] = Field(default="1day", description="Interval of the data to fetch.")
|
||||
|
||||
|
||||
class FMPMajorIndicesEODData(MajorIndicesEODData):
|
||||
"""FMP Major Indices end of day Data."""
|
||||
|
||||
adj_close: Optional[float] = Field(
|
||||
description="Adjusted Close Price of the symbol.",
|
||||
default=None,
|
||||
)
|
||||
unadjusted_volume: Optional[float] = Field(
|
||||
description="Unadjusted volume of the symbol.",
|
||||
default=None,
|
||||
)
|
||||
change: Optional[float] = Field(
|
||||
description="Change in the price of the symbol from the previous day.",
|
||||
default=None,
|
||||
)
|
||||
change_percent: Optional[float] = Field(
|
||||
description=r"Change \% in the price of the symbol.",
|
||||
default=None,
|
||||
)
|
||||
label: Optional[str] = Field(
|
||||
description="Human readable format of the date.", default=None
|
||||
)
|
||||
change_over_time: Optional[float] = Field(
|
||||
description=r"Change \% in the price of the symbol over a period of time.",
|
||||
default=None,
|
||||
)
|
||||
|
||||
@validator("date", pre=True)
|
||||
def date_validate(cls, v) -> datetime: # pylint: disable=E0213
|
||||
"""Return the date as a datetime object."""
|
||||
# TODO: Check if this condition is necessary
|
||||
# if values.get("changeOverTime", None) is not None:
|
||||
# return datetime.strptime(v, "%Y-%m-%d")
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class FMPMajorIndicesEODFetcher(
|
||||
Fetcher[
|
||||
FMPMajorIndicesEODQueryParams,
|
||||
List[FMPMajorIndicesEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the FMP endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> FMPMajorIndicesEODQueryParams:
|
||||
"""Transform the query params."""
|
||||
return FMPMajorIndicesEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: FMPMajorIndicesEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the FMP endpoint."""
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
|
||||
base_url = "https://financialmodelingprep.com/api/v3"
|
||||
query_str = (
|
||||
get_querystring(query.dict(), ["symbol"])
|
||||
.replace("start_date", "from")
|
||||
.replace("end_date", "to")
|
||||
)
|
||||
|
||||
url_params = f"{query.symbol}?{query_str}&apikey={api_key}"
|
||||
url = f"{base_url}/historical-chart/{query.interval}/%5E{url_params}"
|
||||
|
||||
if query.interval == "1day":
|
||||
url = f"{base_url}/historical-price-full/index/%5E{url_params}"
|
||||
|
||||
return get_data_many(url, "historical", **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: List[Dict]) -> List[FMPMajorIndicesEODData]:
|
||||
"""Return the transformed data."""
|
||||
return [FMPMajorIndicesEODData(**d) for d in data]
|
||||
@@ -1,108 +0,0 @@
|
||||
"""FMP Stocks end of day fetcher."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.stock_eod import StockEODData, StockEODQueryParams
|
||||
from openbb_provider.utils.helpers import get_querystring
|
||||
from pydantic import Field, NonNegativeInt, validator
|
||||
|
||||
from openbb_fmp.utils.helpers import get_data_many
|
||||
|
||||
|
||||
class FMPStockEODQueryParams(StockEODQueryParams):
|
||||
"""FMP Stock end of day Query.
|
||||
|
||||
Source: https://financialmodelingprep.com/developer/docs/#Stock-Historical-Price
|
||||
"""
|
||||
|
||||
timeseries: Optional[NonNegativeInt] = Field(
|
||||
default=None, description="Number of days to look back."
|
||||
)
|
||||
interval: Literal[
|
||||
"1min", "5min", "15min", "30min", "1hour", "4hour", "1day"
|
||||
] = Field(default="1day", description="Interval of the data to fetch.")
|
||||
|
||||
|
||||
class FMPStockEODData(StockEODData):
|
||||
"""FMP Stock end of day Data."""
|
||||
|
||||
adjClose: Optional[float] = Field(description="Adjusted Close Price of the symbol.")
|
||||
unadjustedVolume: Optional[float] = Field(
|
||||
description="Unadjusted volume of the symbol."
|
||||
)
|
||||
change: Optional[float] = Field(
|
||||
description="Change in the price of the symbol from the previous day."
|
||||
)
|
||||
changePercent: Optional[float] = Field(
|
||||
description=r"Change \% in the price of the symbol."
|
||||
)
|
||||
vwap: Optional[float] = Field(
|
||||
description="Volume Weighted Average Price of the symbol."
|
||||
)
|
||||
label: Optional[str] = Field(description="Human readable format of the date.")
|
||||
changeOverTime: Optional[float] = Field(
|
||||
description=r"Change \% in the price of the symbol over a period of time."
|
||||
)
|
||||
|
||||
@validator("date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return the date as a datetime object."""
|
||||
try:
|
||||
return datetime.strptime(v, "%Y-%m-%d %H:%M:%S")
|
||||
except ValueError:
|
||||
return datetime.strptime(v, "%Y-%m-%d")
|
||||
|
||||
|
||||
class FMPStockEODFetcher(
|
||||
Fetcher[
|
||||
FMPStockEODQueryParams,
|
||||
List[FMPStockEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the FMP endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> FMPStockEODQueryParams:
|
||||
"""Transform the query params."""
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
|
||||
return FMPStockEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: FMPStockEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the FMP endpoint."""
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
|
||||
base_url = "https://financialmodelingprep.com/api/v3"
|
||||
query_str = (
|
||||
get_querystring(query.dict(), ["symbol"])
|
||||
.replace("start_date", "from")
|
||||
.replace("end_date", "to")
|
||||
)
|
||||
|
||||
url_params = f"{query.symbol}?{query_str}&apikey={api_key}"
|
||||
url = f"{base_url}/historical-chart/{query.interval}/{url_params}"
|
||||
|
||||
if query.interval == "1day":
|
||||
url = f"{base_url}/historical-price-full/{url_params}"
|
||||
|
||||
return get_data_many(url, "historical", **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: List[Dict]) -> List[FMPStockEODData]:
|
||||
"""Return the transformed data."""
|
||||
return [FMPStockEODData(**d) for d in data]
|
||||
@@ -1,110 +0,0 @@
|
||||
"""Polygon crypto end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.crypto_eod import (
|
||||
CryptoEODData,
|
||||
CryptoEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, PositiveInt, validator
|
||||
|
||||
from openbb_polygon.utils.helpers import get_data
|
||||
|
||||
|
||||
class PolygonCryptoEODQueryParams(CryptoEODQueryParams):
|
||||
"""Polygon crypto end of day Query.
|
||||
|
||||
Source: https://polygon.io/docs/crypto/get_v2_aggs_ticker__cryptoticker__range__multiplier___timespan___from___to
|
||||
"""
|
||||
|
||||
timespan: Literal[
|
||||
"minute", "hour", "day", "week", "month", "quarter", "year"
|
||||
] = Field(default="day", description="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="Multiplier of the timespan."
|
||||
)
|
||||
|
||||
|
||||
class PolygonCryptoEODData(CryptoEODData):
|
||||
"""Polygon crypto end of day Data."""
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"date": "t",
|
||||
"open": "o",
|
||||
"high": "h",
|
||||
"low": "l",
|
||||
"close": "c",
|
||||
"volume": "v",
|
||||
"vwap": "vw",
|
||||
}
|
||||
|
||||
n: PositiveInt = Field(
|
||||
description="Number of transactions for the symbol in the time period."
|
||||
)
|
||||
|
||||
@validator("t", pre=True, check_fields=False)
|
||||
def time_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.fromtimestamp(v / 1000)
|
||||
|
||||
|
||||
class PolygonCryptoEODFetcher(
|
||||
Fetcher[
|
||||
PolygonCryptoEODQueryParams,
|
||||
List[PolygonCryptoEODData],
|
||||
]
|
||||
):
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> PolygonCryptoEODQueryParams:
|
||||
now = datetime.now().date()
|
||||
transformed_params = params
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
|
||||
if params.get("symbol"):
|
||||
transformed_params["symbol"] = params["symbol"].replace("-", "")
|
||||
|
||||
return PolygonCryptoEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: PolygonCryptoEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
api_key = credentials.get("polygon_api_key") if credentials else ""
|
||||
|
||||
request_url = (
|
||||
f"https://api.polygon.io/v2/aggs/ticker/"
|
||||
f"X:{query.symbol}/range/{query.multiplier}/{query.timespan}/"
|
||||
f"{query.start_date}/{query.end_date}?adjusted={query.adjusted}"
|
||||
f"&sort={query.sort}&limit={query.limit}&apiKey={api_key}"
|
||||
)
|
||||
|
||||
data = get_data(request_url, **kwargs)
|
||||
if isinstance(data, list):
|
||||
raise ValueError("Expected a dict, got a list")
|
||||
|
||||
if "results" not in data or len(data["results"]) == 0:
|
||||
raise RuntimeError("No results found. Please change your query parameters.")
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: dict) -> List[PolygonCryptoEODData]:
|
||||
return [PolygonCryptoEODData.parse_obj(d) for d in data.get("results", [])]
|
||||
@@ -1,104 +0,0 @@
|
||||
"""Polygon forex end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.forex_eod import ForexEODData, ForexEODQueryParams
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, PositiveInt, validator
|
||||
|
||||
from openbb_polygon.utils.helpers import get_data
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
timespan: Literal[
|
||||
"minute", "hour", "day", "week", "month", "quarter", "year"
|
||||
] = Field(default="day", description="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="Multiplier of the timespan."
|
||||
)
|
||||
|
||||
|
||||
class PolygonForexEODData(ForexEODData):
|
||||
"""Polygon forex end of day Data."""
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"date": "t",
|
||||
"open": "o",
|
||||
"high": "h",
|
||||
"low": "l",
|
||||
"close": "c",
|
||||
"volume": "v",
|
||||
"vwap": "vw",
|
||||
}
|
||||
|
||||
n: PositiveInt = Field(
|
||||
description="Number of transactions for the symbol in the time period."
|
||||
)
|
||||
|
||||
@validator("t", pre=True, check_fields=False)
|
||||
def time_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.fromtimestamp(v / 1000)
|
||||
|
||||
|
||||
class PolygonForexEODFetcher(
|
||||
Fetcher[
|
||||
PolygonForexEODQueryParams,
|
||||
List[PolygonForexEODData],
|
||||
]
|
||||
):
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> PolygonForexEODQueryParams:
|
||||
now = datetime.now().date()
|
||||
transformed_params = params
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
|
||||
return PolygonForexEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: PolygonForexEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
api_key = credentials.get("polygon_api_key") if credentials else ""
|
||||
|
||||
request_url = (
|
||||
f"https://api.polygon.io/v2/aggs/ticker/"
|
||||
f"C:{query.symbol}/range/{query.multiplier}/{query.timespan}/"
|
||||
f"{query.start_date}/{query.end_date}?adjusted={query.adjusted}"
|
||||
f"&sort={query.sort}&limit={query.limit}&apiKey={api_key}"
|
||||
)
|
||||
|
||||
data = get_data(request_url, **kwargs)
|
||||
if isinstance(data, list):
|
||||
raise ValueError("Expected a dict, got a list")
|
||||
|
||||
if "results" not in data or len(data["results"]) == 0:
|
||||
raise RuntimeError("No results found. Please change your query parameters.")
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: dict) -> List[PolygonForexEODData]:
|
||||
return [PolygonForexEODData.parse_obj(d) for d in data.get("results", [])]
|
||||
@@ -1,110 +0,0 @@
|
||||
"""Polygon major indices end of day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.major_indices_eod import (
|
||||
MajorIndicesEODData,
|
||||
MajorIndicesEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, PositiveInt, validator
|
||||
|
||||
from openbb_polygon.utils.helpers import get_data
|
||||
|
||||
|
||||
class PolygonMajorIndicesEODQueryParams(MajorIndicesEODQueryParams):
|
||||
"""Polygon major indices end of day Query.
|
||||
|
||||
Source: https://polygon.io/docs/indices/getting-started
|
||||
"""
|
||||
|
||||
timespan: Literal[
|
||||
"minute", "hour", "day", "week", "month", "quarter", "year"
|
||||
] = Field(default="day", description="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="Multiplier of the timespan."
|
||||
)
|
||||
|
||||
|
||||
class PolygonMajorIndicesEODData(MajorIndicesEODData):
|
||||
"""Polygon major indices end of day Data."""
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"date": "t",
|
||||
"open": "o",
|
||||
"high": "h",
|
||||
"low": "l",
|
||||
"close": "c",
|
||||
"volume": "v",
|
||||
"vwap": "vw",
|
||||
}
|
||||
|
||||
n: PositiveInt = Field(
|
||||
description="Number of transactions for the symbol in the time period."
|
||||
)
|
||||
|
||||
@validator("t", pre=True, check_fields=False)
|
||||
def time_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.fromtimestamp(v / 1000)
|
||||
|
||||
|
||||
class PolygonMajorIndicesEODFetcher(
|
||||
Fetcher[
|
||||
PolygonMajorIndicesEODQueryParams,
|
||||
List[PolygonMajorIndicesEODData],
|
||||
]
|
||||
):
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> PolygonMajorIndicesEODQueryParams:
|
||||
now = datetime.now().date()
|
||||
transformed_params = params
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return PolygonMajorIndicesEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: PolygonMajorIndicesEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
api_key = credentials.get("polygon_api_key") if credentials else ""
|
||||
|
||||
request_url = (
|
||||
f"https://api.polygon.io/v2/aggs/ticker/"
|
||||
f"I:{query.symbol}/range/{query.multiplier}/{query.timespan}/"
|
||||
f"{query.start_date}/{query.end_date}?adjusted={query.adjusted}"
|
||||
f"&sort={query.sort}&limit={query.limit}&apiKey={api_key}"
|
||||
)
|
||||
|
||||
data = get_data(request_url, **kwargs)
|
||||
if isinstance(data, list):
|
||||
raise ValueError("Expected a dict, got a list")
|
||||
|
||||
if "results" not in data or len(data["results"]) == 0:
|
||||
raise RuntimeError("No results found. Please change your query parameters.")
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[PolygonMajorIndicesEODData]:
|
||||
return [
|
||||
PolygonMajorIndicesEODData.parse_obj(d) for d in data.get("results", [])
|
||||
]
|
||||
@@ -1,115 +0,0 @@
|
||||
"""Polygon stocks end of day fetcher."""
|
||||
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import datetime
|
||||
from itertools import repeat
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.stock_eod import StockEODData, StockEODQueryParams
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, PositiveInt, validator
|
||||
|
||||
from openbb_polygon.utils.helpers import get_data
|
||||
|
||||
|
||||
class PolygonStockEODQueryParams(StockEODQueryParams):
|
||||
"""Polygon stocks end of day Query.
|
||||
|
||||
Source: https://polygon.io/docs/stocks/getting-started
|
||||
"""
|
||||
|
||||
timespan: Literal[
|
||||
"minute", "hour", "day", "week", "month", "quarter", "year"
|
||||
] = Field(default="day", description="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="Multiplier of the timespan."
|
||||
)
|
||||
|
||||
|
||||
class PolygonStockEODData(StockEODData):
|
||||
"""Polygon stocks end of day Data."""
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"date": "t",
|
||||
"open": "o",
|
||||
"high": "h",
|
||||
"low": "l",
|
||||
"close": "c",
|
||||
"volume": "v",
|
||||
"vwap": "vw",
|
||||
}
|
||||
|
||||
n: Optional[PositiveInt] = Field(
|
||||
description="Number of transactions for the symbol in the time period."
|
||||
)
|
||||
|
||||
@validator("t", pre=True, check_fields=False)
|
||||
def t_validate(cls, v): # pylint: disable=E0213
|
||||
return datetime.fromtimestamp(v / 1000)
|
||||
|
||||
|
||||
class PolygonStockEODFetcher(
|
||||
Fetcher[
|
||||
PolygonStockEODQueryParams,
|
||||
List[PolygonStockEODData],
|
||||
]
|
||||
):
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> PolygonStockEODQueryParams:
|
||||
now = datetime.now().date()
|
||||
transformed_params = params
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return PolygonStockEODQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: PolygonStockEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> List[dict]:
|
||||
api_key = credentials.get("polygon_api_key") if credentials else ""
|
||||
|
||||
data: list = []
|
||||
|
||||
def multiple_symbols(symbol: str, data: List[PolygonStockEODData]) -> None:
|
||||
request_url = (
|
||||
f"https://api.polygon.io/v2/aggs/ticker/"
|
||||
f"{symbol.upper()}/range/{query.multiplier}/{query.timespan}/"
|
||||
f"{query.start_date}/{query.end_date}?adjusted={query.adjusted}"
|
||||
f"&sort={query.sort}&limit={query.limit}&apiKey={api_key}"
|
||||
)
|
||||
results = get_data(request_url, **kwargs).get("results", [])
|
||||
|
||||
if "," in query.symbol:
|
||||
results = [dict(symbol=symbol, **d) for d in results]
|
||||
|
||||
return data.extend([PolygonStockEODData.parse_obj(d) for d in results])
|
||||
|
||||
with ThreadPoolExecutor() as executor:
|
||||
executor.map(multiple_symbols, query.symbol.split(","), repeat(data))
|
||||
|
||||
data.sort(key=lambda x: x.date)
|
||||
if query.timespan == "day":
|
||||
for d in data:
|
||||
d.date = datetime.replace(d.date, hour=0, minute=0)
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def transform_data(data: List[dict]) -> List[PolygonStockEODData]:
|
||||
return [PolygonStockEODData.parse_obj(d) for d in data]
|
||||
@@ -1,112 +0,0 @@
|
||||
"""yfinance Crypto End of Day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.crypto_eod import (
|
||||
CryptoEODData,
|
||||
CryptoEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, validator
|
||||
from yfinance import Ticker
|
||||
|
||||
from openbb_yfinance.utils.references import INTERVALS, PERIODS
|
||||
|
||||
|
||||
class YFinanceCryptoEODQueryParams(CryptoEODQueryParams):
|
||||
"""YFinance Crypto End of Day Query.
|
||||
|
||||
Source: https://finance.yahoo.com/crypto/
|
||||
"""
|
||||
|
||||
interval: Optional[INTERVALS] = Field(default="1d", description="Data granularity.")
|
||||
period: Optional[PERIODS] = Field(
|
||||
default=None, description=QUERY_DESCRIPTIONS.get("period", "")
|
||||
)
|
||||
prepost: bool = Field(
|
||||
default=False, description="Include Pre and Post market data."
|
||||
)
|
||||
adjust: bool = Field(default=True, description="Adjust all the data automatically.")
|
||||
back_adjust: bool = Field(
|
||||
default=False, description="Back-adjusted data to mimic true historical prices."
|
||||
)
|
||||
|
||||
|
||||
class YFinanceCryptoEODData(CryptoEODData):
|
||||
"""YFinance Crypto End of Day Data."""
|
||||
|
||||
@validator("Date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return datetime object from string."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
class YFinanceCryptoEODFetcher(
|
||||
Fetcher[
|
||||
YFinanceCryptoEODQueryParams,
|
||||
List[YFinanceCryptoEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the yfinance endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> YFinanceCryptoEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
if params.get("period") is None:
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return YFinanceCryptoEODQueryParams(**transformed_params)
|
||||
|
||||
return YFinanceCryptoEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: YFinanceCryptoEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the yfinance endpoint."""
|
||||
if query.period:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
period=query.period,
|
||||
actions=False,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
raise_errors=True,
|
||||
)
|
||||
else:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
start=query.start_date,
|
||||
end=query.end_date,
|
||||
actions=False,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
data = data.reset_index()
|
||||
data["Date"] = (
|
||||
data["Date"].dt.tz_localize(None).dt.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
return data.to_dict("records")
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[YFinanceCryptoEODData]:
|
||||
"""Transform the data to the standard format."""
|
||||
return [YFinanceCryptoEODData.parse_obj(d) for d in data]
|
||||
@@ -1,113 +0,0 @@
|
||||
"""yfinance Forex End of Day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.forex_eod import ForexEODData, ForexEODQueryParams
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, validator
|
||||
from yfinance import Ticker
|
||||
|
||||
from openbb_yfinance.utils.references import INTERVALS, PERIODS
|
||||
|
||||
|
||||
class YFinanceForexEODQueryParams(ForexEODQueryParams):
|
||||
"""YFinance Forex End of Day Query.
|
||||
|
||||
Source: https://finance.yahoo.com/currencies/
|
||||
"""
|
||||
|
||||
interval: Optional[INTERVALS] = Field(default="1d", description="Data granularity.")
|
||||
period: Optional[PERIODS] = Field(
|
||||
default=None, description=QUERY_DESCRIPTIONS.get("period", "")
|
||||
)
|
||||
prepost: bool = Field(
|
||||
default=False, description="Include Pre and Post market data."
|
||||
)
|
||||
adjust: bool = Field(default=True, description="Adjust all the data automatically.")
|
||||
back_adjust: bool = Field(
|
||||
default=False, description="Back-adjusted data to mimic true historical prices."
|
||||
)
|
||||
|
||||
|
||||
class YFinanceForexEODData(ForexEODData):
|
||||
"""YFinance Forex End of Day Data."""
|
||||
|
||||
@validator("Date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return datetime object from string."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
class YFinanceForexEODFetcher(
|
||||
Fetcher[
|
||||
YFinanceForexEODQueryParams,
|
||||
List[YFinanceForexEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the yfinance endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> YFinanceForexEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
if params.get("period") is None:
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return YFinanceForexEODQueryParams(**transformed_params)
|
||||
|
||||
return YFinanceForexEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: YFinanceForexEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the yfinance endpoint."""
|
||||
query.symbol = f"{query.symbol}=X"
|
||||
|
||||
if query.period:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
period=query.period,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
else:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
start=query.start_date,
|
||||
end=query.end_date,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
data = data.reset_index()
|
||||
data["Date"] = (
|
||||
data["Date"].dt.tz_localize(None).dt.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
|
||||
return data.to_dict("records")
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[YFinanceForexEODData]:
|
||||
"""Transform the data to the standard format."""
|
||||
return [YFinanceForexEODData.parse_obj(d) for d in data]
|
||||
@@ -1,125 +0,0 @@
|
||||
"""yfinance Futures End of Day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.futures_eod import (
|
||||
FuturesEODData,
|
||||
FuturesEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, validator
|
||||
from yfinance import Ticker
|
||||
|
||||
from openbb_yfinance.utils.helpers import get_futures_data
|
||||
from openbb_yfinance.utils.references import INTERVALS, MONTHS, PERIODS
|
||||
|
||||
|
||||
class YFinanceFuturesEODQueryParams(FuturesEODQueryParams):
|
||||
"""YFinance Futures End of Day Query.
|
||||
|
||||
Source: https://finance.yahoo.com/crypto/
|
||||
"""
|
||||
|
||||
interval: Optional[INTERVALS] = Field(default="1d", description="Data granularity.")
|
||||
period: Optional[PERIODS] = Field(
|
||||
default=None, description=QUERY_DESCRIPTIONS.get("period", "")
|
||||
)
|
||||
prepost: bool = Field(
|
||||
default=False, description="Include Pre and Post market data."
|
||||
)
|
||||
adjust: bool = Field(default=True, description="Adjust all the data automatically.")
|
||||
back_adjust: bool = Field(
|
||||
default=False, description="Back-adjusted data to mimic true historical prices."
|
||||
)
|
||||
|
||||
|
||||
class YFinanceFuturesEODData(FuturesEODData):
|
||||
"""YFinance Futures End of Day Data."""
|
||||
|
||||
@validator("Date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return datetime object from string."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
class YFinanceFuturesEODFetcher(
|
||||
Fetcher[
|
||||
YFinanceFuturesEODQueryParams,
|
||||
List[YFinanceFuturesEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the yfinance endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> YFinanceFuturesEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
if params.get("period") is None:
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return YFinanceFuturesEODQueryParams(**transformed_params)
|
||||
|
||||
return YFinanceFuturesEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: YFinanceFuturesEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the yfinance endpoint."""
|
||||
symbol = ""
|
||||
|
||||
if query.expiration:
|
||||
expiry_date = datetime.strptime(query.expiration, "%Y-%m")
|
||||
futures_data = get_futures_data()
|
||||
exchange = futures_data[futures_data["Ticker"] == query.symbol][
|
||||
"Exchange"
|
||||
].values[0]
|
||||
symbol = f"{query.symbol}{MONTHS[expiry_date.month]}{str(expiry_date.year)[-2:]}.{exchange}"
|
||||
|
||||
query_symbol = symbol if symbol else f"{query.symbol}=F"
|
||||
|
||||
if query.period:
|
||||
data = Ticker(query_symbol).history(
|
||||
interval=query.interval,
|
||||
period=query.period,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
else:
|
||||
data = Ticker(query_symbol).history(
|
||||
interval=query.interval,
|
||||
start=query.start_date,
|
||||
end=query.end_date,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
data = data.reset_index()
|
||||
data["Date"] = (
|
||||
data["Date"].dt.tz_localize(None).dt.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
return data.to_dict("records")
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[YFinanceFuturesEODData]:
|
||||
"""Transform the data to the standard format."""
|
||||
return [YFinanceFuturesEODData.parse_obj(d) for d in data]
|
||||
@@ -1,114 +0,0 @@
|
||||
"""yfinance Major Indices End of Day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.major_indices_eod import (
|
||||
MajorIndicesEODData,
|
||||
MajorIndicesEODQueryParams,
|
||||
)
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, validator
|
||||
from yfinance import Ticker
|
||||
|
||||
from openbb_yfinance.utils.references import INTERVALS, PERIODS
|
||||
|
||||
|
||||
class YFinanceMajorIndicesEODQueryParams(MajorIndicesEODQueryParams):
|
||||
"""YFinance Major Indices End of Day Query.
|
||||
|
||||
Source: https://finance.yahoo.com/world-indices
|
||||
"""
|
||||
|
||||
interval: Optional[INTERVALS] = Field(default="1d", description="Data granularity.")
|
||||
period: Optional[PERIODS] = Field(
|
||||
default=None, description=QUERY_DESCRIPTIONS.get("period", "")
|
||||
)
|
||||
prepost: bool = Field(
|
||||
default=False, description="Include Pre and Post market data."
|
||||
)
|
||||
adjust: bool = Field(default=True, description="Adjust all the data automatically.")
|
||||
back_adjust: bool = Field(
|
||||
default=False, description="Back-adjusted data to mimic true historical prices."
|
||||
)
|
||||
|
||||
|
||||
class YFinanceMajorIndicesEODData(MajorIndicesEODData):
|
||||
"""YFinance Major Indices End of Day Data."""
|
||||
|
||||
@validator("Date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return datetime object from string."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
class YFinanceMajorIndicesEODFetcher(
|
||||
Fetcher[
|
||||
YFinanceMajorIndicesEODQueryParams,
|
||||
List[YFinanceMajorIndicesEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the yfinance endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> YFinanceMajorIndicesEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
if params.get("period") is None:
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return YFinanceMajorIndicesEODQueryParams(**transformed_params)
|
||||
|
||||
return YFinanceMajorIndicesEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: YFinanceMajorIndicesEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the yfinance endpoint."""
|
||||
query.symbol = f"^{query.symbol}"
|
||||
|
||||
if query.period:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
period=query.period,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
else:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
start=query.start_date,
|
||||
end=query.end_date,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
data = data.reset_index()
|
||||
data["Date"] = (
|
||||
data["Date"].dt.tz_localize(None).dt.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
return data.to_dict("records")
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[YFinanceMajorIndicesEODData]:
|
||||
"""Transform the data to the standard format."""
|
||||
return [YFinanceMajorIndicesEODData.parse_obj(d) for d in data]
|
||||
@@ -1,109 +0,0 @@
|
||||
"""yfinance Stock End of Day fetcher."""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openbb_provider.abstract.fetcher import Fetcher
|
||||
from openbb_provider.standard_models.stock_eod import StockEODData, StockEODQueryParams
|
||||
from openbb_provider.utils.descriptions import QUERY_DESCRIPTIONS
|
||||
from pydantic import Field, validator
|
||||
from yfinance import Ticker
|
||||
|
||||
from openbb_yfinance.utils.references import INTERVALS, PERIODS
|
||||
|
||||
|
||||
class YFinanceStockEODQueryParams(StockEODQueryParams):
|
||||
"""YFinance Stock End of Day Query.
|
||||
|
||||
Source: https://finance.yahoo.com/
|
||||
"""
|
||||
|
||||
interval: Optional[INTERVALS] = Field(default="1d", description="Data granularity.")
|
||||
period: Optional[PERIODS] = Field(
|
||||
default=None, description=QUERY_DESCRIPTIONS.get("period", "")
|
||||
)
|
||||
prepost: bool = Field(
|
||||
default=False, description="Include Pre and Post market data."
|
||||
)
|
||||
adjust: bool = Field(default=True, description="Adjust all the data automatically.")
|
||||
back_adjust: bool = Field(
|
||||
default=False, description="Back-adjusted data to mimic true historical prices."
|
||||
)
|
||||
|
||||
|
||||
class YFinanceStockEODData(StockEODData):
|
||||
"""YFinance Stock End of Day Data."""
|
||||
|
||||
@validator("Date", pre=True, check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
"""Return datetime object from string."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
class YFinanceStockEODFetcher(
|
||||
Fetcher[
|
||||
YFinanceStockEODQueryParams,
|
||||
List[YFinanceStockEODData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the yfinance endpoints."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> YFinanceStockEODQueryParams:
|
||||
"""Transform the query. Setting the start and end dates for a 1 year period."""
|
||||
if params.get("period") is None:
|
||||
transformed_params = params
|
||||
|
||||
now = datetime.now().date()
|
||||
if params.get("start_date") is None:
|
||||
transformed_params["start_date"] = now - relativedelta(years=1)
|
||||
|
||||
if params.get("end_date") is None:
|
||||
transformed_params["end_date"] = now
|
||||
return YFinanceStockEODQueryParams(**transformed_params)
|
||||
|
||||
return YFinanceStockEODQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
def extract_data(
|
||||
query: YFinanceStockEODQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the yfinance endpoint."""
|
||||
if query.period:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
period=query.period,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
else:
|
||||
data = Ticker(query.symbol).history(
|
||||
interval=query.interval,
|
||||
start=query.start_date,
|
||||
end=query.end_date,
|
||||
prepost=query.prepost,
|
||||
auto_adjust=query.adjust,
|
||||
back_adjust=query.back_adjust,
|
||||
actions=False,
|
||||
raise_errors=True,
|
||||
)
|
||||
|
||||
data = data.reset_index()
|
||||
data["Date"] = (
|
||||
data["Date"].dt.tz_localize(None).dt.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
)
|
||||
return data.to_dict("records")
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
data: dict,
|
||||
) -> List[YFinanceStockEODData]:
|
||||
"""Transform the data to the standard format."""
|
||||
return [YFinanceStockEODData.parse_obj(d) for d in data]
|
||||
@@ -1,37 +0,0 @@
|
||||
"""Crypto aggregate end of day price data model."""
|
||||
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field, PositiveFloat
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
from openbb_provider.standard_models.base import BaseSymbol
|
||||
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS
|
||||
|
||||
|
||||
class CryptoEODQueryParams(QueryParams, BaseSymbol):
|
||||
"""Crypto end of day Query."""
|
||||
|
||||
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 CryptoEODData(Data):
|
||||
"""Crypto end of day price Data."""
|
||||
|
||||
date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", ""))
|
||||
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", ""))
|
||||
vwap: Optional[PositiveFloat] = Field(description=DATA_DESCRIPTIONS.get("vwap", ""))
|
||||
@@ -1,37 +0,0 @@
|
||||
"""Forex aggregate end of day price data model."""
|
||||
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field, NonNegativeFloat, PositiveFloat
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
from openbb_provider.standard_models.base import BaseSymbol
|
||||
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS
|
||||
|
||||
|
||||
class ForexEODQueryParams(QueryParams, BaseSymbol):
|
||||
"""Forex end of day Query."""
|
||||
|
||||
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."""
|
||||
|
||||
date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", ""))
|
||||
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", ""))
|
||||
vwap: Optional[PositiveFloat] = Field(description=DATA_DESCRIPTIONS.get("vwap", ""))
|
||||
@@ -1,40 +0,0 @@
|
||||
"""Futures aggregate end of day price data model."""
|
||||
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
from openbb_provider.standard_models.base import BaseSymbol
|
||||
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS
|
||||
|
||||
|
||||
class FuturesEODQueryParams(QueryParams, BaseSymbol):
|
||||
"""Futures end of day Query."""
|
||||
|
||||
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", ""),
|
||||
)
|
||||
expiration: Optional[str] = Field(
|
||||
default=None,
|
||||
description="Future expiry date with format YYYY-MM",
|
||||
)
|
||||
|
||||
|
||||
class FuturesEODData(Data):
|
||||
"""Futures end of day price Data."""
|
||||
|
||||
date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", ""))
|
||||
open: float = Field(description=DATA_DESCRIPTIONS.get("open", ""))
|
||||
high: float = Field(description=DATA_DESCRIPTIONS.get("high", ""))
|
||||
low: float = Field(description=DATA_DESCRIPTIONS.get("low", ""))
|
||||
close: float = Field(description=DATA_DESCRIPTIONS.get("close", ""))
|
||||
volume: float = Field(description=DATA_DESCRIPTIONS.get("volume", ""))
|
||||
@@ -1,35 +0,0 @@
|
||||
"""Major indices aggregate end of day price data model."""
|
||||
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field, PositiveFloat
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
from openbb_provider.standard_models.base import BaseSymbol
|
||||
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS
|
||||
|
||||
|
||||
class MajorIndicesEODQueryParams(QueryParams, BaseSymbol):
|
||||
"""Major Indices end of day Query."""
|
||||
|
||||
start_date: Optional[date] = Field(
|
||||
description=QUERY_DESCRIPTIONS.get("start_date", ""), default=None
|
||||
)
|
||||
end_date: Optional[date] = Field(
|
||||
description=QUERY_DESCRIPTIONS.get("end_date", ""), default=None
|
||||
)
|
||||
|
||||
|
||||
class MajorIndicesEODData(Data):
|
||||
"""Major Indices end of day price data."""
|
||||
|
||||
date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", ""))
|
||||
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: float = Field(description=DATA_DESCRIPTIONS.get("volume", ""))
|
||||
vwap: Optional[float] = Field(description=DATA_DESCRIPTIONS.get("vwap", ""))
|
||||
@@ -1,35 +0,0 @@
|
||||
"""Stock aggregate end of day price data model."""
|
||||
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import Field, PositiveFloat
|
||||
|
||||
from openbb_provider.abstract.data import Data
|
||||
from openbb_provider.abstract.query_params import QueryParams
|
||||
from openbb_provider.standard_models.base import BaseSymbol
|
||||
from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS
|
||||
|
||||
|
||||
class StockEODQueryParams(QueryParams, BaseSymbol):
|
||||
"""Stock end of day Query."""
|
||||
|
||||
start_date: Optional[date] = Field(
|
||||
description=QUERY_DESCRIPTIONS.get("start_date", ""), default=None
|
||||
)
|
||||
end_date: Optional[date] = Field(
|
||||
description=QUERY_DESCRIPTIONS.get("end_date", ""), default=None
|
||||
)
|
||||
|
||||
|
||||
class StockEODData(Data):
|
||||
"""Stock end of day price Data."""
|
||||
|
||||
date: datetime = Field(description=DATA_DESCRIPTIONS.get("date", ""))
|
||||
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: float = Field(description=DATA_DESCRIPTIONS.get("volume", ""))
|
||||
vwap: Optional[PositiveFloat] = Field(description=DATA_DESCRIPTIONS.get("vwap", ""))
|
||||
Reference in New Issue
Block a user