Skip to content

Commit 41c1242

Browse files
allow datetime or int for aggs, lint tests
1 parent 6c05495 commit 41c1242

File tree

9 files changed

+63
-166
lines changed

9 files changed

+63
-166
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ help:
2222

2323
## Check code style
2424
style:
25-
poetry run black polygon
25+
poetry run black polygon tests
2626

2727
## Check static types
2828
static:
29-
poetry run mypy polygon
29+
poetry run mypy polygon tests
3030

3131
## Check code style and static types
3232
lint: style static

polygon/rest/aggs.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Optional, Any, Dict, List, Union
33
from .models import Agg, Sort
44
from urllib3 import HTTPResponse
5+
from datetime import datetime
56

67
# https://polygon.io/docs/stocks
78
class AggsClient(BaseClient):
@@ -11,8 +12,8 @@ def get_aggs(
1112
multiplier: int,
1213
timespan: str,
1314
# "from" is a keyword in python https://www.w3schools.com/python/python_ref_keywords.asp
14-
from_: str,
15-
to: str,
15+
from_: Union[str, int, datetime],
16+
to: Union[str, int, datetime],
1617
adjusted: Optional[bool] = None,
1718
sort: Optional[Union[str, Sort]] = None,
1819
limit: Optional[int] = None,
@@ -25,8 +26,8 @@ def get_aggs(
2526
:param ticker: The ticker symbol.
2627
:param multiplier: The size of the timespan multiplier.
2728
:param timespan: The size of the time window.
28-
:param _from: The start of the aggregate time window.
29-
:param to: The end of the aggregate time window.
29+
:param _from: The start of the aggregate time window as YYYY-MM-DD, Unix MS Timestamps, or a datetime.
30+
:param to: The end of the aggregate time window as YYYY-MM-DD, Unix MS Timestamps, or a datetime.
3031
:param adjusted: Whether or not the results are adjusted for splits. By default, results are adjusted. Set this to false to get results that are NOT adjusted for splits.
3132
:param sort: Sort the results by timestamp. asc will return results in ascending order (oldest at the top), desc will return results in descending order (newest at the top).The end of the aggregate time window.
3233
:param limit: Limits the number of base aggregates queried to create the aggregate results. Max 50000 and Default 5000. Read more about how limit is used to calculate aggregate results in our article on Aggregate Data API Improvements.
@@ -35,6 +36,11 @@ def get_aggs(
3536
:return: List of aggregates
3637
:rtype: List[Agg]
3738
"""
39+
if isinstance(from_, datetime):
40+
from_ = int(from_.timestamp() * 1000)
41+
42+
if isinstance(to, datetime):
43+
to = int(to.timestamp() * 1000)
3844
url = f"/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}"
3945

4046
return self._get(

polygon/rest/models/aggs.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass
22
from typing import Optional
33

4+
45
@dataclass
56
class Agg:
67
timestamp: int
@@ -15,12 +16,12 @@ class Agg:
1516
@staticmethod
1617
def from_dict(d):
1718
return Agg(
18-
timestamp=d["t"],
19-
open=d["o"],
20-
high=d["h"],
21-
low=d["l"],
22-
close=d["c"],
23-
volume=d["v"],
24-
vwap=d.get("vw", None),
25-
transactions=d.get("n", None)
19+
timestamp=d["t"],
20+
open=d["o"],
21+
high=d["h"],
22+
low=d["l"],
23+
close=d["c"],
24+
volume=d["v"],
25+
vwap=d.get("vw", None),
26+
transactions=d.get("n", None),
2627
)

polygon/rest/models/markets.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class MarketHoliday:
1616
def from_dict(d):
1717
return MarketHoliday(**d)
1818

19+
1920
@dataclass
2021
class MarketStatus:
2122
"MarketStatus contains data for the current trading status of the exchanges and overall financial markets."

polygon/rest/models/quotes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Quote:
2323
def from_dict(d):
2424
return Quote(**d)
2525

26+
2627
@dataclass
2728
class LastQuote:
2829
"LastQuote contains data for the most recent NBBO (Quote) tick for a given stock."
@@ -57,5 +58,5 @@ def from_dict(d):
5758
bid_price=d.get("p", None),
5859
bid_size=d.get("s", None),
5960
bid_exchange=d.get("x", None),
60-
tape=d.get("z", None)
61-
)
61+
tape=d.get("z", None),
62+
)

polygon/rest/quotes.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def list_quotes(
1717
sort: Optional[Union[str, Sort]] = None,
1818
order: Optional[Union[str, Order]] = None,
1919
params: Optional[Dict[str, Any]] = None,
20-
raw: bool = False
20+
raw: bool = False,
2121
) -> Union[List[Quote], HTTPResponse]:
2222
"""
2323
Get quotes for a ticker symbol in a given time range.
@@ -44,12 +44,9 @@ def list_quotes(
4444
raw=raw,
4545
deserializer=Quote.from_dict,
4646
)
47-
47+
4848
def get_last_quote(
49-
self,
50-
ticker: str,
51-
params: Optional[Dict[str, Any]] = None,
52-
raw: bool = False
49+
self, ticker: str, params: Optional[Dict[str, Any]] = None, raw: bool = False
5350
) -> Union[LastQuote, HTTPResponse]:
5451
"""
5552
Get the most recent NBBO (Quote) tick for a given stock.
@@ -62,6 +59,6 @@ def get_last_quote(
6259
"""
6360
url = f"/v2/last/nbbo/{ticker}"
6461

65-
return self._get(path=url, params=params, deserializer=LastQuote.from_dict, raw=raw)
66-
67-
62+
return self._get(
63+
path=url, params=params, deserializer=LastQuote.from_dict, raw=raw
64+
)

polygon/rest/reference.py

Lines changed: 5 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
# https://polygon.io/docs/stocks
77
class MarketsClient(BaseClient):
88
def list_market_holidays(
9-
self,
10-
params: Optional[Dict[str, Any]] = None,
11-
raw: bool = False
9+
self, params: Optional[Dict[str, Any]] = None, raw: bool = False
1210
) -> Union[List[MarketHoliday], HTTPResponse]:
1311
"""
1412
Get upcoming market holidays and their open/close times.
@@ -20,12 +18,12 @@ def list_market_holidays(
2018
"""
2119
url = "/v1/marketstatus/upcoming"
2220

23-
return self._get(path=url, params=params, deserializer=MarketHoliday.from_dict, raw=raw)
21+
return self._get(
22+
path=url, params=params, deserializer=MarketHoliday.from_dict, raw=raw
23+
)
2424

2525
def get_market_status(
26-
self,
27-
params: Optional[Dict[str, Any]] = None,
28-
raw: bool = False
26+
self, params: Optional[Dict[str, Any]] = None, raw: bool = False
2927
) -> Union[MarketStatus, HTTPResponse]:
3028
"""
3129
Get the current trading status of the exchanges and overall financial markets.
@@ -38,132 +36,3 @@ def get_market_status(
3836
url = "/v1/marketstatus/now"
3937

4038
return self._get(path=url, params=params, deserializer=MarketStatus.from_dict, raw=raw)
41-
42-
class TickersClient(BaseClient):
43-
def list_tickers(
44-
self,
45-
ticker: Optional[str] = None,
46-
ticker_lt: Optional[str] = None,
47-
ticker_lte: Optional[str] = None,
48-
ticker_gt: Optional[str] = None,
49-
ticker_gte: Optional[str] = None,
50-
type: Optional[str] = None,
51-
market: Optional[str] = None,
52-
exchange: Optional[str] = None,
53-
cusip: Optional[int] = None,
54-
cik: Optional[int] = None,
55-
date: Optional[str] = None,
56-
active: Optional[bool] = None,
57-
search: Optional[str] = None,
58-
limit: Optional[int] = None,
59-
sort: Optional[Union[str, Sort]] = None,
60-
order: Optional[Union[str, Order]] = None,
61-
params: Optional[Dict[str, Any]] = None,
62-
raw: bool = False,
63-
) -> Union[Iterator[Ticker], HTTPResponse]:
64-
"""
65-
Query all ticker symbols which are supported by Polygon.io. This API currently includes Stocks/Equities, Crypto, and Forex.
66-
67-
:param ticker: Specify a ticker symbol. Defaults to empty string which queries all tickers.
68-
:param ticker_lt: Timestamp less than
69-
:param ticker_lte: Ticker less than or equal to
70-
:param ticker_gt: Ticker greater than
71-
:param ticker_gte: Ticker greater than or equal to
72-
:param type: Specify the type of the tickers. Find the types that we support via our Ticker Types API. Defaults to empty string which queries all types.
73-
:param market: Filter by market type. By default all markets are included.
74-
:param exchange: Specify the primary exchange of the asset in the ISO code format. Find more information about the ISO codes at the ISO org website. Defaults to empty string which queries all exchanges.
75-
:param cusip: Specify the CUSIP code of the asset you want to search for. Find more information about CUSIP codes at their website. Defaults to empty string which queries all CUSIPs.
76-
:param cik: Specify the CIK of the asset you want to search for. Find more information about CIK codes at their website. Defaults to empty string which queries all CIKs.
77-
:param date: Specify a point in time to retrieve tickers available on that date. Defaults to the most recent available date.
78-
:param search: Search for terms within the ticker and/or company name.
79-
:param active: Specify if the tickers returned should be actively traded on the queried date. Default is true.
80-
:param limit: Limit the size of the response, default is 100 and max is 1000.
81-
:param sort: The field to sort the results on. Default is ticker. If the search query parameter is present, sort is ignored and results are ordered by relevance.
82-
:param order: The order to sort the results on. Default is asc (ascending).
83-
:param params: Any additional query params
84-
:param raw: Return raw object instead of results object
85-
:return: List of tickers
86-
:rtype: List[Ticker]
87-
"""
88-
url = "/v3/reference/tickers"
89-
90-
return self._paginate(
91-
path=url,
92-
params=self._get_params(self.list_tickers, locals()),
93-
raw=raw,
94-
deserializer=Ticker.from_dict,
95-
)
96-
97-
def get_ticker_details(
98-
self,
99-
ticker: Optional[str] = None,
100-
date: Optional[str] = None,
101-
params: Optional[Dict[str, Any]] = None,
102-
raw: bool = False,
103-
) -> Union[TickerDetails, HTTPResponse]:
104-
"""
105-
Get a single ticker supported by Polygon.io. This response will have detailed information about the ticker and the company behind it.
106-
107-
:param ticker: The ticker symbol of the asset.
108-
:param date: Specify a point in time to get information about the ticker available on that date. When retrieving information from SEC filings, we compare this date with the period of report date on the SEC filing.
109-
:param params: Any additional query params
110-
:param raw: Return raw object instead of results object
111-
:return: Ticker Details V3
112-
:rtype: TickerDetail
113-
"""
114-
url = f"/v3/reference/tickers/{ticker}"
115-
116-
return self._get(path=url, params=params, deserializer=TickerDetails.from_dict, raw=raw)
117-
118-
def get_ticker_news(
119-
self,
120-
ticker: Optional[str] = None,
121-
ticker_lt: Optional[str] = None,
122-
ticker_lte: Optional[str] = None,
123-
ticker_gt: Optional[str] = None,
124-
ticker_gte: Optional[str] = None,
125-
published_utc: Optional[str] = None,
126-
published_utc_lt: Optional[str] = None,
127-
published_utc_lte: Optional[str] = None,
128-
published_utc_gt: Optional[str] = None,
129-
published_utc_gte: Optional[str] = None,
130-
params: Optional[Dict[str, Any]] = None,
131-
raw: bool = False,
132-
) -> Union[TickerDetails, HTTPResponse]:
133-
"""
134-
Get the most recent news articles relating to a stock ticker symbol, including a summary of the article and a link to the original source.
135-
136-
:param ticker: Return results that contain this ticker.
137-
:param published_utc: Return results published on, before, or after this date.
138-
:param limit: Limit the number of results returned, default is 10 and max is 1000.
139-
:param sort: Sort field used for ordering.
140-
:param order: Order results based on the sort field.
141-
:param params: Any additional query params
142-
:param raw: Return raw object instead of results object
143-
:return: Ticker News
144-
:rtype: TickerNews
145-
"""
146-
url = "/v2/reference/news"
147-
148-
return self._get(path=url, params=params, deserializer=TickerNews.from_dict, raw=raw)
149-
150-
def get_ticker_types(
151-
self,
152-
asset_class: Optional[AssetClass] = None,
153-
locale: Optional[Locale] = None,
154-
params: Optional[Dict[str, Any]] = None,
155-
raw: bool = False,
156-
) -> Union[TickerTypes, HTTPResponse]:
157-
"""
158-
List all ticker types that Polygon.io has.
159-
160-
:param asset_class: Filter by asset class.
161-
:param locale: Filter by locale.
162-
:param params: Any additional query params
163-
:param raw: Return raw object instead of results object
164-
:return: Ticker Types
165-
:rtype: TickerTypes
166-
"""
167-
url = "/v3/reference/tickers/types"
168-
169-
return self._get(path=url, params=params, deserializer=TickerTypes.from_dict, raw=raw)

tests/mocks.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
from polygon import RESTClient
22
import unittest
3-
import httpretty
3+
import httpretty # type: ignore
44

55
mocks = [
66
(
77
"/v2/aggs/ticker/AAPL/range/1/day/2005-04-01/2005-04-04",
8-
'{"ticker":"AAPL","queryCount":2,"resultsCount":2,"adjusted":true,"results":[{"v":6.42646396e+08,"vw":1.469,"o":1.5032,"c":1.4604,"h":1.5064,"l":1.4489,"t":1112331600000,"n":82132},{"v":5.78172308e+08,"vw":1.4589,"o":1.4639,"c":1.4675,"h":1.4754,"l":1.4343,"t":1112587200000,"n":65543}],"status":"OK","request_id":"12afda77aab3b1936c5fb6ef4241ae42","count":2}'
8+
'{"ticker":"AAPL","queryCount":2,"resultsCount":2,"adjusted":true,"results":[{"v":6.42646396e+08,"vw":1.469,"o":1.5032,"c":1.4604,"h":1.5064,"l":1.4489,"t":1112331600000,"n":82132},{"v":5.78172308e+08,"vw":1.4589,"o":1.4639,"c":1.4675,"h":1.4754,"l":1.4343,"t":1112587200000,"n":65543}],"status":"OK","request_id":"12afda77aab3b1936c5fb6ef4241ae42","count":2}',
99
)
1010
]
1111

12+
1213
class BaseTest(unittest.TestCase):
1314
setup = False
15+
1416
def setUp(self):
1517
if self.setup:
1618
return
@@ -19,4 +21,3 @@ def setUp(self):
1921
for m in mocks:
2022
httpretty.register_uri(httpretty.GET, c.BASE + m[0], m[1])
2123
self.setup = True
22-

tests/test_aggs.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,31 @@
22
from polygon.rest.models import Agg
33
from mocks import BaseTest
44

5+
56
class AggsTest(BaseTest):
67
def test_get_aggs(self):
78
c = RESTClient("")
89
aggs = c.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04")
9-
expected = [Agg(open=1.5032, high=1.5064, low=1.4489, close=1.4604, volume=642646396.0, vwap=1.469, timestamp=1112331600000, transactions=82132), Agg(open=1.4639, high=1.4754, low=1.4343, close=1.4675, volume=578172308.0, vwap=1.4589, timestamp=1112587200000, transactions=65543)]
10+
expected = [
11+
Agg(
12+
open=1.5032,
13+
high=1.5064,
14+
low=1.4489,
15+
close=1.4604,
16+
volume=642646396.0,
17+
vwap=1.469,
18+
timestamp=1112331600000,
19+
transactions=82132,
20+
),
21+
Agg(
22+
open=1.4639,
23+
high=1.4754,
24+
low=1.4343,
25+
close=1.4675,
26+
volume=578172308.0,
27+
vwap=1.4589,
28+
timestamp=1112587200000,
29+
transactions=65543,
30+
),
31+
]
1032
self.assertEqual(aggs, expected)
11-

0 commit comments

Comments
 (0)