diff --git a/polygon/rest/aggs.py b/polygon/rest/aggs.py index 9643711a..1822471e 100644 --- a/polygon/rest/aggs.py +++ b/polygon/rest/aggs.py @@ -1,9 +1,8 @@ -from email.headerregistry import Group from .base import BaseClient from typing import Optional, Any, Dict, List, Union from .models import Agg, GroupedDailyAgg, DailyOpenCloseAgg, PreviousCloseAgg, Sort from urllib3 import HTTPResponse -from datetime import datetime +from datetime import datetime, date # https://polygon.io/docs/stocks class AggsClient(BaseClient): @@ -13,8 +12,8 @@ def get_aggs( multiplier: int, timespan: str, # "from" is a keyword in python https://www.w3schools.com/python/python_ref_keywords.asp - from_: Union[str, int, datetime], - to: Union[str, int, datetime], + from_: Union[str, int, datetime, date], + to: Union[str, int, datetime, date], adjusted: Optional[bool] = None, sort: Optional[Union[str, Sort]] = None, limit: Optional[int] = None, @@ -23,11 +22,12 @@ def get_aggs( ) -> Union[List[Agg], HTTPResponse]: """ Get aggregate bars for a ticker over a given date range in custom time window sizes. + :param ticker: The ticker symbol. :param multiplier: The size of the timespan multiplier. :param timespan: The size of the time window. - :param _from: The start of the aggregate time window as YYYY-MM-DD, Unix MS Timestamps, or a datetime. - :param to: The end of the aggregate time window as YYYY-MM-DD, Unix MS Timestamps, or a datetime. + :param _from: The start of the aggregate time window as YYYY-MM-DD, a date, Unix MS Timestamp, or a datetime. + :param to: The end of the aggregate time window as YYYY-MM-DD, a date, Unix MS Timestamp, or a datetime. :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. :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. :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. @@ -36,10 +36,10 @@ def get_aggs( :return: List of aggregates """ if isinstance(from_, datetime): - from_ = int(from_.timestamp() * 1000) + from_ = int(from_.timestamp() * self.time_mult("millis")) if isinstance(to, datetime): - to = int(to.timestamp() * 1000) + to = int(to.timestamp() * self.time_mult("millis")) url = f"/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}" return self._get( diff --git a/polygon/rest/base.py b/polygon/rest/base.py index fcad62c4..19b5efd2 100644 --- a/polygon/rest/base.py +++ b/polygon/rest/base.py @@ -3,12 +3,13 @@ import urllib3 import inspect from enum import Enum -from typing import Optional, Any +from typing import Optional, Any, Dict +from datetime import datetime base = "https://api.polygon.io" env_key = "POLYGON_API_KEY" -# https://urllib3.readthedocs.io/en/stable/reference/urllib3.poolmanager.html + class BaseClient: def __init__( self, @@ -18,6 +19,7 @@ def __init__( num_pools: int = 10, retries=3, base: str = base, + verbose: bool = False, ): if api_key is None: raise Exception( @@ -26,12 +28,14 @@ def __init__( self.API_KEY = api_key self.BASE = base + # https://urllib3.readthedocs.io/en/stable/reference/urllib3.poolmanager.html # https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html#urllib3.HTTPConnectionPool self.client = urllib3.PoolManager( num_pools=num_pools, headers={"Authorization": "Bearer " + self.API_KEY} ) self.timeout = urllib3.Timeout(connect=connect_timeout, read=read_timeout) self.retries = retries + self.verbose = verbose def _decode(self, resp): return json.loads(resp.data.decode("utf-8")) @@ -47,6 +51,8 @@ def _get( if params is None: params = {} params = {str(k): str(v) for k, v in params.items() if v is not None} + if self.verbose: + print("_get", path, params) resp = self.client.request( "GET", self.BASE + path, fields=params, retries=self.retries ) @@ -70,7 +76,20 @@ def _get( return obj - def _get_params(self, fn, caller_locals): + @staticmethod + def time_mult(timestamp_res: str) -> int: + if timestamp_res == "nanos": + return 1000000000 + elif timestamp_res == "micros": + return 1000000 + elif timestamp_res == "millis": + return 1000 + + return 1 + + def _get_params( + self, fn, caller_locals: Dict[str, Any], datetime_res: str = "nanos" + ): params = caller_locals["params"] if params is None: params = {} @@ -84,6 +103,8 @@ def _get_params(self, fn, caller_locals): val = caller_locals.get(argname, v.default) if isinstance(val, Enum): val = val.value + elif isinstance(val, datetime): + val = int(val.timestamp() * self.time_mult(datetime_res)) if val is not None: params[argname.replace("_", ".")] = val diff --git a/polygon/rest/quotes.py b/polygon/rest/quotes.py index 198e3adf..e602e61f 100644 --- a/polygon/rest/quotes.py +++ b/polygon/rest/quotes.py @@ -2,17 +2,18 @@ from typing import Optional, Any, Dict, List, Union from .models import Quote, LastQuote, Sort, Order from urllib3 import HTTPResponse +from datetime import datetime, date # https://polygon.io/docs/stocks class QuotesClient(BaseClient): def list_quotes( self, ticker: str, - timestamp: Optional[str] = None, - timestamp_lt: Optional[str] = None, - timestamp_lte: Optional[str] = None, - timestamp_gt: Optional[str] = None, - timestamp_gte: Optional[str] = None, + timestamp: Optional[Union[str, int, datetime, date]] = None, + timestamp_lt: Optional[Union[str, int, datetime, date]] = None, + timestamp_lte: Optional[Union[str, int, datetime, date]] = None, + timestamp_gt: Optional[Union[str, int, datetime, date]] = None, + timestamp_gte: Optional[Union[str, int, datetime, date]] = None, limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, diff --git a/polygon/rest/reference.py b/polygon/rest/reference.py index 67bf2647..592632a2 100644 --- a/polygon/rest/reference.py +++ b/polygon/rest/reference.py @@ -21,6 +21,7 @@ Exchange, ) from urllib3 import HTTPResponse +from datetime import date # https://polygon.io/docs/stocks class MarketsClient(BaseClient): @@ -200,11 +201,11 @@ def list_splits( ticker_lte: Optional[str] = None, ticker_gt: Optional[str] = None, ticker_gte: Optional[str] = None, - execution_date: Optional[str] = None, - execution_date_lt: Optional[str] = None, - execution_date_lte: Optional[str] = None, - execution_date_gt: Optional[str] = None, - execution_date_gte: Optional[str] = None, + execution_date: Optional[Union[str, date]] = None, + execution_date_lt: Optional[Union[str, date]] = None, + execution_date_lte: Optional[Union[str, date]] = None, + execution_date_gt: Optional[Union[str, date]] = None, + execution_date_gte: Optional[Union[str, date]] = None, reverse_split: Optional[bool] = None, limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, @@ -251,26 +252,26 @@ def list_dividends( ticker_lte: Optional[str] = None, ticker_gt: Optional[str] = None, ticker_gte: Optional[str] = None, - ex_dividend_date: Optional[str] = None, - ex_dividend_date_lt: Optional[str] = None, - ex_dividend_date_lte: Optional[str] = None, - ex_dividend_date_gt: Optional[str] = None, - ex_dividend_date_gte: Optional[str] = None, - record_date: Optional[str] = None, - record_date_lt: Optional[str] = None, - record_date_lte: Optional[str] = None, - record_date_gt: Optional[str] = None, - record_date_gte: Optional[str] = None, - declaration_date: Optional[str] = None, - declaration_date_lt: Optional[str] = None, - declaration_date_lte: Optional[str] = None, - declaration_date_gt: Optional[str] = None, - declaration_date_gte: Optional[str] = None, - pay_date: Optional[str] = None, - pay_date_lt: Optional[str] = None, - pay_date_lte: Optional[str] = None, - pay_date_gt: Optional[str] = None, - pay_date_gte: Optional[str] = None, + ex_dividend_date: Optional[Union[str, date]] = None, + ex_dividend_date_lt: Optional[Union[str, date]] = None, + ex_dividend_date_lte: Optional[Union[str, date]] = None, + ex_dividend_date_gt: Optional[Union[str, date]] = None, + ex_dividend_date_gte: Optional[Union[str, date]] = None, + record_date: Optional[Union[str, date]] = None, + record_date_lt: Optional[Union[str, date]] = None, + record_date_lte: Optional[Union[str, date]] = None, + record_date_gt: Optional[Union[str, date]] = None, + record_date_gte: Optional[Union[str, date]] = None, + declaration_date: Optional[Union[str, date]] = None, + declaration_date_lt: Optional[Union[str, date]] = None, + declaration_date_lte: Optional[Union[str, date]] = None, + declaration_date_gt: Optional[Union[str, date]] = None, + declaration_date_gte: Optional[Union[str, date]] = None, + pay_date: Optional[Union[str, date]] = None, + pay_date_lt: Optional[Union[str, date]] = None, + pay_date_lte: Optional[Union[str, date]] = None, + pay_date_gt: Optional[Union[str, date]] = None, + pay_date_gte: Optional[Union[str, date]] = None, frequency: Optional[Union[int, Frequency]] = None, cash_amount: Optional[float] = None, cash_amount_lt: Optional[float] = None, diff --git a/polygon/rest/trades.py b/polygon/rest/trades.py index 85cac40a..c652493b 100644 --- a/polygon/rest/trades.py +++ b/polygon/rest/trades.py @@ -2,17 +2,18 @@ from typing import Optional, Any, Dict, Union, Iterator from .models import Trade, Sort, Order from urllib3 import HTTPResponse +from datetime import datetime, date + -# https://polygon.io/docs/stocks class TradesClient(BaseClient): def list_trades( self, ticker: str, - timestamp: Optional[str] = None, - timestamp_lt: Optional[str] = None, - timestamp_lte: Optional[str] = None, - timestamp_gt: Optional[str] = None, - timestamp_gte: Optional[str] = None, + timestamp: Optional[Union[str, int, datetime, date]] = None, + timestamp_lt: Optional[Union[str, int, datetime, date]] = None, + timestamp_lte: Optional[Union[str, int, datetime, date]] = None, + timestamp_gt: Optional[Union[str, int, datetime, date]] = None, + timestamp_gte: Optional[Union[str, int, datetime, date]] = None, limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, diff --git a/rest-example.py b/rest-example.py index e60ebd54..b16f12e7 100644 --- a/rest-example.py +++ b/rest-example.py @@ -1,9 +1,12 @@ from polygon import RESTClient from polygon.rest.models import Sort +from datetime import date, datetime -client = RESTClient() +client = RESTClient(verbose=True) -aggs = client.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04") +aggs = client.get_aggs("AAPL", 1, "day", "2005-04-04", "2005-04-04") +print(aggs) +aggs = client.get_aggs("AAPL", 1, "day", date(2005, 4, 4), datetime(2005, 4, 4)) print(aggs) trades = []