From 2d60c3d97cbf301d481f8d3b5e026f03e761d058 Mon Sep 17 00:00:00 2001 From: antdjohns <114414459+antdjohns@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:23:41 -0800 Subject: [PATCH 1/4] add options chain endpoint --- polygon/rest/snapshot.py | 24 +++++++++ test_rest/mocks/v3/snapshot/options/AAPL.json | 51 +++++++++++++++++++ test_rest/test_snapshots.py | 51 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 test_rest/mocks/v3/snapshot/options/AAPL.json diff --git a/polygon/rest/snapshot.py b/polygon/rest/snapshot.py index b3806e08..24a3dbaf 100644 --- a/polygon/rest/snapshot.py +++ b/polygon/rest/snapshot.py @@ -137,6 +137,30 @@ def get_snapshot_option( options=options, ) + def get_snapshot_options_chain( + self, + underlying_asset: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[OptionContractSnapshot, HTTPResponse]: + """ + Get the snapshot of an option contract for a stock equity. + + :param underlying_asset: The underlying ticker symbol of the option contract. + :param option_contract: The option contract identifier. + :return: List of Snapshots + """ + url = f"/v3/snapshot/options/{underlying_asset}" + return self._get( + path=url, + params=self._get_params(self.get_snapshot_options_chain, locals()), + result_key="results", + deserializer=OptionContractSnapshot.from_dict, + raw=raw, + options=options, + ) + def get_snapshot_crypto_book( self, ticker: str, diff --git a/test_rest/mocks/v3/snapshot/options/AAPL.json b/test_rest/mocks/v3/snapshot/options/AAPL.json new file mode 100644 index 00000000..f64fbcbd --- /dev/null +++ b/test_rest/mocks/v3/snapshot/options/AAPL.json @@ -0,0 +1,51 @@ +{ + "request_id": "104d9b901d0c9e81d284cb8b41c5cdd3", + "results": { + "break_even_price": 179.075, + "day": { + "change": -2.3999999999999986, + "change_percent": -7.643312101910824, + "close": 29, + "high": 32.25, + "last_updated": 1651204800000000000, + "low": 29, + "open": 29.99, + "previous_close": 31.4, + "volume": 8, + "vwap": 30.7738 + }, + "details": { + "contract_type": "call", + "exercise_style": "american", + "expiration_date": "2023-06-16", + "shares_per_contract": 100, + "strike_price": 150, + "ticker": "O:AAPL230616C00150000" + }, + "greeks": { + "delta": 0.6436614934293701, + "gamma": 0.0061735291012820675, + "theta": -0.028227189324641973, + "vega": 0.6381159723175714 + }, + "implied_volatility": 0.3570277203465058, + "last_quote": { + "ask": 29.25, + "ask_size": 209, + "bid": 28.9, + "bid_size": 294, + "last_updated": 1651254260800059648, + "midpoint": 29.075, + "timeframe": "REAL-TIME" + }, + "open_interest": 8133, + "underlying_asset": { + "change_to_break_even": 19.11439999999999, + "last_updated": 1651254263172073152, + "price": 159.9606, + "ticker": "AAPL", + "timeframe": "REAL-TIME" + } + }, + "status": "OK" +} \ No newline at end of file diff --git a/test_rest/test_snapshots.py b/test_rest/test_snapshots.py index 498fb966..00ff7e5b 100644 --- a/test_rest/test_snapshots.py +++ b/test_rest/test_snapshots.py @@ -210,6 +210,57 @@ def test_get_snapshot_option(self): ) self.assertEqual(snapshots, expected) + def test_get_snapshot_options_chain(self): + snapshots = self.c.get_snapshot_options_chain("AAPL") + expected = OptionContractSnapshot( + break_even_price=179.075, + day=DayOptionContractSnapshot( + change=-2.3999999999999986, + change_percent=-7.643312101910824, + close=29, + high=32.25, + last_updated=1651204800000000000, + low=29, + open=29.99, + previous_close=31.4, + volume=8, + vwap=30.7738, + ), + details=OptionDetails( + contract_type="call", + exercise_style="american", + expiration_date="2023-06-16", + shares_per_contract=100, + strike_price=150, + ticker="O:AAPL230616C00150000", + ), + greeks=Greeks( + delta=0.6436614934293701, + gamma=0.0061735291012820675, + theta=-0.028227189324641973, + vega=0.6381159723175714, + ), + implied_volatility=0.3570277203465058, + last_quote=LastQuoteOptionContractSnapshot( + ask=29.25, + ask_size=209, + bid=28.9, + bid_size=294, + last_updated=1651254260800059648, + midpoint=29.075, + timeframe="REAL-TIME", + ), + open_interest=8133, + underlying_asset=UnderlyingAsset( + change_to_break_even=19.11439999999999, + last_updated=1651254263172073152, + price=159.9606, + ticker="AAPL", + timeframe="REAL-TIME", + ), + ) + self.assertEqual(snapshots, expected) + def test_get_snapshot_crypto_book(self): snapshots = self.c.get_snapshot_crypto_book("X:BTCUSD") expected = SnapshotTickerFullBook( From 16f3b6bbdbc7563d1eb548ace3159da8660bebab Mon Sep 17 00:00:00 2001 From: antdjohns <114414459+antdjohns@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:36:41 -0800 Subject: [PATCH 2/4] fixed response --- polygon/rest/snapshot.py | 2 +- test_rest/mocks/v3/snapshot/options/AAPL.json | 7 +- test_rest/test_snapshots.py | 96 ++++++++++--------- 3 files changed, 54 insertions(+), 51 deletions(-) diff --git a/polygon/rest/snapshot.py b/polygon/rest/snapshot.py index 24a3dbaf..be710f10 100644 --- a/polygon/rest/snapshot.py +++ b/polygon/rest/snapshot.py @@ -143,7 +143,7 @@ def get_snapshot_options_chain( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[OptionContractSnapshot, HTTPResponse]: + ) -> Union[List[OptionContractSnapshot], HTTPResponse]: """ Get the snapshot of an option contract for a stock equity. diff --git a/test_rest/mocks/v3/snapshot/options/AAPL.json b/test_rest/mocks/v3/snapshot/options/AAPL.json index f64fbcbd..677b39ea 100644 --- a/test_rest/mocks/v3/snapshot/options/AAPL.json +++ b/test_rest/mocks/v3/snapshot/options/AAPL.json @@ -1,6 +1,7 @@ -{ + + { "request_id": "104d9b901d0c9e81d284cb8b41c5cdd3", - "results": { + "results": [{ "break_even_price": 179.075, "day": { "change": -2.3999999999999986, @@ -46,6 +47,6 @@ "ticker": "AAPL", "timeframe": "REAL-TIME" } - }, + }], "status": "OK" } \ No newline at end of file diff --git a/test_rest/test_snapshots.py b/test_rest/test_snapshots.py index 00ff7e5b..edbadb8b 100644 --- a/test_rest/test_snapshots.py +++ b/test_rest/test_snapshots.py @@ -212,53 +212,55 @@ def test_get_snapshot_option(self): def test_get_snapshot_options_chain(self): snapshots = self.c.get_snapshot_options_chain("AAPL") - expected = OptionContractSnapshot( - break_even_price=179.075, - day=DayOptionContractSnapshot( - change=-2.3999999999999986, - change_percent=-7.643312101910824, - close=29, - high=32.25, - last_updated=1651204800000000000, - low=29, - open=29.99, - previous_close=31.4, - volume=8, - vwap=30.7738, - ), - details=OptionDetails( - contract_type="call", - exercise_style="american", - expiration_date="2023-06-16", - shares_per_contract=100, - strike_price=150, - ticker="O:AAPL230616C00150000", - ), - greeks=Greeks( - delta=0.6436614934293701, - gamma=0.0061735291012820675, - theta=-0.028227189324641973, - vega=0.6381159723175714, - ), - implied_volatility=0.3570277203465058, - last_quote=LastQuoteOptionContractSnapshot( - ask=29.25, - ask_size=209, - bid=28.9, - bid_size=294, - last_updated=1651254260800059648, - midpoint=29.075, - timeframe="REAL-TIME", - ), - open_interest=8133, - underlying_asset=UnderlyingAsset( - change_to_break_even=19.11439999999999, - last_updated=1651254263172073152, - price=159.9606, - ticker="AAPL", - timeframe="REAL-TIME", - ), - ) + expected = [ + OptionContractSnapshot( + break_even_price=179.075, + day=DayOptionContractSnapshot( + change=-2.3999999999999986, + change_percent=-7.643312101910824, + close=29, + high=32.25, + last_updated=1651204800000000000, + low=29, + open=29.99, + previous_close=31.4, + volume=8, + vwap=30.7738, + ), + details=OptionDetails( + contract_type="call", + exercise_style="american", + expiration_date="2023-06-16", + shares_per_contract=100, + strike_price=150, + ticker="O:AAPL230616C00150000", + ), + greeks=Greeks( + delta=0.6436614934293701, + gamma=0.0061735291012820675, + theta=-0.028227189324641973, + vega=0.6381159723175714, + ), + implied_volatility=0.3570277203465058, + last_quote=LastQuoteOptionContractSnapshot( + ask=29.25, + ask_size=209, + bid=28.9, + bid_size=294, + last_updated=1651254260800059648, + midpoint=29.075, + timeframe="REAL-TIME", + ), + open_interest=8133, + underlying_asset=UnderlyingAsset( + change_to_break_even=19.11439999999999, + last_updated=1651254263172073152, + price=159.9606, + ticker="AAPL", + timeframe="REAL-TIME", + ), + ) + ] self.assertEqual(snapshots, expected) def test_get_snapshot_crypto_book(self): From f42d3baf5aeff3253e89e76e8aa3c3066e1f9b84 Mon Sep 17 00:00:00 2001 From: antdjohns <114414459+antdjohns@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:03:23 -0800 Subject: [PATCH 3/4] changed to pagination --- polygon/rest/snapshot.py | 6 +++--- test_rest/test_snapshots.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/polygon/rest/snapshot.py b/polygon/rest/snapshot.py index be710f10..3522a4c3 100644 --- a/polygon/rest/snapshot.py +++ b/polygon/rest/snapshot.py @@ -137,7 +137,7 @@ def get_snapshot_option( options=options, ) - def get_snapshot_options_chain( + def list_snapshot_options_chain( self, underlying_asset: str, params: Optional[Dict[str, Any]] = None, @@ -152,9 +152,9 @@ def get_snapshot_options_chain( :return: List of Snapshots """ url = f"/v3/snapshot/options/{underlying_asset}" - return self._get( + return self._paginate( path=url, - params=self._get_params(self.get_snapshot_options_chain, locals()), + params=self._get_params(self.list_snapshot_options_chain, locals()), result_key="results", deserializer=OptionContractSnapshot.from_dict, raw=raw, diff --git a/test_rest/test_snapshots.py b/test_rest/test_snapshots.py index edbadb8b..8051d398 100644 --- a/test_rest/test_snapshots.py +++ b/test_rest/test_snapshots.py @@ -210,8 +210,8 @@ def test_get_snapshot_option(self): ) self.assertEqual(snapshots, expected) - def test_get_snapshot_options_chain(self): - snapshots = self.c.get_snapshot_options_chain("AAPL") + def test_list_snapshot_options_chain(self): + snapshots = [s for s in self.c.list_snapshot_options_chain("AAPL")] expected = [ OptionContractSnapshot( break_even_price=179.075, From 5a015ceb32f97e2d8f93d03a0da07edca1d6ceca Mon Sep 17 00:00:00 2001 From: antdjohns <114414459+antdjohns@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:08:24 -0800 Subject: [PATCH 4/4] doc changes --- polygon/rest/snapshot.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/polygon/rest/snapshot.py b/polygon/rest/snapshot.py index 3522a4c3..54376a39 100644 --- a/polygon/rest/snapshot.py +++ b/polygon/rest/snapshot.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, List, Union +from typing import Optional, Any, Dict, List, Union, Iterator from .models import ( TickerSnapshot, Direction, @@ -143,12 +143,11 @@ def list_snapshot_options_chain( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[List[OptionContractSnapshot], HTTPResponse]: + ) -> Union[Iterator[OptionContractSnapshot], HTTPResponse]: """ - Get the snapshot of an option contract for a stock equity. + Get the snapshot of all options contracts for an underlying ticker. :param underlying_asset: The underlying ticker symbol of the option contract. - :param option_contract: The option contract identifier. :return: List of Snapshots """ url = f"/v3/snapshot/options/{underlying_asset}"