Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,19 @@ Once installed run `poetry install` to install the required dependencies. This s

#### Makefile

Our Makefile has the common operations needed when developing on this repo. Running tests and linting can both be run through our Makefile. Just run `make help` to see the list of available commands.
Our Makefile has the common operations needed when developing on this repo. Running tests and linting can both be
run through our Makefile. Just run `make help` to see the list of available commands.

If you're using `pyenv` to manage active Python versions then you might need to launch a Poetry shell before running
Make commands in order to actually use your chosen Python version. This is because Poetry uses the system Python version
by default.

```shell
poetry shell # start shell
poetry install # install deps

make test # run your make commands
```

## Release planning
This client will attempt to follow the release cadence of our API.
Expand Down
30 changes: 30 additions & 0 deletions docs/source/Models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
Models
==============================================================

==============================================================
Universal Snapshot
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshot

==============================================================
Universal Snapshot Session
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshotSession

==============================================================
Universal Snapshot Last Quote
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshotLastQuote

==============================================================
Universal Snapshot Last Trade
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshotLastTrade

==============================================================
Universal Snapshot Details
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshotDetails

==============================================================
Universal Snapshot Underlying Asset
==============================================================
.. autoclass:: polygon.rest.models.UniversalSnapshotUnderlyingAsset

==============================================================
Agg
==============================================================
Expand Down
24 changes: 20 additions & 4 deletions docs/source/Snapshot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ Snapshot
=================================

=================================
Get all snapshots
Get snapshots for all asset types
=================================

- `Stocks snapshot all tickers`_
- `Options snapshot all tickers`_
- `Forex snapshot all tickers`_
- `Crypto snapshot all tickers`_

.. automethod:: polygon.RESTClient.list_universal_snapshots

=================================
Get all snapshots
=================================

- `Stocks snapshot all tickers (deprecated)`_
- `Forex snapshot all tickers (deprecated)`_
- `Crypto snapshot all tickers (deprecated)`_

.. automethod:: polygon.RESTClient.get_snapshot_all

=================================
Expand Down Expand Up @@ -49,9 +60,14 @@ Get crypto L2 book snapshot

.. automethod:: polygon.RESTClient.get_snapshot_crypto_book

.. _Stocks snapshot all tickers: https://polygon.io/docs/stocks/get_v2_snapshot_locale_us_markets_stocks_tickers
.. _Forex snapshot all tickers: https://polygon.io/docs/forex/get_v2_snapshot_locale_global_markets_forex_tickers
.. _Crypto snapshot all tickers: https://polygon.io/docs/crypto/get_v2_snapshot_locale_global_markets_crypto_tickers
.. _Stocks snapshot all tickers: https://polygon.io/docs/stocks/get_v3_snapshot
.. _Options snapshot all tickers: https://polygon.io/docs/options/get_v3_snapshot
.. _Forex snapshot all tickers: https://polygon.io/docs/forex/get_v3_snapshot
.. _Crypto snapshot all tickers:: https://polygon.io/docs/crypto/get_v3_snapshot
.. _Stocks snapshot all tickers (deprecated): https://polygon.io/docs/stocks/get_v2_snapshot_locale_us_markets_stocks_tickers
.. _Options snapshot all tickers (deprecated): https://polygon.io/docs/options/get_v2_snapshot_locale_us_markets_stocks_tickers
.. _Forex snapshot all tickers (deprecated): https://polygon.io/docs/forex/get_v2_snapshot_locale_global_markets_forex_tickers
.. _Crypto snapshot all tickers (deprecated):: https://polygon.io/docs/crypto/get_v2_snapshot_locale_global_markets_crypto_tickers
.. _Stocks snapshot gainers/losers: https://polygon.io/docs/stocks/get_v2_snapshot_locale_us_markets_stocks__direction
.. _Forex snapshot gainers/losers: https://polygon.io/docs/forex/get_v2_snapshot_locale_global_markets_forex__direction
.. _Crypto snapshot gainers/losers: https://polygon.io/docs/crypto/get_v2_snapshot_locale_global_markets_crypto__direction
Expand Down
46 changes: 46 additions & 0 deletions examples/rest/universal-snapshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from typing import cast, Iterator, Union

