Skip to content

Commit 7ca8187

Browse files
author
clickingbuttons
committed
add snapshot (#141)
* add snapshot * style
1 parent 488f2ca commit 7ca8187

File tree

6 files changed

+332
-7
lines changed

6 files changed

+332
-7
lines changed

polygon/rest/aggs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from urllib3 import HTTPResponse
55
from datetime import datetime, date
66

7-
# https://polygon.io/docs/stocks
7+
88
class AggsClient(BaseClient):
99
def get_aggs(
1010
self,

polygon/rest/models/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from .shared import *
12
from .aggs import *
23
from .trades import *
34
from .quotes import *
@@ -7,4 +8,4 @@
78
from .dividends import *
89
from .conditions import *
910
from .exchanges import *
10-
from .shared import *
11+
from .snapshot import *

polygon/rest/models/aggs.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
@dataclass
66
class Agg:
7-
open: float
8-
high: float
9-
low: float
10-
close: float
11-
volume: float
7+
open: Optional[float]
8+
high: Optional[float]
9+
low: Optional[float]
10+
close: Optional[float]
11+
volume: Optional[float]
1212
vwap: Optional[float]
1313
timestamp: Optional[int]
1414
transactions: Optional[int]

polygon/rest/models/shared.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@ class ExchangeType(Enum):
6060
EXCHANGE = "exchange"
6161
TRF = "TRF"
6262
SIP = "SIP"
63+
64+
65+
class Direction(Enum):
66+
GAINERS = "gainers"
67+
LOSERS = "losers"
68+
69+
70+
class SnapshotMarketType(Enum):
71+
STOCKS = "stocks"
72+
FOREX = "forex"
73+
CRYPTO = "crypto"

polygon/rest/models/snapshot.py

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
from dataclasses import dataclass
2+
from typing import Optional, List, Dict
3+
from .aggs import Agg
4+
from .quotes import LastQuote
5+
from .trades import LastTrade
6+
7+
8+
@dataclass
9+
class SnapshotMin:
10+
"Most recent minute bar"
11+
accumulated_volume: Optional[float]
12+
open: Optional[float]
13+
high: Optional[float]
14+
low: Optional[float]
15+
close: Optional[float]
16+
volume: Optional[float]
17+
vwap: Optional[float]
18+
19+
@staticmethod
20+
def from_dict(d):
21+
return SnapshotMin(
22+
d.get("ac", None),
23+
d.get("o", None),
24+
d.get("h", None),
25+
d.get("l", None),
26+
d.get("c", None),
27+
d.get("v", None),
28+
d.get("vw", None),
29+
)
30+
31+
32+
@dataclass
33+
class Snapshot:
34+
day: Optional[Agg]
35+
last_quote: Optional[LastQuote]
36+
last_trade: Optional[LastTrade]
37+
min: Optional[SnapshotMin]
38+
prev_day: Optional[Agg]
39+
ticker: str
40+
todays_change: float
41+
todays_change_percent: float
42+
updated: int
43+
44+
@staticmethod
45+
def from_dict(d):
46+
return Snapshot(
47+
d.get("day", None),
48+
d.get("lastQuote", None),
49+
d.get("lastTrade", None),
50+
d.get("min", None),
51+
d.get("prevDay", None),
52+
d.get("ticker", None),
53+
d.get("todaysChange", None),
54+
d.get("todaysChangePercent", None),
55+
d.get("updated", None),
56+
)
57+
58+
59+
@dataclass
60+
class DayOptionContractSnapshot:
61+
change: Optional[float]
62+
change_percent: Optional[float]
63+
close: Optional[float]
64+
high: Optional[float]
65+
last_updated: Optional[int]
66+
low: Optional[float]
67+
open: Optional[float]
68+
previous_close: Optional[float]
69+
volume: Optional[float]
70+
vwap: Optional[float]
71+
72+
@staticmethod
73+
def from_dict(d):
74+
return DayOptionContractSnapshot(**d)
75+
76+
77+
@dataclass
78+
class OptionDetails:
79+
contract_type: str
80+
exercise_style: str
81+
expiration_date: str
82+
shares_per_contract: float
83+
strike_price: float
84+
ticker: str
85+
86+
@staticmethod
87+
def from_dict(d):
88+
return OptionDetails(**d)
89+
90+
91+
@dataclass
92+
class OptionLastQuote:
93+
ask: Optional[float]
94+
ask_size: Optional[float]
95+
bid: Optional[float]
96+
bid_size: Optional[float]
97+
last_updated: Optional[int]
98+
midpoint: Optional[float]
99+
timeframe: Optional[str]
100+
101+
@staticmethod
102+
def from_dict(d):
103+
return OptionLastQuote(**d)
104+
105+
106+
@dataclass
107+
class OptionGreeks:
108+
delta: Optional[float]
109+
gamma: Optional[float]
110+
theta: Optional[float]
111+
vega: Optional[float]
112+
113+
@staticmethod
114+
def from_dict(d):
115+
return OptionGreeks(**d)
116+
117+
118+
@dataclass
119+
class UnderlyingAsset:
120+
change_to_break_even: Optional[float]
121+
last_updated: Optional[int]
122+
price: Optional[float]
123+
ticker: Optional[str]
124+
timeframe: Optional[str]
125+
126+
@staticmethod
127+
def from_dict(d):
128+
return UnderlyingAsset(**d)
129+
130+
131+
@dataclass
132+
class OptionContractSnapshot:
133+
break_even_price: Optional[float]
134+
day: Optional[Agg]
135+
details: Optional[OptionDetails]
136+
greeks: Optional[OptionGreeks]
137+
implied_volatility: Optional[float]
138+
last_quote: Optional[OptionLastQuote]
139+
open_interest: Optional[float]
140+
underlying_asset: Optional[float]
141+
142+
@staticmethod
143+
def from_dict(d):
144+
return OptionContractSnapshot(**d)
145+
146+
147+
@dataclass
148+
class OrderBookQuote:
149+
price: Optional[float]
150+
exchange_shares: Dict[str, float]
151+
152+
@staticmethod
153+
def from_dict(d):
154+
return OrderBookQuote(**d)
155+
156+
157+
@dataclass
158+
class SnapshotTickerFullBook:
159+
ticker: Optional[str]
160+
bids: Optional[List[OrderBookQuote]]
161+
asks: Optional[List[OrderBookQuote]]
162+
bid_count: Optional[float]
163+
ask_count: Optional[float]
164+
spread: Optional[float]
165+
updated: int
166+
167+
@staticmethod
168+
def from_dict(d):
169+
return SnapshotTickerFullBook(
170+
d.get("ticker", None),
171+
d.get("bids", None),
172+
d.get("asks", None),
173+
d.get("bidCount", None),
174+
d.get("askCount", None),
175+
d.get("spread", None),
176+
d.get("updated", None),
177+
)

polygon/rest/snapshot.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from .base import BaseClient
2+
from typing import Optional, Any, Dict, List, Union
3+
from .models import (
4+
Snapshot,
5+
Direction,
6+
OptionContractSnapshot,
7+
SnapshotMarketType,
8+
SnapshotTickerFullBook,
9+
)
10+
from urllib3 import HTTPResponse
11+
12+
13+
class SnapshotClient(BaseClient):
14+
def get_snapshot_all(
15+
self,
16+
market_type: Optional[Union[str, SnapshotMarketType]] = "stocks",
17+
tickers: Optional[Union[str, List[str]]] = None,
18+
params: Optional[Dict[str, Any]] = None,
19+
raw: bool = False,
20+
) -> Union[List[Snapshot], HTTPResponse]:
21+
"""
22+
Get the most up-to-date market data for all traded stock symbols.
23+
24+
Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. This can happen as early as 4am EST.
25+
26+
:param market_type: Which market to get a snapshot of.
27+
:param tickers: A comma separated list of tickers to get snapshots for.
28+
:return: List of Snapshots
29+
"""
30+
url = f"/v2/snapshot/locale/us/markets/{market_type}/tickers"
31+
if type(tickers) is list:
32+
tickers = ",".join(tickers)
33+
return self._get(
34+
path=url,
35+
params=self._get_params(self.get_snapshot_all, locals()),
36+
deserializer=Snapshot.from_dict,
37+
raw=raw,
38+
)
39+
40+
def get_snapshot_direction(
41+
self,
42+
direction: Union[str, Direction],
43+
market_type: Optional[Union[str, SnapshotMarketType]] = "stocks",
44+
params: Optional[Dict[str, Any]] = None,
45+
raw: bool = False,
46+
) -> Union[List[Snapshot], HTTPResponse]:
47+
"""
48+
Get the most up-to-date market data for the current top 20 gainers or losers of the day in the stocks/equities markets.
49+
50+
Top gainers are those tickers whose price has increased by the highest percentage since the previous day's close. Top losers are those tickers whose price has decreased by the highest percentage since the previous day's close.
51+
52+
Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges.
53+
54+
:param market_type: Which market to get a snapshot of.
55+
:param direction: The direction ("gainers" or "losers")
56+
:return: List of Snapshots
57+
"""
58+
url = f"/v2/snapshot/locale/us/markets/{market_type}/{direction}"
59+
return self._get(
60+
path=url,
61+
params=self._get_params(self.get_snapshot_direction, locals()),
62+
result_key="tickers",
63+
deserializer=Snapshot.from_dict,
64+
raw=raw,
65+
)
66+
67+
def get_snapshot_ticker(
68+
self,
69+
ticker: str,
70+
market_type: Optional[Union[str, SnapshotMarketType]] = "stocks",
71+
params: Optional[Dict[str, Any]] = None,
72+
raw: bool = False,
73+
) -> Union[Snapshot, HTTPResponse]:
74+
"""
75+
Get the most up-to-date market data for all traded stock symbols.
76+
77+
Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. This can happen as early as 4am EST.
78+
79+
:param market_type: Which market to get a snapshot of.
80+
:param ticker: The ticker symbol.
81+
:return: List of Snapshots
82+
"""
83+
url = f"/v2/snapshot/locale/us/markets/{market_type}/tickers/{ticker}"
84+
return self._get(
85+
path=url,
86+
params=self._get_params(self.get_snapshot_ticker, locals()),
87+
result_key="ticker",
88+
deserializer=Snapshot.from_dict,
89+
raw=raw,
90+
)
91+
92+
def get_snapshot_option(
93+
self,
94+
underlying_asset: str,
95+
option_contract: str,
96+
params: Optional[Dict[str, Any]] = None,
97+
raw: bool = False,
98+
) -> Union[OptionContractSnapshot, HTTPResponse]:
99+
"""
100+
Get the snapshot of an option contract for a stock equity.
101+
102+
:param underlying_asset: The underlying ticker symbol of the option contract.
103+
:param option_contract: The option contract identifier.
104+
:return: List of Snapshots
105+
"""
106+
url = f"/v2/snapshot/options/{underlying_asset}/{option_contract}"
107+
return self._get(
108+
path=url,
109+
params=self._get_params(self.get_snapshot_option, locals()),
110+
result_key="results",
111+
deserializer=OptionContractSnapshot.from_dict,
112+
raw=raw,
113+
)
114+
115+
def get_snapshot_crypto_book(
116+
self,
117+
ticker: str,
118+
params: Optional[Dict[str, Any]] = None,
119+
raw: bool = False,
120+
) -> Union[SnapshotTickerFullBook, HTTPResponse]:
121+
"""
122+
Get the current level 2 book of a single ticker. This is the combined book from all of the exchanges.
123+
124+
Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges.
125+
126+
:param ticker: The ticker symbol.
127+
:return: List of Snapshots
128+
"""
129+
url = f" /v2/snapshot/locale/global/markets/crypto/tickers/{ticker}/book"
130+
return self._get(
131+
path=url,
132+
params=self._get_params(self.get_snapshot_crypto_book, locals()),
133+
result_key="data",
134+
deserializer=SnapshotTickerFullBook.from_dict,
135+
raw=raw,
136+
)

0 commit comments

Comments
 (0)