refactored ForexPairs and added Polygon provider

This commit is contained in:
Pratyush Shukla
2023-07-28 01:50:45 +05:30
parent ba8a877452
commit 667bbfc1a9
4 changed files with 161 additions and 29 deletions

View File

@@ -3,24 +3,35 @@
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_pairs import ForexPairsData, ForexPairsQueryParams
from openbb_fmp.utils.helpers import get_data_many
from pydantic import Field
class FMPForexPairsQueryParams(QueryParams):
"""FMP Forex available pairs query.
class FMPForexPairsQueryParams(ForexPairsQueryParams):
"""FMP Forex available pairs Query.
Source: https://site.financialmodelingprep.com/developer/docs/#Historical-Forex-Price
"""
class FMPForexPairsData(Data):
"""FMP Forex available pairs data."""
class FMPForexPairsData(ForexPairsData):
"""FMP Forex available pairs Data."""
symbol: str = Field(description="The symbol of the currency pair.")
currency: str = Field(description="The base currency of the currency pair.")
stockExchange: Optional[str] = Field(
description="The stock exchange of the currency pair.",
alias="stock_exchange",
)
exchange_short_name: Optional[str] = Field(
description="The short name of the stock exchange of the currency pair.",
alias="exchange_short_name",
)
class FMPForexPairsFetcher(
@@ -46,6 +57,7 @@ class FMPForexPairsFetcher(
base_url = "https://financialmodelingprep.com/api/v3"
url = f"{base_url}/symbol/available-forex-currency-pairs?apikey={api_key}"
return get_data_many(url, FMPForexPairsData)
@staticmethod

View File

@@ -0,0 +1,136 @@
"""Polygon available pairs fetcher."""
from datetime import date as dateType, datetime
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.forex_pairs import ForexPairsData, ForexPairsQueryParams
from pydantic import Field, PositiveInt, validator
from openbb_polygon.utils.helpers import get_data
class PolygonForexPairsQueryParams(ForexPairsQueryParams):
"""Polygon available pairs Query.
Source: https://polygon.io/docs/forex/get_v3_reference_tickers
"""
symbol: Optional[str] = Field(description="Symbol of the pair to search.")
date: Optional[dateType] = Field(
default=datetime.now().date(), description=QUERY_DESCRIPTIONS.get("date", "")
)
search: Optional[str] = Field(
default="",
description="Search for terms within the ticker and/or company name.",
)
active: Optional[Literal[True, False]] = Field(
default=True,
description="Specify if the tickers returned should be actively traded on the queried date.",
)
order: Optional[Literal["asc", "desc"]] = Field(
default="asc", description="Order data by ascending or descending."
)
sort: Optional[
Literal[
"ticker",
"name",
"market",
"locale",
"currency_symbol",
"currency_name",
"base_currency_symbol",
"base_currency_name",
"last_updated_utc",
"delisted_utc",
]
] = Field(default="", description="Sort field used for ordering.")
limit: Optional[PositiveInt] = Field(
default=1000, description=QUERY_DESCRIPTIONS.get("limit", "")
)
class PolygonForexPairsData(ForexPairsData):
"""Polygon available pairs Data."""
market: str = Field(description="The name of the trading market. Always 'fx'.")
locale: str = Field(description="The locale of the currency pair.")
currency_symbol: str = Field(description="The symbol of the quote currency.")
currency_name: str = Field(description="The name of the quote currency.")
base_currency_symbol: str = Field(description="The symbol of the base currency.")
base_currency_name: str = Field(description="The name of the base currency.")
last_updated_utc: datetime = Field(description="The last updated timestamp in UTC.")
delisted_utc: Optional[datetime] = Field(
description="The delisted timestamp in UTC."
)
@validator("last_updated_utc", pre=True, check_fields=False)
def last_updated_utc_validate(cls, v): # pylint: disable=E0213
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%SZ")
@validator("delisted_utc", pre=True, check_fields=False)
def delisted_utc_validate(cls, v): # pylint: disable=E0213
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%SZ")
class PolygonForexPairsFetcher(
Fetcher[
ForexPairsQueryParams,
ForexPairsData,
PolygonForexPairsQueryParams,
PolygonForexPairsData,
]
):
@staticmethod
def transform_query(
query: ForexPairsQueryParams, extra_params: Optional[Dict] = None
) -> PolygonForexPairsQueryParams:
return PolygonForexPairsQueryParams(
**extra_params or {},
)
@staticmethod
def extract_data(
query: PolygonForexPairsQueryParams, credentials: Optional[Dict[str, str]]
) -> List[PolygonForexPairsData]:
if credentials:
api_key = credentials.get("polygon_api_key")
tickers = f"ticker=C:{query.symbol}" if query.symbol else ""
request_url = (
f"https://api.polygon.io/v3/reference/"
f"tickers?{tickers}&market=fx&date={query.date}&"
f"search={query.search}&active={query.active}&order={query.order}&"
f"limit={query.limit}&sort={query.sort}&apiKey={api_key}"
)
data = {"next_url": request_url}
all_data: List[Dict] = []
while "next_url" in data:
data = get_data(request_url)
if isinstance(data, list):
raise ValueError("Expected a dict, got a list")
if len(data["results"]) == 0:
raise RuntimeError(
"No results found. Please change your query parameters."
)
if data["status"] == "OK":
all_data.extend(data["results"])
elif data["status"] == "ERROR":
raise UserWarning(data["error"])
if "next_url" in data:
request_url = f"{data['next_url']}&apiKey={api_key}"
return all_data
@staticmethod
def transform_data(data: List[PolygonForexPairsData]) -> List[ForexPairsData]:
return data_transformer(data, ForexPairsData)

View File

@@ -8,6 +8,7 @@ from openbb_polygon.models.cash_flow import PolygonCashFlowStatementFetcher
from openbb_polygon.models.crypto_eod import PolygonCryptoEODFetcher
from openbb_polygon.models.crypto_price import PolygonCryptoPriceFetcher
from openbb_polygon.models.forex_eod import PolygonForexEODFetcher
from openbb_polygon.models.forex_pairs import PolygonForexPairsFetcher
from openbb_polygon.models.forex_price import PolygonForexPriceFetcher
from openbb_polygon.models.income_statement import PolygonIncomeStatementFetcher
from openbb_polygon.models.major_indices_eod import PolygonMajorIndicesEODFetcher
@@ -34,5 +35,6 @@ polygon_provider = Provider(
PolygonMajorIndicesPriceFetcher,
PolygonForexEODFetcher,
PolygonForexPriceFetcher,
PolygonForexPairsFetcher,
],
)

View File

@@ -1,34 +1,16 @@
"""Forex available pairs data model."""
from typing import Optional
from openbb_provider.abstract.data import Data, QueryParams
from pydantic import Field
class ForexPairsQueryParams(QueryParams):
"""Forex available pairs query."""
"""Forex available pairs Query."""
class ForexPairsData(Data):
"""Forex available pairs data.
"""Forex available pairs Data."""
Returns
-------
symbol : str
The symbol of the currency pair.
name : str
The name of the currency pair separated by '/'.
currency : str
The base currency of the currency pair.
stock_exchange : Optional[str]
The stock exchange of the currency pair.
exchange_short_name : Optional[str]
The short name of the stock exchange of the currency pair.
"""
symbol: str
name: str
currency: str
stock_exchange: Optional[str]
exchange_short_name: Optional[str]
name: str = Field(description="The name of the currency pair.")