from urllib3 import HTTPResponse

from polygon import RESTClient
from polygon.rest.models import UniversalSnapshot, SnapshotMarketType

# docs
# https://polygon.io/docs/stocks/get_v3_snapshot
# https://polygon-api-client.readthedocs.io/en/latest/Snapshot.html

# client = RESTClient("XXXXXX") # hardcoded api_key is used
client = RESTClient() # POLYGON_API_KEY environment variable is used


def print_snapshots(iterator: Union[Iterator[UniversalSnapshot], HTTPResponse]):
snapshots = [s for s in iterator]

print(f"count: {len(snapshots)}")

for item in snapshots:
print(item)


# it = client.list_universal_snapshots() # all tickers for all assets types in lexicographical order

it = client.list_universal_snapshots(
ticker_any_of=[
"AAPL",
"O:AAPL230519C00055000",
"DOES_NOT_EXIST",
"X:1INCHUSD",
"C:AEDAUD",
]
)
print_snapshots(it)

it = client.list_universal_snapshots(
market_type=SnapshotMarketType.STOCKS, ticker_gt="A", ticker_lt="AAPL"
)
print_snapshots(it)

it = client.list_universal_snapshots(
market_type=SnapshotMarketType.STOCKS, ticker_gte="AAPL", ticker_lte="ABB"
)
print_snapshots(it)
142 changes: 142 additions & 0 deletions polygon/rest/models/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,145 @@ def from_dict(d):
spread=d.get("spread", None),
updated=d.get("updated", None),
)


@modelclass
class UniversalSnapshotSession:
"""Contains data about the most recent trading session for an asset."""

price: Optional[float] = None
change: Optional[float] = None
change_percent: Optional[float] = None
early_trading_change: Optional[float] = None
early_trading_change_percent: Optional[float] = None
late_trading_change: Optional[float] = None
late_trading_change_percent: Optional[float] = None
open: Optional[float] = None
close: Optional[float] = None
high: Optional[float] = None
low: Optional[float] = None
previous_close: Optional[float] = None
volume: Optional[float] = None

@staticmethod
def from_dict(d):
return UniversalSnapshotSession(**d)


@modelclass
class UniversalSnapshotLastQuote:
"""Contains the most recent quote for an asset."""

ask: Optional[float] = None
ask_size: Optional[float] = None
bid: Optional[float] = None
bid_size: Optional[float] = None
midpoint: Optional[float] = None
exchange: Optional[int] = None
timeframe: Optional[str] = None
last_updated: Optional[int] = None

@staticmethod
def from_dict(d):
return UniversalSnapshotLastQuote(**d)


@modelclass
class UniversalSnapshotLastTrade:
"""Contains the most recent trade for an asset."""

id: Optional[int] = None
price: Optional[float] = None
size: Optional[int] = None
exchange: Optional[int] = None
conditions: Optional[List[int]] = None
timeframe: Optional[str] = None
last_updated: Optional[int] = None
participant_timestamp: Optional[int] = None
sip_timestamp: Optional[int] = None

@staticmethod
def from_dict(d):
return UniversalSnapshotLastTrade(**d)


@modelclass
class UniversalSnapshotUnderlyingAsset:
"""Contains data for the underlying stock in an options contract."""

ticker: Optional[str] = None
price: Optional[float] = None
value: Optional[float] = None
change_to_break_even: Optional[float] = None
timeframe: Optional[str] = None
last_updated: Optional[int] = None

@staticmethod
def from_dict(d):
return UniversalSnapshotUnderlyingAsset(**d)


@modelclass
class UniversalSnapshotDetails:
"""Contains details for an options contract."""

contract_type: Optional[str] = None
exercise_style: Optional[str] = None
expiration_date: Optional[str] = None
shares_per_contract: Optional[float] = None
strike_price: Optional[float] = None

@staticmethod
def from_dict(d):
return UniversalSnapshotDetails(**d)


