From 4ef6f13d6787b215207511f83d380d4a73ef15c8 Mon Sep 17 00:00:00 2001 From: justinpolygon <123573436+justinpolygon@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:28:41 -0700 Subject: [PATCH 1/3] Added Short Interest and IPOs support --- examples/rest/stocks-ipos.py | 13 ++++ examples/rest/stocks-short_interest.py | 21 +++++++ polygon/rest/models/tickers.py | 86 ++++++++++++++++++++++++++ polygon/rest/reference.py | 72 +++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 examples/rest/stocks-ipos.py create mode 100644 examples/rest/stocks-short_interest.py diff --git a/examples/rest/stocks-ipos.py b/examples/rest/stocks-ipos.py new file mode 100644 index 00000000..62e5bdbe --- /dev/null +++ b/examples/rest/stocks-ipos.py @@ -0,0 +1,13 @@ +from polygon import RESTClient + +# docs +# https://polygon.io/docs/stocks/get_v1_reference_ipos + +# client = RESTClient("XXXXXX") # hardcoded api_key is used +client = RESTClient() # POLYGON_API_KEY environment variable is used + +ipos = [] +for ipo in client.list_ipos(ticker="RDDT"): + ipos.append(ipo) + +print(ipos) diff --git a/examples/rest/stocks-short_interest.py b/examples/rest/stocks-short_interest.py new file mode 100644 index 00000000..ddd40fc9 --- /dev/null +++ b/examples/rest/stocks-short_interest.py @@ -0,0 +1,21 @@ +from polygon import RESTClient + +# docs +# https://polygon.io/docs/stocks/get_v1_reference_short-interest__identifierType___identifier + +# client = RESTClient("XXXXXX") # hardcoded api_key is used +client = RESTClient() # POLYGON_API_KEY environment variable is used + +short_interest = [] +for si in client.list_short_interest( + identifier="AMD", + identifier_type="ticker", + params={ + "date.gte": "2024-10-07", + "date.lte": "2024-10-07", + }, + limit=100 +): + short_interest.append(si) + +print(short_interest) diff --git a/polygon/rest/models/tickers.py b/polygon/rest/models/tickers.py index 2554927e..bec48959 100644 --- a/polygon/rest/models/tickers.py +++ b/polygon/rest/models/tickers.py @@ -253,3 +253,89 @@ class TickerChangeResults: @staticmethod def from_dict(d): return TickerChangeResults(**d) + +@modelclass +class ShortInterest: + """ + Short Interest data for a specific identifier. + """ + + currency_code: Optional[str] = None + date: Optional[str] = None + isin: Optional[str] = None + name: Optional[str] = None + security_description: Optional[str] = None + short_volume: Optional[int] = None + short_volume_exempt: Optional[int] = None + ticker: Optional[str] = None + us_code: Optional[str] = None + + @staticmethod + def from_dict(d): + return ShortInterest( + currency_code=d.get("currency_code"), + date=d.get("date"), + isin=d.get("isin"), + name=d.get("name"), + security_description=d.get("security_description"), + short_volume=d.get("short_volume"), + short_volume_exempt=d.get("short_volume_exempt"), + ticker=d.get("ticker"), + us_code=d.get("us_code"), + ) + +@modelclass +class IPOListing: + """ + IPO Listing data. + """ + + currency_code: Optional[str] = None + final_issue_price: Optional[float] = None + highest_offer_price: Optional[float] = None + ipo_status: Optional[str] = None + isin: Optional[str] = None + issue_end_date: Optional[str] = None + issue_start_date: Optional[str] = None + issuer_name: Optional[str] = None + last_updated: Optional[str] = None + listing_date: Optional[str] = None + listing_price: Optional[float] = None + lot_size: Optional[int] = None + lowest_offer_price: Optional[float] = None + max_shares_offered: Optional[int] = None + min_shares_offered: Optional[int] = None + primary_exchange: Optional[str] = None + security_description: Optional[str] = None + security_type: Optional[str] = None + shares_outstanding: Optional[int] = None + ticker: Optional[str] = None + total_offer_size: Optional[float] = None + us_code: Optional[str] = None + + @staticmethod + def from_dict(d): + return IPOListing( + currency_code=d.get("currency_code"), + final_issue_price=d.get("final_issue_price"), + highest_offer_price=d.get("highest_offer_price"), + ipo_status=d.get("ipo_status"), + isin=d.get("isin"), + issue_end_date=d.get("issue_end_date"), + issue_start_date=d.get("issue_start_date"), + issuer_name=d.get("issuer_name"), + last_updated=d.get("last_updated"), + listing_date=d.get("listing_date"), + listing_price=d.get("listing_price"), + lot_size=d.get("lot_size"), + lowest_offer_price=d.get("lowest_offer_price"), + max_shares_offered=d.get("max_shares_offered"), + min_shares_offered=d.get("min_shares_offered"), + primary_exchange=d.get("primary_exchange"), + security_description=d.get("security_description"), + security_type=d.get("security_type"), + shares_outstanding=d.get("shares_outstanding"), + ticker=d.get("ticker"), + total_offer_size=d.get("total_offer_size"), + us_code=d.get("us_code"), + ) diff --git a/polygon/rest/reference.py b/polygon/rest/reference.py index 7af5b10f..3c3e4114 100644 --- a/polygon/rest/reference.py +++ b/polygon/rest/reference.py @@ -22,6 +22,8 @@ SIP, Exchange, OptionsContract, + ShortInterest, + IPOListing, ) from urllib3 import HTTPResponse from datetime import date @@ -567,3 +569,73 @@ def list_options_contracts( deserializer=OptionsContract.from_dict, options=options, ) + + def list_short_interest( + self, + identifier: str, + identifier_type: str = "ticker", + date: Optional[str] = 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[ShortInterest], HTTPResponse]: + """ + Query for short interest data by Identifier and Date. + + :param identifier: The case-sensitive identifier (e.g., "AAPL"). + :param identifier_type: The type of identifier ("ticker", "us_code", "isin"). + :param date: Either a date with the format YYYY-MM-DD or a nanosecond timestamp. + :param params: Additional query parameters (e.g., date, order, limit, sort). + :param raw: Return raw HTTPResponse instead of parsed data. + :return: List of ShortInterest objects or HTTPResponse. + """ + url = f"/v1/reference/short-interest/{identifier_type}/{identifier}" + + return self._paginate( + path=url, + params=self._get_params(self.list_short_interest, locals()), + deserializer=ShortInterest.from_dict, + raw=raw, + result_key="results", + options=options, + ) + + def list_ipos( + self, + ticker: Optional[str] = None, + us_code: Optional[str] = None, + isin: Optional[str] = None, + listing_date: Optional[str] = None, + ipo_status: Optional[str] = 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[IPOListing], HTTPResponse]: + """ + Retrieve upcoming or historical IPOs. + + :param ticker: Specify a case-sensitive ticker symbol. For example, AAPL represents Apple Inc. + :param us_code: Specify a us_code. This is a unique nine-character alphanumeric code that identifies a North American financial security for the purposes of facilitating clearing and settlement of trades. + :param isin: Specify an International Securities Identification Number (ISIN). This is a unique twelve-digit code that is assigned to every security issuance in the world. + :param listing_date: Specify a listing date. This is the first trading date for the newly listed entity. + :param ipo_status: Specify an IPO status. + :param params: Query parameters (e.g., ticker, us_code, isin, listing_date, order, limit, sort). + :param raw: Return raw HTTPResponse instead of parsed data. + :return: List of IPOListing objects or HTTPResponse. + """ + url = "/v1/reference/ipos" + + return self._paginate( + path=url, + params=self._get_params(self.list_ipos, locals()), + deserializer=IPOListing.from_dict, + raw=raw, + result_key="results", + options=options, + ) From 7acc4ad41d541dcfa4068a7d5548104bcac0bb9b Mon Sep 17 00:00:00 2001 From: justinpolygon <123573436+justinpolygon@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:36:20 -0700 Subject: [PATCH 2/3] Fix lint --- examples/rest/stocks-short_interest.py | 4 ++-- polygon/rest/models/tickers.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/rest/stocks-short_interest.py b/examples/rest/stocks-short_interest.py index ddd40fc9..8f5b1cf4 100644 --- a/examples/rest/stocks-short_interest.py +++ b/examples/rest/stocks-short_interest.py @@ -8,13 +8,13 @@ short_interest = [] for si in client.list_short_interest( - identifier="AMD", + identifier="AMD", identifier_type="ticker", params={ "date.gte": "2024-10-07", "date.lte": "2024-10-07", }, - limit=100 + limit=100, ): short_interest.append(si) diff --git a/polygon/rest/models/tickers.py b/polygon/rest/models/tickers.py index bec48959..e1b48d40 100644 --- a/polygon/rest/models/tickers.py +++ b/polygon/rest/models/tickers.py @@ -254,6 +254,7 @@ class TickerChangeResults: def from_dict(d): return TickerChangeResults(**d) + @modelclass class ShortInterest: """ @@ -284,6 +285,7 @@ def from_dict(d): us_code=d.get("us_code"), ) + @modelclass class IPOListing: """ From d60456eb678614fca65e6b63d2697e20aebcba80 Mon Sep 17 00:00:00 2001 From: justinpolygon <123573436+justinpolygon@users.noreply.github.com> Date: Thu, 10 Oct 2024 23:10:44 -0700 Subject: [PATCH 3/3] Fix api paths to vX --- polygon/rest/reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polygon/rest/reference.py b/polygon/rest/reference.py index 3c3e4114..296d75aa 100644 --- a/polygon/rest/reference.py +++ b/polygon/rest/reference.py @@ -592,7 +592,7 @@ def list_short_interest( :param raw: Return raw HTTPResponse instead of parsed data. :return: List of ShortInterest objects or HTTPResponse. """ - url = f"/v1/reference/short-interest/{identifier_type}/{identifier}" + url = f"/vX/reference/short-interest/{identifier_type}/{identifier}" return self._paginate( path=url, @@ -629,7 +629,7 @@ def list_ipos( :param raw: Return raw HTTPResponse instead of parsed data. :return: List of IPOListing objects or HTTPResponse. """ - url = "/v1/reference/ipos" + url = "/vX/reference/ipos" return self._paginate( path=url,