Skip to content

Commit 5d33f34

Browse files
chaig15jbonzo
andauthored
add summaries endpoint (#340)
* summaries endpoint framework * summaries endpoint framework * add models * lint * add test * Fix any_of being a list * Test fixes * lint * fix list tickers * fix list tickers * add new tests * lint * remove test and format json * lint * fix test expected response for summaries Co-authored-by: jbonzo <[email protected]>
1 parent 3cee0bc commit 5d33f34

7 files changed

+317
-1
lines changed

polygon/rest/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from .quotes import QuotesClient
44
from .snapshot import SnapshotClient
55
from .indicators import IndicatorsClient
6+
from .summaries import SummariesClient
67
from .reference import (
78
MarketsClient,
89
TickersClient,
@@ -34,6 +35,7 @@ class RESTClient(
3435
ExchangesClient,
3536
ContractsClient,
3637
IndicatorsClient,
38+
SummariesClient,
3739
):
3840
def __init__(
3941
self,

polygon/rest/base.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,11 @@ def _get_params(
151151
or argname.endswith("_lte")
152152
or argname.endswith("_gt")
153153
or argname.endswith("_gte")
154+
or argname.endswith("_any_of")
154155
):
155-
argname = ".".join(argname.rsplit("_", 1))
156+
argname = ".".join(argname.split("_", 1))
157+
if argname.endswith("any_of"):
158+
val = ",".join(val)
156159
params[argname] = val
157160

158161
return params

polygon/rest/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
from .splits import *
1313
from .tickers import *
1414
from .trades import *
15+
from .summaries import *

polygon/rest/models/summaries.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from sqlite3 import Timestamp
2+
from typing import Optional
3+
from ...modelclass import modelclass
4+
from .tickers import Branding
5+
6+
7+
@modelclass
8+
class Session:
9+
"Contains Session data for the summaries endpoint."
10+
change: Optional[float] = None
11+
change_percent: Optional[float] = None
12+
early_trading_change: Optional[float] = None
13+
early_trading_change_percent: Optional[float] = None
14+
late_trading_change: Optional[float] = None
15+
late_trading_change_percent: Optional[float] = None
16+
close: Optional[float] = None
17+
high: Optional[float] = None
18+
low: Optional[float] = None
19+
open: Optional[float] = None
20+
previous_close: Optional[float] = None
21+
volume: Optional[float] = None
22+
23+
@staticmethod
24+
def from_dict(d):
25+
return Session(**d)
26+
27+
28+
@modelclass
29+
class Options:
30+
"Contains options data for the summaries endpoint"
31+
contract_type: Optional[str] = None
32+
exercise_style: Optional[str] = None
33+
expiration_date: Optional[str] = None
34+
shares_per_contract: Optional[float] = None
35+
strike_price: Optional[float] = None
36+
underlying_ticker: Optional[float] = None
37+
38+
@staticmethod
39+
def from_dict(d):
40+
return Options(**d)
41+
42+
43+
@modelclass
44+
class SummaryResult:
45+
"Contains summary result data for a list of tickers"
46+
price: Optional[float] = None
47+
name: Optional[str] = None
48+
ticker: Optional[str] = None
49+
branding: Optional[Branding] = None
50+
market_status: Optional[str] = None
51+
type: Optional[str] = None
52+
session: Optional[Session] = None
53+
options: Optional[Options] = None
54+
error: Optional[str] = None
55+
message: Optional[str] = None
56+
57+
@staticmethod
58+
def from_dict(d):
59+
return SummaryResult(
60+
price=d.get("price", None),
61+
name=d.get("name", None),
62+
ticker=d.get("ticker", None),
63+
branding=None if "branding" not in d else Branding.from_dict(d["branding"]),
64+
market_status=d.get("market_status", None),
65+
type=d.get("type", None),
66+
session=None if "session" not in d else Session.from_dict(d["session"]),
67+
options=None if "options" not in d else Options.from_dict(d["options"]),
68+
error=d.get("error", None),
69+
message=d.get("message", None),
70+
)

polygon/rest/summaries.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from polygon.rest.models.summaries import SummaryResult
2+
from .base import BaseClient
3+
from typing import Optional, Any, Dict, List, Union, Iterator
4+
from .models import Order
5+
from urllib3 import HTTPResponse
6+
from datetime import datetime, date
7+
8+
9+
class SummariesClient(BaseClient):
10+
def get_summaries(
11+
self,
12+
ticker_any_of: Optional[List[str]] = None,
13+
params: Optional[Dict[str, Any]] = None,
14+
raw: bool = False,
15+
) -> Union[List[SummaryResult], HTTPResponse]:
16+
"""
17+
GetSummaries retrieves summaries for the ticker list with the given params.
18+
For more details see https://polygon.io/docs/stocks/get_v1_summaries.
19+
20+
:param ticker_any_of: The ticker symbol
21+
:param params: Any additional query params
22+
:param raw: Return raw object instead of results object
23+
:return: SummaryResults
24+
"""
25+
26+
url = f"/v1/summaries"
27+
return self._get(
28+
path=url,
29+
params=self._get_params(self.get_summaries, locals()),
30+
result_key="results",
31+
deserializer=SummaryResult.from_dict,
32+
raw=raw,
33+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"request_id":"abc123",
3+
"results":[
4+
{
5+
"branding":{
6+
"icon_url":"https://api.polygon.io/icon.png",
7+
"logo_url":"https://api.polygon.io/logo.svg"
8+
},
9+
"market_status":"closed",
10+
"name":"Norwegian Cruise Lines",
11+
"price":22.3,
12+
"session":{
13+
"change":-1.05,
14+
"change_percent":-4.67,
15+
"close":21.4,
16+
"early_trading_change":-0.39,
17+
"early_trading_change_percent":-0.07,
18+
"high":22.49,
19+
"late_trading_change":1.2,
20+
"late_trading_change_percent":3.92,
21+
"low":21.35,
22+
"open":22.49,
23+
"previous_close":22.45,
24+
"volume":37
25+
},
26+
"ticker":"NCLH",
27+
"type":"stocks"
28+
},
29+
{
30+
"market_status":"closed",
31+
"name":"NCLH $5 Call",
32+
"options":{
33+
"contract_type":"call",
34+
"exercise_style":"american",
35+
"expiration_date":"2022-10-14",
36+
"shares_per_contract":100,
37+
"strike_price":5,
38+
"underlying_ticker":"NCLH"
39+
},
40+
"price":6.6,
41+
"session":{
42+
"change":-0.05,
43+
"change_percent":-1.07,
44+
"close":6.65,
45+
"early_trading_change":-0.01,
46+
"early_trading_change_percent":-0.03,
47+
"high":7.01,
48+
"late_trading_change":-0.4,
49+
"late_trading_change_percent":-0.02,
50+
"low":5.42,
51+
"open":6.7,
52+
"previous_close":6.71,
53+
"volume":67
54+
},
55+
"ticker":"O:NCLH221014C00005000",
56+
"type":"options"
57+
},
58+
{
59+
"market_status":"open",
60+
"name":"Euro - United States Dollar",
61+
"price":0.97989,
62+
"session":{
63+
"change":-0.0001,
64+
"change_percent":-0.67,
65+
"close":0.97989,
66+
"high":0.98999,
67+
"low":0.96689,
68+
"open":0.97889,
69+
"previous_close":0.98001
70+
},
71+
"ticker":"C:EURUSD",
72+
"type":"fx"
73+
},
74+
{
75+
"branding":{
76+
"icon_url":"https://api.polygon.io/icon.png",
77+
"logo_url":"https://api.polygon.io/logo.svg"
78+
},
79+
"market_status":"open",
80+
"name":"Bitcoin - United States Dollar",
81+
"price":32154.68,
82+
"session":{
83+
"change":-201.23,
84+
"change_percent":-0.77,
85+
"close":32154.68,
86+
"high":33124.28,
87+
"low":28182.88,
88+
"open":31129.32,
89+
"previous_close":33362.18
90+
},
91+
"ticker":"X:BTCUSD",
92+
"type":"crypto"
93+
},
94+
{
95+
"error":"NOT_FOUND",
96+
"message":"Ticker not found.",
97+
"ticker":"APx"
98+
}
99+
],
100+
"status":"OK"
101+
}

test_rest/test_summaries.py

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from polygon.rest.models import SummaryResult, Branding, Session, Options
2+
from base import BaseTest
3+
4+
5+
class SummariesTest(BaseTest):
6+
def test_get_summaries_list(self):
7+
ticker_any_of = ["NCLH", "O:NCLH221014C00005000", "C:EURUSD", "X:BTCUSD", "APx"]
8+
summary_results = self.c.get_summaries(ticker_any_of)
9+
expected = [
10+
SummaryResult(
11+
price=22.3,
12+
name="Norwegian Cruise Lines",
13+
ticker="NCLH",
14+
branding=Branding(
15+
icon_url="https://api.polygon.io/icon.png",
16+
logo_url="https://api.polygon.io/logo.svg",
17+
),
18+
market_status="closed",
19+
type="stocks",
20+
session=Session(
21+
change=-1.05,
22+
change_percent=-4.67,
23+
close=21.4,
24+
early_trading_change=-0.39,
25+
early_trading_change_percent=-0.07,
26+
high=22.49,
27+
late_trading_change=1.2,
28+
late_trading_change_percent=3.92,
29+
low=21.35,
30+
open=22.49,
31+
previous_close=22.45,
32+
volume=37,
33+
),
34+
),
35+
SummaryResult(
36+
price=6.6,
37+
name="NCLH $5 Call",
38+
ticker="O:NCLH221014C00005000",
39+
market_status="closed",
40+
type="options",
41+
session=Session(
42+
change=-0.05,
43+
change_percent=-1.07,
44+
close=6.65,
45+
early_trading_change=-0.01,
46+
early_trading_change_percent=-0.03,
47+
high=7.01,
48+
late_trading_change=-0.4,
49+
late_trading_change_percent=-0.02,
50+
low=5.42,
51+
open=6.7,
52+
previous_close=6.71,
53+
volume=67,
54+
),
55+
options=Options(
56+
contract_type="call",
57+
exercise_style="american",
58+
expiration_date="2022-10-14",
59+
shares_per_contract=100,
60+
strike_price=5,
61+
underlying_ticker="NCLH",
62+
),
63+
),
64+
SummaryResult(
65+
price=0.97989,
66+
name="Euro - United States Dollar",
67+
ticker="C:EURUSD",
68+
market_status="open",
69+
type="fx",
70+
session=Session(
71+
change=-0.0001,
72+
change_percent=-0.67,
73+
close=0.97989,
74+
high=0.98999,
75+
low=0.96689,
76+
open=0.97889,
77+
previous_close=0.98001,
78+
),
79+
),
80+
SummaryResult(
81+
price=32154.68,
82+
name="Bitcoin - United States Dollar",
83+
ticker="X:BTCUSD",
84+
branding=Branding(
85+
icon_url="https://api.polygon.io/icon.png",
86+
logo_url="https://api.polygon.io/logo.svg",
87+
),
88+
market_status="open",
89+
type="crypto",
90+
session=Session(
91+
change=-201.23,
92+
change_percent=-0.77,
93+
close=32154.68,
94+
high=33124.28,
95+
low=28182.88,
96+
open=31129.32,
97+
previous_close=33362.18,
98+
),
99+
),
100+
SummaryResult(
101+
ticker="APx",
102+
error="NOT_FOUND",
103+
message="Ticker not found.",
104+
),
105+
]
106+
self.assertEqual(summary_results, expected)

0 commit comments

Comments
 (0)