diff --git a/polygon/rest/__init__.py b/polygon/rest/__init__.py index 849443f1..a04cf1d0 100644 --- a/polygon/rest/__init__.py +++ b/polygon/rest/__init__.py @@ -1,8 +1,10 @@ from .aggs import AggsClient from .trades import TradesClient from .quotes import QuotesClient -from .reference import MarketsClient, TickersClient +from .reference import MarketsClient, TickersClient, SplitsClient -class RESTClient(AggsClient, TradesClient, QuotesClient, MarketsClient, TickersClient): +class RESTClient( + AggsClient, TradesClient, QuotesClient, MarketsClient, TickersClient, SplitsClient +): pass diff --git a/polygon/rest/models/__init__.py b/polygon/rest/models/__init__.py index 13bc71ea..914cc3a6 100644 --- a/polygon/rest/models/__init__.py +++ b/polygon/rest/models/__init__.py @@ -3,6 +3,7 @@ from .quotes import * from .markets import * from .tickers import * +from .splits import * from enum import Enum @@ -11,6 +12,7 @@ class Sort(Enum): ASC = "asc" DESC = "desc" + class Order(Enum): ASC = "asc" DESC = "desc" diff --git a/polygon/rest/models/aggs.py b/polygon/rest/models/aggs.py index bdaa311c..7b3548a5 100644 --- a/polygon/rest/models/aggs.py +++ b/polygon/rest/models/aggs.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from typing import Optional + @dataclass class Agg: timestamp: int @@ -15,12 +16,12 @@ class Agg: @staticmethod def from_dict(d): return Agg( - timestamp=d["t"], - open=d["o"], - high=d["h"], - low=d["l"], - close=d["c"], - volume=d["v"], - vwap=d.get("vw", None), - transactions=d.get("n", None) + timestamp=d["t"], + open=d["o"], + high=d["h"], + low=d["l"], + close=d["c"], + volume=d["v"], + vwap=d.get("vw", None), + transactions=d.get("n", None), ) diff --git a/polygon/rest/models/markets.py b/polygon/rest/models/markets.py index 561dbeef..b2b3078f 100644 --- a/polygon/rest/models/markets.py +++ b/polygon/rest/models/markets.py @@ -16,6 +16,7 @@ class MarketHoliday: def from_dict(d): return MarketHoliday(**d) + @dataclass class MarketStatus: "MarketStatus contains data for the current trading status of the exchanges and overall financial markets." diff --git a/polygon/rest/models/quotes.py b/polygon/rest/models/quotes.py index fa2b4503..a83f0a36 100644 --- a/polygon/rest/models/quotes.py +++ b/polygon/rest/models/quotes.py @@ -23,6 +23,7 @@ class Quote: def from_dict(d): return Quote(**d) + @dataclass class LastQuote: "LastQuote contains data for the most recent NBBO (Quote) tick for a given stock." @@ -57,5 +58,5 @@ def from_dict(d): bid_price=d.get("p", None), bid_size=d.get("s", None), bid_exchange=d.get("x", None), - tape=d.get("z", None) - ) \ No newline at end of file + tape=d.get("z", None), + ) diff --git a/polygon/rest/models/splits.py b/polygon/rest/models/splits.py new file mode 100644 index 00000000..037a3e1e --- /dev/null +++ b/polygon/rest/models/splits.py @@ -0,0 +1,15 @@ +from typing import Optional +from dataclasses import dataclass + + +@dataclass +class Split: + "Split contains data for a historical stock split, including the ticker symbol, the execution date, and the factors of the split ratio." + execution_date: Optional[str] = None + split_from: Optional[int] = None + split_to: Optional[int] = None + ticker: Optional[str] = None + + @staticmethod + def from_dict(d): + return Split(**d) diff --git a/polygon/rest/models/tickers.py b/polygon/rest/models/tickers.py index 105a8a30..d5382a8a 100644 --- a/polygon/rest/models/tickers.py +++ b/polygon/rest/models/tickers.py @@ -2,32 +2,38 @@ from enum import Enum from dataclasses import dataclass + class Locale(Enum): US = "us" GLOBAL = "global" + class Market(Enum): STOCKS = "stocks" CRYPTO = "crypto" FX = "fx" + class AssetClass(Enum): STOCKS = "stocks" OPTIONS = "options" CRYPTO = "crypto" FX = "fx" + @dataclass class Address: address1: Optional[str] = None city: Optional[str] = None state: Optional[str] = None + @dataclass class Branding: icon_url: Optional[str] = None logo_url: Optional[str] = None + @dataclass class Publisher: favicon_url: Optional[str] = None @@ -57,6 +63,7 @@ class Ticker: def from_dict(d): return Ticker(**d) + @dataclass class TickerDetails: "TickerDetails contains data for a specified ticker symbol." @@ -89,6 +96,7 @@ class TickerDetails: def from_dict(d): return TickerDetails(**d) + @dataclass class TickerNews: "TickerDetails contains data for news articles relating to a stock ticker symbol." @@ -108,6 +116,7 @@ class TickerNews: def from_dict(d): return TickerNews(**d) + @dataclass class TickerTypes: "TickerTypes contains data for ticker types." diff --git a/polygon/rest/quotes.py b/polygon/rest/quotes.py index c8710958..198e3adf 100644 --- a/polygon/rest/quotes.py +++ b/polygon/rest/quotes.py @@ -17,7 +17,7 @@ def list_quotes( sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False + raw: bool = False, ) -> Union[List[Quote], HTTPResponse]: """ Get quotes for a ticker symbol in a given time range. @@ -34,7 +34,6 @@ def list_quotes( :param params: Any additional query params :param raw: Return HTTPResponse object instead of results object :return: List of quotes - :rtype: List[Quote] """ url = f"/v3/quotes/{ticker}" @@ -44,12 +43,9 @@ def list_quotes( raw=raw, deserializer=Quote.from_dict, ) - + def get_last_quote( - self, - ticker: str, - params: Optional[Dict[str, Any]] = None, - raw: bool = False + self, ticker: str, params: Optional[Dict[str, Any]] = None, raw: bool = False ) -> Union[LastQuote, HTTPResponse]: """ Get the most recent NBBO (Quote) tick for a given stock. @@ -58,10 +54,9 @@ def get_last_quote( :param params: Any additional query params :param raw: Return HTTPResponse object instead of results object :return: Last Quote - :rtype: LastQuote """ url = f"/v2/last/nbbo/{ticker}" - return self._get(path=url, params=params, deserializer=LastQuote.from_dict, raw=raw) - - \ No newline at end of file + return self._get( + path=url, params=params, deserializer=LastQuote.from_dict, raw=raw + ) diff --git a/polygon/rest/reference.py b/polygon/rest/reference.py index bfe5899f..d2c83b3d 100644 --- a/polygon/rest/reference.py +++ b/polygon/rest/reference.py @@ -1,14 +1,24 @@ from .base import BaseClient from typing import Optional, Any, Dict, List, Union, Iterator -from .models import MarketHoliday, MarketStatus, Ticker, TickerDetails, TickerNews, TickerTypes, Sort, Order, AssetClass, Locale +from .models import ( + MarketHoliday, + MarketStatus, + Ticker, + TickerDetails, + TickerNews, + TickerTypes, + Sort, + Order, + AssetClass, + Locale, + Split, +) from urllib3 import HTTPResponse # https://polygon.io/docs/stocks class MarketsClient(BaseClient): def list_market_holidays( - self, - params: Optional[Dict[str, Any]] = None, - raw: bool = False + self, params: Optional[Dict[str, Any]] = None, raw: bool = False ) -> Union[List[MarketHoliday], HTTPResponse]: """ Get upcoming market holidays and their open/close times. @@ -16,16 +26,15 @@ def list_market_holidays( :param params: Any additional query params :param raw: Return HTTPResponse object instead of results object :return: List of quotes - :rtype: List[Quote] """ url = "/v1/marketstatus/upcoming" - return self._get(path=url, params=params, deserializer=MarketHoliday.from_dict, raw=raw) + return self._get( + path=url, params=params, deserializer=MarketHoliday.from_dict, raw=raw + ) def get_market_status( - self, - params: Optional[Dict[str, Any]] = None, - raw: bool = False + self, params: Optional[Dict[str, Any]] = None, raw: bool = False ) -> Union[MarketStatus, HTTPResponse]: """ Get the current trading status of the exchanges and overall financial markets. @@ -33,11 +42,13 @@ def get_market_status( :param params: Any additional query params :param raw: Return HTTPResponse object instead of results object :return: List of quotes - :rtype: List[Quote] """ url = "/v1/marketstatus/now" - return self._get(path=url, params=params, deserializer=MarketStatus.from_dict, raw=raw) + return self._get( + path=url, params=params, deserializer=MarketStatus.from_dict, raw=raw + ) + class TickersClient(BaseClient): def list_tickers( @@ -65,7 +76,7 @@ def list_tickers( Query all ticker symbols which are supported by Polygon.io. This API currently includes Stocks/Equities, Crypto, and Forex. :param ticker: Specify a ticker symbol. Defaults to empty string which queries all tickers. - :param ticker_lt: Timestamp less than + :param ticker_lt: Ticker less than :param ticker_lte: Ticker less than or equal to :param ticker_gt: Ticker greater than :param ticker_gte: Ticker greater than or equal to @@ -83,7 +94,6 @@ def list_tickers( :param params: Any additional query params :param raw: Return raw object instead of results object :return: List of tickers - :rtype: List[Ticker] """ url = "/v3/reference/tickers" @@ -109,11 +119,12 @@ def get_ticker_details( :param params: Any additional query params :param raw: Return raw object instead of results object :return: Ticker Details V3 - :rtype: TickerDetail """ url = f"/v3/reference/tickers/{ticker}" - return self._get(path=url, params=params, deserializer=TickerDetails.from_dict, raw=raw) + return self._get( + path=url, params=params, deserializer=TickerDetails.from_dict, raw=raw + ) def get_ticker_news( self, @@ -141,11 +152,12 @@ def get_ticker_news( :param params: Any additional query params :param raw: Return raw object instead of results object :return: Ticker News - :rtype: TickerNews """ url = "/v2/reference/news" - return self._get(path=url, params=params, deserializer=TickerNews.from_dict, raw=raw) + return self._get( + path=url, params=params, deserializer=TickerNews.from_dict, raw=raw + ) def get_ticker_types( self, @@ -162,8 +174,60 @@ def get_ticker_types( :param params: Any additional query params :param raw: Return raw object instead of results object :return: Ticker Types - :rtype: TickerTypes """ url = "/v3/reference/tickers/types" - return self._get(path=url, params=params, deserializer=TickerTypes.from_dict, raw=raw) \ No newline at end of file + return self._get( + path=url, params=params, deserializer=TickerTypes.from_dict, raw=raw + ) + + +class SplitsClient(BaseClient): + def list_splits( + self, + ticker: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + execution_date: Optional[str] = None, + execution_lt: Optional[str] = None, + execution_lte: Optional[str] = None, + execution_gt: Optional[str] = None, + execution_gte: Optional[str] = None, + reverse_split: Optional[bool] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[Iterator[Split], HTTPResponse]: + """ + Get a list of historical stock splits, including the ticker symbol, the execution date, and the factors of the split ratio. + + :param ticker: Return the stock splits that contain this ticker. + :param ticker_lt: Ticker less than + :param ticker_lte: Ticker less than or equal to + :param ticker_gt: Ticker greater than + :param ticker_gte: Ticker greater than or equal to + :param execution_date: Query by execution date with the format YYYY-MM-DD. + :param execution_date_lt: Execution date less than + :param execution_date_lte: Execution date less than or equal to + :param execution_date_gt: Execution date greater than + :param execution_date_gte: Execution date greater than or equal to + :param reverse_split: Query for reverse stock splits. A split ratio where split_from is greater than split_to represents a reverse split. By default this filter is not used. + :param limit: Limit the number of results returned, default is 10 and max is 1000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of splits + """ + url = "/v3/reference/splits" + + return self._paginate( + path=url, + params=self._get_params(self.list_splits, locals()), + raw=raw, + deserializer=Split.from_dict, + )