@modelclass
class UniversalSnapshot:
"""Contains snapshot data for an asset."""

ticker: Optional[str] = None
type: Optional[str] = None
session: Optional[UniversalSnapshotSession] = None
last_quote: Optional[UniversalSnapshotLastQuote] = None
last_trade: Optional[UniversalSnapshotLastTrade] = None
greeks: Optional[Greeks] = None
underlying_asset: Optional[UniversalSnapshotUnderlyingAsset] = None
details: Optional[UniversalSnapshotDetails] = None
break_even_price: Optional[float] = None
implied_volatility: Optional[float] = None
open_interest: Optional[float] = None
market_status: Optional[str] = None
name: Optional[str] = None
error: Optional[str] = None
message: Optional[str] = None

@staticmethod
def from_dict(d):
return UniversalSnapshot(
ticker=d.get("ticker", None),
type=d.get("type", None),
session=None
if "session" not in d
else UniversalSnapshotSession.from_dict(d["session"]),
last_quote=None
if "last_quote" not in d
else UniversalSnapshotLastQuote.from_dict(d["last_quote"]),
last_trade=None
if "last_trade" not in d
else UniversalSnapshotLastTrade.from_dict(d["last_trade"]),
greeks=None if "greeks" not in d else Greeks.from_dict(d["greeks"]),
underlying_asset=None
if "underlying_asset" not in d
else UniversalSnapshotUnderlyingAsset.from_dict(d["underlying_asset"]),
details=None
if "details" not in d
else UniversalSnapshotDetails.from_dict(d["details"]),
break_even_price=d.get("break_even_price", None),
implied_volatility=d.get("implied_volatility", None),
open_interest=d.get("open_interest", None),
market_status=d.get("market_status", None),
name=d.get("name", None),
error=d.get("error", None),
message=d.get("message", None),
)
43 changes: 43 additions & 0 deletions polygon/rest/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
OptionContractSnapshot,
SnapshotMarketType,
SnapshotTickerFullBook,
UniversalSnapshot,
IndicesSnapshot,
)
from urllib3 import HTTPResponse
Expand All @@ -21,6 +22,48 @@ def get_locale(market_type: Union[SnapshotMarketType, str]):


class SnapshotClient(BaseClient):
def list_universal_snapshots(
self,
market_type: Optional[Union[str, SnapshotMarketType]] = None,
ticker_any_of: Optional[List[str]] = None,
ticker_lt: Optional[str] = None,
ticker_lte: Optional[str] = None,
ticker_gt: Optional[str] = None,
ticker_gte: Optional[str] = None,
params: Optional[Dict[str, Any]] = None,
raw: bool = False,
options: Optional[RequestOptionBuilder] = None,
) -> Union[Iterator[UniversalSnapshot], HTTPResponse]:
"""
Get snapshots for assets of all types
- https://polygon.io/docs/stocks/get_v3_snapshot
- https://polygon.io/docs/options/get_v3_snapshot
- https://polygon.io/docs/indices/get_v3_snapshot
- https://polygon.io/docs/forex/get_v3_snapshot
- https://polygon.io/docs/crypto/get_v3_snapshot

:param market_type: the type of the asset
:param ticker_any_of: Comma-separated list of tickers, up to a maximum of 250. If no tickers are passed then all
results will be returned in a paginated manner. Warning: The maximum number of characters allowed in a URL
are subject to your technology stack.
:param ticker_lt search for tickers less than
:param ticker_lte search for tickers less than or equal to
:param ticker_gt search for tickers greater than
:param ticker_gte search for tickers greater than or equal to
:param raw: returns the raw HTTP response if true, else the response is deserialized into a structured object
:param options: request options
:return: list of Snapshots
"""
url = f"/v3/snapshot"
return self._paginate(
path=url,
params=self._get_params(self.list_universal_snapshots, locals()),
result_key="results",
deserializer=UniversalSnapshot.from_dict,
raw=raw,
options=options,
)

def get_snapshot_all(
self,
market_type: Union[str, SnapshotMarketType],
Expand Down
Loading