Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions polygon/rest/__init__.py
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions polygon/rest/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .quotes import *
from .markets import *
from .tickers import *
from .splits import *

from enum import Enum

Expand All @@ -11,6 +12,7 @@ class Sort(Enum):
ASC = "asc"
DESC = "desc"


class Order(Enum):
ASC = "asc"
DESC = "desc"
17 changes: 9 additions & 8 deletions polygon/rest/models/aggs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass
from typing import Optional


@dataclass
class Agg:
timestamp: int
Expand All @@ -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),
)
1 change: 1 addition & 0 deletions polygon/rest/models/markets.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
5 changes: 3 additions & 2 deletions polygon/rest/models/quotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down Expand Up @@ -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)
)
tape=d.get("z", None),
)
15 changes: 15 additions & 0 deletions polygon/rest/models/splits.py
Original file line number Diff line number Diff line change
@@ -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)
9 changes: 9 additions & 0 deletions polygon/rest/models/tickers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -57,6 +63,7 @@ class Ticker:
def from_dict(d):
return Ticker(**d)


@dataclass
class TickerDetails:
"TickerDetails contains data for a specified ticker symbol."
Expand Down Expand Up @@ -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."
Expand All @@ -108,6 +116,7 @@ class TickerNews:
def from_dict(d):
return TickerNews(**d)


@dataclass
class TickerTypes:
"TickerTypes contains data for ticker types."
Expand Down
17 changes: 6 additions & 11 deletions polygon/rest/quotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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}"

Expand All @@ -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.
Expand All @@ -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)


return self._get(
path=url, params=params, deserializer=LastQuote.from_dict, raw=raw
)
102 changes: 83 additions & 19 deletions polygon/rest/reference.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
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.

: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.

: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(
Expand Down Expand Up @@ -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
Expand All @@ -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"

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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)
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,
)