diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 178de444..00000000 --- a/.drone.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -kind: pipeline -type: docker -name: release - -platform: - os: linux - arch: amd64 - -steps: - - name: build - image: python:3.7.5-alpine - commands: - - python setup.py sdist bdist_wheel - environment: - VERSION: ${DRONE_TAG##v} - - - name: release - image: python:3.7.5 - commands: - - pip install --user --upgrade twine - - ./upload - environment: - PASSWORD: - from_secret: pypi_token - USERNAME: __token__ - -trigger: - event: - - tag - ref: - - refs/tags/v* - ---- -kind: signature -hmac: c5572884fdd2183d7c63100530974a649f4607ee18c813570741d7a63f31cfae - -... diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..c9fc2fc4 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,33 @@ +name: lint +on: + push: + tags: + - v* + branches: + - v1 + pull_request: +permissions: + contents: read +jobs: + lint: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.7', '3.8', '3.9', '3.10'] + name: Lint ${{ matrix.python-version }} + steps: + - uses: actions/checkout@v3 + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Setup Poetry + uses: abatilo/actions-poetry@v2.0.0 + - name: Install pypi deps + run: poetry install + - name: Style lint + run: make style + - name: Static lint + run: make static + if: always() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..a1afc865 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: unittest +on: + push: + tags: + - v* + branches: + - v1 + pull_request: +permissions: + contents: read +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.7', '3.8', '3.9', '3.10'] + name: Lint ${{ matrix.python-version }} + steps: + - uses: actions/checkout@v3 + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Setup Poetry + uses: abatilo/actions-poetry@v2.0.0 + - name: Install pypi deps + run: poetry install + - name: Unit tests + run: make test diff --git a/.gitignore b/.gitignore index a655050c..300a17c1 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,7 @@ venv/ *.log # Sphinx documentation -docs/_build/ +docs/build/ # PyBuilder target/ diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..7e83cd34 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,11 @@ +# https://docs.readthedocs.io/en/latest/config-file/index.html#configuration-file +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +python: + install: + - requirements: docs/requirements.txt + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..af69d83e --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +.DEFAULT_GOAL := help +TARGET_MAX_CHAR_NUM := 20 + +GREEN := $(shell tput -Txterm setaf 2) +YELLOW := $(shell tput -Txterm setaf 3) +WHITE := $(shell tput -Txterm setaf 7) +RESET := $(shell tput -Txterm sgr0) + +.PHONY: help lint style static test + +## Show help +help: + @awk '/^[a-zA-Z\-_0-9]+:/ { \ + helpMessage = match(lastLine, /^## (.*)/); \ + if (helpMessage) { \ + helpCommand = substr($$1, 0, index($$1, ":")-1); \ + helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ + printf " ${YELLOW}%-$(TARGET_MAX_CHAR_NUM)s${RESET} ${GREEN}%s${RESET}\n", helpCommand, helpMessage; \ + } \ + } \ + { lastLine = $$0 }' $(MAKEFILE_LIST) + +## Check code style +style: + poetry run black $(if $(CI),--check,) polygon tests + +## Check static types +static: + poetry run mypy polygon tests + +## Check code style and static types +lint: style static + +## Run unit tests +test: + poetry run python -m unittest discover -s tests + diff --git a/README.md b/README.md index 6a1636e1..6fbf6ded 100644 --- a/README.md +++ b/README.md @@ -1,115 +1,43 @@ -[![Build Status](https://drone.polygon.io/api/badges/polygon-io/client-python/status.svg)](https://drone.polygon.io/polygon-io/client-python) [![PyPI version](https://badge.fury.io/py/polygon-api-client.svg)](https://badge.fury.io/py/polygon-api-client) +[![Docs](https://readthedocs.org/projects/polygon-api-client/badge/?version=latest)](https://polygon-api-client.readthedocs.io/en/latest/) # Polygon Python Client - WebSocket & RESTful APIs -Python client for the Polygon.io [Stocks API](https://polygon.io) - -## Getting Started - -For a basic product overview, check out our [setup and use documentation](https://polygon.io/sockets) +Python client for the [Polygon.io API](https://polygon.io). +## Getting started ### Install `pip install polygon-api-client` -`polygon-api-client` supports python version >= 3.6 +Requires python version >= 3.7 -## Simple WebSocket Demo +### Getting aggs ```python -import time - -from polygon import WebSocketClient, STOCKS_CLUSTER - - -def my_custom_process_message(message): - print("this is my custom message processing", message) - - -def my_custom_error_handler(ws, error): - print("this is my custom error handler", error) - - -def my_custom_close_handler(ws): - print("this is my custom close handler") - - -def main(): - key = 'your api key' - my_client = WebSocketClient(STOCKS_CLUSTER, key, my_custom_process_message) - my_client.run_async() - - my_client.subscribe("T.MSFT", "T.AAPL", "T.AMD", "T.NVDA") - time.sleep(1) - - my_client.close_connection() - +from polygon import RESTClient -if __name__ == "__main__": - main() +client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key. +aggs = client.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04") ``` -## Simple REST Demo +### Getting trades ```python from polygon import RESTClient +from polygon.rest.models import Sort +client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key. -def main(): - key = "your api key" - - # RESTClient can be used as a context manager to facilitate closing the underlying http session - # https://requests.readthedocs.io/en/master/user/advanced/#session-objects - with RESTClient(key) as client: - resp = client.stocks_equities_daily_open_close("AAPL", "2021-06-11") - print(f"On: {resp.from_} Apple opened at {resp.open} and closed at {resp.close}") - - -if __name__ == '__main__': - main() - +trades = [] +for t in client.list_trades("AAA", timestamp="2022-04-20", limit=5, sort=Sort.ASC): + trades.append(t) ``` -### Query parameters for REST calls - -Every function call under our RESTClient has the `query_params` kwargs. These kwargs are passed along and mapped 1:1 -as query parameters to the underling HTTP call. For more information on the different query parameters please reference -our [API Docs](https://polygon.io/docs/). - -#### Example with query parameters +### Getting raw response +To handle the raw [urllib3 response](https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html?highlight=response#response) yourself, pass `raw=True`: ```python -import datetime - from polygon import RESTClient - -def ts_to_datetime(ts) -> str: - return datetime.datetime.fromtimestamp(ts / 1000.0).strftime('%Y-%m-%d %H:%M') - - -def main(): - key = "your api key" - - # RESTClient can be used as a context manager to facilitate closing the underlying http session - # https://requests.readthedocs.io/en/master/user/advanced/#session-objects - with RESTClient(key) as client: - from_ = "2021-01-01" - to = "2021-02-01" - resp = client.stocks_equities_aggregates("AAPL", 1, "minute", from_, to, unadjusted=False) - - print(f"Minute aggregates for {resp.ticker} between {from_} and {to}.") - - for result in resp.results: - dt = ts_to_datetime(result["t"]) - print(f"{dt}\n\tO: {result['o']}\n\tH: {result['h']}\n\tL: {result['l']}\n\tC: {result['c']} ") - - -if __name__ == '__main__': - main() -``` - -## Notes about the REST Client - -We use swagger as our API spec and we used this swagger to generate most of the code that defines the REST client. -We made this decision due to the size of our API, many endpoints and object definitions, and to accommodate future changes. - +client = RESTClient() # Uses POLYGON_API_KEY env var. Can optionally supply your key. +response = client.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04", raw=True) +``` diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..bed4efb2 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..5977ad6f --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +sphinx-autodoc-typehints~=1.18.1 diff --git a/docs/source/Aggs.rst b/docs/source/Aggs.rst new file mode 100644 index 00000000..6db60e68 --- /dev/null +++ b/docs/source/Aggs.rst @@ -0,0 +1,25 @@ +.. _aggs_header: + +Aggs +========== + +=========== +Get aggs +=========== +.. automethod:: polygon.RESTClient.get_aggs + +============================ +Get grouped daily aggs +============================ +.. automethod:: polygon.RESTClient.get_grouped_daily_aggs + +============================ +Get daily open close agg +============================ +.. automethod:: polygon.RESTClient.get_daily_open_close_agg + +============================ +Get previous close agg +============================ +.. automethod:: polygon.RESTClient.get_previous_close_agg + diff --git a/docs/source/Getting-Started.rst b/docs/source/Getting-Started.rst new file mode 100644 index 00000000..e7ad27c0 --- /dev/null +++ b/docs/source/Getting-Started.rst @@ -0,0 +1,176 @@ +Getting Started +=============== + +Requirements: + - `Polygon.io API key `_ + - `Python >= 3.7 `_ + - `This package `_ + +.. code-block:: shell + + pip install polygon-api-client + +HTTP client usage +----------------- + +.. automethod:: polygon.RESTClient.__init__ + +You can pass your API key via the environment variable :code:`POLYGON_API_KEY` or as the first parameter to the :code:`RESTClient` constructor: + +.. code-block:: python + + from polygon import RESTClient + + client = RESTClient() # POLYGON_API_KEY is used + client = RESTClient("api_key") # api_key is used + +For non-paginated endpoints call :code:`get_*`: + +.. code-block:: python + + aggs = client.get_aggs("AAPL", 1, "day", "2022-04-01", "2022-04-04") + print(aggs) + +For paginated endpoints call :code:`list_*` and use the provided iterator: + +.. code-block:: python + + trades = [] + for t in client.list_trades("AAA", timestamp="2022-04-20", limit=5, sort=Sort.ASC) + trades.append(t) + print(trades) + +For endpoints that have a set of parameters you can use the provided enums: + +.. code-block:: python + + from polygon.rest.models import Sort + + client.list_trades(..., sort=Sort.ASC) + +To handle the raw `urllib3 response `_ yourself pass :code:`raw=True`: + +.. code-block:: python + + aggs = client.get_aggs("AAPL", 1, "day", "2022-04-01", "2022-04-04", raw=True) + print(aggs.geturl()) + # https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2022-04-01/2022-04-04 + print(aggs.status) + # 200 + print(aggs.data) + # b'{ + # "ticker": "AAPL", + # "queryCount": 2, + # "resultsCount": 2, + # "adjusted": true, + # "results": [ + # { + # "v": 78251328, + # "vw": 173.4143, + # "o": 174.03, + # "c": 174.31, + # "h": 174.88, + # "l": 171.94, + # "t": 1648785600000, + # "n": 661160 + # }, + # { + # "v": 76545983, + # "vw": 177.4855, + # "o": 174.57, + # "c": 178.44, + # "h": 178.49, + # "l": 174.44, + # "t": 1649044800000, + # "n": 630374 + # } + # ], + # "status": "OK", + # "request_id": "d8882a9d5194978819777f49c44b09c6", + # "count": 2 + # }' + +If it is a paginated :code:`list_*` response it's up to you to handle the "next_url" iteration: + +.. code-block:: python + + trades = client.list_trades("AAA", timestamp="2022-04-20", limit=5) + print(aggs.data) + # b'{ + # "results": [ + # { + # "conditions": [ + # 15 + # ], + # "exchange": 11, + # "id": "52983575627601", + # "participant_timestamp": 1650499200029279200, + # "price": 24.875, + # "sequence_number": 1591291, + # "sip_timestamp": 1650499200029316600, + # "size": 100, + # "tape": 1 + # }, + # { + # "conditions": [ + # 38, + # 41 + # ], + # "exchange": 11, + # "id": "52983575627600", + # "participant_timestamp": 1650499200029279200, + # "price": 24.875, + # "sequence_number": 1591290, + # "sip_timestamp": 1650499200029316600, + # "tape": 1 + # }, + # { + # "conditions": [ + # 15 + # ], + # "exchange": 11, + # "id": "52983575622470", + # "participant_timestamp": 1650493800003024000, + # "price": 24.875, + # "sequence_number": 1571279, + # "sip_timestamp": 1650493800003645400, + # "size": 100, + # "tape": 1 + # }, + # { + # "conditions": [ + # 38, + # 41 + # ], + # "exchange": 11, + # "id": "52983575622469", + # "participant_timestamp": 1650493800003024000, + # "price": 24.875, + # "sequence_number": 1571276, + # "sip_timestamp": 1650493800003635500, + # "tape": 1 + # }, + # { + # "conditions": [ + # 15 + # ], + # "exchange": 11, + # "id": "52983575556178", + # "participant_timestamp": 1650485400002987800, + # "price": 24.875, + # "sequence_number": 1536223, + # "sip_timestamp": 1650485400003870000, + # "size": 100, + # "tape": 1 + # } + # ], + # "status": "OK", + # "request_id": "618bb99e7a632ed9f55454a541404b44", + # "next_url": "https://api.polygon.io/v3/trades/AAA?cursor=YXA9NSZhcz0mbGltaXQ9NSZvcmRlcj1kZXNjJnNvcnQ9dGltZXN0YW1wJnRpbWVzdGFtcC5ndGU9MjAyMi0wNC0yMFQwNCUzQTAwJTNBMDBaJnRpbWVzdGFtcC5sdGU9MjAyMi0wNC0yMFQyMCUzQTEwJTNBMDAuMDAzODY5OTUyWg" + # }' + + +Websocket client usage +---------------------- + +Coming soon. diff --git a/docs/source/Quotes.rst b/docs/source/Quotes.rst new file mode 100644 index 00000000..f5b7b824 --- /dev/null +++ b/docs/source/Quotes.rst @@ -0,0 +1,14 @@ +.. _quotes_header: + +Quotes +========== + +=========== +List quotes +=========== +.. automethod:: polygon.RESTClient.list_quotes + +============== +Get last quote +============== +.. automethod:: polygon.RESTClient.get_last_quote diff --git a/docs/source/Reference.rst b/docs/source/Reference.rst new file mode 100644 index 00000000..a74caf64 --- /dev/null +++ b/docs/source/Reference.rst @@ -0,0 +1,54 @@ +.. _reference_header: + +Reference +=============== + +==================== +Get market holidays +==================== +.. automethod:: polygon.RESTClient.get_market_holidays + +==================== +Get market status +==================== +.. automethod:: polygon.RESTClient.get_market_status + +==================== +List tickers +==================== +.. automethod:: polygon.RESTClient.list_tickers + +==================== +Get ticker details +==================== +.. automethod:: polygon.RESTClient.get_ticker_details + +==================== +List ticker news +==================== +.. automethod:: polygon.RESTClient.list_ticker_news + +==================== +Get ticker types +==================== +.. automethod:: polygon.RESTClient.get_ticker_types + +==================== +List splits +==================== +.. automethod:: polygon.RESTClient.list_splits + +==================== +List dividends +==================== +.. automethod:: polygon.RESTClient.list_dividends + +==================== +List conditions +==================== +.. automethod:: polygon.RESTClient.list_conditions + +==================== +Get exchanges +==================== +.. automethod:: polygon.RESTClient.get_exchanges diff --git a/docs/source/Snapshot.rst b/docs/source/Snapshot.rst new file mode 100644 index 00000000..274341e1 --- /dev/null +++ b/docs/source/Snapshot.rst @@ -0,0 +1,29 @@ +.. _snapshot_header: + +Snapshot +================================= + +================================= +Get all snapshots +================================= +.. automethod:: polygon.RESTClient.get_snapshot_all + +================================= +Get gainers/losers snapshot +================================= +.. automethod:: polygon.RESTClient.get_snapshot_direction + +================================= +Get ticker snapshot +================================= +.. automethod:: polygon.RESTClient.get_snapshot_ticker + +================================= +Get options snapshot +================================= +.. automethod:: polygon.RESTClient.get_snapshot_option + +================================= +Get crypto L2 book snapshot +================================= +.. automethod:: polygon.RESTClient.get_snapshot_crypto_book \ No newline at end of file diff --git a/docs/source/Trades.rst b/docs/source/Trades.rst new file mode 100644 index 00000000..fc3d9d96 --- /dev/null +++ b/docs/source/Trades.rst @@ -0,0 +1,19 @@ +.. _trades_header: + +Trades +============= + +=========== +List trades +=========== +.. automethod:: polygon.RESTClient.list_trades + +=========== +Get last trade +=========== +.. automethod:: polygon.RESTClient.get_last_trade + +=========== +Get last trade (crypto) +=========== +.. automethod:: polygon.RESTClient.get_last_trade_crypto diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..235ee004 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,59 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../..')) +print('docs path', sys.path[0]) +os.environ['POLYGON_API_KEY'] = 'POLYGON_API_KEY' + +# -- Project information ----------------------------------------------------- + +project = 'polygon-api-client' +copyright = '2022, Polygon.io' +author = 'Polygon.io' + +# The full version, including alpha/beta/rc tags +release = '0.3.0' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx_autodoc_typehints', + 'sphinx_rtd_theme', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..fbcb3e3d --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,22 @@ +Welcome to polygon-api-client's documentation! +============================================== + +This documentation is for the Python client only. For details about the responses see `the official docs `_. + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + Getting-Started + Aggs + Snapshot + Quotes + Reference + Trades + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..6c2f429a --- /dev/null +++ b/poetry.lock @@ -0,0 +1,716 @@ +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "babel" +version = "2.10.1" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytz = ">=2015.7" + +[[package]] +name = "black" +version = "22.3.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "certifi" +version = "2021.10.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.1.2" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "docutils" +version = "0.17.1" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "httpretty" +version = "1.1.4" +description = "HTTP client mock for Python" +category = "dev" +optional = false +python-versions = ">=3" + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "imagesize" +version = "1.3.0" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "importlib-metadata" +version = "4.11.3" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] + +[[package]] +name = "jinja2" +version = "3.1.1" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "markupsafe" +version = "2.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "mypy" +version = "0.942" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = ">=1.1.0" +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "platformdirs" +version = "2.5.2" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] + +[[package]] +name = "pygments" +version = "2.12.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pyparsing" +version = "3.0.8" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "dev" +optional = false +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["railroad-diagrams", "jinja2"] + +[[package]] +name = "pytz" +version = "2022.1" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "requests" +version = "2.27.1" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "sphinx" +version = "4.5.0" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.18" +imagesize = "*" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"] +test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] + +[[package]] +name = "sphinx-autodoc-typehints" +version = "1.18.1" +description = "Type hints (PEP 484) support for the Sphinx autodoc extension" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +Sphinx = ">=4.5" + +[package.extras] +testing = ["covdefaults (>=2.2)", "coverage (>=6.3)", "diff-cover (>=6.4)", "nptyping (>=2)", "pytest (>=7.1)", "pytest-cov (>=3)", "sphobjinv (>=2)", "typing-extensions (>=4.1)"] +type_comments = ["typed-ast (>=1.5.2)"] + +[[package]] +name = "sphinx-rtd-theme" +version = "1.0.0" +description = "Read the Docs theme for Sphinx" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[package.dependencies] +docutils = "<0.18" +sphinx = ">=1.6" + +[package.extras] +dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "typed-ast" +version = "1.5.3" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "types-urllib3" +version = "1.26.13" +description = "Typing stubs for urllib3" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typing-extensions" +version = "4.2.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "urllib3" +version = "1.26.9" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "zipp" +version = "3.8.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.7" +content-hash = "8ea6c39c95fde83519380774c4bff55aacb6249c9a0b61437fadd4946cb2aaef" + +[metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] +babel = [ + {file = "Babel-2.10.1-py3-none-any.whl", hash = "sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2"}, + {file = "Babel-2.10.1.tar.gz", hash = "sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"}, +] +black = [ + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, +] +certifi = [ + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +] +click = [ + {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, + {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +docutils = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, +] +httpretty = [ + {file = "httpretty-1.1.4.tar.gz", hash = "sha256:20de0e5dd5a18292d36d928cc3d6e52f8b2ac73daec40d41eb62dee154933b68"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] +imagesize = [ + {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"}, + {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, +] +importlib-metadata = [ + {file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"}, + {file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"}, +] +jinja2 = [ + {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, + {file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, +] +markupsafe = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] +mypy = [ + {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, + {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, + {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, + {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, + {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, + {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, + {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, + {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, + {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, + {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, + {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, + {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, + {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, + {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, + {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, + {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, + {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, + {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +platformdirs = [ + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, +] +pygments = [ + {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, + {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, +] +pyparsing = [ + {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, + {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, +] +pytz = [ + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, +] +requests = [ + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, +] +snowballstemmer = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] +sphinx = [ + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, +] +sphinx-autodoc-typehints = [ + {file = "sphinx_autodoc_typehints-1.18.1-py3-none-any.whl", hash = "sha256:f8f5bb7c13a9a71537dc2be2eb3b9e28a9711e2454df63587005eacf6fbac453"}, + {file = "sphinx_autodoc_typehints-1.18.1.tar.gz", hash = "sha256:07631c5f0c6641e5ba27143494aefc657e029bed3982138d659250e617f6f929"}, +] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, + {file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +typed-ast = [ + {file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"}, + {file = "typed_ast-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:542cd732351ba8235f20faa0fc7398946fe1a57f2cdb289e5497e1e7f48cfedb"}, + {file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc2c11ae59003d4a26dda637222d9ae924387f96acae9492df663843aefad55"}, + {file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd5df1313915dbd70eaaa88c19030b441742e8b05e6103c631c83b75e0435ccc"}, + {file = "typed_ast-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:e34f9b9e61333ecb0f7d79c21c28aa5cd63bec15cb7e1310d7d3da6ce886bc9b"}, + {file = "typed_ast-1.5.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f818c5b81966d4728fec14caa338e30a70dfc3da577984d38f97816c4b3071ec"}, + {file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3042bfc9ca118712c9809201f55355479cfcdc17449f9f8db5e744e9625c6805"}, + {file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fff9fdcce59dc61ec1b317bdb319f8f4e6b69ebbe61193ae0a60c5f9333dc49"}, + {file = "typed_ast-1.5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8e0b8528838ffd426fea8d18bde4c73bcb4167218998cc8b9ee0a0f2bfe678a6"}, + {file = "typed_ast-1.5.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ef1d96ad05a291f5c36895d86d1375c0ee70595b90f6bb5f5fdbee749b146db"}, + {file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed44e81517364cb5ba367e4f68fca01fba42a7a4690d40c07886586ac267d9b9"}, + {file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f60d9de0d087454c91b3999a296d0c4558c1666771e3460621875021bf899af9"}, + {file = "typed_ast-1.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9e237e74fd321a55c90eee9bc5d44be976979ad38a29bbd734148295c1ce7617"}, + {file = "typed_ast-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ee852185964744987609b40aee1d2eb81502ae63ee8eef614558f96a56c1902d"}, + {file = "typed_ast-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:27e46cdd01d6c3a0dd8f728b6a938a6751f7bd324817501c15fb056307f918c6"}, + {file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d64dabc6336ddc10373922a146fa2256043b3b43e61f28961caec2a5207c56d5"}, + {file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8cdf91b0c466a6c43f36c1964772918a2c04cfa83df8001ff32a89e357f8eb06"}, + {file = "typed_ast-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:9cc9e1457e1feb06b075c8ef8aeb046a28ec351b1958b42c7c31c989c841403a"}, + {file = "typed_ast-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e20d196815eeffb3d76b75223e8ffed124e65ee62097e4e73afb5fec6b993e7a"}, + {file = "typed_ast-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:37e5349d1d5de2f4763d534ccb26809d1c24b180a477659a12c4bde9dd677d74"}, + {file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f1a27592fac87daa4e3f16538713d705599b0a27dfe25518b80b6b017f0a6d"}, + {file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8831479695eadc8b5ffed06fdfb3e424adc37962a75925668deeb503f446c0a3"}, + {file = "typed_ast-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:20d5118e494478ef2d3a2702d964dae830aedd7b4d3b626d003eea526be18718"}, + {file = "typed_ast-1.5.3.tar.gz", hash = "sha256:27f25232e2dd0edfe1f019d6bfaaf11e86e657d9bdb7b0956db95f560cceb2b3"}, +] +types-urllib3 = [ + {file = "types-urllib3-1.26.13.tar.gz", hash = "sha256:40f8fb5e8cd7d57e8aefdee3fdd5e930aa1a1bb4179cdadd55226cea588af790"}, + {file = "types_urllib3-1.26.13-py3-none-any.whl", hash = "sha256:ff7500641824f881b2c7bde4cc57e6c3abf03d1e005bae83aca752e77213a5da"}, +] +typing-extensions = [ + {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, + {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, +] +urllib3 = [ + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, +] +zipp = [ + {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, + {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"}, +] diff --git a/polygon/__init__.py b/polygon/__init__.py index 9eb4d89a..f87495cd 100644 --- a/polygon/__init__.py +++ b/polygon/__init__.py @@ -1,2 +1 @@ -from .websocket import WebSocketClient, STOCKS_CLUSTER, FOREX_CLUSTER, CRYPTO_CLUSTER from .rest import RESTClient diff --git a/polygon/rest/__init__.py b/polygon/rest/__init__.py index fb5d2b40..4be8a032 100644 --- a/polygon/rest/__init__.py +++ b/polygon/rest/__init__.py @@ -1 +1,27 @@ -from .client import RESTClient +from .aggs import AggsClient +from .trades import TradesClient +from .quotes import QuotesClient +from .snapshot import SnapshotClient +from .reference import ( + MarketsClient, + TickersClient, + SplitsClient, + DividendsClient, + ConditionsClient, + ExchangesClient, +) + + +class RESTClient( + AggsClient, + TradesClient, + QuotesClient, + SnapshotClient, + MarketsClient, + TickersClient, + SplitsClient, + DividendsClient, + ConditionsClient, + ExchangesClient, +): + pass diff --git a/polygon/rest/aggs.py b/polygon/rest/aggs.py new file mode 100644 index 00000000..da77d97e --- /dev/null +++ b/polygon/rest/aggs.py @@ -0,0 +1,130 @@ +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, date + + +class AggsClient(BaseClient): + def get_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + # "from" is a keyword in python https://www.w3schools.com/python/python_ref_keywords.asp + 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, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> 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, 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. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of aggregates + """ + if isinstance(from_, datetime): + from_ = int(from_.timestamp() * self.time_mult("millis")) + + if isinstance(to, datetime): + to = int(to.timestamp() * self.time_mult("millis")) + url = f"/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}" + + return self._get( + path=url, + params=self._get_params(self.get_aggs, locals()), + result_key="results", + deserializer=Agg.from_dict, + raw=raw, + ) + + def get_grouped_daily_aggs( + self, + date: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[GroupedDailyAgg], HTTPResponse]: + """ + Get the daily open, high, low, and close (OHLC) for the entire market. + + :param date: The beginning date for the aggregate window. + :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 params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of grouped daily aggregates + """ + url = f"/v2/aggs/grouped/locale/us/market/stocks/{date}" + + return self._get( + path=url, + params=self._get_params(self.get_grouped_daily_aggs, locals()), + result_key="results", + deserializer=GroupedDailyAgg.from_dict, + raw=raw, + ) + + def get_daily_open_close_agg( + self, + ticker: str, + date: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[DailyOpenCloseAgg, HTTPResponse]: + """ + Get the open, close and afterhours prices of a stock symbol on a certain date. + + :param ticker: The exchange symbol that this item is traded under. + :param date: The beginning date for the aggregate window. + :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 params: Any additional query params + :param raw: Return raw object instead of results object + :return: Daily open close aggregate + """ + url = f"/v1/open-close/{ticker}/{date}" + + return self._get( + path=url, + params=self._get_params(self.get_daily_open_close_agg, locals()), + deserializer=DailyOpenCloseAgg.from_dict, + raw=raw, + ) + + def get_previous_close_agg( + self, + ticker: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[PreviousCloseAgg, HTTPResponse]: + """ + Get the previous day's open, high, low, and close (OHLC) for the specified stock ticker. + + :param ticker: The ticker symbol of the stock/equity. + :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 params: Any additional query params + :param raw: Return raw object instead of results object + :return: Previous close aggregate + """ + url = f"/v2/aggs/ticker/{ticker}/prev" + + return self._get( + path=url, + params=self._get_params(self.get_previous_close_agg, locals()), + result_key="results", + deserializer=PreviousCloseAgg.from_dict, + raw=raw, + ) diff --git a/polygon/rest/base.py b/polygon/rest/base.py new file mode 100644 index 00000000..f719a8e9 --- /dev/null +++ b/polygon/rest/base.py @@ -0,0 +1,163 @@ +import os +import json +import urllib3 +import inspect +from enum import Enum +from typing import Optional, Any, Dict +from datetime import datetime + +base = "https://api.polygon.io" +env_key = "POLYGON_API_KEY" + + +class BaseClient: + def __init__( + self, + api_key: Optional[str] = os.getenv(env_key), + connect_timeout: float = 10.0, + read_timeout: float = 10.0, + num_pools: int = 10, + retries=3, + base: str = base, + verbose: bool = False, + ): + if api_key is None: + raise Exception( + f"Must specify env var {env_key} or pass api_key in constructor" + ) + 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, + "User-Agent": "Python client", + }, + ) + 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")) + + def _get( + self, + path: str, + params: Optional[dict] = None, + result_key: Optional[str] = None, + deserializer=None, + raw: bool = False, + ) -> Any: + 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 + ) + + if resp.status != 200: + raise Exception(resp.data.decode("utf-8")) + + if raw: + return resp + + obj = self._decode(resp) + + if result_key: + obj = obj[result_key] + + # If obj is not yet a list, need to turn it into a list + # This is for the Daily Open/Close and Last Trade endpoints + if type(obj) != list: + obj = [obj] + + if deserializer: + obj = [deserializer(o) for o in obj] + + return obj + + @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 = {} + # https://docs.python.org/3.7/library/inspect.html#inspect.Signature + for argname, v in inspect.signature(fn).parameters.items(): + # https://docs.python.org/3.7/library/inspect.html#inspect.Parameter + if argname in ["params", "raw"]: + continue + if v.default != v.empty: + # timestamp_lt -> timestamp.lt + 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 + + return params + + def _paginate_iter( + self, + path: str, + params: dict, + raw: bool, + deserializer, + result_key: str = "results", + ): + while True: + resp = self._get( + path=path, + params=params, + deserializer=deserializer, + result_key=result_key, + raw=True, + ) + decoded = self._decode(resp) + for t in decoded[result_key]: + yield deserializer(t) + if "next_url" in decoded: + path = decoded["next_url"].replace(self.BASE, "") + params = {} + else: + return + + def _paginate( + self, + path: str, + params: dict, + raw: bool, + deserializer, + result_key: str = "results", + ): + if raw: + return self._get( + path=path, params=params, deserializer=deserializer, raw=True + ) + + return self._paginate_iter( + path=path, + params=params, + deserializer=deserializer, + result_key=result_key, + raw=True, + ) diff --git a/polygon/rest/client.py b/polygon/rest/client.py deleted file mode 100644 index 3b05fd75..00000000 --- a/polygon/rest/client.py +++ /dev/null @@ -1,253 +0,0 @@ -from typing import Dict, Type - -import requests - -from polygon.rest import models -from polygon.rest.models import unmarshal - - -class RESTClient: - """ This is a custom generated class """ - DEFAULT_HOST = "api.polygon.io" - - def __init__(self, auth_key: str, timeout: int=None): - self.auth_key = auth_key - self.url = "https://" + self.DEFAULT_HOST - - self._session = requests.Session() - self._session.params["apiKey"] = self.auth_key - self.timeout = timeout - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def close(self): - self._session.close() - - def _handle_response(self, response_type: str, endpoint: str, params: Dict[str, str]) -> Type[models.AnyDefinition]: - resp: requests.Response = self._session.get(endpoint, params=params, timeout=self.timeout) - if resp.status_code == 200: - return unmarshal.unmarshal_json(response_type, resp.json()) - else: - resp.raise_for_status() - - def reference_tickers(self, **query_params) -> models.ReferenceTickersApiResponse: - endpoint = f"{self.url}/v2/reference/tickers" - return self._handle_response("ReferenceTickersApiResponse", endpoint, query_params) - - def reference_tickers_v3(self, next_url=None, **query_params) -> models.ReferenceTickersV3ApiResponse: - endpoint = f"{self.url}/v3/reference/tickers" if not next_url else next_url - return self._handle_response("ReferenceTickersV3ApiResponse", endpoint, query_params) - - def reference_ticker_types(self, **query_params) -> models.ReferenceTickerTypesApiResponse: - endpoint = f"{self.url}/v2/reference/types" - return self._handle_response("ReferenceTickerTypesApiResponse", endpoint, query_params) - - def reference_ticker_details(self, symbol, **query_params) -> models.ReferenceTickerDetailsApiResponse: - endpoint = f"{self.url}/v1/meta/symbols/{symbol}/company" - return self._handle_response("ReferenceTickerDetailsApiResponse", endpoint, query_params) - - def reference_ticker_details_vx(self, symbol, **query_params) -> models.ReferenceTickerDetailsV3ApiResponse: - endpoint = f"{self.url}/vX/reference/tickers/{symbol}" - return self._handle_response("ReferenceTickerDetailsV3ApiResponse", endpoint, query_params) - - def reference_ticker_news(self, symbol, **query_params) -> models.ReferenceTickerNewsApiResponse: - endpoint = f"{self.url}/v1/meta/symbols/{symbol}/news" - return self._handle_response("ReferenceTickerNewsApiResponse", endpoint, query_params) - - def reference_ticker_news_v2(self, **query_params) -> models.ReferenceTickerNewsV2ApiResponse: - endpoint = f"{self.url}/v2/reference/news" - return self._handle_response("ReferenceTickerNewsV2ApiResponse", endpoint, query_params) - - def reference_markets(self, **query_params) -> models.ReferenceMarketsApiResponse: - endpoint = f"{self.url}/v2/reference/markets" - return self._handle_response("ReferenceMarketsApiResponse", endpoint, query_params) - - def reference_locales(self, **query_params) -> models.ReferenceLocalesApiResponse: - endpoint = f"{self.url}/v2/reference/locales" - return self._handle_response("ReferenceLocalesApiResponse", endpoint, query_params) - - def reference_stock_splits(self, symbol, **query_params) -> models.ReferenceStockSplitsApiResponse: - endpoint = f"{self.url}/v2/reference/splits/{symbol}" - return self._handle_response("ReferenceStockSplitsApiResponse", endpoint, query_params) - - def reference_stock_dividends(self, symbol, **query_params) -> models.ReferenceStockDividendsApiResponse: - endpoint = f"{self.url}/v2/reference/dividends/{symbol}" - return self._handle_response("ReferenceStockDividendsApiResponse", endpoint, query_params) - - def reference_stock_financials(self, symbol, **query_params) -> models.ReferenceStockFinancialsApiResponse: - endpoint = f"{self.url}/v2/reference/financials/{symbol}" - return self._handle_response("ReferenceStockFinancialsApiResponse", endpoint, query_params) - - def reference_market_status(self, **query_params) -> models.ReferenceMarketStatusApiResponse: - endpoint = f"{self.url}/v1/marketstatus/now" - return self._handle_response("ReferenceMarketStatusApiResponse", endpoint, query_params) - - def reference_market_holidays(self, **query_params) -> models.ReferenceMarketHolidaysApiResponse: - endpoint = f"{self.url}/v1/marketstatus/upcoming" - return self._handle_response("ReferenceMarketHolidaysApiResponse", endpoint, query_params) - - def stocks_equities_exchanges(self, **query_params) -> models.StocksEquitiesExchangesApiResponse: - endpoint = f"{self.url}/v1/meta/exchanges" - return self._handle_response("StocksEquitiesExchangesApiResponse", endpoint, query_params) - - def stocks_equities_historic_trades(self, symbol, date, - **query_params) -> models.StocksEquitiesHistoricTradesApiResponse: - endpoint = f"{self.url}/v1/historic/trades/{symbol}/{date}" - return self._handle_response("StocksEquitiesHistoricTradesApiResponse", endpoint, query_params) - - def historic_trades_v2(self, ticker, date, **query_params) -> models.HistoricTradesV2ApiResponse: - endpoint = f"{self.url}/v2/ticks/stocks/trades/{ticker}/{date}" - return self._handle_response("HistoricTradesV2ApiResponse", endpoint, query_params) - - def stocks_equities_historic_quotes(self, symbol, date, - **query_params) -> models.StocksEquitiesHistoricQuotesApiResponse: - endpoint = f"{self.url}/v1/historic/quotes/{symbol}/{date}" - return self._handle_response("StocksEquitiesHistoricQuotesApiResponse", endpoint, query_params) - - def historic_n___bbo_quotes_v2(self, ticker, date, **query_params) -> models.HistoricNBboQuotesV2ApiResponse: - endpoint = f"{self.url}/v2/ticks/stocks/nbbo/{ticker}/{date}" - return self._handle_response("HistoricNBboQuotesV2ApiResponse", endpoint, query_params) - - def stocks_equities_last_trade_for_a_symbol(self, symbol, - **query_params) -> models.StocksEquitiesLastTradeForASymbolApiResponse: - endpoint = f"{self.url}/v1/last/stocks/{symbol}" - return self._handle_response("StocksEquitiesLastTradeForASymbolApiResponse", endpoint, query_params) - - def stocks_equities_last_quote_for_a_symbol(self, symbol, - **query_params) -> models.StocksEquitiesLastQuoteForASymbolApiResponse: - endpoint = f"{self.url}/v1/last_quote/stocks/{symbol}" - return self._handle_response("StocksEquitiesLastQuoteForASymbolApiResponse", endpoint, query_params) - - def stocks_equities_daily_open_close(self, symbol, date, - **query_params) -> models.StocksEquitiesDailyOpenCloseApiResponse: - endpoint = f"{self.url}/v1/open-close/{symbol}/{date}" - return self._handle_response("StocksEquitiesDailyOpenCloseApiResponse", endpoint, query_params) - - def stocks_equities_condition_mappings(self, ticktype, - **query_params) -> models.StocksEquitiesConditionMappingsApiResponse: - endpoint = f"{self.url}/v1/meta/conditions/{ticktype}" - return self._handle_response("StocksEquitiesConditionMappingsApiResponse", endpoint, query_params) - - def stocks_equities_snapshot_all_tickers(self, - **query_params) -> models.StocksEquitiesSnapshotAllTickersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/us/markets/stocks/tickers" - return self._handle_response("StocksEquitiesSnapshotAllTickersApiResponse", endpoint, query_params) - - def stocks_equities_snapshot_single_ticker(self, ticker, - **query_params) -> models.StocksEquitiesSnapshotSingleTickerApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/us/markets/stocks/tickers/{ticker}" - return self._handle_response("StocksEquitiesSnapshotSingleTickerApiResponse", endpoint, query_params) - - def stocks_equities_snapshot_gainers_losers(self, direction, - **query_params) -> models.StocksEquitiesSnapshotGainersLosersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/us/markets/stocks/{direction}" - return self._handle_response("StocksEquitiesSnapshotGainersLosersApiResponse", endpoint, query_params) - - def stocks_equities_previous_close(self, ticker, **query_params) -> models.StocksEquitiesPreviousCloseApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/prev" - return self._handle_response("StocksEquitiesPreviousCloseApiResponse", endpoint, query_params) - - def stocks_equities_aggregates(self, ticker, multiplier, timespan, from_, to, - **query_params) -> models.StocksEquitiesAggregatesApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}" - return self._handle_response("StocksEquitiesAggregatesApiResponse", endpoint, query_params) - - def stocks_equities_grouped_daily(self, locale, market, date, - **query_params) -> models.StocksEquitiesGroupedDailyApiResponse: - endpoint = f"{self.url}/v2/aggs/grouped/locale/{locale}/market/{market}/{date}" - return self._handle_response("StocksEquitiesGroupedDailyApiResponse", endpoint, query_params) - - def forex_currencies_historic_forex_ticks(self, from_, to, date, - **query_params) -> models.ForexCurrenciesHistoricForexTicksApiResponse: - endpoint = f"{self.url}/v1/historic/forex/{from_}/{to}/{date}" - return self._handle_response("ForexCurrenciesHistoricForexTicksApiResponse", endpoint, query_params) - - def forex_currencies_real_time_currency_conversion(self, from_, to, - **query_params) -> models.ForexCurrenciesRealTimeCurrencyConversionApiResponse: - endpoint = f"{self.url}/v1/conversion/{from_}/{to}" - return self._handle_response("ForexCurrenciesRealTimeCurrencyConversionApiResponse", endpoint, query_params) - - def forex_currencies_last_quote_for_a_currency_pair(self, from_, to, - **query_params) -> models.ForexCurrenciesLastQuoteForACurrencyPairApiResponse: - endpoint = f"{self.url}/v1/last_quote/currencies/{from_}/{to}" - return self._handle_response("ForexCurrenciesLastQuoteForACurrencyPairApiResponse", endpoint, query_params) - - def forex_currencies_grouped_daily(self, date, **query_params) -> models.ForexCurrenciesGroupedDailyApiResponse: - endpoint = f"{self.url}/v2/aggs/grouped/locale/global/market/fx/{date}" - return self._handle_response("ForexCurrenciesGroupedDailyApiResponse", endpoint, query_params) - - def forex_currencies_previous_close(self, ticker, **query_params) -> models.ForexCurrenciesGroupedDailyApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/prev" - return self._handle_response("ForexCurrenciesPreviousCloseApiResponse", endpoint, query_params) - - def forex_currencies_snapshot_all_tickers(self, - **query_params) -> models.ForexCurrenciesSnapshotAllTickersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/forex/tickers" - return self._handle_response("ForexCurrenciesSnapshotAllTickersApiResponse", endpoint, query_params) - - def forex_currencies_snapshot_single_ticker(self, ticker, **query_params) -> models.ForexCurrenciesSnapshotSingleTickerApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/forex/tickers/{ticker}" - return self._handle_response("ForexCurrenciesSnapshotSingleTickerApiResponse", endpoint, query_params) - - def forex_currencies_snapshot_gainers_losers(self, direction, - **query_params) -> models.ForexCurrenciesSnapshotGainersLosersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/forex/{direction}" - return self._handle_response("ForexCurrenciesSnapshotGainersLosersApiResponse", endpoint, query_params) - - def forex_currencies_aggregates(self, ticker, multiplier, timespan, from_, to, - **query_params) -> models.CurrenciesAggregatesApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}" - return self._handle_response("CurrenciesAggregatesApiResponse", endpoint, query_params) - - def crypto_crypto_exchanges(self, **query_params) -> models.CryptoCryptoExchangesApiResponse: - endpoint = f"{self.url}/v1/meta/crypto-exchanges" - return self._handle_response("CryptoCryptoExchangesApiResponse", endpoint, query_params) - - def crypto_last_trade_for_a_crypto_pair(self, from_, to, - **query_params) -> models.CryptoLastTradeForACryptoPairApiResponse: - endpoint = f"{self.url}/v1/last/crypto/{from_}/{to}" - return self._handle_response("CryptoLastTradeForACryptoPairApiResponse", endpoint, query_params) - - def crypto_daily_open_close(self, from_, to, date, **query_params) -> models.CryptoDailyOpenCloseApiResponse: - endpoint = f"{self.url}/v1/open-close/crypto/{from_}/{to}/{date}" - return self._handle_response("CryptoDailyOpenCloseApiResponse", endpoint, query_params) - - def crypto_aggregates(self, ticker, multiplier, timespan, from_, to, - **query_params) -> models.CurrenciesAggregatesApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from_}/{to}" - return self._handle_response("CurrenciesAggregatesApiResponse", endpoint, query_params) - - def crypto_historic_crypto_trades(self, from_, to, date, - **query_params) -> models.CryptoHistoricCryptoTradesApiResponse: - endpoint = f"{self.url}/v1/historic/crypto/{from_}/{to}/{date}" - return self._handle_response("CryptoHistoricCryptoTradesApiResponse", endpoint, query_params) - - def crypto_grouped_daily(self, date, **query_params) -> models.CryptoGroupedDailyApiResponse: - endpoint = f"{self.url}/v2/aggs/grouped/locale/global/market/crypto/{date}" - return self._handle_response("CryptoGroupedDailyApiResponse", endpoint, query_params) - - def crypto_previous_close(self, ticker, **query_params) -> models.CryptoPreviousCloseApiResponse: - endpoint = f"{self.url}/v2/aggs/ticker/{ticker}/prev" - return self._handle_response("CryptoPreviousCloseApiResponse", endpoint, query_params) - - def crypto_snapshot_all_tickers(self, **query_params) -> models.CryptoSnapshotAllTickersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/crypto/tickers" - return self._handle_response("CryptoSnapshotAllTickersApiResponse", endpoint, query_params) - - def crypto_snapshot_single_ticker(self, ticker, **query_params) -> models.CryptoSnapshotSingleTickerApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/crypto/tickers/{ticker}" - return self._handle_response("CryptoSnapshotSingleTickerApiResponse", endpoint, query_params) - - def crypto_snapshot_single_ticker_full_book(self, ticker, - **query_params) -> models.CryptoSnapshotSingleTickerFullBookApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/crypto/tickers/{ticker}/book" - return self._handle_response("CryptoSnapshotSingleTickerFullBookApiResponse", endpoint, query_params) - - def crypto_snapshot_gainers_losers(self, direction, - **query_params) -> models.CryptoSnapshotGainersLosersApiResponse: - endpoint = f"{self.url}/v2/snapshot/locale/global/markets/crypto/{direction}" - return self._handle_response("CryptoSnapshotGainersLosersApiResponse", endpoint, query_params) diff --git a/polygon/rest/models/__init__.py b/polygon/rest/models/__init__.py index 8afea378..29c99ecd 100644 --- a/polygon/rest/models/__init__.py +++ b/polygon/rest/models/__init__.py @@ -1,223 +1,11 @@ -from .definitions import LastTrade -from .definitions import LastQuote -from .definitions import HistTrade -from .definitions import Quote -from .definitions import Aggregate -from .definitions import Company -from .definitions import CompanyV3 -from .definitions import Address -from .definitions import Symbol -from .definitions import SymbolV3 -from .definitions import Dividend -from .definitions import News -from .definitions import NewsV2 -from .definitions import Publisher -from .definitions import Earning -from .definitions import Financial -from .definitions import Exchange -from .definitions import Error -from .definitions import NotFound -from .definitions import Conflict -from .definitions import Unauthorized -from .definitions import MarketStatus -from .definitions import MarketHoliday -from .definitions import AnalystRatings -from .definitions import RatingSection -from .definitions import CryptoTick -from .definitions import CryptoTickJson -from .definitions import CryptoExchange -from .definitions import CryptoSnapshotTicker -from .definitions import CryptoSnapshotBookItem -from .definitions import CryptoSnapshotTickerBook -from .definitions import CryptoSnapshotAgg -from .definitions import Forex -from .definitions import LastForexTrade -from .definitions import LastForexQuote -from .definitions import ForexAggregate -from .definitions import ForexSnapshotTicker -from .definitions import ForexSnapshotAgg -from .definitions import Ticker -from .definitions import Split -from .definitions import Financials -from .definitions import Trade -from .definitions import StocksSnapshotTicker -from .definitions import StocksSnapshotBookItem -from .definitions import StocksSnapshotTickerBook -from .definitions import StocksV2Trade -from .definitions import StocksV2NBBO -from .definitions import StocksSnapshotAgg -from .definitions import StocksSnapshotQuote -from .definitions import Aggv2 -from .definitions import AggResponse -from .definitions import ReferenceTickersApiResponse -from .definitions import ReferenceTickersV3ApiResponse -from .definitions import ReferenceTickerTypesApiResponse -from .definitions import ReferenceTickerDetailsApiResponse -from .definitions import ReferenceTickerDetailsV3ApiResponse -from .definitions import ReferenceTickerNewsApiResponse -from .definitions import ReferenceTickerNewsV2ApiResponse -from .definitions import ReferenceMarketsApiResponse -from .definitions import ReferenceLocalesApiResponse -from .definitions import ReferenceStockSplitsApiResponse -from .definitions import ReferenceStockDividendsApiResponse -from .definitions import ReferenceStockFinancialsApiResponse -from .definitions import ReferenceMarketStatusApiResponse -from .definitions import ReferenceMarketHolidaysApiResponse -from .definitions import StocksEquitiesExchangesApiResponse -from .definitions import StocksEquitiesHistoricTradesApiResponse -from .definitions import HistoricTradesV2ApiResponse -from .definitions import StocksEquitiesHistoricQuotesApiResponse -from .definitions import HistoricNBboQuotesV2ApiResponse -from .definitions import StocksEquitiesLastTradeForASymbolApiResponse -from .definitions import StocksEquitiesLastQuoteForASymbolApiResponse -from .definitions import StocksEquitiesDailyOpenCloseApiResponse -from .definitions import StocksEquitiesConditionMappingsApiResponse -from .definitions import StocksEquitiesSnapshotAllTickersApiResponse -from .definitions import StocksEquitiesSnapshotSingleTickerApiResponse -from .definitions import StocksEquitiesSnapshotGainersLosersApiResponse -from .definitions import StocksEquitiesPreviousCloseApiResponse -from .definitions import StocksEquitiesAggregatesApiResponse -from .definitions import StocksEquitiesGroupedDailyApiResponse -from .definitions import ForexCurrenciesHistoricForexTicksApiResponse -from .definitions import ForexCurrenciesRealTimeCurrencyConversionApiResponse -from .definitions import ForexCurrenciesLastQuoteForACurrencyPairApiResponse -from. definitions import ForexCurrenciesGroupedDailyApiResponse -from .definitions import ForexCurrenciesPreviousCloseApiResponse -from .definitions import ForexCurrenciesSnapshotAllTickersApiResponse -from .definitions import ForexCurrenciesSnapshotSingleTickerApiResponse -from .definitions import ForexCurrenciesSnapshotGainersLosersApiResponse -from .definitions import CryptoCryptoExchangesApiResponse -from .definitions import CryptoLastTradeForACryptoPairApiResponse -from .definitions import CryptoDailyOpenCloseApiResponse -from .definitions import CryptoHistoricCryptoTradesApiResponse -from .definitions import CryptoGroupedDailyApiResponse -from .definitions import CryptoPreviousCloseApiResponse -from .definitions import CryptoSnapshotAllTickersApiResponse -from .definitions import CryptoSnapshotSingleTickerApiResponse -from .definitions import CryptoSnapshotSingleTickerFullBookApiResponse -from .definitions import CryptoSnapshotGainersLosersApiResponse -from .definitions import CurrenciesAggregatesApiResponse -from .definitions import StockSymbol -from .definitions import ConditionTypeMap -from .definitions import SymbolTypeMap -from .definitions import TickerSymbol - - -import typing - -from .definitions import Definition - - -AnyDefinition = typing.TypeVar("AnyDefinition", bound=Definition) - -# noinspection SpellCheckingInspection -name_to_class: typing.Dict[str, typing.Callable[[], typing.Type[AnyDefinition]]] = { - "LastTrade": LastTrade, - "LastQuote": LastQuote, - "HistTrade": HistTrade, - "Quote": Quote, - "Aggregate": Aggregate, - "Company": Company, - "CompanyV3": CompanyV3, - "Address": Address, - "Symbol": Symbol, - "Dividend": Dividend, - "News": News, - "NewsV2": NewsV2, - "Publisher": Publisher, - "Earning": Earning, - "Financial": Financial, - "Exchange": Exchange, - "Error": Error, - "NotFound": NotFound, - "Conflict": Conflict, - "Unauthorized": Unauthorized, - "MarketStatus": MarketStatus, - "MarketHoliday": MarketHoliday, - "AnalystRatings": AnalystRatings, - "RatingSection": RatingSection, - "CryptoTick": CryptoTick, - "CryptoTickJson": CryptoTickJson, - "CryptoExchange": CryptoExchange, - "CryptoSnapshotTicker": CryptoSnapshotTicker, - "CryptoSnapshotBookItem": CryptoSnapshotBookItem, - "CryptoSnapshotTickerBook": CryptoSnapshotTickerBook, - "CryptoSnapshotAgg": CryptoSnapshotAgg, - "Forex": Forex, - "LastForexTrade": LastForexTrade, - "LastForexQuote": LastForexQuote, - "ForexAggregate": ForexAggregate, - "ForexSnapshotTicker": ForexSnapshotTicker, - "ForexSnapshotAgg": ForexSnapshotAgg, - "Ticker": Ticker, - "Split": Split, - "Financials": Financials, - "Trade": Trade, - "StocksSnapshotTicker": StocksSnapshotTicker, - "StocksSnapshotBookItem": StocksSnapshotBookItem, - "StocksSnapshotTickerBook": StocksSnapshotTickerBook, - "StocksV2Trade": StocksV2Trade, - "StocksV2NBBO": StocksV2NBBO, - "StocksSnapshotAgg": StocksSnapshotAgg, - "StocksSnapshotQuote": StocksSnapshotQuote, - "Aggv2": Aggv2, - "AggResponse": AggResponse, - "ReferenceTickersApiResponse": ReferenceTickersApiResponse, - "ReferenceTickersV3ApiResponse": ReferenceTickersV3ApiResponse, - "ReferenceTickerTypesApiResponse": ReferenceTickerTypesApiResponse, - "ReferenceTickerDetailsApiResponse": ReferenceTickerDetailsApiResponse, - "ReferenceTickerDetailsV3ApiResponse": ReferenceTickerDetailsV3ApiResponse, - "ReferenceTickerNewsApiResponse": ReferenceTickerNewsApiResponse, - "ReferenceTickerNewsV2ApiResponse": ReferenceTickerNewsV2ApiResponse, - "ReferenceMarketsApiResponse": ReferenceMarketsApiResponse, - "ReferenceLocalesApiResponse": ReferenceLocalesApiResponse, - "ReferenceStockSplitsApiResponse": ReferenceStockSplitsApiResponse, - "ReferenceStockDividendsApiResponse": ReferenceStockDividendsApiResponse, - "ReferenceStockFinancialsApiResponse": ReferenceStockFinancialsApiResponse, - "ReferenceMarketStatusApiResponse": ReferenceMarketStatusApiResponse, - "ReferenceMarketHolidaysApiResponse": ReferenceMarketHolidaysApiResponse, - "StocksEquitiesExchangesApiResponse": StocksEquitiesExchangesApiResponse, - "StocksEquitiesHistoricTradesApiResponse": StocksEquitiesHistoricTradesApiResponse, - "HistoricTradesV2ApiResponse": HistoricTradesV2ApiResponse, - "StocksEquitiesHistoricQuotesApiResponse": StocksEquitiesHistoricQuotesApiResponse, - "HistoricNBboQuotesV2ApiResponse": HistoricNBboQuotesV2ApiResponse, - "StocksEquitiesLastTradeForASymbolApiResponse": StocksEquitiesLastTradeForASymbolApiResponse, - "StocksEquitiesLastQuoteForASymbolApiResponse": StocksEquitiesLastQuoteForASymbolApiResponse, - "StocksEquitiesDailyOpenCloseApiResponse": StocksEquitiesDailyOpenCloseApiResponse, - "StocksEquitiesConditionMappingsApiResponse": StocksEquitiesConditionMappingsApiResponse, - "StocksEquitiesSnapshotAllTickersApiResponse": StocksEquitiesSnapshotAllTickersApiResponse, - "StocksEquitiesSnapshotSingleTickerApiResponse": StocksEquitiesSnapshotSingleTickerApiResponse, - "StocksEquitiesSnapshotGainersLosersApiResponse": StocksEquitiesSnapshotGainersLosersApiResponse, - "StocksEquitiesPreviousCloseApiResponse": StocksEquitiesPreviousCloseApiResponse, - "StocksEquitiesAggregatesApiResponse": StocksEquitiesAggregatesApiResponse, - "StocksEquitiesGroupedDailyApiResponse": StocksEquitiesGroupedDailyApiResponse, - "ForexCurrenciesHistoricForexTicksApiResponse": ForexCurrenciesHistoricForexTicksApiResponse, - "ForexCurrenciesRealTimeCurrencyConversionApiResponse": ForexCurrenciesRealTimeCurrencyConversionApiResponse, - "ForexCurrenciesLastQuoteForACurrencyPairApiResponse": ForexCurrenciesLastQuoteForACurrencyPairApiResponse, - "ForexCurrenciesGroupedDailyApiResponse": ForexCurrenciesGroupedDailyApiResponse, - "ForexCurrenciesPreviousCloseApiResponse": ForexCurrenciesPreviousCloseApiResponse, - "ForexCurrenciesSnapshotAllTickersApiResponse": ForexCurrenciesSnapshotAllTickersApiResponse, - "ForexCurrenciesSnapshotSingleTickerApiResponse": ForexCurrenciesSnapshotSingleTickerApiResponse, - "ForexCurrenciesSnapshotGainersLosersApiResponse": ForexCurrenciesSnapshotGainersLosersApiResponse, - "CryptoCryptoExchangesApiResponse": CryptoCryptoExchangesApiResponse, - "CryptoLastTradeForACryptoPairApiResponse": CryptoLastTradeForACryptoPairApiResponse, - "CryptoDailyOpenCloseApiResponse": CryptoDailyOpenCloseApiResponse, - "CryptoHistoricCryptoTradesApiResponse": CryptoHistoricCryptoTradesApiResponse, - "CryptoGroupedDailyApiResponse": CryptoGroupedDailyApiResponse, - "CryptoPreviousCloseApiResponse": CryptoPreviousCloseApiResponse, - "CryptoSnapshotAllTickersApiResponse": CryptoSnapshotAllTickersApiResponse, - "CryptoSnapshotSingleTickerApiResponse": CryptoSnapshotSingleTickerApiResponse, - "CryptoSnapshotSingleTickerFullBookApiResponse": CryptoSnapshotSingleTickerFullBookApiResponse, - "CryptoSnapshotGainersLosersApiResponse": CryptoSnapshotGainersLosersApiResponse, - "CurrenciesAggregatesApiResponse": CurrenciesAggregatesApiResponse, - -} - -# noinspection SpellCheckingInspection -name_to_type = { - "StockSymbol": StockSymbol, - "ConditionTypeMap": ConditionTypeMap, - "SymbolTypeMap": SymbolTypeMap, - "TickerSymbol": TickerSymbol, - -} \ No newline at end of file +from .shared import * +from .aggs import * +from .trades import * +from .quotes import * +from .markets import * +from .tickers import * +from .splits import * +from .dividends import * +from .conditions import * +from .exchanges import * +from .snapshot import * diff --git a/polygon/rest/models/aggs.py b/polygon/rest/models/aggs.py new file mode 100644 index 00000000..892ab197 --- /dev/null +++ b/polygon/rest/models/aggs.py @@ -0,0 +1,108 @@ +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class Agg: + open: Optional[float] + high: Optional[float] + low: Optional[float] + close: Optional[float] + volume: Optional[float] + vwap: Optional[float] + timestamp: Optional[int] + transactions: Optional[int] + + @staticmethod + def from_dict(d): + return Agg( + d.get("o", None), + d.get("h", None), + d.get("l", None), + d.get("c", None), + d.get("v", None), + d.get("vw", None), + d.get("t", None), + d.get("n", None), + ) + + +@dataclass +class GroupedDailyAgg: + ticker: str + open: float + high: float + low: float + close: float + volume: float + vwap: Optional[float] + timestamp: Optional[int] + transactions: Optional[int] + + @staticmethod + def from_dict(d): + return GroupedDailyAgg( + d.get("T", None), + d.get("o", None), + d.get("h", None), + d.get("l", None), + d.get("c", None), + d.get("v", None), + d.get("vw", None), + d.get("t", None), + d.get("n", None), + ) + + +@dataclass +class DailyOpenCloseAgg: + after_hours: Optional[float] + close: float + from_: str + high: float + low: float + open: float + pre_market: Optional[float] + status: Optional[str] + symbol: str + volume: float + + @staticmethod + def from_dict(d): + return DailyOpenCloseAgg( + d.get("afterHours", None), + d.get("close", None), + d.get("from", None), + d.get("high", None), + d.get("low", None), + d.get("open", None), + d.get("preMarket", None), + d.get("status", None), + d.get("symbol", None), + d.get("volume", None), + ) + + +@dataclass +class PreviousCloseAgg: + ticker: str + close: float + high: float + low: float + open: float + timestamp: Optional[float] + volume: float + vwap: Optional[float] + + @staticmethod + def from_dict(d): + return PreviousCloseAgg( + d.get("T", None), + d.get("c", None), + d.get("h", None), + d.get("l", None), + d.get("o", None), + d.get("t", None), + d.get("v", None), + d.get("vw", None), + ) diff --git a/polygon/rest/models/conditions.py b/polygon/rest/models/conditions.py new file mode 100644 index 00000000..81949353 --- /dev/null +++ b/polygon/rest/models/conditions.py @@ -0,0 +1,50 @@ +from typing import Optional +from .shared import AssetClass, DataType +from dataclasses import dataclass + + +@dataclass +class SipMapping: + CTA: Optional[str] = None + OPRA: Optional[str] = None + UTP: Optional[str] = None + + +@dataclass +class Consolidated: + updates_high_low: Optional[bool] = None + updates_open_close: Optional[bool] = None + updates_volume: Optional[bool] = None + + +@dataclass +class MarketCenter: + updates_high_low: Optional[bool] = None + updates_open_close: Optional[bool] = None + updates_volume: Optional[bool] = None + + +@dataclass +class UpdateRules: + consolidated: Optional[Consolidated] = None + market_center: Optional[MarketCenter] = None + + +@dataclass +class Condition: + "Condition contains data for a condition that Polygon.io uses." + abbreviation: Optional[str] = None + asset_class: Optional[AssetClass] = None + data_types: Optional[DataType] = None + description: Optional[str] = None + exchange: Optional[int] = None + id: Optional[int] = None + legacy: Optional[bool] = None + name: Optional[str] = None + sip_mapping: Optional[SipMapping] = None + type: Optional[str] = None + update_rules: Optional[UpdateRules] = None + + @staticmethod + def from_dict(d): + return Condition(**d) diff --git a/polygon/rest/models/definitions.py b/polygon/rest/models/definitions.py deleted file mode 100644 index c05b7cde..00000000 --- a/polygon/rest/models/definitions.py +++ /dev/null @@ -1,4180 +0,0 @@ -import keyword -from typing import List, Dict, Any - -from polygon.rest import models - - -class Definition: - _swagger_name_to_python: Dict[str, str] - _attribute_is_primitive: Dict[str, bool] - _attributes_to_types: Dict[str, Any] - - def unmarshal_json(self, input_json): - if isinstance(input_json, list): - list_attribute_name = list(self._swagger_name_to_python.values())[0] - if list_attribute_name in self._attributes_to_types: - list_type = self._attributes_to_types[list_attribute_name] - known_type = list_type.split("[")[1][:-1] - list_items = self._unmarshal_json_list(input_json, known_type) - else: - list_items = input_json - self.__setattr__(list_attribute_name, list_items) - return self - elif isinstance(input_json, dict): - self._unmarshal_json_object(input_json) - return self - elif isinstance(input_json, float) or isinstance(input_json, int): - return input_json - - @staticmethod - def _unmarshal_json_list(input_json, known_type): - items = [] - for item in input_json: - new_item = models.name_to_class[known_type]() - items.append(new_item._unmarshal_json_object(item)) - - return items - - def _unmarshal_json_object(self, input_json): - for key, value in input_json.items(): - if key in self._swagger_name_to_python: - attribute_name = self._swagger_name_to_python[key] - if not self._attribute_is_primitive[attribute_name]: - if attribute_name in self._attributes_to_types: - attribute_type = self._attributes_to_types[attribute_name] - if attribute_type in models.name_to_class: - model = models.name_to_class[attribute_type]() - value = model.unmarshal_json(input_json[key]) - else: - attribute_name = key + ('_' if keyword.iskeyword(key) else '') - - self.__setattr__(attribute_name, value) - return self - - -# noinspection SpellCheckingInspection -class LastTrade(Definition): - _swagger_name_to_python = { - "price": "price", - "size": "size", - "exchange": "exchange", - "cond1": "cond1", - "cond2": "cond2", - "cond3": "cond3", - "cond4": "cond4", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "price": True, - "size": True, - "exchange": True, - "cond1": True, - "cond2": True, - "cond3": True, - "cond4": True, - "timestamp": True, - - } - - _attributes_to_types = { - "price": "int", - "size": "int", - "exchange": "int", - "cond1": "int", - "cond2": "int", - "cond3": "int", - "cond4": "int", - "timestamp": "int", - - } - - def __init__(self): - self.price: int - self.size: int - self.exchange: int - self.cond1: int - self.cond2: int - self.cond3: int - self.cond4: int - self.timestamp: int - - -# noinspection SpellCheckingInspection -class LastQuote(Definition): - _swagger_name_to_python = { - "askprice": "askprice", - "asksize": "asksize", - "askexchange": "askexchange", - "bidprice": "bidprice", - "bidsize": "bidsize", - "bidexchange": "bidexchange", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "askprice": True, - "asksize": True, - "askexchange": True, - "bidprice": True, - "bidsize": True, - "bidexchange": True, - "timestamp": True, - - } - - _attributes_to_types = { - "askprice": "int", - "asksize": "int", - "askexchange": "int", - "bidprice": "int", - "bidsize": "int", - "bidexchange": "int", - "timestamp": "int", - - } - - def __init__(self): - self.askprice: int - self.asksize: int - self.askexchange: int - self.bidprice: int - self.bidsize: int - self.bidexchange: int - self.timestamp: int - - -# noinspection SpellCheckingInspection -class HistTrade(Definition): - _swagger_name_to_python = { - "condition1": "condition1", - "condition2": "condition2", - "condition3": "condition3", - "condition4": "condition4", - "exchange": "exchange", - "price": "price", - "size": "size", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "condition1": True, - "condition2": True, - "condition3": True, - "condition4": True, - "exchange": True, - "price": True, - "size": True, - "timestamp": True, - - } - - _attributes_to_types = { - "condition1": "int", - "condition2": "int", - "condition3": "int", - "condition4": "int", - "exchange": "str", - "price": "int", - "size": "int", - "timestamp": "str", - - } - - def __init__(self): - self.condition1: int - self.condition2: int - self.condition3: int - self.condition4: int - self.exchange: str - self.price: int - self.size: int - self.timestamp: str - - -# noinspection SpellCheckingInspection -class Quote(Definition): - _swagger_name_to_python = { - "c": "condition_of_this_quote", - "bE": "bid_exchange", - "aE": "ask_exchange", - "aP": "ask_price", - "bP": "bid_price", - "bS": "bid_size", - "aS": "ask_size", - "t": "timestamp_of_this_trade", - - } - - _attribute_is_primitive = { - "condition_of_this_quote": True, - "bid_exchange": True, - "ask_exchange": True, - "ask_price": True, - "bid_price": True, - "bid_size": True, - "ask_size": True, - "timestamp_of_this_trade": True, - - } - - _attributes_to_types = { - "condition_of_this_quote": "int", - "bid_exchange": "str", - "ask_exchange": "str", - "ask_price": "int", - "bid_price": "int", - "bid_size": "int", - "ask_size": "int", - "timestamp_of_this_trade": "int", - - } - - def __init__(self): - self.condition_of_this_quote: int - self.bid_exchange: str - self.ask_exchange: str - self.ask_price: int - self.bid_price: int - self.bid_size: int - self.ask_size: int - self.timestamp_of_this_trade: int - - -# noinspection SpellCheckingInspection -class Aggregate(Definition): - _swagger_name_to_python = { - "o": "open_price", - "c": "close_price", - "l": "low_price", - "h": "high_price", - "v": "total_volume_of_all_trades", - "k": "transactions", - "t": "timestamp_of_this_aggregation", - - } - - _attribute_is_primitive = { - "open_price": True, - "close_price": True, - "low_price": True, - "high_price": True, - "total_volume_of_all_trades": True, - "transactions": True, - "timestamp_of_this_aggregation": True, - - } - - _attributes_to_types = { - "open_price": "int", - "close_price": "int", - "low_price": "int", - "high_price": "int", - "total_volume_of_all_trades": "int", - "transactions": "int", - "timestamp_of_this_aggregation": "int", - - } - - def __init__(self): - self.open_price: int - self.close_price: int - self.low_price: int - self.high_price: int - self.total_volume_of_all_trades: int - self.transactions: int - self.timestamp_of_this_aggregation: int - - -# noinspection SpellCheckingInspection -class Company(Definition): - _swagger_name_to_python = { - "logo": "logo", - "exchange": "exchange", - "name": "name", - "symbol": "symbol", - "listdate": "listdate", - "cik": "cik", - "bloomberg": "bloomberg", - "figi": "figi", - "lei": "lei", - "sic": "sic", - "country": "country", - "industry": "industry", - "sector": "sector", - "marketcap": "marketcap", - "employees": "employees", - "phone": "phone", - "ceo": "ceo", - "url": "url", - "description": "description", - "similar": "similar", - "tags": "tags", - "updated": "updated", - - } - - _attribute_is_primitive = { - "logo": True, - "exchange": True, - "name": True, - "symbol": False, - "listdate": True, - "cik": True, - "bloomberg": True, - "figi": True, - "lei": True, - "sic": True, - "country": True, - "industry": True, - "sector": True, - "marketcap": True, - "employees": True, - "phone": True, - "ceo": True, - "url": True, - "description": True, - "similar": False, - "tags": False, - "updated": True, - - } - - _attributes_to_types = { - "logo": "str", - "exchange": "str", - "name": "str", - "symbol": "StockSymbol", - "listdate": "str", - "cik": "str", - "bloomberg": "str", - "figi": "str", - "lei": "str", - "sic": "float", - "country": "str", - "industry": "str", - "sector": "str", - "marketcap": "float", - "employees": "float", - "phone": "str", - "ceo": "str", - "url": "str", - "description": "str", - "similar": "List[StockSymbol]", - "tags": "List[str]", - "updated": "str", - - } - - def __init__(self): - self.logo: str - self.exchange: str - self.name: str - self.symbol: StockSymbol - self.listdate: str - self.cik: str - self.bloomberg: str - self.figi: str - self.lei: str - self.sic: float - self.country: str - self.industry: str - self.sector: str - self.marketcap: float - self.employees: float - self.phone: str - self.ceo: str - self.url: str - self.description: str - self.similar: List[StockSymbol] - self.tags: List[str] - self.updated: str - -class Address(Definition): - _swagger_name_to_python = { - "address1": "address1", - "city": "city", - "state": "state", - } - - _attributes_is_primitive = { - "address1": True, - "city": True, - "state": True, - } - - _attributes_to_types = { - "address1": "str", - "city": "str", - "state": "str", - } - - def __init__(self): - self.address1: str - self.city: str - self.state: str - - -# noinspection SpellCheckingInspection -class CompanyV3(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "name": "name", - "market": "market", - "locale": "locale", - "primary_exchange": "primary_exchange", - "type": "type", - "active": "active", - "currency_name": "currency_name", - "cik": "cik", - "composite_figi": "composite_figi", - "share_class_figi": "share_class_figi", - "last_updated_utc": "last_updated_utc", - "outstanding_shares": "outstanding_shares", - "market_cap": "market_cap", - "phone_number": "phone_number", - "address": "address", - "sic_code": "sic_code", - "sic_description": "sic_description", - } - - _attributes_is_primitive = { - "ticker": True, - "name": True, - "market": True, - "primary_exchange": True, - "type": True, - "active": True, - "currency_name": True, - "cik": True, - "composite_figi": True, - "share_class_figi": True, - "last_updated_utc": True, - "outstanding_shares": True, - "market_cap": True, - "phone_number": True, - "address": False, - "sic_code": True, - "sic_description": True, - } - - _attributes_to_types = { - "ticker": "str", - "name": "str", - "market": "str", - "primary_exchange": "str", - "type": "str", - "active": "bool", - "currency_name": "str", - "cik": "str", - "composite_figi": "str", - "share_class_figi": "str", - "last_updated_utc": "str", - "outstanding_shares": "int", - "market_cap": "int", - "phone_number": "str", - "address": "Address", - "sic_code": "str", - "sic_description": "str", - } - - def __init__(self): - self.ticker: str - self.name: str - self.market: str - self.primary_exchange: str - self.type: str - self.active: bool - self.currency_name: str - self.cik: str - self.composite_figi: str - self.share_class_figi: str - self.last_updated_utc: str - self.outstanding_shares: int - self.market_cap: int - self.phone_number: str - self.address: Address - self.sic_code: str - self.sic_description: str - -# noinspection SpellCheckingInspection -class Symbol(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "name": "name", - "type": "type", - "url": "url", - "updated": "updated", - "isOTC": "is___otc", - - } - - _attribute_is_primitive = { - "symbol": False, - "name": True, - "type": True, - "url": True, - "updated": True, - "is___otc": True, - - } - - _attributes_to_types = { - "symbol": "StockSymbol", - "name": "str", - "type": "str", - "url": "str", - "updated": "str", - "is___otc": "bool", - - } - - def __init__(self): - self.symbol: StockSymbol - self.name: str - self.type: str - self.url: str - self.updated: str - self.is___otc: bool - - -# noinspection SpellCheckingInspection -class SymbolV3(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "name": "name", - "market": "market", - "locale": "locale", - "primary_exchange": "primary_exchange", - "type": "type", - "active": "active", - "currency_name": "currency_name", - "cik": "cik", - "composite_figi": "composite_figi", - "share_class_figi": "share_class_figi", - "last_updated_utc": "last_updated_utc", - "delisted_utc": "delisted_utc", - } - - _attributes_is_primitive = { - "ticker": True, - "name": True, - "market": True, - "primary_exchange": True, - "type": True, - "active": True, - "currency_name": True, - "cik": True, - "composite_figi": True, - "share_class_figi": True, - "last_updated_utc": True, - "delisted_utc": True, - } - - _attributes_to_types = { - "ticker": "str", - "name": "str", - "market": "str", - "primary_exchange": "str", - "type": "str", - "active": "bool", - "currency_name": "str", - "cik": "str", - "composite_figi": "str", - "share_class_figi": "str", - "last_updated_utc": "str", - "delisted_utc": "str", - } - - def __init__(self): - self.ticker: str - self.name: str - self.market: str - self.primary_exchange: str - self.type: str - self.active: bool - self.currency_name: str - self.cik: str - self.composite_figi: str - self.share_class_figi: str - self.last_updated_utc: str - self.delisted_utc: str - -# noinspection SpellCheckingInspection -class Dividend(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "type": "type", - "exDate": "ex_date", - "paymentDate": "payment_date", - "recordDate": "record_date", - "declaredDate": "declared_date", - "amount": "amount", - "qualified": "qualified", - "flag": "flag", - - } - - _attribute_is_primitive = { - "symbol": False, - "type": True, - "ex_date": True, - "payment_date": True, - "record_date": True, - "declared_date": True, - "amount": True, - "qualified": True, - "flag": True, - - } - - _attributes_to_types = { - "symbol": "StockSymbol", - "type": "str", - "ex_date": "str", - "payment_date": "str", - "record_date": "str", - "declared_date": "str", - "amount": "float", - "qualified": "str", - "flag": "str", - - } - - def __init__(self): - self.symbol: StockSymbol - self.type: str - self.ex_date: str - self.payment_date: str - self.record_date: str - self.declared_date: str - self.amount: float - self.qualified: str - self.flag: str - - -# noinspection SpellCheckingInspection -class News(Definition): - _swagger_name_to_python = { - "symbols": "symbols", - "title": "title", - "url": "url", - "source": "source", - "summary": "summary", - "image": "image", - "timestamp": "timestamp", - "keywords": "keywords", - - } - - _attribute_is_primitive = { - "symbols": False, - "title": True, - "url": True, - "source": True, - "summary": True, - "image": True, - "timestamp": True, - "keywords": False, - - } - - _attributes_to_types = { - "symbols": "List[StockSymbol]", - "title": "str", - "url": "str", - "source": "str", - "summary": "str", - "image": "str", - "timestamp": "str", - "keywords": "List[str]", - - } - - def __init__(self): - self.symbols: List[StockSymbol] - self.title: str - self.url: str - self.source: str - self.summary: str - self.image: str - self.timestamp: str - self.keywords: List[str] - -class Publisher(Definition): - _swagger_name_to_python = { - "name": "name", - "logo_url": "logo_url", - "homepage_url": "homepage_url", - "favicon_url": "favicon_url", - } - - _attribute_is_primitive = { - "name": True, - "logo_url": True, - "homepage_url": True, - "favicon_url": True, - } - - _attributes_to_type = { - "name": "str", - "logo_url": "str", - "homepage_url": "str", - "favicon_url": "str", - } - - def __init__(self): - self.name: str - self.logo_url: str - self.homepage_url: str - self.favicon_url: str - - -# noinspection SpellCheckingInspection -class NewsV2(Definition): - _swagger_name_to_python = { - "id": "id", - "publisher": "publisher", - "title": "title", - "author": "author", - "published_utc": "published_utc", - "tickers": "tickers", - "amp_url": "amp_url", - "image_url": "image_url", - "description": "description", - "keywords": "keywords", - } - - _attribute_is_primitive = { - "id": True, - "publisher": False, - "title": True, - "author": True, - "published_utc": True, - "tickers": True, - "amp_url": True, - "image_url": True, - "description": True, - "keywords": True, - } - - _attributes_to_type = { - "id": "str", - "publisher": "Publisher", - "title": "str", - "author": "str", - "published_utc": "str", - "tickers": "List[str]", - "amp_url": "str", - "image_url": "str", - "description": "str", - "keywords": "str", - } - - def __init__(self): - self.id: str - self.publisher: Publisher - self.title: str - self.author: str - self.published_utc: str - self.tickers: List[str] - self.amp_url: str - self.image_url: str - self.description: str - self.keywords: str - -# noinspection SpellCheckingInspection -class Earning(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "EPSReportDate": "e___psrep_ortdate", - "EPSReportDateStr": "e___psrep_ort_datestr", - "fiscalPeriod": "fiscal_period", - "fiscalEndDate": "fiscal_en_ddate", - "actualEPS": "actual___eps", - "consensusEPS": "consensus___eps", - "estimatedEPS": "estimated___eps", - "announceTime": "announce_time", - "numberOfEstimates": "number_o_festimates", - "EPSSurpriseDollar": "e___pssurpr_isedollar", - "yearAgo": "year_ago", - "yearAgoChangePercent": "year_ag_ochan_gepercent", - "estimatedChangePercent": "estimated_chang_epercent", - - } - - _attribute_is_primitive = { - "symbol": True, - "e___psrep_ortdate": True, - "e___psrep_ort_datestr": True, - "fiscal_period": True, - "fiscal_en_ddate": True, - "actual___eps": True, - "consensus___eps": True, - "estimated___eps": True, - "announce_time": True, - "number_o_festimates": True, - "e___pssurpr_isedollar": True, - "year_ago": True, - "year_ag_ochan_gepercent": True, - "estimated_chang_epercent": True, - - } - - _attributes_to_types = { - "symbol": "str", - "e___psrep_ortdate": "str", - "e___psrep_ort_datestr": "str", - "fiscal_period": "str", - "fiscal_en_ddate": "str", - "actual___eps": "float", - "consensus___eps": "float", - "estimated___eps": "float", - "announce_time": "str", - "number_o_festimates": "float", - "e___pssurpr_isedollar": "float", - "year_ago": "float", - "year_ag_ochan_gepercent": "float", - "estimated_chang_epercent": "float", - - } - - def __init__(self): - self.symbol: str - self.e___psrep_ortdate: str - self.e___psrep_ort_datestr: str - self.fiscal_period: str - self.fiscal_en_ddate: str - self.actual___eps: float - self.consensus___eps: float - self.estimated___eps: float - self.announce_time: str - self.number_o_festimates: float - self.e___pssurpr_isedollar: float - self.year_ago: float - self.year_ag_ochan_gepercent: float - self.estimated_chang_epercent: float - - -# noinspection SpellCheckingInspection -class Financial(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "reportDate": "report_date", - "reportDateStr": "report_dat_estr", - "grossProfit": "gross_profit", - "costOfRevenue": "cost_o_frevenue", - "operatingRevenue": "operating_revenue", - "totalRevenue": "total_revenue", - "operatingIncome": "operating_income", - "netIncome": "net_income", - "researchAndDevelopment": "research_an_ddevelopment", - "operatingExpense": "operating_expense", - "currentAssets": "current_assets", - "totalAssets": "total_assets", - "totalLiabilities": "total_liabilities", - "currentCash": "current_cash", - "currentDebt": "current_debt", - "totalCash": "total_cash", - "totalDebt": "total_debt", - "shareholderEquity": "shareholder_equity", - "cashChange": "cash_change", - "cashFlow": "cash_flow", - "operatingGainsLosses": "operating_gain_slosses", - - } - - _attribute_is_primitive = { - "symbol": True, - "report_date": True, - "report_dat_estr": True, - "gross_profit": True, - "cost_o_frevenue": True, - "operating_revenue": True, - "total_revenue": True, - "operating_income": True, - "net_income": True, - "research_an_ddevelopment": True, - "operating_expense": True, - "current_assets": True, - "total_assets": True, - "total_liabilities": True, - "current_cash": True, - "current_debt": True, - "total_cash": True, - "total_debt": True, - "shareholder_equity": True, - "cash_change": True, - "cash_flow": True, - "operating_gain_slosses": True, - - } - - _attributes_to_types = { - "symbol": "str", - "report_date": "str", - "report_dat_estr": "str", - "gross_profit": "float", - "cost_o_frevenue": "float", - "operating_revenue": "float", - "total_revenue": "float", - "operating_income": "float", - "net_income": "float", - "research_an_ddevelopment": "float", - "operating_expense": "float", - "current_assets": "float", - "total_assets": "float", - "total_liabilities": "float", - "current_cash": "float", - "current_debt": "float", - "total_cash": "float", - "total_debt": "float", - "shareholder_equity": "float", - "cash_change": "float", - "cash_flow": "float", - "operating_gain_slosses": "float", - - } - - def __init__(self): - self.symbol: str - self.report_date: str - self.report_dat_estr: str - self.gross_profit: float - self.cost_o_frevenue: float - self.operating_revenue: float - self.total_revenue: float - self.operating_income: float - self.net_income: float - self.research_an_ddevelopment: float - self.operating_expense: float - self.current_assets: float - self.total_assets: float - self.total_liabilities: float - self.current_cash: float - self.current_debt: float - self.total_cash: float - self.total_debt: float - self.shareholder_equity: float - self.cash_change: float - self.cash_flow: float - self.operating_gain_slosses: float - - -# noinspection SpellCheckingInspection -class Exchange(Definition): - _swagger_name_to_python = { - "id": "i_d_of_the_exchange", - "type": "type", - "market": "market", - "mic": "mic", - "name": "name", - "tape": "tape", - - } - - _attribute_is_primitive = { - "i_d_of_the_exchange": True, - "type": True, - "market": True, - "mic": True, - "name": True, - "tape": True, - - } - - _attributes_to_types = { - "i_d_of_the_exchange": "float", - "type": "str", - "market": "str", - "mic": "str", - "name": "str", - "tape": "str", - - } - - def __init__(self): - self.i_d_of_the_exchange: float - self.type: str - self.market: str - self.mic: str - self.name: str - self.tape: str - - -# noinspection SpellCheckingInspection -class Error(Definition): - _swagger_name_to_python = { - "code": "code", - "message": "message", - "fields": "fields", - - } - - _attribute_is_primitive = { - "code": True, - "message": True, - "fields": True, - - } - - _attributes_to_types = { - "code": "int", - "message": "str", - "fields": "str", - - } - - def __init__(self): - self.code: int - self.message: str - self.fields: str - - -# noinspection SpellCheckingInspection -class NotFound(Definition): - _swagger_name_to_python = { - "message": "message", - - } - - _attribute_is_primitive = { - "message": True, - - } - - _attributes_to_types = { - "message": "str", - - } - - def __init__(self): - self.message: str - - -# noinspection SpellCheckingInspection -class Conflict(Definition): - _swagger_name_to_python = { - "message": "message", - - } - - _attribute_is_primitive = { - "message": True, - - } - - _attributes_to_types = { - "message": "str", - - } - - def __init__(self): - self.message: str - - -# noinspection SpellCheckingInspection -class Unauthorized(Definition): - _swagger_name_to_python = { - "message": "message", - - } - - _attribute_is_primitive = { - "message": True, - - } - - _attributes_to_types = { - "message": "str", - - } - - def __init__(self): - self.message: str - - -# noinspection SpellCheckingInspection -class MarketStatus(Definition): - _swagger_name_to_python = { - "market": "market", - "serverTime": "server_time", - "exchanges": "exchanges", - "currencies": "currencies", - - } - - _attribute_is_primitive = { - "market": True, - "server_time": True, - "exchanges": True, - "currencies": True, - - } - - _attributes_to_types = { - "market": "str", - "server_time": "str", - "exchanges": "Dict[str, str]", - "currencies": "Dict[str, str]", - - } - - def __init__(self): - self.market: str - self.server_time: str - self.exchanges: Dict[str, str] - self.currencies: Dict[str, str] - - -# noinspection SpellCheckingInspection -class MarketHoliday(Definition): - _swagger_name_to_python = { - "exchange": "exchange", - "name": "name", - "status": "status", - "date": "date", - "open": "open", - "close": "close", - - } - - _attribute_is_primitive = { - "exchange": True, - "name": True, - "status": True, - "date": True, - "open": True, - "close": True, - - } - - _attributes_to_types = { - "exchange": "str", - "name": "str", - "status": "str", - "date": "str", - "open": "str", - "close": "str", - - } - - def __init__(self): - self.exchange: str - self.name: str - self.status: str - self.date: str - self.open: str - self.close: str - - -# noinspection SpellCheckingInspection -class AnalystRatings(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "analysts": "analysts", - "change": "change", - "strongBuy": "strong_buy", - "buy": "buy", - "hold": "hold", - "sell": "sell", - "strongSell": "strong_sell", - "updated": "updated", - - } - - _attribute_is_primitive = { - "symbol": True, - "analysts": True, - "change": True, - "strong_buy": False, - "buy": False, - "hold": False, - "sell": False, - "strong_sell": False, - "updated": True, - - } - - _attributes_to_types = { - "symbol": "str", - "analysts": "float", - "change": "float", - "strong_buy": "RatingSection", - "buy": "RatingSection", - "hold": "RatingSection", - "sell": "RatingSection", - "strong_sell": "RatingSection", - "updated": "str", - - } - - def __init__(self): - self.symbol: str - self.analysts: float - self.change: float - self.strong_buy: RatingSection - self.buy: RatingSection - self.hold: RatingSection - self.sell: RatingSection - self.strong_sell: RatingSection - self.updated: str - - -# noinspection SpellCheckingInspection -class RatingSection(Definition): - _swagger_name_to_python = { - "current": "current", - "month1": "month1", - "month2": "month2", - "month3": "month3", - "month4": "month4", - "month5": "month5", - - } - - _attribute_is_primitive = { - "current": True, - "month1": True, - "month2": True, - "month3": True, - "month4": True, - "month5": True, - - } - - _attributes_to_types = { - "current": "float", - "month1": "float", - "month2": "float", - "month3": "float", - "month4": "float", - "month5": "float", - - } - - def __init__(self): - self.current: float - self.month1: float - self.month2: float - self.month3: float - self.month4: float - self.month5: float - - -# noinspection SpellCheckingInspection -class CryptoTick(Definition): - _swagger_name_to_python = { - "price": "price", - "size": "size", - "exchange": "exchange", - "conditions": "conditions", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "price": True, - "size": True, - "exchange": True, - "conditions": False, - "timestamp": True, - - } - - _attributes_to_types = { - "price": "int", - "size": "int", - "exchange": "int", - "conditions": "List[int]", - "timestamp": "int", - - } - - def __init__(self): - self.price: int - self.size: int - self.exchange: int - self.conditions: List[int] - self.timestamp: int - - -# noinspection SpellCheckingInspection -class CryptoTickJson(Definition): - _swagger_name_to_python = { - "p": "trade_price", - "s": "size_of_the_trade", - "x": "exchange_the_trade_occured_on", - "c": "c", - "t": "timestamp_of_this_trade", - - } - - _attribute_is_primitive = { - "trade_price": True, - "size_of_the_trade": True, - "exchange_the_trade_occured_on": True, - "c": False, - "timestamp_of_this_trade": True, - - } - - _attributes_to_types = { - "trade_price": "int", - "size_of_the_trade": "int", - "exchange_the_trade_occured_on": "int", - "c": "List[int]", - "timestamp_of_this_trade": "int", - - } - - def __init__(self): - self.trade_price: int - self.size_of_the_trade: int - self.exchange_the_trade_occured_on: int - self.c: List[int] - self.timestamp_of_this_trade: int - - -# noinspection SpellCheckingInspection -class CryptoExchange(Definition): - _swagger_name_to_python = { - "id": "i_d_of_the_exchange", - "type": "type", - "market": "market", - "name": "name", - "url": "url", - - } - - _attribute_is_primitive = { - "i_d_of_the_exchange": True, - "type": True, - "market": True, - "name": True, - "url": True, - - } - - _attributes_to_types = { - "i_d_of_the_exchange": "float", - "type": "str", - "market": "str", - "name": "str", - "url": "str", - - } - - def __init__(self): - self.i_d_of_the_exchange: float - self.type: str - self.market: str - self.name: str - self.url: str - - -# noinspection SpellCheckingInspection -class CryptoSnapshotTicker(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "day": "day", - "lastTrade": "last_trade", - "min": "min", - "prevDay": "prev_day", - "todaysChange": "todays_change", - "todaysChangePerc": "todays_chang_eperc", - "updated": "updated", - - } - - _attribute_is_primitive = { - "ticker": True, - "day": False, - "last_trade": False, - "min": False, - "prev_day": False, - "todays_change": True, - "todays_chang_eperc": True, - "updated": True, - - } - - _attributes_to_types = { - "ticker": "str", - "day": "CryptoSnapshotAgg", - "last_trade": "CryptoTickJson", - "min": "CryptoSnapshotAgg", - "prev_day": "CryptoSnapshotAgg", - "todays_change": "int", - "todays_chang_eperc": "int", - "updated": "int", - - } - - def __init__(self): - self.ticker: str - self.day: CryptoSnapshotAgg - self.last_trade: CryptoTickJson - self.min: CryptoSnapshotAgg - self.prev_day: CryptoSnapshotAgg - self.todays_change: int - self.todays_chang_eperc: int - self.updated: int - - -# noinspection SpellCheckingInspection -class CryptoSnapshotBookItem(Definition): - _swagger_name_to_python = { - "p": "price_of_this_book_level", - "x": "exchange_to_size_of_this_price_level", - - } - - _attribute_is_primitive = { - "price_of_this_book_level": True, - "exchange_to_size_of_this_price_level": True, - - } - - _attributes_to_types = { - "price_of_this_book_level": "int", - "exchange_to_size_of_this_price_level": "Dict[str, str]", - - } - - def __init__(self): - self.price_of_this_book_level: int - self.exchange_to_size_of_this_price_level: Dict[str, str] - - -# noinspection SpellCheckingInspection -class CryptoSnapshotTickerBook(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "bids": "bids", - "asks": "asks", - "bidCount": "bid_count", - "askCount": "ask_count", - "spread": "spread", - "updated": "updated", - - } - - _attribute_is_primitive = { - "ticker": True, - "bids": False, - "asks": False, - "bid_count": True, - "ask_count": True, - "spread": True, - "updated": True, - - } - - _attributes_to_types = { - "ticker": "str", - "bids": "List[CryptoSnapshotBookItem]", - "asks": "List[CryptoSnapshotBookItem]", - "bid_count": "int", - "ask_count": "int", - "spread": "int", - "updated": "int", - - } - - def __init__(self): - self.ticker: str - self.bids: List[CryptoSnapshotBookItem] - self.asks: List[CryptoSnapshotBookItem] - self.bid_count: int - self.ask_count: int - self.spread: int - self.updated: int - - -# noinspection SpellCheckingInspection -class CryptoSnapshotAgg(Definition): - _swagger_name_to_python = { - "c": "close_price", - "h": "high_price", - "l": "low_price", - "o": "open_price", - "v": "volume", - - } - - _attribute_is_primitive = { - "close_price": True, - "high_price": True, - "low_price": True, - "open_price": True, - "volume": True, - - } - - _attributes_to_types = { - "close_price": "int", - "high_price": "int", - "low_price": "int", - "open_price": "int", - "volume": "int", - - } - - def __init__(self): - self.close_price: int - self.high_price: int - self.low_price: int - self.open_price: int - self.volume: int - - -# noinspection SpellCheckingInspection -class Forex(Definition): - _swagger_name_to_python = { - "a": "ask_price", - "b": "bid_price", - "t": "timestamp_of_this_trade", - - } - - _attribute_is_primitive = { - "ask_price": True, - "bid_price": True, - "timestamp_of_this_trade": True, - - } - - _attributes_to_types = { - "ask_price": "int", - "bid_price": "int", - "timestamp_of_this_trade": "int", - - } - - def __init__(self): - self.ask_price: int - self.bid_price: int - self.timestamp_of_this_trade: int - - -# noinspection SpellCheckingInspection -class LastForexTrade(Definition): - _swagger_name_to_python = { - "price": "price", - "exchange": "exchange", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "price": True, - "exchange": True, - "timestamp": True, - - } - - _attributes_to_types = { - "price": "int", - "exchange": "int", - "timestamp": "int", - - } - - def __init__(self): - self.price: int - self.exchange: int - self.timestamp: int - - -# noinspection SpellCheckingInspection -class LastForexQuote(Definition): - _swagger_name_to_python = { - "ask": "ask", - "bid": "bid", - "exchange": "exchange", - "timestamp": "timestamp", - - } - - _attribute_is_primitive = { - "ask": True, - "bid": True, - "exchange": True, - "timestamp": True, - - } - - _attributes_to_types = { - "ask": "int", - "bid": "int", - "exchange": "int", - "timestamp": "int", - - } - - def __init__(self): - self.ask: int - self.bid: int - self.exchange: int - self.timestamp: int - - -# noinspection SpellCheckingInspection -class ForexAggregate(Definition): - _swagger_name_to_python = { - "o": "open_price", - "c": "close_price", - "l": "low_price", - "h": "high_price", - "v": "volume_of_all_trades", - "t": "timestamp_of_this_aggregation", - - } - - _attribute_is_primitive = { - "open_price": True, - "close_price": True, - "low_price": True, - "high_price": True, - "volume_of_all_trades": True, - "timestamp_of_this_aggregation": True, - - } - - _attributes_to_types = { - "open_price": "int", - "close_price": "int", - "low_price": "int", - "high_price": "int", - "volume_of_all_trades": "int", - "timestamp_of_this_aggregation": "int", - - } - - def __init__(self): - self.open_price: int - self.close_price: int - self.low_price: int - self.high_price: int - self.volume_of_all_trades: int - self.timestamp_of_this_aggregation: int - - -# noinspection SpellCheckingInspection -class ForexSnapshotTicker(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "day": "day", - "lastTrade": "last_trade", - "min": "min", - "prevDay": "prev_day", - "todaysChange": "todays_change", - "todaysChangePerc": "todays_chang_eperc", - "updated": "updated", - - } - - _attribute_is_primitive = { - "ticker": True, - "day": False, - "last_trade": False, - "min": False, - "prev_day": False, - "todays_change": True, - "todays_chang_eperc": True, - "updated": True, - - } - - _attributes_to_types = { - "ticker": "str", - "day": "ForexSnapshotAgg", - "last_trade": "Forex", - "min": "ForexSnapshotAgg", - "prev_day": "ForexSnapshotAgg", - "todays_change": "int", - "todays_chang_eperc": "int", - "updated": "int", - - } - - def __init__(self): - self.ticker: str - self.day: ForexSnapshotAgg - self.last_trade: Forex - self.min: ForexSnapshotAgg - self.prev_day: ForexSnapshotAgg - self.todays_change: int - self.todays_chang_eperc: int - self.updated: int - - -# noinspection SpellCheckingInspection -class ForexSnapshotAgg(Definition): - _swagger_name_to_python = { - "c": "close_price", - "h": "high_price", - "l": "low_price", - "o": "open_price", - "v": "volume", - - } - - _attribute_is_primitive = { - "close_price": True, - "high_price": True, - "low_price": True, - "open_price": True, - "volume": True, - - } - - _attributes_to_types = { - "close_price": "int", - "high_price": "int", - "low_price": "int", - "open_price": "int", - "volume": "int", - - } - - def __init__(self): - self.close_price: int - self.high_price: int - self.low_price: int - self.open_price: int - self.volume: int - - -# noinspection SpellCheckingInspection -class Ticker(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "name": "name", - "market": "market", - "locale": "locale", - "currency": "currency", - "active": "active", - "primaryExch": "primary_exch", - "url": "url", - "updated": "updated", - "attrs": "attrs", - "codes": "codes", - - } - - _attribute_is_primitive = { - "ticker": False, - "name": True, - "market": True, - "locale": True, - "currency": True, - "active": True, - "primary_exch": True, - "url": True, - "updated": True, - "attrs": True, - "codes": True, - - } - - _attributes_to_types = { - "ticker": "StockSymbol", - "name": "str", - "market": "str", - "locale": "str", - "currency": "str", - "active": "bool", - "primary_exch": "str", - "url": "str", - "updated": "str", - "attrs": "Dict[str, str]", - "codes": "Dict[str, str]", - - } - - def __init__(self): - self.ticker: StockSymbol - self.name: str - self.market: str - self.locale: str - self.currency: str - self.active: bool - self.primary_exch: str - self.url: str - self.updated: str - self.attrs: Dict[str, str] - self.codes: Dict[str, str] - - -# noinspection SpellCheckingInspection -class Split(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "exDate": "ex_date", - "paymentDate": "payment_date", - "recordDate": "record_date", - "declaredDate": "declared_date", - "ratio": "ratio", - "tofactor": "tofactor", - "forfactor": "forfactor", - - } - - _attribute_is_primitive = { - "ticker": False, - "ex_date": True, - "payment_date": True, - "record_date": True, - "declared_date": True, - "ratio": True, - "tofactor": True, - "forfactor": True, - - } - - _attributes_to_types = { - "ticker": "TickerSymbol", - "ex_date": "str", - "payment_date": "str", - "record_date": "str", - "declared_date": "str", - "ratio": "float", - "tofactor": "float", - "forfactor": "float", - - } - - def __init__(self): - self.ticker: TickerSymbol - self.ex_date: str - self.payment_date: str - self.record_date: str - self.declared_date: str - self.ratio: float - self.tofactor: float - self.forfactor: float - - -# noinspection SpellCheckingInspection -class Financials(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "period": "period", - "calendarDate": "calendar_date", - "reportPeriod": "report_period", - "updated": "updated", - "accumulatedOtherComprehensiveIncome": "accumulated_othe_rcomprehensi_veincome", - "assets": "assets", - "assetsAverage": "assets_average", - "assetsCurrent": "assets_current", - "assetTurnover": "asset_turnover", - "assetsNonCurrent": "assets_no_ncurrent", - "bookValuePerShare": "book_valu_ep_ershare", - "capitalExpenditure": "capital_expenditure", - "cashAndEquivalents": "cash_an_dequivalents", - "cashAndEquivalentsUSD": "cash_an_dequivalen___tsusd", - "costOfRevenue": "cost_o_frevenue", - "consolidatedIncome": "consolidated_income", - "currentRatio": "current_ratio", - "debtToEquityRatio": "debt_t_oequi_tyratio", - "debt": "debt", - "debtCurrent": "debt_current", - "debtNonCurrent": "debt_no_ncurrent", - "debtUSD": "debt___usd", - "deferredRevenue": "deferred_revenue", - "depreciationAmortizationAndAccretion": "depreciation_amortizatio_na_ndaccretion", - "deposits": "deposits", - "dividendYield": "dividend_yield", - "dividendsPerBasicCommonShare": "dividends_pe_rbas_iccom_monshare", - "earningBeforeInterestTaxes": "earning_befor_eintere_sttaxes", - "earningsBeforeInterestTaxesDepreciationAmortization": "earnings_befor_eintere_stta_xesdeprecia_tionamortization", - "EBITDAMargin": "e______bitdamargin", - "earningsBeforeInterestTaxesDepreciationAmortizationUSD": "earnings_befor_eintere_stta_xesdeprecia_tionamortiz___ationusd", - "earningBeforeInterestTaxesUSD": "earning_befor_eintere_stta___xesusd", - "earningsBeforeTax": "earnings_befor_etax", - "earningsPerBasicShare": "earnings_pe_rbas_icshare", - "earningsPerDilutedShare": "earnings_pe_rdilut_edshare", - "earningsPerBasicShareUSD": "earnings_pe_rbas_icsh___areusd", - "shareholdersEquity": "shareholders_equity", - "averageEquity": "average_equity", - "shareholdersEquityUSD": "shareholders_equit___yusd", - "enterpriseValue": "enterprise_value", - "enterpriseValueOverEBIT": "enterprise_valu_eov____erebit", - "enterpriseValueOverEBITDA": "enterprise_valu_eov______erebitda", - "freeCashFlow": "free_cas_hflow", - "freeCashFlowPerShare": "free_cas_hfl_ow_pershare", - "foreignCurrencyUSDExchangeRate": "foreign_currenc____yusdexc_hangerate", - "grossProfit": "gross_profit", - "grossMargin": "gross_margin", - "goodwillAndIntangibleAssets": "goodwill_an_dintangib_leassets", - "interestExpense": "interest_expense", - "investedCapital": "invested_capital", - "investedCapitalAverage": "invested_capita_laverage", - "inventory": "inventory", - "investments": "investments", - "investmentsCurrent": "investments_current", - "investmentsNonCurrent": "investments_no_ncurrent", - "totalLiabilities": "total_liabilities", - "currentLiabilities": "current_liabilities", - "liabilitiesNonCurrent": "liabilities_no_ncurrent", - "marketCapitalization": "market_capitalization", - "netCashFlow": "net_cas_hflow", - "netCashFlowBusinessAcquisitionsDisposals": "net_cas_hfl_owbusin_essacquisit_ionsdisposals", - "issuanceEquityShares": "issuance_equit_yshares", - "issuanceDebtSecurities": "issuance_deb_tsecurities", - "paymentDividendsOtherCashDistributions": "payment_dividend_soth_erc_ashdistributions", - "netCashFlowFromFinancing": "net_cas_hfl_owf_romfinancing", - "netCashFlowFromInvesting": "net_cas_hfl_owf_rominvesting", - "netCashFlowInvestmentAcquisitionsDisposals": "net_cas_hfl_owinvestm_entacquisit_ionsdisposals", - "netCashFlowFromOperations": "net_cas_hfl_owf_romoperations", - "effectOfExchangeRateChangesOnCash": "effect_o_fexchan_ger_atecha_n_gesoncash", - "netIncome": "net_income", - "netIncomeCommonStock": "net_incom_ecomm_onstock", - "netIncomeCommonStockUSD": "net_incom_ecomm_onst___ockusd", - "netLossIncomeFromDiscontinuedOperations": "net_los_sinco_mef_romdisconti_nuedoperations", - "netIncomeToNonControllingInterests": "net_incom_e_to_noncontrol_linginterests", - "profitMargin": "profit_margin", - "operatingExpenses": "operating_expenses", - "operatingIncome": "operating_income", - "tradeAndNonTradePayables": "trade_an_dn_ontr_adepayables", - "payoutRatio": "payout_ratio", - "priceToBookValue": "price_t_obo_okvalue", - "priceEarnings": "price_earnings", - "priceToEarningsRatio": "price_t_oearnin_gsratio", - "propertyPlantEquipmentNet": "property_plan_tequipme_ntnet", - "preferredDividendsIncomeStatementImpact": "preferred_dividend_sinco_mestatem_entimpact", - "sharePriceAdjustedClose": "share_pric_eadjust_edclose", - "priceSales": "price_sales", - "priceToSalesRatio": "price_t_osal_esratio", - "tradeAndNonTradeReceivables": "trade_an_dn_ontr_adereceivables", - "accumulatedRetainedEarningsDeficit": "accumulated_retaine_dearnin_gsdeficit", - "revenues": "revenues", - "revenuesUSD": "revenues___usd", - "researchAndDevelopmentExpense": "research_an_ddevelopme_ntexpense", - "returnOnAverageAssets": "return_o_navera_geassets", - "returnOnAverageEquity": "return_o_navera_geequity", - "returnOnInvestedCapital": "return_o_ninvest_edcapital", - "returnOnSales": "return_o_nsales", - "shareBasedCompensation": "share_base_dcompensation", - "sellingGeneralAndAdministrativeExpense": "selling_genera_la_ndadministrat_iveexpense", - "shareFactor": "share_factor", - "shares": "shares", - "weightedAverageShares": "weighted_averag_eshares", - "weightedAverageSharesDiluted": "weighted_averag_eshar_esdiluted", - "salesPerShare": "sales_pe_rshare", - "tangibleAssetValue": "tangible_asse_tvalue", - "taxAssets": "tax_assets", - "incomeTaxExpense": "income_ta_xexpense", - "taxLiabilities": "tax_liabilities", - "tangibleAssetsBookValuePerShare": "tangible_asset_sbo_okva_lu_epershare", - "workingCapital": "working_capital", - - } - - _attribute_is_primitive = { - "ticker": False, - "period": True, - "calendar_date": True, - "report_period": True, - "updated": True, - "accumulated_othe_rcomprehensi_veincome": True, - "assets": True, - "assets_average": True, - "assets_current": True, - "asset_turnover": True, - "assets_no_ncurrent": True, - "book_valu_ep_ershare": True, - "capital_expenditure": True, - "cash_an_dequivalents": True, - "cash_an_dequivalen___tsusd": True, - "cost_o_frevenue": True, - "consolidated_income": True, - "current_ratio": True, - "debt_t_oequi_tyratio": True, - "debt": True, - "debt_current": True, - "debt_no_ncurrent": True, - "debt___usd": True, - "deferred_revenue": True, - "depreciation_amortizatio_na_ndaccretion": True, - "deposits": True, - "dividend_yield": True, - "dividends_pe_rbas_iccom_monshare": True, - "earning_befor_eintere_sttaxes": True, - "earnings_befor_eintere_stta_xesdeprecia_tionamortization": True, - "e______bitdamargin": True, - "earnings_befor_eintere_stta_xesdeprecia_tionamortiz___ationusd": True, - "earning_befor_eintere_stta___xesusd": True, - "earnings_befor_etax": True, - "earnings_pe_rbas_icshare": True, - "earnings_pe_rdilut_edshare": True, - "earnings_pe_rbas_icsh___areusd": True, - "shareholders_equity": True, - "average_equity": True, - "shareholders_equit___yusd": True, - "enterprise_value": True, - "enterprise_valu_eov____erebit": True, - "enterprise_valu_eov______erebitda": True, - "free_cas_hflow": True, - "free_cas_hfl_ow_pershare": True, - "foreign_currenc____yusdexc_hangerate": True, - "gross_profit": True, - "gross_margin": True, - "goodwill_an_dintangib_leassets": True, - "interest_expense": True, - "invested_capital": True, - "invested_capita_laverage": True, - "inventory": True, - "investments": True, - "investments_current": True, - "investments_no_ncurrent": True, - "total_liabilities": True, - "current_liabilities": True, - "liabilities_no_ncurrent": True, - "market_capitalization": True, - "net_cas_hflow": True, - "net_cas_hfl_owbusin_essacquisit_ionsdisposals": True, - "issuance_equit_yshares": True, - "issuance_deb_tsecurities": True, - "payment_dividend_soth_erc_ashdistributions": True, - "net_cas_hfl_owf_romfinancing": True, - "net_cas_hfl_owf_rominvesting": True, - "net_cas_hfl_owinvestm_entacquisit_ionsdisposals": True, - "net_cas_hfl_owf_romoperations": True, - "effect_o_fexchan_ger_atecha_n_gesoncash": True, - "net_income": True, - "net_incom_ecomm_onstock": True, - "net_incom_ecomm_onst___ockusd": True, - "net_los_sinco_mef_romdisconti_nuedoperations": True, - "net_incom_e_to_noncontrol_linginterests": True, - "profit_margin": True, - "operating_expenses": True, - "operating_income": True, - "trade_an_dn_ontr_adepayables": True, - "payout_ratio": True, - "price_t_obo_okvalue": True, - "price_earnings": True, - "price_t_oearnin_gsratio": True, - "property_plan_tequipme_ntnet": True, - "preferred_dividend_sinco_mestatem_entimpact": True, - "share_pric_eadjust_edclose": True, - "price_sales": True, - "price_t_osal_esratio": True, - "trade_an_dn_ontr_adereceivables": True, - "accumulated_retaine_dearnin_gsdeficit": True, - "revenues": True, - "revenues___usd": True, - "research_an_ddevelopme_ntexpense": True, - "return_o_navera_geassets": True, - "return_o_navera_geequity": True, - "return_o_ninvest_edcapital": True, - "return_o_nsales": True, - "share_base_dcompensation": True, - "selling_genera_la_ndadministrat_iveexpense": True, - "share_factor": True, - "shares": True, - "weighted_averag_eshares": True, - "weighted_averag_eshar_esdiluted": True, - "sales_pe_rshare": True, - "tangible_asse_tvalue": True, - "tax_assets": True, - "income_ta_xexpense": True, - "tax_liabilities": True, - "tangible_asset_sbo_okva_lu_epershare": True, - "working_capital": True, - - } - - _attributes_to_types = { - "ticker": "TickerSymbol", - "period": "str", - "calendar_date": "str", - "report_period": "str", - "updated": "str", - "accumulated_othe_rcomprehensi_veincome": "int", - "assets": "int", - "assets_average": "int", - "assets_current": "int", - "asset_turnover": "int", - "assets_no_ncurrent": "int", - "book_valu_ep_ershare": "int", - "capital_expenditure": "int", - "cash_an_dequivalents": "int", - "cash_an_dequivalen___tsusd": "int", - "cost_o_frevenue": "int", - "consolidated_income": "int", - "current_ratio": "int", - "debt_t_oequi_tyratio": "int", - "debt": "int", - "debt_current": "int", - "debt_no_ncurrent": "int", - "debt___usd": "int", - "deferred_revenue": "int", - "depreciation_amortizatio_na_ndaccretion": "int", - "deposits": "int", - "dividend_yield": "int", - "dividends_pe_rbas_iccom_monshare": "int", - "earning_befor_eintere_sttaxes": "int", - "earnings_befor_eintere_stta_xesdeprecia_tionamortization": "int", - "e______bitdamargin": "int", - "earnings_befor_eintere_stta_xesdeprecia_tionamortiz___ationusd": "int", - "earning_befor_eintere_stta___xesusd": "int", - "earnings_befor_etax": "int", - "earnings_pe_rbas_icshare": "int", - "earnings_pe_rdilut_edshare": "int", - "earnings_pe_rbas_icsh___areusd": "int", - "shareholders_equity": "int", - "average_equity": "int", - "shareholders_equit___yusd": "int", - "enterprise_value": "int", - "enterprise_valu_eov____erebit": "int", - "enterprise_valu_eov______erebitda": "int", - "free_cas_hflow": "int", - "free_cas_hfl_ow_pershare": "int", - "foreign_currenc____yusdexc_hangerate": "int", - "gross_profit": "int", - "gross_margin": "int", - "goodwill_an_dintangib_leassets": "int", - "interest_expense": "int", - "invested_capital": "int", - "invested_capita_laverage": "int", - "inventory": "int", - "investments": "int", - "investments_current": "int", - "investments_no_ncurrent": "int", - "total_liabilities": "int", - "current_liabilities": "int", - "liabilities_no_ncurrent": "int", - "market_capitalization": "int", - "net_cas_hflow": "int", - "net_cas_hfl_owbusin_essacquisit_ionsdisposals": "int", - "issuance_equit_yshares": "int", - "issuance_deb_tsecurities": "int", - "payment_dividend_soth_erc_ashdistributions": "int", - "net_cas_hfl_owf_romfinancing": "int", - "net_cas_hfl_owf_rominvesting": "int", - "net_cas_hfl_owinvestm_entacquisit_ionsdisposals": "int", - "net_cas_hfl_owf_romoperations": "int", - "effect_o_fexchan_ger_atecha_n_gesoncash": "int", - "net_income": "int", - "net_incom_ecomm_onstock": "int", - "net_incom_ecomm_onst___ockusd": "int", - "net_los_sinco_mef_romdisconti_nuedoperations": "int", - "net_incom_e_to_noncontrol_linginterests": "int", - "profit_margin": "int", - "operating_expenses": "int", - "operating_income": "int", - "trade_an_dn_ontr_adepayables": "int", - "payout_ratio": "int", - "price_t_obo_okvalue": "int", - "price_earnings": "int", - "price_t_oearnin_gsratio": "int", - "property_plan_tequipme_ntnet": "int", - "preferred_dividend_sinco_mestatem_entimpact": "int", - "share_pric_eadjust_edclose": "int", - "price_sales": "int", - "price_t_osal_esratio": "int", - "trade_an_dn_ontr_adereceivables": "int", - "accumulated_retaine_dearnin_gsdeficit": "int", - "revenues": "int", - "revenues___usd": "int", - "research_an_ddevelopme_ntexpense": "int", - "return_o_navera_geassets": "int", - "return_o_navera_geequity": "int", - "return_o_ninvest_edcapital": "int", - "return_o_nsales": "int", - "share_base_dcompensation": "int", - "selling_genera_la_ndadministrat_iveexpense": "int", - "share_factor": "int", - "shares": "int", - "weighted_averag_eshares": "int", - "weighted_averag_eshar_esdiluted": "int", - "sales_pe_rshare": "int", - "tangible_asse_tvalue": "int", - "tax_assets": "int", - "income_ta_xexpense": "int", - "tax_liabilities": "int", - "tangible_asset_sbo_okva_lu_epershare": "int", - "working_capital": "int", - - } - - def __init__(self): - self.ticker: TickerSymbol - self.period: str - self.calendar_date: str - self.report_period: str - self.updated: str - self.accumulated_othe_rcomprehensi_veincome: int - self.assets: int - self.assets_average: int - self.assets_current: int - self.asset_turnover: int - self.assets_no_ncurrent: int - self.book_valu_ep_ershare: int - self.capital_expenditure: int - self.cash_an_dequivalents: int - self.cash_an_dequivalen___tsusd: int - self.cost_o_frevenue: int - self.consolidated_income: int - self.current_ratio: int - self.debt_t_oequi_tyratio: int - self.debt: int - self.debt_current: int - self.debt_no_ncurrent: int - self.debt___usd: int - self.deferred_revenue: int - self.depreciation_amortizatio_na_ndaccretion: int - self.deposits: int - self.dividend_yield: int - self.dividends_pe_rbas_iccom_monshare: int - self.earning_befor_eintere_sttaxes: int - self.earnings_befor_eintere_stta_xesdeprecia_tionamortization: int - self.e______bitdamargin: int - self.earnings_befor_eintere_stta_xesdeprecia_tionamortiz___ationusd: int - self.earning_befor_eintere_stta___xesusd: int - self.earnings_befor_etax: int - self.earnings_pe_rbas_icshare: int - self.earnings_pe_rdilut_edshare: int - self.earnings_pe_rbas_icsh___areusd: int - self.shareholders_equity: int - self.average_equity: int - self.shareholders_equit___yusd: int - self.enterprise_value: int - self.enterprise_valu_eov____erebit: int - self.enterprise_valu_eov______erebitda: int - self.free_cas_hflow: int - self.free_cas_hfl_ow_pershare: int - self.foreign_currenc____yusdexc_hangerate: int - self.gross_profit: int - self.gross_margin: int - self.goodwill_an_dintangib_leassets: int - self.interest_expense: int - self.invested_capital: int - self.invested_capita_laverage: int - self.inventory: int - self.investments: int - self.investments_current: int - self.investments_no_ncurrent: int - self.total_liabilities: int - self.current_liabilities: int - self.liabilities_no_ncurrent: int - self.market_capitalization: int - self.net_cas_hflow: int - self.net_cas_hfl_owbusin_essacquisit_ionsdisposals: int - self.issuance_equit_yshares: int - self.issuance_deb_tsecurities: int - self.payment_dividend_soth_erc_ashdistributions: int - self.net_cas_hfl_owf_romfinancing: int - self.net_cas_hfl_owf_rominvesting: int - self.net_cas_hfl_owinvestm_entacquisit_ionsdisposals: int - self.net_cas_hfl_owf_romoperations: int - self.effect_o_fexchan_ger_atecha_n_gesoncash: int - self.net_income: int - self.net_incom_ecomm_onstock: int - self.net_incom_ecomm_onst___ockusd: int - self.net_los_sinco_mef_romdisconti_nuedoperations: int - self.net_incom_e_to_noncontrol_linginterests: int - self.profit_margin: int - self.operating_expenses: int - self.operating_income: int - self.trade_an_dn_ontr_adepayables: int - self.payout_ratio: int - self.price_t_obo_okvalue: int - self.price_earnings: int - self.price_t_oearnin_gsratio: int - self.property_plan_tequipme_ntnet: int - self.preferred_dividend_sinco_mestatem_entimpact: int - self.share_pric_eadjust_edclose: int - self.price_sales: int - self.price_t_osal_esratio: int - self.trade_an_dn_ontr_adereceivables: int - self.accumulated_retaine_dearnin_gsdeficit: int - self.revenues: int - self.revenues___usd: int - self.research_an_ddevelopme_ntexpense: int - self.return_o_navera_geassets: int - self.return_o_navera_geequity: int - self.return_o_ninvest_edcapital: int - self.return_o_nsales: int - self.share_base_dcompensation: int - self.selling_genera_la_ndadministrat_iveexpense: int - self.share_factor: int - self.shares: int - self.weighted_averag_eshares: int - self.weighted_averag_eshar_esdiluted: int - self.sales_pe_rshare: int - self.tangible_asse_tvalue: int - self.tax_assets: int - self.income_ta_xexpense: int - self.tax_liabilities: int - self.tangible_asset_sbo_okva_lu_epershare: int - self.working_capital: int - - -# noinspection SpellCheckingInspection -class Trade(Definition): - _swagger_name_to_python = { - "c1": "condition_1_of_this_trade", - "c2": "condition_2_of_this_trade", - "c3": "condition_3_of_this_trade", - "c4": "condition_4_of_this_trade", - "e": "the_exchange_this_trade_happened_on", - "p": "price_of_the_trade", - "s": "size_of_the_trade", - "t": "timestamp_of_this_trade", - - } - - _attribute_is_primitive = { - "condition_1_of_this_trade": True, - "condition_2_of_this_trade": True, - "condition_3_of_this_trade": True, - "condition_4_of_this_trade": True, - "the_exchange_this_trade_happened_on": True, - "price_of_the_trade": True, - "size_of_the_trade": True, - "timestamp_of_this_trade": True, - - } - - _attributes_to_types = { - "condition_1_of_this_trade": "int", - "condition_2_of_this_trade": "int", - "condition_3_of_this_trade": "int", - "condition_4_of_this_trade": "int", - "the_exchange_this_trade_happened_on": "str", - "price_of_the_trade": "int", - "size_of_the_trade": "int", - "timestamp_of_this_trade": "int", - - } - - def __init__(self): - self.condition_1_of_this_trade: int - self.condition_2_of_this_trade: int - self.condition_3_of_this_trade: int - self.condition_4_of_this_trade: int - self.the_exchange_this_trade_happened_on: str - self.price_of_the_trade: int - self.size_of_the_trade: int - self.timestamp_of_this_trade: int - - -# noinspection SpellCheckingInspection -class StocksSnapshotTicker(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "day": "day", - "lastTrade": "last_trade", - "lastQuote": "last_quote", - "min": "min", - "prevDay": "prev_day", - "todaysChange": "todays_change", - "todaysChangePerc": "todays_chang_eperc", - "updated": "updated", - - } - - _attribute_is_primitive = { - "ticker": True, - "day": False, - "last_trade": False, - "last_quote": False, - "min": False, - "prev_day": False, - "todays_change": True, - "todays_chang_eperc": True, - "updated": True, - - } - - _attributes_to_types = { - "ticker": "str", - "day": "StocksSnapshotAgg", - "last_trade": "Trade", - "last_quote": "StocksSnapshotQuote", - "min": "StocksSnapshotAgg", - "prev_day": "StocksSnapshotAgg", - "todays_change": "int", - "todays_chang_eperc": "int", - "updated": "int", - - } - - def __init__(self): - self.ticker: str - self.day: StocksSnapshotAgg - self.last_trade: Trade - self.last_quote: StocksSnapshotQuote - self.min: StocksSnapshotAgg - self.prev_day: StocksSnapshotAgg - self.todays_change: int - self.todays_chang_eperc: int - self.updated: int - - -# noinspection SpellCheckingInspection -class StocksSnapshotBookItem(Definition): - _swagger_name_to_python = { - "p": "price_of_this_book_level", - "x": "exchange_to_size_of_this_price_level", - - } - - _attribute_is_primitive = { - "price_of_this_book_level": True, - "exchange_to_size_of_this_price_level": True, - - } - - _attributes_to_types = { - "price_of_this_book_level": "int", - "exchange_to_size_of_this_price_level": "Dict[str, str]", - - } - - def __init__(self): - self.price_of_this_book_level: int - self.exchange_to_size_of_this_price_level: Dict[str, str] - - -# noinspection SpellCheckingInspection -class StocksSnapshotTickerBook(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "bids": "bids", - "asks": "asks", - "bidCount": "bid_count", - "askCount": "ask_count", - "spread": "spread", - "updated": "updated", - - } - - _attribute_is_primitive = { - "ticker": True, - "bids": False, - "asks": False, - "bid_count": True, - "ask_count": True, - "spread": True, - "updated": True, - - } - - _attributes_to_types = { - "ticker": "str", - "bids": "List[StocksSnapshotBookItem]", - "asks": "List[StocksSnapshotBookItem]", - "bid_count": "int", - "ask_count": "int", - "spread": "int", - "updated": "int", - - } - - def __init__(self): - self.ticker: str - self.bids: List[StocksSnapshotBookItem] - self.asks: List[StocksSnapshotBookItem] - self.bid_count: int - self.ask_count: int - self.spread: int - self.updated: int - - -# noinspection SpellCheckingInspection -class StocksV2Trade(Definition): - _swagger_name_to_python = { - "T": "ticker_of_the_object", - "t": "nanosecond_accuracy_s__ip_unix_timestamp", - "y": "nanosecond_accuracy_participant_exchange_unix_timestamp", - "f": "nanosecond_accuracy_t__rf", - "q": "sequence_number", - "i": "trade_i_d", - "x": "exchange_i_d", - "s": "size_volume_of_the_trade", - "c": "c", - "p": "price_of_the_trade", - "z": "tape_where_trade_occured", - - } - - _attribute_is_primitive = { - "ticker_of_the_object": True, - "nanosecond_accuracy_s__ip_unix_timestamp": True, - "nanosecond_accuracy_participant_exchange_unix_timestamp": True, - "nanosecond_accuracy_t__rf": True, - "sequence_number": True, - "trade_i_d": True, - "exchange_i_d": True, - "size_volume_of_the_trade": True, - "c": False, - "price_of_the_trade": True, - "tape_where_trade_occured": True, - - } - - _attributes_to_types = { - "ticker_of_the_object": "str", - "nanosecond_accuracy_s__ip_unix_timestamp": "int", - "nanosecond_accuracy_participant_exchange_unix_timestamp": "int", - "nanosecond_accuracy_t__rf": "int", - "sequence_number": "int", - "trade_i_d": "str", - "exchange_i_d": "int", - "size_volume_of_the_trade": "int", - "c": "List[int]", - "price_of_the_trade": "int", - "tape_where_trade_occured": "int", - - } - - def __init__(self): - self.ticker_of_the_object: str - self.nanosecond_accuracy_s__ip_unix_timestamp: int - self.nanosecond_accuracy_participant_exchange_unix_timestamp: int - self.nanosecond_accuracy_t__rf: int - self.sequence_number: int - self.trade_i_d: str - self.exchange_i_d: int - self.size_volume_of_the_trade: int - self.c: List[int] - self.price_of_the_trade: int - self.tape_where_trade_occured: int - - -# noinspection SpellCheckingInspection -class StocksV2NBBO(Definition): - _swagger_name_to_python = { - "T": "ticker_of_the_object", - "t": "nanosecond_accuracy_s__ip_unix_timestamp", - "y": "nanosecond_accuracy_participant_exchange_unix_timestamp", - "f": "nanosecond_accuracy_t__rf", - "q": "sequence_number", - "c": "c", - "i": "i", - "p": "b__id_price", - "x": "b__id_exchange__id", - "s": "b__id_size", - "P": "a__sk_price", - "X": "a__sk_exchange__id", - "S": "a__sk_size", - "z": "tape_where_trade_occured", - - } - - _attribute_is_primitive = { - "ticker_of_the_object": True, - "nanosecond_accuracy_s__ip_unix_timestamp": True, - "nanosecond_accuracy_participant_exchange_unix_timestamp": True, - "nanosecond_accuracy_t__rf": True, - "sequence_number": True, - "c": False, - "i": False, - "b__id_price": True, - "b__id_exchange__id": True, - "b__id_size": True, - "a__sk_price": True, - "a__sk_exchange__id": True, - "a__sk_size": True, - "tape_where_trade_occured": True, - - } - - _attributes_to_types = { - "ticker_of_the_object": "str", - "nanosecond_accuracy_s__ip_unix_timestamp": "int", - "nanosecond_accuracy_participant_exchange_unix_timestamp": "int", - "nanosecond_accuracy_t__rf": "int", - "sequence_number": "int", - "c": "List[int]", - "i": "List[int]", - "b__id_price": "int", - "b__id_exchange__id": "int", - "b__id_size": "int", - "a__sk_price": "int", - "a__sk_exchange__id": "int", - "a__sk_size": "int", - "tape_where_trade_occured": "int", - - } - - def __init__(self): - self.ticker_of_the_object: str - self.nanosecond_accuracy_s__ip_unix_timestamp: int - self.nanosecond_accuracy_participant_exchange_unix_timestamp: int - self.nanosecond_accuracy_t__rf: int - self.sequence_number: int - self.c: List[int] - self.i: List[int] - self.b__id_price: int - self.b__id_exchange__id: int - self.b__id_size: int - self.a__sk_price: int - self.a__sk_exchange__id: int - self.a__sk_size: int - self.tape_where_trade_occured: int - - -# noinspection SpellCheckingInspection -class StocksSnapshotAgg(Definition): - _swagger_name_to_python = { - "c": "close_price", - "h": "high_price", - "l": "low_price", - "o": "open_price", - "v": "volume", - - } - - _attribute_is_primitive = { - "close_price": True, - "high_price": True, - "low_price": True, - "open_price": True, - "volume": True, - - } - - _attributes_to_types = { - "close_price": "int", - "high_price": "int", - "low_price": "int", - "open_price": "int", - "volume": "int", - - } - - def __init__(self): - self.close_price: int - self.high_price: int - self.low_price: int - self.open_price: int - self.volume: int - - -# noinspection SpellCheckingInspection -class StocksSnapshotQuote(Definition): - _swagger_name_to_python = { - "p": "bid_price", - "s": "bid_size_in_lots", - "P": "ask_price", - "S": "ask_size_in_lots", - "t": "last_updated_timestamp", - - } - - _attribute_is_primitive = { - "bid_price": True, - "bid_size_in_lots": True, - "ask_price": True, - "ask_size_in_lots": True, - "last_updated_timestamp": True, - - } - - _attributes_to_types = { - "bid_price": "int", - "bid_size_in_lots": "int", - "ask_price": "int", - "ask_size_in_lots": "int", - "last_updated_timestamp": "int", - - } - - def __init__(self): - self.bid_price: int - self.bid_size_in_lots: int - self.ask_price: int - self.ask_size_in_lots: int - self.last_updated_timestamp: int - - -# noinspection SpellCheckingInspection -class Aggv2(Definition): - _swagger_name_to_python = { - "T": "ticker_symbol", - "v": "volume", - "o": "open", - "c": "close", - "h": "high", - "l": "low", - "t": "unix_msec_timestamp", - "n": "number_of_items_in_aggregate_window", - - } - - _attribute_is_primitive = { - "ticker_symbol": True, - "volume": True, - "open": True, - "close": True, - "high": True, - "low": True, - "unix_msec_timestamp": True, - "number_of_items_in_aggregate_window": True, - - } - - _attributes_to_types = { - "ticker_symbol": "str", - "volume": "int", - "open": "int", - "close": "int", - "high": "int", - "low": "int", - "unix_msec_timestamp": "float", - "number_of_items_in_aggregate_window": "float", - - } - - def __init__(self): - self.ticker_symbol: str - self.volume: int - self.open: int - self.close: int - self.high: int - self.low: int - self.unix_msec_timestamp: float - self.number_of_items_in_aggregate_window: float - - -# noinspection SpellCheckingInspection -class AggResponse(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "status": "status", - "adjusted": "adjusted", - "queryCount": "query_count", - "resultsCount": "results_count", - "results": "results", - - } - - _attribute_is_primitive = { - "ticker": True, - "status": True, - "adjusted": True, - "query_count": True, - "results_count": True, - "results": False, - - } - - _attributes_to_types = { - "ticker": "str", - "status": "str", - "adjusted": "bool", - "query_count": "float", - "results_count": "float", - "results": "List[Aggv2]", - - } - - def __init__(self): - self.ticker: str - self.status: str - self.adjusted: bool - self.query_count: float - self.results_count: float - self.results: List[Aggv2] - - -# noinspection SpellCheckingInspection -class ReferenceTickersApiResponse(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - - } - - _attribute_is_primitive = { - "symbol": False, - - } - - _attributes_to_types = { - "symbol": "List[Symbol]", - - } - - def __init__(self): - self.symbol: List[Symbol] - - -# noinspection SpellCheckingInspection -class ReferenceTickersV3ApiResponse(Definition): - _swagger_name_to_python = { - "results": "results", - "status": "status", - "count": "count", - "next_url": "next_url", - } - - _attribute_is_primitive = { - "results": False, - "status": True, - "count": True, - "next_url": True, - } - - _attributes_to_types = { - "results": "List[SymbolV3]", - "status": "str", - "count": "float", - "next_url": "str", - } - - def __init__(self): - self.results: List[SymbolV3] - self.status: str - self.count: float - self.next_url: str - - -# noinspection SpellCheckingInspection -class ReferenceTickerTypesApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "results": True, - - } - - _attributes_to_types = { - "status": "str", - "results": "Dict[str, str]", - - } - - def __init__(self): - self.status: str - self.results: Dict[str, str] - - -# noinspection SpellCheckingInspection -class ReferenceTickerDetailsApiResponse(Definition): - _swagger_name_to_python = { - "company": "company", - - } - - _attribute_is_primitive = { - "company": False, - - } - - _attributes_to_types = { - "company": "Company", - - } - - def __init__(self): - self.company: Company - - -# noinspection SpellCheckingInspection -class ReferenceTickerDetailsV3ApiResponse(Definition): - _swagger_name_to_python = { - "results": "results", - "status": "status", - "count": "count", - } - - _attribute_is_primitive = { - "results": False, - "status": True, - "count": True, - } - - _attributes_to_types = { - "results": "List[CompanyV3]", - "status": "str", - "count": "float", - } - - def __init__(self): - self.results: List[CompanyV3] - self.status: str - self.count: float - - -# noinspection SpellCheckingInspection -class ReferenceTickerNewsApiResponse(Definition): - _swagger_name_to_python = { - "news": "news", - - } - - _attribute_is_primitive = { - "news": False, - - } - - _attributes_to_types = { - "news": "List[News]", - - } - - def __init__(self): - self.news: List[News] - - -# noinspection SpellCheckingInspection -class ReferenceTickerNewsV2ApiResponse(Definition): - _swagger_name_to_python = { - "results": "results", - "next_url": "next_url", - "status": "status", - "count": "count", - } - - _attribute_is_primitive = { - "results": False, - "next_url": True, - "status": True, - "count": True, - } - - _attributes_to_types = { - "results": "List[NewsV2]", - "next_url": "str", - "status": "str", - "count": "float", - } - - def __init__(self): - self.results: List[NewsV2] - self.next_url: str - self.status: str - self.count: float - - -# noinspection SpellCheckingInspection -class ReferenceMarketsApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "results": False, - - } - - _attributes_to_types = { - "status": "str", - "results": "List[Dict[str, str]]", - - } - - def __init__(self): - self.status: str - self.results: List[Dict[str, str]] - - -# noinspection SpellCheckingInspection -class ReferenceLocalesApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "results": False, - - } - - _attributes_to_types = { - "status": "str", - "results": "List[Dict[str, str]]", - - } - - def __init__(self): - self.status: str - self.results: List[Dict[str, str]] - - -# noinspection SpellCheckingInspection -class ReferenceStockSplitsApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "count": "count", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "count": True, - "results": False, - - } - - _attributes_to_types = { - "status": "str", - "count": "float", - "results": "List[Split]", - - } - - def __init__(self): - self.status: str - self.count: float - self.results: List[Split] - - -# noinspection SpellCheckingInspection -class ReferenceStockDividendsApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "count": "count", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "count": True, - "results": False, - - } - - _attributes_to_types = { - "status": "str", - "count": "float", - "results": "List[Dividend]", - - } - - def __init__(self): - self.status: str - self.count: float - self.results: List[Dividend] - - -# noinspection SpellCheckingInspection -class ReferenceStockFinancialsApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "count": "count", - "results": "results", - - } - - _attribute_is_primitive = { - "status": True, - "count": True, - "results": False, - - } - - _attributes_to_types = { - "status": "str", - "count": "float", - "results": "List[Financials]", - - } - - def __init__(self): - self.status: str - self.count: float - self.results: List[Financials] - - -# noinspection SpellCheckingInspection -class ReferenceMarketStatusApiResponse(Definition): - _swagger_name_to_python = { - "marketstatus": "marketstatus", - - } - - _attribute_is_primitive = { - "marketstatus": False, - - } - - _attributes_to_types = { - "marketstatus": "MarketStatus", - - } - - def __init__(self): - self.marketstatus: MarketStatus - - -# noinspection SpellCheckingInspection -class ReferenceMarketHolidaysApiResponse(Definition): - _swagger_name_to_python = { - "marketholiday": "marketholiday", - - } - - _attribute_is_primitive = { - "marketholiday": False, - - } - - _attributes_to_types = { - "marketholiday": "List[MarketHoliday]", - - } - - def __init__(self): - self.marketholiday: List[MarketHoliday] - - -# noinspection SpellCheckingInspection -class StocksEquitiesExchangesApiResponse(Definition): - _swagger_name_to_python = { - "exchange": "exchange", - - } - - _attribute_is_primitive = { - "exchange": False, - - } - - _attributes_to_types = { - "exchange": "List[Exchange]", - - } - - def __init__(self): - self.exchange: List[Exchange] - - -# noinspection SpellCheckingInspection -class StocksEquitiesHistoricTradesApiResponse(Definition): - _swagger_name_to_python = { - "day": "day", - "map": "map", - "msLatency": "ms_latency", - "status": "status", - "symbol": "symbol", - "ticks": "ticks", - - } - - _attribute_is_primitive = { - "day": True, - "map": True, - "ms_latency": True, - "status": True, - "symbol": True, - "ticks": False, - - } - - _attributes_to_types = { - "day": "str", - "map": "Dict[str, str]", - "ms_latency": "int", - "status": "str", - "symbol": "str", - "ticks": "List[Trade]", - - } - - def __init__(self): - self.day: str - self.map: Dict[str, str] - self.ms_latency: int - self.status: str - self.symbol: str - self.ticks: List[Trade] - - -# noinspection SpellCheckingInspection -class HistoricTradesV2ApiResponse(Definition): - _swagger_name_to_python = { - "results_count": "results_count", - "db_latency": "db_latency", - "success": "success", - "ticker": "ticker", - "results": "results", - - } - - _attribute_is_primitive = { - "results_count": True, - "db_latency": True, - "success": True, - "ticker": True, - "results": False, - - } - - _attributes_to_types = { - "results_count": "int", - "db_latency": "int", - "success": "bool", - "ticker": "str", - "results": "List[StocksV2Trade]", - - } - - def __init__(self): - self.results_count: int - self.db_latency: int - self.success: bool - self.ticker: str - self.results: List[StocksV2Trade] - - -# noinspection SpellCheckingInspection -class StocksEquitiesHistoricQuotesApiResponse(Definition): - _swagger_name_to_python = { - "day": "day", - "map": "map", - "msLatency": "ms_latency", - "status": "status", - "symbol": "symbol", - "ticks": "ticks", - - } - - _attribute_is_primitive = { - "day": True, - "map": True, - "ms_latency": True, - "status": True, - "symbol": True, - "ticks": False, - - } - - _attributes_to_types = { - "day": "str", - "map": "Dict[str, str]", - "ms_latency": "int", - "status": "str", - "symbol": "str", - "ticks": "List[Quote]", - - } - - def __init__(self): - self.day: str - self.map: Dict[str, str] - self.ms_latency: int - self.status: str - self.symbol: str - self.ticks: List[Quote] - - -# noinspection SpellCheckingInspection -class HistoricNBboQuotesV2ApiResponse(Definition): - _swagger_name_to_python = { - "results_count": "results_count", - "db_latency": "db_latency", - "success": "success", - "ticker": "ticker", - "results": "results", - - } - - _attribute_is_primitive = { - "results_count": True, - "db_latency": True, - "success": True, - "ticker": True, - "results": False, - - } - - _attributes_to_types = { - "results_count": "int", - "db_latency": "int", - "success": "bool", - "ticker": "str", - "results": "List[StocksV2NBBO]", - - } - - def __init__(self): - self.results_count: int - self.db_latency: int - self.success: bool - self.ticker: str - self.results: List[StocksV2NBBO] - - -# noinspection SpellCheckingInspection -class StocksEquitiesLastTradeForASymbolApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "symbol": "symbol", - "last": "last", - - } - - _attribute_is_primitive = { - "status": True, - "symbol": True, - "last": False, - - } - - _attributes_to_types = { - "status": "str", - "symbol": "str", - "last": "LastTrade", - - } - - def __init__(self): - self.status: str - self.symbol: str - self.last: LastTrade - - -# noinspection SpellCheckingInspection -class StocksEquitiesLastQuoteForASymbolApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "symbol": "symbol", - "last": "last", - - } - - _attribute_is_primitive = { - "status": True, - "symbol": True, - "last": False, - - } - - _attributes_to_types = { - "status": "str", - "symbol": "str", - "last": "LastQuote", - - } - - def __init__(self): - self.status: str - self.symbol: str - self.last: LastQuote - - -# noinspection SpellCheckingInspection -class StocksEquitiesDailyOpenCloseApiResponse(Definition): - _swagger_name_to_python = { - "from": "from_", - "symbol": "symbol", - "open": "open", - "high": "high", - "low": "low", - "close": "close", - "volume": "volume", - "afterHours": "after_hours", - "preMarket": "pre_market", - } - - _attribute_is_primitive = { - "from_": True, - "symbol": True, - "open": True, - "high": True, - "low": True, - "close": True, - "volume": True, - "after_hours": True, - "pre_market": True, - } - - _attributes_to_types = { - "from_": "str", - "symbol": "str", - "open": "float", - "high": "float", - "low": "float", - "close": "float", - "volume": "float", - "after_hours": "float", - "pre_market": "float", - } - - def __init__(self): - self.from_: str - self.symbol: str - self.open: float - self.high: float - self.low: float - self.close: float - self.volume: float - self.after_hours: float - self.pre_market: float - - -# noinspection SpellCheckingInspection -class StocksEquitiesConditionMappingsApiResponse(Definition): - _swagger_name_to_python = { - "conditiontypemap": "conditiontypemap", - - } - - _attribute_is_primitive = { - "conditiontypemap": False, - - } - - _attributes_to_types = { - "conditiontypemap": "ConditionTypeMap", - - } - - def __init__(self): - self.conditiontypemap: ConditionTypeMap - - -# noinspection SpellCheckingInspection -class StocksEquitiesSnapshotAllTickersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[StocksSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[StocksSnapshotTicker] - - -# noinspection SpellCheckingInspection -class StocksEquitiesSnapshotSingleTickerApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "ticker": "ticker", - - } - - _attribute_is_primitive = { - "status": True, - "ticker": False, - - } - - _attributes_to_types = { - "status": "str", - "ticker": "StocksSnapshotTicker", - - } - - def __init__(self): - self.status: str - self.ticker: StocksSnapshotTicker - - -# noinspection SpellCheckingInspection -class StocksEquitiesSnapshotGainersLosersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[StocksSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[StocksSnapshotTicker] - - -# noinspection SpellCheckingInspection -class StocksEquitiesPreviousCloseApiResponse(Definition): - _swagger_name_to_python = { - "aggresponse": "aggresponse", - - } - - _attribute_is_primitive = { - "aggresponse": False, - - } - - _attributes_to_types = { - "aggresponse": "AggResponse", - - } - - def __init__(self): - self.aggresponse: AggResponse - - -# noinspection SpellCheckingInspection -class StocksEquitiesAggregatesApiResponse(Definition): - _swagger_name_to_python = { - "aggresponse": "aggresponse", - - } - - _attribute_is_primitive = { - "aggresponse": False, - - } - - _attributes_to_types = { - "aggresponse": "AggResponse", - - } - - def __init__(self): - self.aggresponse: AggResponse - - -# noinspection SpellCheckingInspection -class StocksEquitiesGroupedDailyApiResponse(Definition): - _swagger_name_to_python = { - "aggresponse": "aggresponse", - - } - - _attribute_is_primitive = { - "aggresponse": False, - - } - - _attributes_to_types = { - "aggresponse": "AggResponse", - - } - - def __init__(self): - self.aggresponse: AggResponse - - -# noinspection SpellCheckingInspection -class CurrenciesAggregatesApiResponse(Definition): - _swagger_name_to_python = { - "aggresponse": "aggresponse", - - } - - _attribute_is_primitive = { - "aggresponse": False, - - } - - _attributes_to_types = { - "aggresponse": "AggResponse", - - } - - def __init__(self): - self.aggresponse: AggResponse - -# noinspection SpellCheckingInspection -class ForexCurrenciesHistoricForexTicksApiResponse(Definition): - _swagger_name_to_python = { - "day": "day", - "map": "map", - "msLatency": "ms_latency", - "status": "status", - "pair": "pair", - "ticks": "ticks", - - } - - _attribute_is_primitive = { - "day": True, - "map": True, - "ms_latency": True, - "status": True, - "pair": True, - "ticks": False, - - } - - _attributes_to_types = { - "day": "str", - "map": "Dict[str, str]", - "ms_latency": "int", - "status": "str", - "pair": "str", - "ticks": "List[Forex]", - - } - - def __init__(self): - self.day: str - self.map: Dict[str, str] - self.ms_latency: int - self.status: str - self.pair: str - self.ticks: List[Forex] - - -# noinspection SpellCheckingInspection -class ForexCurrenciesRealTimeCurrencyConversionApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "from": "from_", - "to": "to_currency_symbol", - "initialAmount": "initial_amount", - "converted": "converted", - "lastTrade": "last_trade", - "symbol": "symbol", - - } - - _attribute_is_primitive = { - "status": True, - "from_": True, - "to_currency_symbol": True, - "initial_amount": True, - "converted": True, - "last_trade": False, - "symbol": True, - - } - - _attributes_to_types = { - "status": "str", - "from_": "str", - "to_currency_symbol": "str", - "initial_amount": "float", - "converted": "float", - "last_trade": "LastForexTrade", - "symbol": "str", - - } - - def __init__(self): - self.status: str - self.from_: str - self.to_currency_symbol: str - self.initial_amount: float - self.converted: float - self.last_trade: LastForexTrade - self.symbol: str - - -# noinspection SpellCheckingInspection -class ForexCurrenciesLastQuoteForACurrencyPairApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "symbol": "symbol", - "last": "last", - - } - - _attribute_is_primitive = { - "status": True, - "symbol": True, - "last": False, - - } - - _attributes_to_types = { - "status": "str", - "symbol": "str", - "last": "LastForexQuote", - - } - - def __init__(self): - self.status: str - self.symbol: str - self.last: LastForexQuote - - -# noinspection SpellCheckingInspection -class ForexCurrenciesGroupedDailyApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "adjusted": "adjusted", - "queryCount": "queryCount", - "resultsCount": "resultsCount", - "results": "results", - } - - _attribute_is_primitive = { - "status": True, - "adjusted": True, - "queryCount": True, - "resultsCount": True, - "results": False, - } - - _attributes_to_types = { - "status": "str", - "adjusted": "bool", - "queryCount": "int", - "resultsCount": "int", - "results": "List[Aggv2]" - } - - def __init__(self): - self.status: str - self.adjusted: bool - self.queryCount: int - self.resultsCount: int - self.results: List[Aggv2] - - -# noinspection SpellCheckingInspection -class ForexCurrenciesPreviousCloseApiResponse(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "status": "status", - "adjusted": "adjusted", - "queryCount": "queryCount", - "resultsCount": "resultsCount", - "results": "results", - } - - _attribute_is_primitive = { - "ticker": True, - "status": True, - "adjusted": True, - "queryCount": True, - "resultsCount": True, - "results": False, - } - - _attributes_to_types = { - "ticker": "str", - "status": "str", - "adjusted": "bool", - "queryCount": "int", - "resultsCount": "int", - "results": "List[Aggv2]" - } - - def __init__(self): - self.ticker: str - self.status: str - self.adjusted: bool - self.queryCount: int - self.resultsCount: int - self.results: List[Aggv2] - - -# noinspection SpellCheckingInspection -class ForexCurrenciesSnapshotAllTickersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[ForexSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[ForexSnapshotTicker] - - -# noinspection SpellCheckingInspection -class ForexCurrenciesSnapshotSingleTickerApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "ticker": "ticker", - } - - _attribute_is_primitive = { - "status": True, - "ticker": False, - } - - _attributes_to_types = { - "status": "str", - "ticker": "ForexSnapshotTicker", - } - - def __init__(self): - self.status: str - self.ticker: ForexSnapshotTicker - - -# noinspection SpellCheckingInspection -class ForexCurrenciesSnapshotGainersLosersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[ForexSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[ForexSnapshotTicker] - - -# noinspection SpellCheckingInspection -class CryptoCryptoExchangesApiResponse(Definition): - _swagger_name_to_python = { - "cryptoexchange": "cryptoexchange", - - } - - _attribute_is_primitive = { - "cryptoexchange": False, - - } - - _attributes_to_types = { - "cryptoexchange": "List[CryptoExchange]", - - } - - def __init__(self): - self.cryptoexchange: List[CryptoExchange] - - -# noinspection SpellCheckingInspection -class CryptoLastTradeForACryptoPairApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "symbol": "symbol", - "last": "last", - "lastAverage": "last_average", - - } - - _attribute_is_primitive = { - "status": True, - "symbol": True, - "last": False, - "last_average": True, - - } - - _attributes_to_types = { - "status": "str", - "symbol": "str", - "last": "CryptoTick", - "last_average": "Dict[str, str]", - - } - - def __init__(self): - self.status: str - self.symbol: str - self.last: CryptoTick - self.last_average: Dict[str, str] - - -# noinspection SpellCheckingInspection -class CryptoDailyOpenCloseApiResponse(Definition): - _swagger_name_to_python = { - "symbol": "symbol", - "isUTC": "is___utc", - "day": "day", - "open": "open", - "close": "close", - "openTrades": "open_trades", - "closingTrades": "closing_trades", - - } - - _attribute_is_primitive = { - "symbol": True, - "is___utc": True, - "day": True, - "open": True, - "close": True, - "open_trades": False, - "closing_trades": False, - - } - - _attributes_to_types = { - "symbol": "str", - "is___utc": "bool", - "day": "str", - "open": "int", - "close": "int", - "open_trades": "List[CryptoTickJson]", - "closing_trades": "List[CryptoTickJson]", - - } - - def __init__(self): - self.symbol: str - self.is___utc: bool - self.day: str - self.open: int - self.close: int - self.open_trades: List[CryptoTickJson] - self.closing_trades: List[CryptoTickJson] - - -# noinspection SpellCheckingInspection -class CryptoHistoricCryptoTradesApiResponse(Definition): - _swagger_name_to_python = { - "day": "day", - "map": "map", - "msLatency": "ms_latency", - "status": "status", - "symbol": "symbol", - "ticks": "ticks", - - } - - _attribute_is_primitive = { - "day": True, - "map": True, - "ms_latency": True, - "status": True, - "symbol": True, - "ticks": False, - - } - - _attributes_to_types = { - "day": "str", - "map": "Dict[str, str]", - "ms_latency": "int", - "status": "str", - "symbol": "str", - "ticks": "List[CryptoTickJson]", - - } - - def __init__(self): - self.day: str - self.map: Dict[str, str] - self.ms_latency: int - self.status: str - self.symbol: str - self.ticks: List[CryptoTickJson] - - -# noinspection SpellCheckingInspection -class CryptoGroupedDailyApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "adjusted": "adjusted", - "queryCount": "queryCount", - "resultsCount": "resultsCount", - "results": "results", - } - - _attribute_is_primitive = { - "status": True, - "adjusted": True, - "queryCount": True, - "resultsCount": True, - "results": False, - } - - _attributes_to_types = { - "status": "str", - "adjusted": "bool", - "queryCount": "int", - "resultsCount": "int", - "results": "List[Aggv2]" - } - - def __init__(self): - self.status: str - self.adjusted: bool - self.queryCount: int - self.resultsCount: int - self.results: List[Aggv2] - - -# noinspection SpellCheckingInspection -class CryptoPreviousCloseApiResponse(Definition): - _swagger_name_to_python = { - "ticker": "ticker", - "status": "status", - "adjusted": "adjusted", - "queryCount": "queryCount", - "resultsCount": "resultsCount", - "results": "results", - } - - _attribute_is_primitive = { - "ticker": True, - "status": True, - "adjusted": True, - "queryCount": True, - "resultsCount": True, - "results": False, - } - - _attributes_to_types = { - "ticker": "str", - "status": "str", - "adjusted": "bool", - "queryCount": "int", - "resultsCount": "int", - "results": "List[Aggv2]" - } - - def __init__(self): - self.ticker: str - self.status: str - self.adjusted: bool - self.queryCount: int - self.resultsCount: int - self.results: List[Aggv2] - -# noinspection SpellCheckingInspection -class CryptoSnapshotAllTickersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[CryptoSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[CryptoSnapshotTicker] - - -# noinspection SpellCheckingInspection -class CryptoSnapshotSingleTickerApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "ticker": "ticker", - - } - - _attribute_is_primitive = { - "status": True, - "ticker": False, - - } - - _attributes_to_types = { - "status": "str", - "ticker": "CryptoSnapshotTicker", - - } - - def __init__(self): - self.status: str - self.ticker: CryptoSnapshotTicker - - -# noinspection SpellCheckingInspection -class CryptoSnapshotSingleTickerFullBookApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "data": "data", - - } - - _attribute_is_primitive = { - "status": True, - "data": False, - - } - - _attributes_to_types = { - "status": "str", - "data": "CryptoSnapshotTickerBook", - - } - - def __init__(self): - self.status: str - self.data: CryptoSnapshotTickerBook - - -# noinspection SpellCheckingInspection -class CryptoSnapshotGainersLosersApiResponse(Definition): - _swagger_name_to_python = { - "status": "status", - "tickers": "tickers", - - } - - _attribute_is_primitive = { - "status": True, - "tickers": False, - - } - - _attributes_to_types = { - "status": "str", - "tickers": "List[CryptoSnapshotTicker]", - - } - - def __init__(self): - self.status: str - self.tickers: List[CryptoSnapshotTicker] - - -StockSymbol = str -ConditionTypeMap = Dict[str, str] -SymbolTypeMap = Dict[str, str] -TickerSymbol = str diff --git a/polygon/rest/models/dividends.py b/polygon/rest/models/dividends.py new file mode 100644 index 00000000..f70adf9f --- /dev/null +++ b/polygon/rest/models/dividends.py @@ -0,0 +1,20 @@ +from typing import Optional +from .shared import DividendType, Frequency +from dataclasses import dataclass + + +@dataclass +class Dividend: + "Dividend contains data for a historical cash dividend, including the ticker symbol, declaration date, ex-dividend date, record date, pay date, frequency, and amount." + cash_amount: Optional[float] = None + declaration_date: Optional[str] = None + dividend_type: Optional[DividendType] = None + ex_dividend_date: Optional[str] = None + frequency: Optional[Frequency] = None + pay_date: Optional[str] = None + record_date: Optional[str] = None + ticker: Optional[str] = None + + @staticmethod + def from_dict(d): + return Dividend(**d) diff --git a/polygon/rest/models/exchanges.py b/polygon/rest/models/exchanges.py new file mode 100644 index 00000000..64527710 --- /dev/null +++ b/polygon/rest/models/exchanges.py @@ -0,0 +1,22 @@ +from typing import Optional +from .shared import AssetClass, Locale, ExchangeType +from dataclasses import dataclass + + +@dataclass +class Exchange: + "Exchange contains data for a condition that Polygon.io uses." + acronym: Optional[str] = None + asset_class: Optional[AssetClass] = None + id: Optional[int] = None + locale: Optional[Locale] = None + mic: Optional[str] = None + name: Optional[str] = None + operating_mic: Optional[str] = None + participant_id: Optional[str] = None + type: Optional[ExchangeType] = None + url: Optional[str] = None + + @staticmethod + def from_dict(d): + return Exchange(**d) diff --git a/polygon/rest/models/markets.py b/polygon/rest/models/markets.py new file mode 100644 index 00000000..85adfa7b --- /dev/null +++ b/polygon/rest/models/markets.py @@ -0,0 +1,52 @@ +from typing import Optional +from dataclasses import dataclass + + +@dataclass +class Currencies: + crypto: Optional[str] = None + fx: Optional[str] = None + + +@dataclass +class Exchanges: + nasdaq: Optional[str] = None + nyse: Optional[str] = None + otc: Optional[str] = None + + +@dataclass +class MarketHoliday: + "MarketHoliday contains data for upcoming market holidays and their open/close times." + close: Optional[str] = None + date: Optional[str] = None + exchange: Optional[str] = None + name: Optional[str] = None + open: Optional[str] = None + status: Optional[str] = None + + @staticmethod + def from_dict(d): + return MarketHoliday(**d) + + +@dataclass +class MarketStatus: + "MarketStatus contains data for the current trading status of the exchanges and overall financial markets." + after_hours: Optional[bool] = None + currencies: Optional[Currencies] = None + early_hours: Optional[bool] = None + exchanges: Optional[Exchanges] = None + market: Optional[str] = None + server_time: Optional[str] = None + + @staticmethod + def from_dict(d): + return MarketStatus( + d.get("afterHours", None), + d.get("currencies", None), + d.get("earlyHours", None), + d.get("exchanges", None), + d.get("market", None), + d.get("serverTime", None), + ) diff --git a/polygon/rest/models/quotes.py b/polygon/rest/models/quotes.py new file mode 100644 index 00000000..a83f0a36 --- /dev/null +++ b/polygon/rest/models/quotes.py @@ -0,0 +1,62 @@ +from typing import Optional, List +from dataclasses import dataclass + + +@dataclass +class Quote: + "Quote contains quote data for a specified ticker symbol." + ask_exchange: Optional[int] = None + ask_price: Optional[float] = None + ask_size: Optional[float] = None + bid_exchange: Optional[int] = None + bid_price: Optional[float] = None + bid_size: Optional[float] = None + conditions: Optional[List[int]] = None + indicators: Optional[List[int]] = None + participant_timestamp: Optional[int] = None + sequence_number: Optional[int] = None + sip_timestamp: Optional[int] = None + tape: Optional[int] = None + trf_timestamp: Optional[int] = None + + @staticmethod + def from_dict(d): + return Quote(**d) + + +@dataclass +class LastQuote: + "LastQuote contains data for the most recent NBBO (Quote) tick for a given stock." + ticker: Optional[str] = None + trf_timestamp: Optional[int] = None + sequence_number: Optional[int] = None + sip_timestamp: Optional[int] = None + participant_timestamp: Optional[int] = None + ask_price: Optional[float] = None + ask_size: Optional[int] = None + ask_exchange: Optional[int] = None + conditions: Optional[List[int]] = None + indicators: Optional[List[int]] = None + bid_price: Optional[float] = None + bid_size: Optional[int] = None + bid_exchange: Optional[int] = None + tape: Optional[int] = None + + @staticmethod + def from_dict(d): + return LastQuote( + ticker=d.get("T", None), + trf_timestamp=d.get("f", None), + sequence_number=d.get("q", None), + sip_timestamp=d.get("t", None), + participant_timestamp=d.get("y", None), + ask_price=d.get("P", None), + ask_size=d.get("S", None), + ask_exchange=d.get("X", None), + conditions=d.get("c", None), + indicators=d.get("i", None), + bid_price=d.get("p", None), + bid_size=d.get("s", None), + bid_exchange=d.get("x", None), + tape=d.get("z", None), + ) diff --git a/polygon/rest/models/shared.py b/polygon/rest/models/shared.py new file mode 100644 index 00000000..c3f0d851 --- /dev/null +++ b/polygon/rest/models/shared.py @@ -0,0 +1,73 @@ +from enum import Enum + + +class Sort(Enum): + ASC = "asc" + DESC = "desc" + + +class Order(Enum): + ASC = "asc" + DESC = "desc" + + +class Locale(Enum): + US = "us" + GLOBAL = "global" + + +class Market(Enum): + STOCKS = "stocks" + CRYPTO = "crypto" + FX = "fx" + + +class AssetClass(Enum): + STOCKS = "stocks" + OPTIONS = "options" + CRYPTO = "crypto" + FX = "fx" + + +class DividendType(Enum): + CD = "CD" + SC = "SC" + LT = "LT" + ST = "ST" + + +class Frequency(Enum): + ONE_TIME = 0 + ANUALLY = 1 + BIANUALLY = 2 + QUARTERLY = 4 + MONTHLY = 12 + + +class DataType(Enum): + DATA_TRADE = "trade" + DATA_BBO = "bbo" + DATA_NBBO = "nbbo" + + +class SIP(Enum): + CTA = "CTA" + UTP = "UTP" + OPRA = "OPRA" + + +class ExchangeType(Enum): + EXCHANGE = "exchange" + TRF = "TRF" + SIP = "SIP" + + +class Direction(Enum): + GAINERS = "gainers" + LOSERS = "losers" + + +class SnapshotMarketType(Enum): + STOCKS = "stocks" + FOREX = "forex" + CRYPTO = "crypto" diff --git a/polygon/rest/models/snapshot.py b/polygon/rest/models/snapshot.py new file mode 100644 index 00000000..4a814d28 --- /dev/null +++ b/polygon/rest/models/snapshot.py @@ -0,0 +1,177 @@ +from dataclasses import dataclass +from typing import Optional, List, Dict +from .aggs import Agg +from .quotes import LastQuote +from .trades import LastTrade + + +@dataclass +class SnapshotMin: + "Most recent minute bar" + accumulated_volume: Optional[float] = None + open: Optional[float] = None + high: Optional[float] = None + low: Optional[float] = None + close: Optional[float] = None + volume: Optional[float] = None + vwap: Optional[float] = None + + @staticmethod + def from_dict(d): + return SnapshotMin( + d.get("ac", None), + d.get("o", None), + d.get("h", None), + d.get("l", None), + d.get("c", None), + d.get("v", None), + d.get("vw", None), + ) + + +@dataclass +class Snapshot: + day: Optional[Agg] = None + last_quote: Optional[LastQuote] = None + last_trade: Optional[LastTrade] = None + min: Optional[SnapshotMin] = None + prev_day: Optional[Agg] = None + ticker: Optional[str] = None + todays_change: Optional[float] = None + todays_change_percent: Optional[float] = None + updated: Optional[int] = None + + @staticmethod + def from_dict(d): + return Snapshot( + d.get("day", None), + d.get("lastQuote", None), + d.get("lastTrade", None), + d.get("min", None), + d.get("prevDay", None), + d.get("ticker", None), + d.get("todaysChange", None), + d.get("todaysChangePercent", None), + d.get("updated", None), + ) + + +@dataclass +class DayOptionContractSnapshot: + change: Optional[float] = None + change_percent: Optional[float] = None + close: Optional[float] = None + high: Optional[float] = None + last_updated: Optional[int] = None + low: Optional[float] = None + open: Optional[float] = None + previous_close: Optional[float] = None + volume: Optional[float] = None + vwap: Optional[float] = None + + @staticmethod + def from_dict(d): + return DayOptionContractSnapshot(**d) + + +@dataclass +class OptionDetails: + 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 + ticker: Optional[str] = None + + @staticmethod + def from_dict(d): + return OptionDetails(**d) + + +@dataclass +class OptionLastQuote: + ask: Optional[float] = None + ask_size: Optional[float] = None + bid: Optional[float] = None + bid_size: Optional[float] = None + last_updated: Optional[int] = None + midpoint: Optional[float] = None + timeframe: Optional[str] = None + + @staticmethod + def from_dict(d): + return OptionLastQuote(**d) + + +@dataclass +class OptionGreeks: + delta: Optional[float] = None + gamma: Optional[float] = None + theta: Optional[float] = None + vega: Optional[float] = None + + @staticmethod + def from_dict(d): + return OptionGreeks(**d) + + +@dataclass +class UnderlyingAsset: + change_to_break_even: Optional[float] = None + last_updated: Optional[int] = None + price: Optional[float] = None + ticker: Optional[str] = None + timeframe: Optional[str] = None + + @staticmethod + def from_dict(d): + return UnderlyingAsset(**d) + + +@dataclass +class OptionContractSnapshot: + break_even_price: Optional[float] = None + day: Optional[Agg] = None + details: Optional[OptionDetails] = None + greeks: Optional[OptionGreeks] = None + implied_volatility: Optional[float] = None + last_quote: Optional[OptionLastQuote] = None + open_interest: Optional[float] = None + underlying_asset: Optional[float] = None + + @staticmethod + def from_dict(d): + return OptionContractSnapshot(**d) + + +@dataclass +class OrderBookQuote: + price: Optional[float] = None + exchange_shares: Optional[Dict[str, float]] = None + + @staticmethod + def from_dict(d): + return OrderBookQuote(**d) + + +@dataclass +class SnapshotTickerFullBook: + ticker: Optional[str] = None + bids: Optional[List[OrderBookQuote]] = None + asks: Optional[List[OrderBookQuote]] = None + bid_count: Optional[float] = None + ask_count: Optional[float] = None + spread: Optional[float] = None + updated: Optional[int] = None + + @staticmethod + def from_dict(d): + return SnapshotTickerFullBook( + d.get("ticker", None), + d.get("bids", None), + d.get("asks", None), + d.get("bidCount", None), + d.get("askCount", None), + d.get("spread", None), + d.get("updated", None), + ) diff --git a/polygon/rest/models/splits.py b/polygon/rest/models/splits.py new file mode 100644 index 00000000..037a3e1e --- /dev/null +++ b/polygon/rest/models/splits.py @@ -0,0 +1,15 @@ +from typing import Optional +from dataclasses import dataclass + + +@dataclass +class Split: + "Split contains data for a historical stock split, including the ticker symbol, the execution date, and the factors of the split ratio." + execution_date: Optional[str] = None + split_from: Optional[int] = None + split_to: Optional[int] = None + ticker: Optional[str] = None + + @staticmethod + def from_dict(d): + return Split(**d) diff --git a/polygon/rest/models/tickers.py b/polygon/rest/models/tickers.py new file mode 100644 index 00000000..a7c2b0ca --- /dev/null +++ b/polygon/rest/models/tickers.py @@ -0,0 +1,116 @@ +from typing import Optional, List +from .shared import Locale, Market, AssetClass +from dataclasses import dataclass + + +@dataclass +class Address: + address1: Optional[str] = None + city: Optional[str] = None + state: Optional[str] = None + + +@dataclass +class Branding: + icon_url: Optional[str] = None + logo_url: Optional[str] = None + + +@dataclass +class Publisher: + favicon_url: Optional[str] = None + homepage_url: Optional[str] = None + logo_url: Optional[str] = None + name: Optional[str] = None + + +@dataclass +class Ticker: + "Ticker contains data for a specified ticker symbol." + active: Optional[bool] = None + cik: Optional[str] = None + composite_figi: Optional[str] = None + currency_name: Optional[str] = None + currency_symbol: Optional[str] = None + base_currency_symbol: Optional[str] = None + base_currency_name: Optional[str] = None + delisted_utc: Optional[str] = None + last_updated_utc: Optional[str] = None + locale: Optional[Locale] = None + market: Optional[Market] = None + name: Optional[str] = None + primary_exchange: Optional[str] = None + share_class_figi: Optional[str] = None + ticker: Optional[str] = None + type: Optional[str] = None + + @staticmethod + def from_dict(d): + return Ticker(**d) + + +@dataclass +class TickerDetails: + "TickerDetails contains data for a specified ticker symbol." + active: Optional[bool] = None + address: Optional[Address] = None + branding: Optional[Branding] = None + cik: Optional[str] = None + composite_figi: Optional[str] = None + currency_name: Optional[str] = None + delisted_utc: Optional[str] = None + description: Optional[str] = None + ticker_root: Optional[str] = None + homepage_url: Optional[str] = None + list_date: Optional[str] = None + locale: Optional[Locale] = None + market: Optional[Market] = None + market_cap: Optional[float] = None + name: Optional[str] = None + phone_number: Optional[str] = None + primary_exchange: Optional[str] = None + share_class_figi: Optional[str] = None + share_class_shares_outstanding: Optional[int] = None + sic_code: Optional[str] = None + sic_description: Optional[str] = None + ticker: Optional[str] = None + total_employees: Optional[int] = None + type: Optional[str] = None + weighted_shares_outstanding: Optional[int] = None + + @staticmethod + def from_dict(d): + return TickerDetails(**d) + + +@dataclass +class TickerNews: + "TickerDetails contains data for news articles relating to a stock ticker symbol." + amp_url: Optional[str] = None + article_url: Optional[str] = None + author: Optional[str] = None + description: Optional[str] = None + id: Optional[str] = None + image_url: Optional[str] = None + keywords: Optional[List[str]] = None + published_utc: Optional[str] = None + publisher: Optional[Publisher] = None + tickers: Optional[List[str]] = None + title: Optional[str] = None + + @staticmethod + def from_dict(d): + return TickerNews(**d) + + +@dataclass +class TickerTypes: + "TickerTypes contains data for ticker types." + asset_class: Optional[AssetClass] = None + code: Optional[str] = None + description: Optional[str] = None + locale: Optional[Locale] = None + + @staticmethod + def from_dict(d): + return TickerTypes(**d) diff --git a/polygon/rest/models/trades.py b/polygon/rest/models/trades.py new file mode 100644 index 00000000..e14cfa0b --- /dev/null +++ b/polygon/rest/models/trades.py @@ -0,0 +1,88 @@ +from typing import Optional, List +from dataclasses import dataclass + + +@dataclass +class Trade: + "Trade contains trade data for a specified ticker symbol." + conditions: Optional[List[int]] = None + correction: Optional[int] = None + exchange: Optional[int] = None + id: Optional[str] = None + participant_timestamp: Optional[int] = None + price: Optional[float] = None + sequence_number: Optional[int] = None + sip_timestamp: Optional[int] = None + size: Optional[float] = None + tape: Optional[int] = None + trf_id: Optional[int] = None + trf_timestamp: Optional[int] = None + + @staticmethod + def from_dict(d): + return Trade(**d) + + +@dataclass +class LastTrade: + ticker: str + trf_timestamp: int + sequence_number: float + sip_timestamp: int + participant_timestamp: int + conditions: List[int] + correction: int + id: str + price: float + trf_id: int + size: float + exchange: int + tape: int + + @staticmethod + def from_dict(d): + return LastTrade( + d.get("T", None), + d.get("f", None), + d.get("q", None), + d.get("t", None), + d.get("y", None), + d.get("c", None), + d.get("e", None), + d.get("i", None), + d.get("p", None), + d.get("r", None), + d.get("s", None), + d.get("x", None), + d.get("z", None), + ) + + +@dataclass +class Last: + conditions: List[int] + exchange: int + price: float + size: float + timestamp: int + + @staticmethod + def from_dict(d): + return Last(**d) + + +@dataclass +class LastTradeCrypto: + last: Last + ticker: str + status: str + request_id: str + + @staticmethod + def from_dict(d): + return LastTradeCrypto( + d.get("last", None), + d.get("symbol", None), + d.get("status", None), + d.get("request_id", None), + ) diff --git a/polygon/rest/models/unmarshal.py b/polygon/rest/models/unmarshal.py deleted file mode 100644 index 720fe7c0..00000000 --- a/polygon/rest/models/unmarshal.py +++ /dev/null @@ -1,9 +0,0 @@ -from typing import Type - -from polygon.rest import models - - -def unmarshal_json(response_type, resp_json) -> Type[models.AnyDefinition]: - obj = models.name_to_class[response_type]() - obj.unmarshal_json(resp_json) - return obj diff --git a/polygon/rest/quotes.py b/polygon/rest/quotes.py new file mode 100644 index 00000000..e602e61f --- /dev/null +++ b/polygon/rest/quotes.py @@ -0,0 +1,63 @@ +from .base import BaseClient +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[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, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[Quote], HTTPResponse]: + """ + Get quotes for a ticker symbol in a given time range. + + :param ticker: The ticker symbol to get quotes for. + :param timestamp: Query by timestamp. Either a date with the format YYYY-MM-DD or a nanosecond timestamp. + :param timestamp_lt: Timestamp less than + :param timestamp_lte: Timestamp less than or equal to + :param timestamp_gt: Timestamp greater than + :param timestamp_gte: Timestamp greater than or equal to + :param limit: Limit the number of results returned, default is 10 and max is 50000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return HTTPResponse object instead of results object + :return: List of quotes + """ + url = f"/v3/quotes/{ticker}" + + return self._paginate( + path=url, + params=self._get_params(self.list_quotes, locals()), + raw=raw, + deserializer=Quote.from_dict, + ) + + def get_last_quote( + self, ticker: str, params: Optional[Dict[str, Any]] = None, raw: bool = False + ) -> Union[LastQuote, HTTPResponse]: + """ + Get the most recent NBBO (Quote) tick for a given stock. + + :param ticker: The ticker symbol of the stock/equity. + :param params: Any additional query params + :param raw: Return HTTPResponse object instead of results object + :return: Last Quote + """ + url = f"/v2/last/nbbo/{ticker}" + + return self._get( + path=url, params=params, deserializer=LastQuote.from_dict, raw=raw + ) diff --git a/polygon/rest/reference.py b/polygon/rest/reference.py new file mode 100644 index 00000000..5082e35b --- /dev/null +++ b/polygon/rest/reference.py @@ -0,0 +1,406 @@ +from .base import BaseClient +from typing import Optional, Any, Dict, List, Union, Iterator +from .models import ( + MarketHoliday, + MarketStatus, + Ticker, + TickerDetails, + TickerNews, + TickerTypes, + Sort, + Order, + AssetClass, + Locale, + Split, + Dividend, + DividendType, + Frequency, + Condition, + DataType, + SIP, + Exchange, +) +from urllib3 import HTTPResponse +from datetime import date + + +class MarketsClient(BaseClient): + def get_market_holidays( + self, params: Optional[Dict[str, Any]] = None, raw: bool = False + ) -> Union[List[MarketHoliday], HTTPResponse]: + """ + Get upcoming market holidays and their open/close times. + + :param params: Any additional query params + :param raw: Return HTTPResponse object instead of results object + :return: List of market holidays + """ + url = "/v1/marketstatus/upcoming" + + return self._get( + path=url, + params=params, + deserializer=MarketHoliday.from_dict, + raw=raw, + result_key="", + ) + + def get_market_status( + self, params: Optional[Dict[str, Any]] = None, raw: bool = False + ) -> Union[MarketStatus, HTTPResponse]: + """ + Get the current trading status of the exchanges and overall financial markets. + + :param params: Any additional query params + :param raw: Return HTTPResponse object instead of results object + :return: Market status + """ + url = "/v1/marketstatus/now" + + return self._get( + path=url, params=params, deserializer=MarketStatus.from_dict, raw=raw + ) + + +class TickersClient(BaseClient): + def list_tickers( + self, + ticker: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + type: Optional[str] = None, + market: Optional[str] = None, + exchange: Optional[str] = None, + cusip: Optional[int] = None, + cik: Optional[int] = None, + date: Optional[str] = None, + active: Optional[bool] = None, + search: 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, + ) -> Union[Iterator[Ticker], HTTPResponse]: + """ + Query all ticker symbols which are supported by Polygon.io. This API currently includes Stocks/Equities, Crypto, and Forex. + + :param ticker: Specify a ticker symbol. Defaults to empty string which queries all tickers. + :param ticker_lt: Ticker less than + :param ticker_lte: Ticker less than or equal to + :param ticker_gt: Ticker greater than + :param ticker_gte: Ticker greater than or equal to + :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. + :param market: Filter by market type. By default all markets are included. + :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. + :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. + :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. + :param date: Specify a point in time to retrieve tickers available on that date. Defaults to the most recent available date. + :param search: Search for terms within the ticker and/or company name. + :param active: Specify if the tickers returned should be actively traded on the queried date. Default is true. + :param limit: Limit the size of the response, default is 100 and max is 1000. + :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. + :param order: The order to sort the results on. Default is asc (ascending). + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of tickers + """ + url = "/v3/reference/tickers" + + return self._paginate( + path=url, + params=self._get_params(self.list_tickers, locals()), + raw=raw, + deserializer=Ticker.from_dict, + ) + + def get_ticker_details( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[TickerDetails, HTTPResponse]: + """ + Get a single ticker supported by Polygon.io. This response will have detailed information about the ticker and the company behind it. + + :param ticker: The ticker symbol of the asset. + :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. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Ticker Details V3 + """ + url = f"/v3/reference/tickers/{ticker}" + + return self._get( + path=url, params=params, deserializer=TickerDetails.from_dict, raw=raw + ) + + def list_ticker_news( + self, + ticker: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + published_utc: Optional[str] = None, + published_utc_lt: Optional[str] = None, + published_utc_lte: Optional[str] = None, + published_utc_gt: Optional[str] = None, + published_utc_gte: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[Iterator[TickerNews], HTTPResponse]: + """ + 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. + + :param ticker: Return results that contain this ticker. + :param published_utc: Return results published on, before, or after this date. + :param limit: Limit the number of results returned, default is 10 and max is 1000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Ticker News + """ + url = "/v2/reference/news" + + return self._paginate( + path=url, + params=self._get_params(self.list_ticker_news, locals()), + raw=raw, + deserializer=TickerNews.from_dict, + ) + + def get_ticker_types( + self, + asset_class: Optional[Union[str, AssetClass]] = None, + locale: Optional[Union[str, Locale]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[TickerTypes], HTTPResponse]: + """ + List all ticker types that Polygon.io has. + + :param asset_class: Filter by asset class. + :param locale: Filter by locale. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Ticker Types + """ + url = "/v3/reference/tickers/types" + + return self._get( + path=url, + params=params, + deserializer=TickerTypes.from_dict, + raw=raw, + result_key="results", + ) + + +class SplitsClient(BaseClient): + def list_splits( + self, + ticker: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_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, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[Iterator[Split], HTTPResponse]: + """ + Get a list of historical stock splits, including the ticker symbol, the execution date, and the factors of the split ratio. + + :param ticker: Return the stock splits that contain this ticker. + :param ticker_lt: Ticker less than + :param ticker_lte: Ticker less than or equal to + :param ticker_gt: Ticker greater than + :param ticker_gte: Ticker greater than or equal to + :param execution_date: Query by execution date with the format YYYY-MM-DD. + :param execution_date_lt: Execution date less than + :param execution_date_lte: Execution date less than or equal to + :param execution_date_gt: Execution date greater than + :param execution_date_gte: Execution date greater than or equal to + :param reverse_split: Query for reverse stock splits. A split ratio where split_from is greater than split_to represents a reverse split. By default this filter is not used. + :param limit: Limit the number of results returned, default is 10 and max is 1000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of splits + """ + url = "/v3/reference/splits" + + return self._paginate( + path=url, + params=self._get_params(self.list_splits, locals()), + raw=raw, + deserializer=Split.from_dict, + ) + + +class DividendsClient(BaseClient): + def list_dividends( + self, + ticker: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_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, + cash_amount_lte: Optional[float] = None, + cash_amount_gt: Optional[float] = None, + cash_amount_gte: Optional[float] = None, + dividend_type: Optional[Union[str, DividendType]] = 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, + ) -> Union[Iterator[Dividend], HTTPResponse]: + """ + Get a list of historical cash dividends, including the ticker symbol, declaration date, ex-dividend date, record date, pay date, frequency, and amount. + + :param ticker: Return the dividends that contain this ticker. + :param ticker_lt: Ticker less than + :param ticker_lte: Ticker less than or equal to + :param ticker_gt: Ticker greater than + :param ticker_gte: Ticker greater than or equal to + :param ex_dividend_date: Query by ex-dividend date with the format YYYY-MM-DD. + :param ex_dividend_date_lt: Ex-dividend date less than + :param ex_dividend_date_lte: Ex-dividend date less than or equal to + :param ex_dividend_date_gt: Ex-dividend date greater than + :param ex_dividend_date_gte: Ex-dividend date greater than or equal to + :param record_date: Query by record date with the format YYYY-MM-DD. + :param record_date_lt: Record date less than + :param record_date_lte: Record date less than or equal to + :param record_date_gt: Record date greater than + :param record_date_gte: Record date greater than or equal to + :param declaration_date: Query by declaration date with the format YYYY-MM-DD. + :param declaration_date_lt: Declaration date less than + :param declaration_date_lte: Declaration date less than or equal to + :param declaration_date_gt: Declaration date greater than + :param declaration_date_gte: Declaration date greater than or equal to + :param pay_date: Query by pay date with the format YYYY-MM-DD. + :param pay_date_lt: Pay date less than + :param pay_date_lte: Pay date less than or equal to + :param pay_date_gt: Pay date greater than + :param pay_date_gte: Pay date greater than or equal to + :param frequency: Query by the number of times per year the dividend is paid out. Possible values are 0 (one-time), 1 (annually), 2 (bi-annually), 4 (quarterly), and 12 (monthly). + :param cash_amount: Query by the cash amount of the dividend. + :param dividend_type: Query by the type of dividend. Dividends that have been paid and/or are expected to be paid on consistent schedules are denoted as CD. Special Cash dividends that have been paid that are infrequent or unusual, and/or can not be expected to occur in the future are denoted as SC. + :param limit: Limit the number of results returned, default is 10 and max is 1000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of dividends + """ + url = "/v3/reference/dividends" + + return self._paginate( + path=url, + params=self._get_params(self.list_dividends, locals()), + raw=raw, + deserializer=Dividend.from_dict, + ) + + +class ConditionsClient(BaseClient): + def list_conditions( + self, + asset_class: Optional[Union[str, AssetClass]] = None, + data_type: Optional[Union[str, DataType]] = None, + id: Optional[int] = None, + sip: Optional[Union[str, SIP]] = 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, + ) -> Union[Iterator[Condition], HTTPResponse]: + """ + List all conditions that Polygon.io uses. + + :param asset_class: Filter for conditions within a given asset class. + :param data_type: Data types that this condition applies to. + :param id: Filter for conditions with a given ID. + :param sip: Filter by SIP. If the condition contains a mapping for that SIP, the condition will be returned. + :param limit: Limit the number of results returned, default is 10 and max is 1000. + :param sort: Sort field used for ordering. + :param order: Order results based on the sort field. + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: List of conditions + """ + url = "/v3/reference/conditions" + + return self._paginate( + path=url, + params=self._get_params(self.list_conditions, locals()), + raw=raw, + deserializer=Condition.from_dict, + ) + + +class ExchangesClient(BaseClient): + def get_exchanges( + self, + asset_class: Optional[Union[str, AssetClass]] = None, + locale: Optional[Union[str, Locale]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[Exchange], HTTPResponse]: + """ + List all exchanges that Polygon.io knows about. + + :param asset_class: Filter by asset class. + :param locale: Filter by locale. + :param params: Any additional query params + :param raw: Return HTTPResponse object instead of results object + :return: List of exchanges + """ + url = "/v3/reference/exchanges" + + return self._get( + path=url, + params=params, + deserializer=Exchange.from_dict, + raw=raw, + result_key="results", + ) diff --git a/polygon/rest/snapshot.py b/polygon/rest/snapshot.py new file mode 100644 index 00000000..2aa5eefa --- /dev/null +++ b/polygon/rest/snapshot.py @@ -0,0 +1,137 @@ +from .base import BaseClient +from typing import Optional, Any, Dict, List, Union +from .models import ( + Snapshot, + Direction, + OptionContractSnapshot, + SnapshotMarketType, + SnapshotTickerFullBook, +) +from urllib3 import HTTPResponse + + +class SnapshotClient(BaseClient): + def get_snapshot_all( + self, + market_type: Optional[Union[str, SnapshotMarketType]] = "stocks", + tickers: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[Snapshot], HTTPResponse]: + """ + Get the most up-to-date market data for all traded stock symbols. + + Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. This can happen as early as 4am EST. + + :param market_type: Which market to get a snapshot of. + :param tickers: A comma separated list of tickers to get snapshots for. + :return: List of Snapshots + """ + url = f"/v2/snapshot/locale/us/markets/{market_type}/tickers" + if type(tickers) is list: + tickers = ",".join(tickers) + return self._get( + path=url, + params=self._get_params(self.get_snapshot_all, locals()), + deserializer=Snapshot.from_dict, + raw=raw, + result_key="tickers", + ) + + def get_snapshot_direction( + self, + direction: Union[str, Direction], + market_type: Optional[Union[str, SnapshotMarketType]] = "stocks", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[List[Snapshot], HTTPResponse]: + """ + Get the most up-to-date market data for the current top 20 gainers or losers of the day in the stocks/equities markets. + + Top gainers are those tickers whose price has increased by the highest percentage since the previous day's close. Top losers are those tickers whose price has decreased by the highest percentage since the previous day's close. + + Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. + + :param market_type: Which market to get a snapshot of. + :param direction: The direction ("gainers" or "losers") + :return: List of Snapshots + """ + url = f"/v2/snapshot/locale/us/markets/{market_type}/{direction}" + return self._get( + path=url, + params=self._get_params(self.get_snapshot_direction, locals()), + result_key="tickers", + deserializer=Snapshot.from_dict, + raw=raw, + ) + + def get_snapshot_ticker( + self, + ticker: str, + market_type: Optional[Union[str, SnapshotMarketType]] = "stocks", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[Snapshot, HTTPResponse]: + """ + Get the most up-to-date market data for all traded stock symbols. + + Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. This can happen as early as 4am EST. + + :param market_type: Which market to get a snapshot of. + :param ticker: The ticker symbol. + :return: List of Snapshots + """ + url = f"/v2/snapshot/locale/us/markets/{market_type}/tickers/{ticker}" + return self._get( + path=url, + params=self._get_params(self.get_snapshot_ticker, locals()), + result_key="ticker", + deserializer=Snapshot.from_dict, + raw=raw, + ) + + def get_snapshot_option( + self, + underlying_asset: str, + option_contract: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> 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}/{option_contract}" + return self._get( + path=url, + params=self._get_params(self.get_snapshot_option, locals()), + result_key="results", + deserializer=OptionContractSnapshot.from_dict, + raw=raw, + ) + + def get_snapshot_crypto_book( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[SnapshotTickerFullBook, HTTPResponse]: + """ + Get the current level 2 book of a single ticker. This is the combined book from all of the exchanges. + + Note: Snapshot data is cleared at 12am EST and gets populated as data is received from the exchanges. + + :param ticker: The ticker symbol. + :return: List of Snapshots + """ + url = f"/v2/snapshot/locale/global/markets/crypto/tickers/{ticker}/book" + return self._get( + path=url, + params=self._get_params(self.get_snapshot_crypto_book, locals()), + result_key="data", + deserializer=SnapshotTickerFullBook.from_dict, + raw=raw, + ) diff --git a/polygon/rest/trades.py b/polygon/rest/trades.py new file mode 100644 index 00000000..89dd24eb --- /dev/null +++ b/polygon/rest/trades.py @@ -0,0 +1,94 @@ +from .base import BaseClient +from typing import Optional, Any, Dict, Union, Iterator +from .models import Trade, LastTrade, LastTradeCrypto, Sort, Order +from urllib3 import HTTPResponse +from datetime import datetime, date + + +class TradesClient(BaseClient): + def list_trades( + self, + ticker: str, + 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, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[Iterator[Trade], HTTPResponse]: + """ + Get trades for a ticker symbol in a given time range. + + :param ticker: The ticker symbol. + :param timestamp: Either a date with the format YYYY-MM-DD or a nanosecond timestamp. + :param timestamp_lt: Timestamp less than + :param timestamp_lte: Timestamp less than or equal to + :param timestamp_gt: Timestamp greater than + :param timestamp_gte: Timestamp greater than or equal to + :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. + :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 order: Order results based on the sort field + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Iterator of trades + """ + url = f"/v3/trades/{ticker}" + + return self._paginate( + path=url, + params=self._get_params(self.list_trades, locals()), + raw=raw, + deserializer=Trade.from_dict, + ) + + def get_last_trade( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[LastTrade, HTTPResponse]: + """ + Get the most recent trade for a ticker. + + :param ticker: The ticker symbol of the asset + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Last trade + """ + url = f"/v2/last/trade/{ticker}" + + return self._get( + path=url, + params=self._get_params(self.get_last_trade, locals()), + result_key="results", + deserializer=LastTrade.from_dict, + raw=raw, + ) + + def get_last_trade_crypto( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + ) -> Union[LastTrade, HTTPResponse]: + """ + Get the most recent trade for a ticker. + + :param ticker: The ticker symbol of the asset + :param params: Any additional query params + :param raw: Return raw object instead of results object + :return: Last trade + """ + url = f"/v1/last/crypto/{from_}/{to}" + + return self._get( + path=url, + params=self._get_params(self.get_last_trade_crypto, locals()), + deserializer=LastTradeCrypto.from_dict, + raw=raw, + ) diff --git a/polygon/websocket/__init__.py b/polygon/websocket/__init__.py deleted file mode 100644 index a0f9603a..00000000 --- a/polygon/websocket/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .websocket_client import WebSocketClient, STOCKS_CLUSTER, FOREX_CLUSTER, CRYPTO_CLUSTER diff --git a/polygon/websocket/websocket_client.py b/polygon/websocket/websocket_client.py deleted file mode 100644 index 3c046485..00000000 --- a/polygon/websocket/websocket_client.py +++ /dev/null @@ -1,111 +0,0 @@ -import signal -import threading -from typing import Optional, Callable - -import websocket - -STOCKS_CLUSTER = "stocks" -FOREX_CLUSTER = "forex" -CRYPTO_CLUSTER = "crypto" - - -class WebSocketClient: - DEFAULT_HOST = "socket.polygon.io" - - # TODO: Either an instance of the client couples 1:1 with the cluster or an instance of the Client couples 1:3 with - # the 3 possible clusters (I think I like client per, but then a problem is the user can make multiple clients for - # the same cluster and that's not desirable behavior, - # somehow keeping track with multiple Client instances will be the difficulty) - def __init__(self, cluster: str, auth_key: str, process_message: Optional[Callable[[str], None]] = None, - on_close: Optional[Callable[[websocket.WebSocketApp], None]] = None, - on_error: Optional[Callable[[websocket.WebSocketApp, str], None]] = None): - self._host = self.DEFAULT_HOST - self.url = f"wss://{self._host}/{cluster}" - self.ws: websocket.WebSocketApp = websocket.WebSocketApp(self.url, on_open=self._default_on_open(), - on_close=self._default_on_close, - on_error=self._default_on_error, - on_message=self._default_on_message()) - self.auth_key = auth_key - - self.process_message = process_message - self.ws.on_close = on_close - self.ws.on_error = on_error - - # being authenticated is an event that must occur before any other action is sent to the server - self._authenticated = threading.Event() - # self._run_thread is only set if the client is run asynchronously - self._run_thread: Optional[threading.Thread] = None - - # TODO: this probably isn't great design. - # If the user defines their own signal handler then this will gets overwritten. - # We still need to make sure that killing, terminating, interrupting the program closes the connection - signal.signal(signal.SIGINT, self._cleanup_signal_handler()) - signal.signal(signal.SIGTERM, self._cleanup_signal_handler()) - - def run(self): - self.ws.run_forever() - - def run_async(self): - self._run_thread = threading.Thread(target=self.run) - self._run_thread.start() - - def close_connection(self): - self.ws.close() - if self._run_thread: - self._run_thread.join() - - def subscribe(self, *params): - # TODO: make this a decorator or context manager - self._authenticated.wait() - - sub_message = '{"action":"subscribe","params":"%s"}' % self._format_params(params) - self.ws.send(sub_message) - - def unsubscribe(self, *params): - # TODO: make this a decorator or context manager - self._authenticated.wait() - - sub_message = '{"action":"unsubscribe","params":"%s"}' % self._format_params(params) - self.ws.send(sub_message) - - def _cleanup_signal_handler(self): - return lambda signalnum, frame: self.close_connection() - - def _authenticate(self, ws): - ws.send('{"action":"auth","params":"%s"}' % self.auth_key) - self._authenticated.set() - - @staticmethod - def _format_params(params): - return ",".join(params) - - @property - def process_message(self): - return self.__process_message - - @process_message.setter - def process_message(self, pm): - if pm: - self.__process_message = pm - self.ws.on_message = lambda ws, message: self.__process_message(message) - - def _default_on_message(self): - return lambda ws, message: self._default_process_message(message) - - @staticmethod - def _default_process_message(message): - print(message) - - def _default_on_open(self): - def f(ws): - self._authenticate(ws) - - return f - - @staticmethod - def _default_on_error(ws, error): - print("error:", error) - - @staticmethod - def _default_on_close(ws): - print("### closed ###") diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..26207f9f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[tool.poetry] +name = "client-python" +version = "0.3.0" +description = "Official Polygon.io REST and Websocket client." +authors = ["polygon.io"] +license = "MIT" +homepage = "https://polygon.io" +repository = "https://github.com/polygon-io/client-python" +documentation = "https://polygon.io/docs" +keywords = [ + "polygon", + "free", + "rest", + "stock", + "market", + "data", + "api", + "polygon.io", + "websocket", + "client" +] + +[tool.poetry.dependencies] +python = "^3.7" +urllib3 = "^1.26.9" + +[tool.poetry.dev-dependencies] +black = "^22.3.0" +mypy = "^0.942" +types-urllib3 = "^1.26.13" +httpretty = "^1.1.4" +Sphinx = "^4.5.0" +sphinx-rtd-theme = "^1.0.0" +# keep this in sync with docs/requirements.txt for readthedocs.org +sphinx-autodoc-typehints = "^1.18.1" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a62a3359..00000000 --- a/requirements.txt +++ /dev/null @@ -1,19 +0,0 @@ -atomicwrites>=1.3.0 -attrs>=19.3.0 -certifi>=2019.9.11 -chardet>=3.0.4 -idna>=2.8 -importlib-metadata>=0.23 -more-itertools>=7.2.0 -packaging>=19.2 -pluggy>=0.13.0 -py>=1.8.0 -pyparsing>=2.4.4 -pytest>=5.2.2 -requests>=2.22.0 -six>=1.13.0 -urllib3>=1.25.6 -wcwidth>=0.1.7 -websocket-client>=0.56.0 -websockets>=8.0.2 -zipp>=0.6.0 diff --git a/rest-example.py b/rest-example.py index a517db12..b2bca0cc 100644 --- a/rest-example.py +++ b/rest-example.py @@ -1,28 +1,10 @@ -import datetime - from polygon import RESTClient +from polygon.rest.models import Sort +from datetime import date, datetime +client = RESTClient(verbose=True) -def ts_to_datetime(ts) -> str: - return datetime.datetime.fromtimestamp(ts / 1000.0).strftime('%Y-%m-%d %H:%M') - - -def main(): - key = "your api key" - - # RESTClient can be used as a context manager to facilitate closing the underlying http session - # https://requests.readthedocs.io/en/master/user/advanced/#session-objects - with RESTClient(key) as client: - from_ = "2019-01-01" - to = "2019-02-01" - resp = client.stocks_equities_aggregates("AAPL", 1, "minute", from_, to, unadjusted=False) - - print(f"Minute aggregates for {resp.ticker} between {from_} and {to}.") - - for result in resp.results: - dt = ts_to_datetime(result["t"]) - print(f"{dt}\n\tO: {result['o']}\n\tH: {result['h']}\n\tL: {result['l']}\n\tC: {result['c']} ") - - -if __name__ == '__main__': - main() \ No newline at end of file +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) diff --git a/setup.py b/setup.py deleted file mode 100644 index 45095315..00000000 --- a/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup, find_packages - -import os -import sys - -version = os.getenv("VERSION") -if not version: - print("no version supplied") - sys.exit(1) - -def get_readme_md_contents(): - """read the contents of your README file""" - with open("README.md", encoding='utf-8') as f: - long_description = f.read() - return long_description - -setup( - name="polygon-api-client", - version=version, - description="Polygon API client", - long_description=get_readme_md_contents(), - long_description_content_type="text/markdown", - author_email="support@polygon.io", - url="https://github.com/polygon-io/client-python", - packages=find_packages(), - classifiers=[ - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Operating System :: OS Independent", - "Topic :: Office/Business :: Financial :: Investment" - ], - install_requires=[ - "websocket-client>=0.56.0", - "websockets>=8.0.2", - "requests>=2.22.0" - ] -) diff --git a/tests/mocks.py b/tests/mocks.py new file mode 100644 index 00000000..6a6491ae --- /dev/null +++ b/tests/mocks.py @@ -0,0 +1,110 @@ +from polygon import RESTClient +import unittest +import httpretty # type: ignore + +mocks = [ + ( + "/v2/aggs/ticker/AAPL/range/1/day/2005-04-01/2005-04-04", + '{"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}', + ), + ( + "/v2/aggs/grouped/locale/us/market/stocks/2005-04-04?adjusted=True", + '{"queryCount":1,"resultsCount":1,"adjusted": true,"results": [{"T":"GIK","v":895345,"vw":9.9979,"o":9.99,"c":10.02,"h":10.02,"l":9.9,"t":1602705600000,"n":96}],"status":"OK","request_id":"eae3ded2d6d43f978125b7a8a609fad9","count":1}', + ), + ( + "/v1/open-close/AAPL/2005-04-01?adjusted=True", + '{"status": "OK","from": "2021-04-01","symbol": "AAPL","open": 123.66,"high": 124.18,"low": 122.49,"close": 123,"volume": 75089134,"afterHours": 123,"preMarket": 123.45}', + ), + ( + "/v2/aggs/ticker/AAPL/prev", + '{"ticker":"AAPL","queryCount":1,"resultsCount":1,"adjusted":true,"results":[{"T":"AAPL","v":9.5595226e+07,"vw":158.6074,"o":162.25,"c":156.8,"h":162.34,"l":156.72,"t":1651003200000,"n":899965}],"status":"OK","request_id":"5e5378d5ecaf3df794bb52e45d015d2e","count":1}', + ), + ( + "/v3/reference/tickers", + '{"results":[{"ticker":"A","name":"Agilent Technologies Inc.","market":"stocks","locale":"us","primary_exchange":"XNYS","type":"CS","active":true,"currency_name":"usd","cik":"0001090872","composite_figi":"BBG000C2V3D6","share_class_figi":"BBG001SCTQY4","last_updated_utc":"2022-04-27T00:00:00Z"},{"ticker":"AA","name":"Alcoa Corporation","market":"stocks","locale":"us","primary_exchange":"XNYS","type":"CS","active":true,"currency_name":"usd","cik":"0001675149","composite_figi":"BBG00B3T3HD3","share_class_figi":"BBG00B3T3HF1","last_updated_utc":"2022-04-27T00:00:00Z"}],"status":"OK","request_id":"37089bb3b4ef99a796cdc82ff971e447","count":2,"next_url":"https://api.polygon.io/v3/reference/tickers?cursor=YWN0aXZlPXRydWUmZGF0ZT0yMDIyLTA0LTI3JmxpbWl0PTImb3JkZXI9YXNjJnBhZ2VfbWFya2VyPUFBJTdDZjEyMmJjYmY4YWQwNzRmZmJlMTZmNjkxOWQ0ZDc3NjZlMzA3MWNmNmU1Nzg3OGE0OGU1NjQ1YzQyM2U3NzJhOSZzb3J0PXRpY2tlcg"}', + ), + ( + "/v3/reference/tickers?cursor=YWN0aXZlPXRydWUmZGF0ZT0yMDIyLTA0LTI3JmxpbWl0PTImb3JkZXI9YXNjJnBhZ2VfbWFya2VyPUFBJTdDZjEyMmJjYmY4YWQwNzRmZmJlMTZmNjkxOWQ0ZDc3NjZlMzA3MWNmNmU1Nzg3OGE0OGU1NjQ1YzQyM2U3NzJhOSZzb3J0PXRpY2tlcg", + '{"results":[{"ticker":"AAA","name":"AAF First Priority CLO Bond ETF","market":"stocks","locale":"us","primary_exchange":"ARCX","type":"ETF","active":true,"currency_name":"usd","composite_figi":"BBG00X5FSP48","share_class_figi":"BBG00X5FSPZ4","last_updated_utc":"2022-04-27T00:00:00Z"},{"ticker":"AAAU","name":"Goldman Sachs Physical Gold ETF Shares","market":"stocks","locale":"us","primary_exchange":"BATS","type":"ETF","active":true,"currency_name":"usd","cik":"0001708646","composite_figi":"BBG00LPXX872","share_class_figi":"BBG00LPXX8Z1","last_updated_utc":"2022-04-27T00:00:00Z"}],"status":"OK","request_id":"40d60d83fa0628503b4d13387b7bde2a","count":2}', + ), + ( + "/v3/reference/tickers/AAPL", + '{"ticker":"AAPL","name":"Apple Inc.","market":"stocks","locale":"us","primary_exchange":"XNAS","type":"CS","active":true,"currency_name":"usd","cik":"0000320193","composite_figi":"BBG000B9XRY4","share_class_figi":"BBG001S5N8V8","market_cap":2.6714924917e+12,"phone_number":"(408) 996-1010","address":{"address1":"ONE APPLE PARK WAY","city":"CUPERTINO","state":"CA","postal_code":"95014"},"description":"Apple designs a wide variety of consumer electronic devices, including smartphones (iPhone), tablets (iPad), PCs (Mac), smartwatches (Apple Watch), AirPods, and TV boxes (Apple TV), among others. The iPhone makes up the majority of Apples total revenue. In addition, Apple offers its customers a variety of services such as Apple Music, iCloud, Apple Care, Apple TV+, Apple Arcade, Apple Card, and Apple Pay, among others. Apples products run internally developed software and semiconductors, and the firm is well known for its integration of hardware, software and services. Apples products are distributed online as well as through company-owned stores and third-party retailers. The company generates roughly 40 of its revenue from the Americas, with the remainder earned internationally.","sic_code":"3571","sic_description":"ELECTRONIC COMPUTERS","ticker_root":"AAPL","homepage_url":"https://www.apple.com","total_employees":154000,"list_date":"1980-12-12","branding":{"logo_url":"https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-02-01_logo.svg","icon_url":"https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-02-01_icon.png"},"share_class_shares_outstanding":16319440000,"weighted_shares_outstanding":16319441000}', + ), + ( + "/v2/reference/news?ticker=NFLX", + '{"results":[{"id":"JeJEhAVoKaqJ2zF9nzQYMg07UlEeWlis6Dsop33TPQY","publisher":{"name":"MarketWatch","homepage_url":"https://www.marketwatch.com/","logo_url":"https://s3.polygon.io/public/assets/news/logos/marketwatch.svg","favicon_url":"https://s3.polygon.io/public/assets/news/favicons/marketwatch.ico"},"title":"Theres a big hole in the Feds theory of inflation—incomes are falling at a record 10.9 rate","author":"MarketWatch","published_utc":"2022-04-28T17:08:00Z","article_url":"https://www.marketwatch.com/story/theres-a-big-hole-in-the-feds-theory-of-inflationincomes-are-falling-at-a-record-10-9-rate-11651165705","tickers":["MSFT","TSN","NFLX","AMZN"],"amp_url":"https://www.marketwatch.com/amp/story/theres-a-big-hole-in-the-feds-theory-of-inflationincomes-are-falling-at-a-record-10-9-rate-11651165705","image_url":"https://images.mktw.net/im-533637/social","description":"If inflation is all due to an overly generous federal government giving its people too much money, then our inflation problem is about to go away."}],"status":"OK","request_id":"f5248459196e12f27520afd41cee5126","count":10}', + ), + ( + "/v3/reference/tickers/types", + '{"results":[{"code":"CS","description":"Common Stock","asset_class":"stocks","locale":"us"},{"code":"PFD","description":"Preferred Stock","asset_class":"stocks","locale":"us"},{"code":"WARRANT","description":"Warrant","asset_class":"stocks","locale":"us"},{"code":"RIGHT","description":"Rights","asset_class":"stocks","locale":"us"},{"code":"BOND","description":"Corporate Bond","asset_class":"stocks","locale":"us"},{"code":"ETF","description":"Exchange Traded Fund","asset_class":"stocks","locale":"us"},{"code":"ETN","description":"Exchange Traded Note","asset_class":"stocks","locale":"us"},{"code":"SP","description":"Structured Product","asset_class":"stocks","locale":"us"},{"code":"ADRC","description":"American Depository Receipt Common","asset_class":"stocks","locale":"us"},{"code":"ADRW","description":"American Depository Receipt Warrants","asset_class":"stocks","locale":"us"},{"code":"ADRR","description":"American Depository Receipt Rights","asset_class":"stocks","locale":"us"},{"code":"FUND","description":"Fund","asset_class":"stocks","locale":"us"},{"code":"BASKET","description":"Basket","asset_class":"stocks","locale":"us"},{"code":"UNIT","description":"Unit","asset_class":"stocks","locale":"us"},{"code":"LT","description":"Liquidating Trust","asset_class":"stocks","locale":"us"}],"status":"OK","request_id":"efbfc7c2304bba6c2f19a2567f568134","count":15}', + ), + ( + "/v2/last/trade/AAPL", + '{"results":{"c":[12,37],"i":"237688","p":166.25,"s":2,"x":4,"r":202,"z":3,"T":"AAPL","t":1651179319310617300,"y":1651179319308000000,"f":1651179319310588400,"q":7084210},"status":"OK","request_id":"d4bafa50e72cf9ed19ac538ae1a3185a"}', + ), + ( + "/v1/last/crypto/BTC/USD", + '{"last":{"conditions":[2],"exchange":2,"price":39976.89682331,"size":0.005,"timestamp":1651180409688},"request_id":"d67c9bfe1fa0c29db9177d78b3ab713c","status":"success","symbol":"BTC-USD"}', + ), + ( + "/v3/trades/AAPL?limit=2", + '{"results":[{"conditions":[12,37],"correction":1,"exchange":11,"id":"183276","participant_timestamp":1651181822461636600,"price":156.43,"sequence_number":7179341,"sip_timestamp":1651181822461979400,"size":10,"tape":3,"trf_id":3,"trf_timestamp":1651181557090806500},{"conditions":[12,37],"correction":1,"exchange":12,"id":"183276","participant_timestamp":1651181822461636600,"price":157.43,"sequence_number":7179341,"sip_timestamp":1651181822461979400,"size":10,"tape":3,"trf_id":3,"trf_timestamp":1651181557090806500}],"status":"OK","request_id":"756f9910624b35a47eb07f21a7a373bb"}', + ), + ( + "/v1/marketstatus/upcoming", + '[{"exchange":"NYSE","name":"Memorial Day","date":"2022-05-30","status":"closed"},{"exchange":"NASDAQ","name":"Memorial Day","date":"2022-05-30","status":"closed"},{"exchange":"NASDAQ","name":"Juneteenth","date":"2022-06-20","status":"closed"},{"exchange":"NYSE","name":"Juneteenth","date":"2022-06-20","status":"closed"},{"exchange":"NYSE","name":"Independence Day","date":"2022-07-04","status":"closed"},{"exchange":"NASDAQ","name":"Independence Day","date":"2022-07-04","status":"closed"},{"exchange":"NYSE","name":"Labor Day","date":"2022-09-05","status":"closed"},{"exchange":"NASDAQ","name":"Labor Day","date":"2022-09-05","status":"closed"},{"exchange":"NYSE","name":"Thanksgiving","date":"2022-11-24","status":"closed"},{"exchange":"NASDAQ","name":"Thanksgiving","date":"2022-11-24","status":"closed"},{"exchange":"NYSE","name":"Thanksgiving","date":"2022-11-25","status":"early-close","open":"2022-11-25T14:30:00.000Z","close":"2022-11-25T18:00:00.000Z"},{"exchange":"NASDAQ","name":"Thanksgiving","date":"2022-11-25","status":"early-close","open":"2022-11-25T14:30:00.000Z","close":"2022-11-25T18:00:00.000Z"},{"exchange":"NYSE","name":"Christmas","date":"2022-12-26","status":"closed"},{"exchange":"NASDAQ","name":"Christmas","date":"2022-12-26","status":"closed"}]', + ), + ( + "/v1/marketstatus/now", + '{"market":"extended-hours","earlyHours":false,"afterHours":true,"serverTime":"2022-04-28T16:48:08-04:00","exchanges":{"nyse":"extended-hours","nasdaq":"extended-hours","otc":"extended-hours"},"currencies":{"fx":"open","crypto":"open"}}', + ), + ( + "/v3/reference/splits", + '{"results":[{"execution_date":"2022-07-18","split_from":1,"split_to":20,"ticker":"GOOGL"},{"execution_date":"2022-07-18","split_from":1,"split_to":20,"ticker":"GOOG"},{"execution_date":"2022-07-01","split_from":1,"split_to":3,"ticker":"CTO"},{"execution_date":"2022-06-29","split_from":1,"split_to":10,"ticker":"SHOP"},{"execution_date":"2022-06-22","split_from":1,"split_to":10,"ticker":"SHOP"},{"execution_date":"2022-06-10","split_from":1,"split_to":4,"ticker":"DXCM"},{"execution_date":"2022-06-06","split_from":1,"split_to":20,"ticker":"AMZN"},{"execution_date":"2022-05-20","split_from":2,"split_to":1,"ticker":"BRW"},{"execution_date":"2022-05-16","split_from":1,"split_to":2,"ticker":"CM"},{"execution_date":"2022-05-02","split_from":3,"split_to":4,"ticker":"CIG.C"}],"status":"OK","request_id":"b52de486daf5491e6b9ebdf5e0bf65bc"}', + ), + ( + "/v3/reference/dividends", + '{"results":[{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2025-06-12","frequency":4,"pay_date":"2025-06-30","record_date":"2025-06-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2025-03-13","frequency":4,"pay_date":"2025-03-31","record_date":"2025-03-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2024-12-12","frequency":4,"pay_date":"2024-12-31","record_date":"2024-12-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2024-09-12","frequency":4,"pay_date":"2024-09-30","record_date":"2024-09-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2024-06-13","frequency":4,"pay_date":"2024-06-30","record_date":"2024-06-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2024-03-14","frequency":4,"pay_date":"2024-03-31","record_date":"2024-03-15","ticker":"CSSEN"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2023-12-14","frequency":4,"pay_date":"2023-12-31","record_date":"2023-12-15","ticker":"CSSEN"},{"cash_amount":0.5,"declaration_date":"2022-02-10","dividend_type":"CD","ex_dividend_date":"2023-11-13","frequency":4,"pay_date":"2023-11-15","record_date":"2023-11-14","ticker":"AIRTP"},{"cash_amount":0.59375,"declaration_date":"2020-09-09","dividend_type":"CD","ex_dividend_date":"2023-09-14","frequency":4,"pay_date":"2023-09-30","record_date":"2023-09-15","ticker":"CSSEN"},{"cash_amount":0.5,"declaration_date":"2022-02-10","dividend_type":"CD","ex_dividend_date":"2023-08-11","frequency":4,"pay_date":"2023-08-15","record_date":"2023-08-14","ticker":"AIRTP"}],"status":"OK","request_id":"0326f1f88a2867a7184c116f5b1edd00"}', + ), + ( + "/v3/reference/conditions?asset.class=stocks", + '{"results":[{"id":1,"type":"sale_condition","name":"Acquisition","asset_class":"stocks","sip_mapping":{"UTP":"A"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"]},{"id":2,"type":"sale_condition","name":"Average Price Trade","asset_class":"stocks","sip_mapping":{"CTA":"B","UTP":"W"},"update_rules":{"consolidated":{"updates_high_low":false,"updates_open_close":false,"updates_volume":true},"market_center":{"updates_high_low":false,"updates_open_close":false,"updates_volume":true}},"data_types":["trade"]},{"id":3,"type":"sale_condition","name":"Automatic Execution","asset_class":"stocks","sip_mapping":{"CTA":"E"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"]},{"id":4,"type":"sale_condition","name":"Bunched Trade","asset_class":"stocks","sip_mapping":{"UTP":"B"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"]},{"id":5,"type":"sale_condition","name":"Bunched Sold Trade","asset_class":"stocks","sip_mapping":{"UTP":"G"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":false,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":false,"updates_volume":true}},"data_types":["trade"]},{"id":6,"type":"sale_condition","name":"CAP Election","asset_class":"stocks","sip_mapping":{"CTA":"I"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"],"legacy":true},{"id":7,"type":"sale_condition","name":"Cash Sale","asset_class":"stocks","sip_mapping":{"CTA":"C","UTP":"C"},"update_rules":{"consolidated":{"updates_high_low":false,"updates_open_close":false,"updates_volume":true},"market_center":{"updates_high_low":false,"updates_open_close":false,"updates_volume":true}},"data_types":["trade"]},{"id":8,"type":"sale_condition","name":"Closing Prints","asset_class":"stocks","sip_mapping":{"UTP":"6"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"]},{"id":9,"type":"sale_condition","name":"Cross Trade","asset_class":"stocks","sip_mapping":{"CTA":"X","UTP":"X"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":true,"updates_volume":true}},"data_types":["trade"]},{"id":10,"type":"sale_condition","name":"Derivatively Priced","asset_class":"stocks","sip_mapping":{"CTA":"4","UTP":"4"},"update_rules":{"consolidated":{"updates_high_low":true,"updates_open_close":false,"updates_volume":true},"market_center":{"updates_high_low":true,"updates_open_close":false,"updates_volume":true}},"data_types":["trade"]}],"status":"OK","request_id":"4c915a9cb249e40d08d031d70567d615","count":10}', + ), + ( + "/v3/reference/exchanges", + '{"results":[{"id":1,"type":"exchange","asset_class":"stocks","locale":"us","name":"NYSE American, LLC","acronym":"AMEX","mic":"XASE","operating_mic":"XNYS","participant_id":"A","url":"https://www.nyse.com/markets/nyse-american"},{"id":2,"type":"exchange","asset_class":"stocks","locale":"us","name":"Nasdaq OMX BX, Inc.","mic":"XBOS","operating_mic":"XNAS","participant_id":"B","url":"https://www.nasdaq.com/solutions/nasdaq-bx-stock-market"},{"id":3,"type":"exchange","asset_class":"stocks","locale":"us","name":"NYSE National, Inc.","acronym":"NSX","mic":"XCIS","operating_mic":"XNYS","participant_id":"C","url":"https://www.nyse.com/markets/nyse-national"},{"id":4,"type":"TRF","asset_class":"stocks","locale":"us","name":"FINRA NYSE TRF","mic":"FINY","operating_mic":"XNYS","participant_id":"D","url":"https://www.finra.org"},{"id":4,"type":"TRF","asset_class":"stocks","locale":"us","name":"FINRA Nasdaq TRF Carteret","mic":"FINN","operating_mic":"FINR","participant_id":"D","url":"https://www.finra.org"},{"id":4,"type":"TRF","asset_class":"stocks","locale":"us","name":"FINRA Nasdaq TRF Chicago","mic":"FINC","operating_mic":"FINR","participant_id":"D","url":"https://www.finra.org"},{"id":4,"type":"TRF","asset_class":"stocks","locale":"us","name":"FINRA Alternative Display Facility","mic":"XADF","operating_mic":"FINR","participant_id":"D","url":"https://www.finra.org"},{"id":5,"type":"SIP","asset_class":"stocks","locale":"us","name":"Unlisted Trading Privileges","operating_mic":"XNAS","participant_id":"E","url":"https://www.utpplan.com"},{"id":6,"type":"TRF","asset_class":"stocks","locale":"us","name":"International Securities Exchange, LLC - Stocks","mic":"XISE","operating_mic":"XNAS","participant_id":"I","url":"https://nasdaq.com/solutions/nasdaq-ise"},{"id":7,"type":"exchange","asset_class":"stocks","locale":"us","name":"Cboe EDGA","mic":"EDGA","operating_mic":"XCBO","participant_id":"J","url":"https://www.cboe.com/us/equities"},{"id":8,"type":"exchange","asset_class":"stocks","locale":"us","name":"Cboe EDGX","mic":"EDGX","operating_mic":"XCBO","participant_id":"K","url":"https://www.cboe.com/us/equities"},{"id":9,"type":"exchange","asset_class":"stocks","locale":"us","name":"NYSE Chicago, Inc.","mic":"XCHI","operating_mic":"XNYS","participant_id":"M","url":"https://www.nyse.com/markets/nyse-chicago"},{"id":10,"type":"exchange","asset_class":"stocks","locale":"us","name":"New York Stock Exchange","mic":"XNYS","operating_mic":"XNYS","participant_id":"N","url":"https://www.nyse.com"},{"id":11,"type":"exchange","asset_class":"stocks","locale":"us","name":"NYSE Arca, Inc.","mic":"ARCX","operating_mic":"XNYS","participant_id":"P","url":"https://www.nyse.com/markets/nyse-arca"},{"id":12,"type":"exchange","asset_class":"stocks","locale":"us","name":"Nasdaq","mic":"XNAS","operating_mic":"XNAS","participant_id":"T","url":"https://www.nasdaq.com"},{"id":13,"type":"SIP","asset_class":"stocks","locale":"us","name":"Consolidated Tape Association","operating_mic":"XNYS","participant_id":"S","url":"https://www.nyse.com/data/cta"},{"id":14,"type":"exchange","asset_class":"stocks","locale":"us","name":"Long-Term Stock Exchange","mic":"LTSE","operating_mic":"LTSE","participant_id":"L","url":"https://www.ltse.com"},{"id":15,"type":"exchange","asset_class":"stocks","locale":"us","name":"Investors Exchange","mic":"IEXG","operating_mic":"IEXG","participant_id":"V","url":"https://www.iextrading.com"},{"id":16,"type":"TRF","asset_class":"stocks","locale":"us","name":"Cboe Stock Exchange","mic":"CBSX","operating_mic":"XCBO","participant_id":"W","url":"https://www.cboe.com"},{"id":17,"type":"exchange","asset_class":"stocks","locale":"us","name":"Nasdaq Philadelphia Exchange LLC","mic":"XPHL","operating_mic":"XNAS","participant_id":"X","url":"https://www.nasdaq.com/solutions/nasdaq-phlx"},{"id":18,"type":"exchange","asset_class":"stocks","locale":"us","name":"Cboe BYX","mic":"BATY","operating_mic":"XCBO","participant_id":"Y","url":"https://www.cboe.com/us/equities"},{"id":19,"type":"exchange","asset_class":"stocks","locale":"us","name":"Cboe BZX","mic":"BATS","operating_mic":"XCBO","participant_id":"Z","url":"https://www.cboe.com/us/equities"},{"id":20,"type":"exchange","asset_class":"stocks","locale":"us","name":"MIAX Pearl","mic":"EPRL","operating_mic":"MIHI","participant_id":"H","url":"https://www.miaxoptions.com/alerts/pearl-equities"},{"id":21,"type":"exchange","asset_class":"stocks","locale":"us","name":"Members Exchange","mic":"MEMX","operating_mic":"MEMX","participant_id":"U","url":"https://www.memx.com"}],"status":"OK","request_id":"c0109b8a70a931efe47cef085c7a7f5e","count":24}', + ), + ( + "/v2/snapshot/locale/us/markets/stocks/tickers?market.type=stocks", + '{"count": 1,"status": "OK","tickers": [{"day": {"c": 20.506,"h": 20.64,"l": 20.506,"o": 20.64,"v": 37216,"vw": 20.616},"lastQuote": {"P": 20.6,"S": 22,"p": 20.5,"s": 13,"t": 1605192959994246100},"lastTrade": {"c": [14,41],"i": "71675577320245","p": 20.506,"s": 2416,"t": 1605192894630916600,"x": 4},"min": {"av": 37216,"c": 20.506,"h": 20.506,"l": 20.506,"o": 20.506,"v": 5000,"vw": 20.5105},"prevDay": {"c": 20.63,"h": 21,"l": 20.5,"o": 20.79,"v": 292738,"vw": 20.6939},"ticker": "BCAT","todaysChange": -0.124,"todaysChangePerc": -0.601,"updated": 1605192894630916600}]}', + ), + ( + "/v2/snapshot/locale/us/markets/stocks/gainers?market.type=stocks", + '{"status":"OK","tickers":[{"day":{"c":6.42,"h":6.99,"l":6.4,"o":6.81,"v":115782,"vw":6.656},"lastQuote":{"P":6.43,"S":1,"p":6.4,"s":1,"t":1651251738312628478},"lastTrade":{"c":[14,41],"i":"100","p":6.42,"s":200,"t":1651251334045891221,"x":8},"min":{"av":115689,"c":6.42,"h":6.542,"l":6.42,"o":6.49,"v":2671,"vw":6.4604},"prevDay":{"c":0.29,"h":0.348,"l":0.29,"o":0.3443,"v":1488660,"vw":0.317},"ticker":"NVCN","todaysChange":6.13,"todaysChangePerc":2113.793,"updated":1651251360000000000},{"day":{"c":4.2107,"h":4.95,"l":4.21,"o":4.31,"v":453199,"vw":4.4181},"lastQuote":{"P":4.22,"S":9,"p":4.21,"s":11,"t":1651251781709136903},"lastTrade":{"c":null,"i":"1084","p":4.2116,"s":241,"t":1651251789345841015,"x":4},"min":{"av":453189,"c":4.2107,"h":4.2107,"l":4.2107,"o":4.2107,"v":1012,"vw":4.2107},"prevDay":{"c":0.1953,"h":0.2966,"l":0.195,"o":0.29,"v":8784033,"vw":0.2278},"ticker":"BIOL","todaysChange":4.016,"todaysChangePerc":2056.477,"updated":1651251789345841015}]}', + ), + ( + "/v2/snapshot/locale/us/markets/stocks/tickers/AAPL?market.type=stocks", + '{"request_id":"957db942cab2d6b0633b9b4820db0cb2","status":"OK","ticker":{"day":{"c":160.315,"h":166.2,"l":159.8,"o":161.84,"v":68840127,"vw":162.7124},"lastQuote":{"P":159.99,"S":5,"p":159.98,"s":3,"t":1651251948407646487},"lastTrade":{"c":null,"i":"121351","p":159.99,"s":200,"t":1651251948294080343,"x":12},"min":{"av":68834255,"c":160.3,"h":160.71,"l":160.3,"o":160.71,"v":197226,"vw":160.5259},"prevDay":{"c":163.64,"h":164.515,"l":158.93,"o":159.25,"v":130149192,"vw":161.8622},"ticker":"AAPL","todaysChange":-3.65,"todaysChangePerc":-2.231,"updated":1651251948294080343}}', + ), + ( + "/v2/snapshot/locale/global/markets/crypto/tickers/X:BTCUSD/book", + '{"data": {"askCount": 593.1412981600005,"asks": [{"p": 11454,"x": {"2": 1}},{"p": 11455,"x": {"2": 1}}],"bidCount": 694.951789670001,"bids": [{"p": 16303.17,"x": {"1": 2}},{"p": 16302.94,"x": {"1": 0.02859424,"6": 0.023455}}],"spread": -4849.17,"ticker": "X:BTCUSD","updated": 1605295074162},"status": "OK"}', + ), + ( + "/v3/snapshot/options/AAPL/O:AAPL230616C00150000", + '{"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"}', + ), +] + + +class BaseTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.maxDiff = None + cls.c = RESTClient("", verbose=True) + httpretty.enable(verbose=True, allow_net_connect=False) + for m in mocks: + httpretty.register_uri( + httpretty.GET, cls.c.BASE + m[0], m[1], match_querystring=True + ) diff --git a/tests/test_aggs.py b/tests/test_aggs.py new file mode 100644 index 00000000..5e651786 --- /dev/null +++ b/tests/test_aggs.py @@ -0,0 +1,86 @@ +from mocks import BaseTest +from polygon.rest.models import ( + Agg, + GroupedDailyAgg, + DailyOpenCloseAgg, + PreviousCloseAgg, +) + + +class AggsTest(BaseTest): + def test_get_aggs(self): + aggs = self.c.get_aggs("AAPL", 1, "day", "2005-04-01", "2005-04-04") + 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, + ), + ] + self.assertEqual(aggs, expected) + + def test_get_grouped_daily_aggs(self): + aggs = self.c.get_grouped_daily_aggs("2005-04-04", True) + expected = [ + GroupedDailyAgg( + ticker="GIK", + open=9.99, + high=10.02, + low=9.9, + close=10.02, + volume=895345, + vwap=9.9979, + timestamp=1602705600000, + transactions=96, + ) + ] + self.assertEqual(aggs, expected) + + def test_get_daily_open_close_agg(self): + aggs = self.c.get_daily_open_close_agg("AAPL", "2005-04-01", True) + expected = [ + DailyOpenCloseAgg( + after_hours=123, + close=123, + from_="2021-04-01", + high=124.18, + low=122.49, + open=123.66, + pre_market=123.45, + status="OK", + symbol="AAPL", + volume=75089134, + ) + ] + self.assertEqual(aggs, expected) + + def test_get_previous_close_agg(self): + aggs = self.c.get_previous_close_agg("AAPL") + expected = [ + PreviousCloseAgg( + ticker="AAPL", + close=156.8, + high=162.34, + low=156.72, + open=162.25, + timestamp=1651003200000, + volume=95595226.0, + vwap=158.6074, + ) + ] + self.assertEqual(aggs, expected) diff --git a/tests/test_conditions.py b/tests/test_conditions.py new file mode 100644 index 00000000..0e1b2fb1 --- /dev/null +++ b/tests/test_conditions.py @@ -0,0 +1,250 @@ +from polygon.rest.models import Condition +from mocks import BaseTest + + +class ConditionsTest(BaseTest): + def test_list_conditions(self): + conditions = [c for c in self.c.list_conditions("stocks")] + expected = [ + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=1, + legacy=None, + name="Acquisition", + sip_mapping={"UTP": "A"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=2, + legacy=None, + name="Average Price Trade", + sip_mapping={"CTA": "B", "UTP": "W"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": False, + "updates_open_close": False, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": False, + "updates_open_close": False, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=3, + legacy=None, + name="Automatic Execution", + sip_mapping={"CTA": "E"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=4, + legacy=None, + name="Bunched Trade", + sip_mapping={"UTP": "B"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=5, + legacy=None, + name="Bunched Sold Trade", + sip_mapping={"UTP": "G"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": False, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": False, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=6, + legacy=True, + name="CAP Election", + sip_mapping={"CTA": "I"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=7, + legacy=None, + name="Cash Sale", + sip_mapping={"CTA": "C", "UTP": "C"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": False, + "updates_open_close": False, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": False, + "updates_open_close": False, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=8, + legacy=None, + name="Closing Prints", + sip_mapping={"UTP": "6"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=9, + legacy=None, + name="Cross Trade", + sip_mapping={"CTA": "X", "UTP": "X"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": True, + "updates_volume": True, + }, + }, + ), + Condition( + abbreviation=None, + asset_class="stocks", + data_types=["trade"], + description=None, + exchange=None, + id=10, + legacy=None, + name="Derivatively Priced", + sip_mapping={"CTA": "4", "UTP": "4"}, + type="sale_condition", + update_rules={ + "consolidated": { + "updates_high_low": True, + "updates_open_close": False, + "updates_volume": True, + }, + "market_center": { + "updates_high_low": True, + "updates_open_close": False, + "updates_volume": True, + }, + }, + ), + ] + self.assertEqual(conditions, expected) diff --git a/tests/test_dividends.py b/tests/test_dividends.py new file mode 100644 index 00000000..925f1f2f --- /dev/null +++ b/tests/test_dividends.py @@ -0,0 +1,110 @@ +from polygon.rest.models import Dividend +from mocks import BaseTest + + +class DividendsTest(BaseTest): + def test_list_dividends(self): + dividends = [d for d in self.c.list_dividends()] + expected = [ + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2025-06-12", + frequency=4, + pay_date="2025-06-30", + record_date="2025-06-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2025-03-13", + frequency=4, + pay_date="2025-03-31", + record_date="2025-03-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2024-12-12", + frequency=4, + pay_date="2024-12-31", + record_date="2024-12-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2024-09-12", + frequency=4, + pay_date="2024-09-30", + record_date="2024-09-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2024-06-13", + frequency=4, + pay_date="2024-06-30", + record_date="2024-06-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2024-03-14", + frequency=4, + pay_date="2024-03-31", + record_date="2024-03-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2023-12-14", + frequency=4, + pay_date="2023-12-31", + record_date="2023-12-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.5, + declaration_date="2022-02-10", + dividend_type="CD", + ex_dividend_date="2023-11-13", + frequency=4, + pay_date="2023-11-15", + record_date="2023-11-14", + ticker="AIRTP", + ), + Dividend( + cash_amount=0.59375, + declaration_date="2020-09-09", + dividend_type="CD", + ex_dividend_date="2023-09-14", + frequency=4, + pay_date="2023-09-30", + record_date="2023-09-15", + ticker="CSSEN", + ), + Dividend( + cash_amount=0.5, + declaration_date="2022-02-10", + dividend_type="CD", + ex_dividend_date="2023-08-11", + frequency=4, + pay_date="2023-08-15", + record_date="2023-08-14", + ticker="AIRTP", + ), + ] + self.assertEqual(dividends, expected) diff --git a/tests/test_exchanges.py b/tests/test_exchanges.py new file mode 100644 index 00000000..13157437 --- /dev/null +++ b/tests/test_exchanges.py @@ -0,0 +1,298 @@ +from polygon.rest.models import Exchange +from mocks import BaseTest + + +class ExchangesTest(BaseTest): + def test_get_exchanges(self): + exchanges = self.c.get_exchanges("stocks") + expected = [ + Exchange( + acronym="AMEX", + asset_class="stocks", + id=1, + locale="us", + mic="XASE", + name="NYSE American, LLC", + operating_mic="XNYS", + participant_id="A", + type="exchange", + url="https://www.nyse.com/markets/nyse-american", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=2, + locale="us", + mic="XBOS", + name="Nasdaq OMX BX, Inc.", + operating_mic="XNAS", + participant_id="B", + type="exchange", + url="https://www.nasdaq.com/solutions/nasdaq-bx-stock-market", + ), + Exchange( + acronym="NSX", + asset_class="stocks", + id=3, + locale="us", + mic="XCIS", + name="NYSE National, Inc.", + operating_mic="XNYS", + participant_id="C", + type="exchange", + url="https://www.nyse.com/markets/nyse-national", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=4, + locale="us", + mic="FINY", + name="FINRA NYSE TRF", + operating_mic="XNYS", + participant_id="D", + type="TRF", + url="https://www.finra.org", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=4, + locale="us", + mic="FINN", + name="FINRA Nasdaq TRF Carteret", + operating_mic="FINR", + participant_id="D", + type="TRF", + url="https://www.finra.org", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=4, + locale="us", + mic="FINC", + name="FINRA Nasdaq TRF Chicago", + operating_mic="FINR", + participant_id="D", + type="TRF", + url="https://www.finra.org", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=4, + locale="us", + mic="XADF", + name="FINRA Alternative Display Facility", + operating_mic="FINR", + participant_id="D", + type="TRF", + url="https://www.finra.org", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=5, + locale="us", + mic=None, + name="Unlisted Trading Privileges", + operating_mic="XNAS", + participant_id="E", + type="SIP", + url="https://www.utpplan.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=6, + locale="us", + mic="XISE", + name="International Securities Exchange, LLC - Stocks", + operating_mic="XNAS", + participant_id="I", + type="TRF", + url="https://nasdaq.com/solutions/nasdaq-ise", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=7, + locale="us", + mic="EDGA", + name="Cboe EDGA", + operating_mic="XCBO", + participant_id="J", + type="exchange", + url="https://www.cboe.com/us/equities", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=8, + locale="us", + mic="EDGX", + name="Cboe EDGX", + operating_mic="XCBO", + participant_id="K", + type="exchange", + url="https://www.cboe.com/us/equities", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=9, + locale="us", + mic="XCHI", + name="NYSE Chicago, Inc.", + operating_mic="XNYS", + participant_id="M", + type="exchange", + url="https://www.nyse.com/markets/nyse-chicago", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=10, + locale="us", + mic="XNYS", + name="New York Stock Exchange", + operating_mic="XNYS", + participant_id="N", + type="exchange", + url="https://www.nyse.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=11, + locale="us", + mic="ARCX", + name="NYSE Arca, Inc.", + operating_mic="XNYS", + participant_id="P", + type="exchange", + url="https://www.nyse.com/markets/nyse-arca", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=12, + locale="us", + mic="XNAS", + name="Nasdaq", + operating_mic="XNAS", + participant_id="T", + type="exchange", + url="https://www.nasdaq.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=13, + locale="us", + mic=None, + name="Consolidated Tape Association", + operating_mic="XNYS", + participant_id="S", + type="SIP", + url="https://www.nyse.com/data/cta", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=14, + locale="us", + mic="LTSE", + name="Long-Term Stock Exchange", + operating_mic="LTSE", + participant_id="L", + type="exchange", + url="https://www.ltse.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=15, + locale="us", + mic="IEXG", + name="Investors Exchange", + operating_mic="IEXG", + participant_id="V", + type="exchange", + url="https://www.iextrading.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=16, + locale="us", + mic="CBSX", + name="Cboe Stock Exchange", + operating_mic="XCBO", + participant_id="W", + type="TRF", + url="https://www.cboe.com", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=17, + locale="us", + mic="XPHL", + name="Nasdaq Philadelphia Exchange LLC", + operating_mic="XNAS", + participant_id="X", + type="exchange", + url="https://www.nasdaq.com/solutions/nasdaq-phlx", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=18, + locale="us", + mic="BATY", + name="Cboe BYX", + operating_mic="XCBO", + participant_id="Y", + type="exchange", + url="https://www.cboe.com/us/equities", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=19, + locale="us", + mic="BATS", + name="Cboe BZX", + operating_mic="XCBO", + participant_id="Z", + type="exchange", + url="https://www.cboe.com/us/equities", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=20, + locale="us", + mic="EPRL", + name="MIAX Pearl", + operating_mic="MIHI", + participant_id="H", + type="exchange", + url="https://www.miaxoptions.com/alerts/pearl-equities", + ), + Exchange( + acronym=None, + asset_class="stocks", + id=21, + locale="us", + mic="MEMX", + name="Members Exchange", + operating_mic="MEMX", + participant_id="U", + type="exchange", + url="https://www.memx.com", + ), + ] + self.assertEqual(exchanges, expected) diff --git a/tests/test_markets.py b/tests/test_markets.py new file mode 100644 index 00000000..5076babc --- /dev/null +++ b/tests/test_markets.py @@ -0,0 +1,141 @@ +from polygon import RESTClient +from polygon.rest.models import MarketHoliday, MarketStatus +from mocks import BaseTest + + +class MarketsTest(BaseTest): + def test_get_market_holidays(self): + holidays = self.c.get_market_holidays() + expected = [ + MarketHoliday( + close=None, + date="2022-05-30", + exchange="NYSE", + name="Memorial Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-05-30", + exchange="NASDAQ", + name="Memorial Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-06-20", + exchange="NASDAQ", + name="Juneteenth", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-06-20", + exchange="NYSE", + name="Juneteenth", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-07-04", + exchange="NYSE", + name="Independence Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-07-04", + exchange="NASDAQ", + name="Independence Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-09-05", + exchange="NYSE", + name="Labor Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-09-05", + exchange="NASDAQ", + name="Labor Day", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-11-24", + exchange="NYSE", + name="Thanksgiving", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-11-24", + exchange="NASDAQ", + name="Thanksgiving", + open=None, + status="closed", + ), + MarketHoliday( + close="2022-11-25T18:00:00.000Z", + date="2022-11-25", + exchange="NYSE", + name="Thanksgiving", + open="2022-11-25T14:30:00.000Z", + status="early-close", + ), + MarketHoliday( + close="2022-11-25T18:00:00.000Z", + date="2022-11-25", + exchange="NASDAQ", + name="Thanksgiving", + open="2022-11-25T14:30:00.000Z", + status="early-close", + ), + MarketHoliday( + close=None, + date="2022-12-26", + exchange="NYSE", + name="Christmas", + open=None, + status="closed", + ), + MarketHoliday( + close=None, + date="2022-12-26", + exchange="NASDAQ", + name="Christmas", + open=None, + status="closed", + ), + ] + self.assertEqual(holidays, expected) + + def test_get_market_status(self): + status = self.c.get_market_status() + expected = [ + MarketStatus( + after_hours=True, + currencies={"fx": "open", "crypto": "open"}, + early_hours=False, + exchanges={ + "nyse": "extended-hours", + "nasdaq": "extended-hours", + "otc": "extended-hours", + }, + market="extended-hours", + server_time="2022-04-28T16:48:08-04:00", + ) + ] + self.assertEqual(status, expected) diff --git a/tests/test_snapshots.py b/tests/test_snapshots.py new file mode 100644 index 00000000..5de72195 --- /dev/null +++ b/tests/test_snapshots.py @@ -0,0 +1,277 @@ +from polygon.rest.models import Snapshot, OptionContractSnapshot, SnapshotTickerFullBook +from mocks import BaseTest + + +class SnapshotsTest(BaseTest): + def test_get_snapshot_all(self): + snapshots = self.c.get_snapshot_all() + expected = [ + Snapshot( + day={ + "c": 20.506, + "h": 20.64, + "l": 20.506, + "o": 20.64, + "v": 37216, + "vw": 20.616, + }, + last_quote={ + "P": 20.6, + "S": 22, + "p": 20.5, + "s": 13, + "t": 1605192959994246100, + }, + last_trade={ + "c": [14, 41], + "i": "71675577320245", + "p": 20.506, + "s": 2416, + "t": 1605192894630916600, + "x": 4, + }, + min={ + "av": 37216, + "c": 20.506, + "h": 20.506, + "l": 20.506, + "o": 20.506, + "v": 5000, + "vw": 20.5105, + }, + prev_day={ + "c": 20.63, + "h": 21, + "l": 20.5, + "o": 20.79, + "v": 292738, + "vw": 20.6939, + }, + ticker="BCAT", + todays_change=-0.124, + todays_change_percent=None, + updated=1605192894630916600, + ) + ] + self.assertEqual(snapshots, expected) + + def test_get_snapshot_direction(self): + snapshots = self.c.get_snapshot_direction("gainers") + expected = [ + Snapshot( + day={ + "c": 6.42, + "h": 6.99, + "l": 6.4, + "o": 6.81, + "v": 115782, + "vw": 6.656, + }, + last_quote={ + "P": 6.43, + "S": 1, + "p": 6.4, + "s": 1, + "t": 1651251738312628478, + }, + last_trade={ + "c": [14, 41], + "i": "100", + "p": 6.42, + "s": 200, + "t": 1651251334045891221, + "x": 8, + }, + min={ + "av": 115689, + "c": 6.42, + "h": 6.542, + "l": 6.42, + "o": 6.49, + "v": 2671, + "vw": 6.4604, + }, + prev_day={ + "c": 0.29, + "h": 0.348, + "l": 0.29, + "o": 0.3443, + "v": 1488660, + "vw": 0.317, + }, + ticker="NVCN", + todays_change=6.13, + todays_change_percent=None, + updated=1651251360000000000, + ), + Snapshot( + day={ + "c": 4.2107, + "h": 4.95, + "l": 4.21, + "o": 4.31, + "v": 453199, + "vw": 4.4181, + }, + last_quote={ + "P": 4.22, + "S": 9, + "p": 4.21, + "s": 11, + "t": 1651251781709136903, + }, + last_trade={ + "c": None, + "i": "1084", + "p": 4.2116, + "s": 241, + "t": 1651251789345841015, + "x": 4, + }, + min={ + "av": 453189, + "c": 4.2107, + "h": 4.2107, + "l": 4.2107, + "o": 4.2107, + "v": 1012, + "vw": 4.2107, + }, + prev_day={ + "c": 0.1953, + "h": 0.2966, + "l": 0.195, + "o": 0.29, + "v": 8784033, + "vw": 0.2278, + }, + ticker="BIOL", + todays_change=4.016, + todays_change_percent=None, + updated=1651251789345841015, + ), + ] + self.assertEqual(snapshots, expected) + + def test_get_snapshot_ticker(self): + snapshots = self.c.get_snapshot_ticker("AAPL") + expected = [ + Snapshot( + day={ + "c": 160.315, + "h": 166.2, + "l": 159.8, + "o": 161.84, + "v": 68840127, + "vw": 162.7124, + }, + last_quote={ + "P": 159.99, + "S": 5, + "p": 159.98, + "s": 3, + "t": 1651251948407646487, + }, + last_trade={ + "c": None, + "i": "121351", + "p": 159.99, + "s": 200, + "t": 1651251948294080343, + "x": 12, + }, + min={ + "av": 68834255, + "c": 160.3, + "h": 160.71, + "l": 160.3, + "o": 160.71, + "v": 197226, + "vw": 160.5259, + }, + prev_day={ + "c": 163.64, + "h": 164.515, + "l": 158.93, + "o": 159.25, + "v": 130149192, + "vw": 161.8622, + }, + ticker="AAPL", + todays_change=-3.65, + todays_change_percent=None, + updated=1651251948294080343, + ) + ] + self.assertEqual(snapshots, expected) + + def test_get_snapshot_option(self): + snapshots = self.c.get_snapshot_option("AAPL", "O:AAPL230616C00150000") + expected = [ + OptionContractSnapshot( + 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", + }, + ) + ] + self.assertEqual(snapshots, expected) + + def test_get_snapshot_crypto_book(self): + snapshots = self.c.get_snapshot_crypto_book("X:BTCUSD") + expected = [ + SnapshotTickerFullBook( + ticker="X:BTCUSD", + bids=[ + {"p": 16303.17, "x": {"1": 2}}, + {"p": 16302.94, "x": {"1": 0.02859424, "6": 0.023455}}, + ], + asks=[{"p": 11454, "x": {"2": 1}}, {"p": 11455, "x": {"2": 1}}], + bid_count=694.951789670001, + ask_count=593.1412981600005, + spread=-4849.17, + updated=1605295074162, + ) + ] + self.assertEqual(snapshots, expected) diff --git a/tests/test_splits.py b/tests/test_splits.py new file mode 100644 index 00000000..83b8f184 --- /dev/null +++ b/tests/test_splits.py @@ -0,0 +1,32 @@ +from polygon.rest.models import Split +from mocks import BaseTest + + +class SplitsTest(BaseTest): + def test_list_splits(self): + splits = [s for s in self.c.list_splits()] + expected = [ + Split( + execution_date="2022-07-18", split_from=1, split_to=20, ticker="GOOGL" + ), + Split( + execution_date="2022-07-18", split_from=1, split_to=20, ticker="GOOG" + ), + Split(execution_date="2022-07-01", split_from=1, split_to=3, ticker="CTO"), + Split( + execution_date="2022-06-29", split_from=1, split_to=10, ticker="SHOP" + ), + Split( + execution_date="2022-06-22", split_from=1, split_to=10, ticker="SHOP" + ), + Split(execution_date="2022-06-10", split_from=1, split_to=4, ticker="DXCM"), + Split( + execution_date="2022-06-06", split_from=1, split_to=20, ticker="AMZN" + ), + Split(execution_date="2022-05-20", split_from=2, split_to=1, ticker="BRW"), + Split(execution_date="2022-05-16", split_from=1, split_to=2, ticker="CM"), + Split( + execution_date="2022-05-02", split_from=3, split_to=4, ticker="CIG.C" + ), + ] + self.assertEqual(splits, expected) diff --git a/tests/test_tickers.py b/tests/test_tickers.py new file mode 100644 index 00000000..58d60adc --- /dev/null +++ b/tests/test_tickers.py @@ -0,0 +1,231 @@ +from polygon.rest.models import ( + Ticker, + TickerDetails, + TickerNews, + TickerTypes, +) +from mocks import BaseTest + + +class TickersTest(BaseTest): + def test_list_tickers(self): + tickers = [t for t in self.c.list_tickers()] + expected = [ + Ticker( + active=True, + cik="0001090872", + composite_figi="BBG000C2V3D6", + currency_name="usd", + currency_symbol=None, + base_currency_symbol=None, + base_currency_name=None, + delisted_utc=None, + last_updated_utc="2022-04-27T00:00:00Z", + locale="us", + market="stocks", + name="Agilent Technologies Inc.", + primary_exchange="XNYS", + share_class_figi="BBG001SCTQY4", + ticker="A", + type="CS", + ), + Ticker( + active=True, + cik="0001675149", + composite_figi="BBG00B3T3HD3", + currency_name="usd", + currency_symbol=None, + base_currency_symbol=None, + base_currency_name=None, + delisted_utc=None, + last_updated_utc="2022-04-27T00:00:00Z", + locale="us", + market="stocks", + name="Alcoa Corporation", + primary_exchange="XNYS", + share_class_figi="BBG00B3T3HF1", + ticker="AA", + type="CS", + ), + Ticker( + active=True, + cik=None, + composite_figi="BBG00X5FSP48", + currency_name="usd", + currency_symbol=None, + base_currency_symbol=None, + base_currency_name=None, + delisted_utc=None, + last_updated_utc="2022-04-27T00:00:00Z", + locale="us", + market="stocks", + name="AAF First Priority CLO Bond ETF", + primary_exchange="ARCX", + share_class_figi="BBG00X5FSPZ4", + ticker="AAA", + type="ETF", + ), + Ticker( + active=True, + cik="0001708646", + composite_figi="BBG00LPXX872", + currency_name="usd", + currency_symbol=None, + base_currency_symbol=None, + base_currency_name=None, + delisted_utc=None, + last_updated_utc="2022-04-27T00:00:00Z", + locale="us", + market="stocks", + name="Goldman Sachs Physical Gold ETF Shares", + primary_exchange="BATS", + share_class_figi="BBG00LPXX8Z1", + ticker="AAAU", + type="ETF", + ), + ] + self.assertEqual(tickers, expected) + + def test_get_ticker_details(self): + details = self.c.get_ticker_details("AAPL") + expected = [ + TickerDetails( + active=True, + address={ + "address1": "ONE APPLE PARK WAY", + "city": "CUPERTINO", + "state": "CA", + "postal_code": "95014", + }, + branding={ + "logo_url": "https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-02-01_logo.svg", + "icon_url": "https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-02-01_icon.png", + }, + cik="0000320193", + composite_figi="BBG000B9XRY4", + currency_name="usd", + delisted_utc=None, + description="Apple designs a wide variety of consumer electronic devices, including smartphones (iPhone), tablets (iPad), PCs (Mac), smartwatches (Apple Watch), AirPods, and TV boxes (Apple TV), among others. The iPhone makes up the majority of Apples total revenue. In addition, Apple offers its customers a variety of services such as Apple Music, iCloud, Apple Care, Apple TV+, Apple Arcade, Apple Card, and Apple Pay, among others. Apples products run internally developed software and semiconductors, and the firm is well known for its integration of hardware, software and services. Apples products are distributed online as well as through company-owned stores and third-party retailers. The company generates roughly 40 of its revenue from the Americas, with the remainder earned internationally.", + ticker_root="AAPL", + homepage_url="https://www.apple.com", + list_date="1980-12-12", + locale="us", + market="stocks", + market_cap=2671492491700.0, + name="Apple Inc.", + phone_number="(408) 996-1010", + primary_exchange="XNAS", + share_class_figi="BBG001S5N8V8", + share_class_shares_outstanding=16319440000, + sic_code="3571", + sic_description="ELECTRONIC COMPUTERS", + ticker="AAPL", + total_employees=154000, + type="CS", + weighted_shares_outstanding=16319441000, + ) + ] + self.assertEqual(details, expected) + + def test_list_ticker_news(self): + news = [t for t in self.c.list_ticker_news("NFLX")] + expected = [ + TickerNews( + amp_url="https://www.marketwatch.com/amp/story/theres-a-big-hole-in-the-feds-theory-of-inflationincomes-are-falling-at-a-record-10-9-rate-11651165705", + article_url="https://www.marketwatch.com/story/theres-a-big-hole-in-the-feds-theory-of-inflationincomes-are-falling-at-a-record-10-9-rate-11651165705", + author="MarketWatch", + description="If inflation is all due to an overly generous federal government giving its people too much money, then our inflation problem is about to go away.", + id="JeJEhAVoKaqJ2zF9nzQYMg07UlEeWlis6Dsop33TPQY", + image_url="https://images.mktw.net/im-533637/social", + keywords=None, + published_utc="2022-04-28T17:08:00Z", + publisher={ + "name": "MarketWatch", + "homepage_url": "https://www.marketwatch.com/", + "logo_url": "https://s3.polygon.io/public/assets/news/logos/marketwatch.svg", + "favicon_url": "https://s3.polygon.io/public/assets/news/favicons/marketwatch.ico", + }, + tickers=["MSFT", "TSN", "NFLX", "AMZN"], + title="Theres a big hole in the Feds theory of inflation—incomes are falling at a record 10.9 rate", + ) + ] + self.assertEqual(news, expected) + + def test_get_ticker_types(self): + types = self.c.get_ticker_types("stocks") + expected = [ + TickerTypes( + asset_class="stocks", code="CS", description="Common Stock", locale="us" + ), + TickerTypes( + asset_class="stocks", + code="PFD", + description="Preferred Stock", + locale="us", + ), + TickerTypes( + asset_class="stocks", code="WARRANT", description="Warrant", locale="us" + ), + TickerTypes( + asset_class="stocks", code="RIGHT", description="Rights", locale="us" + ), + TickerTypes( + asset_class="stocks", + code="BOND", + description="Corporate Bond", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="ETF", + description="Exchange Traded Fund", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="ETN", + description="Exchange Traded Note", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="SP", + description="Structured Product", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="ADRC", + description="American Depository Receipt Common", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="ADRW", + description="American Depository Receipt Warrants", + locale="us", + ), + TickerTypes( + asset_class="stocks", + code="ADRR", + description="American Depository Receipt Rights", + locale="us", + ), + TickerTypes( + asset_class="stocks", code="FUND", description="Fund", locale="us" + ), + TickerTypes( + asset_class="stocks", code="BASKET", description="Basket", locale="us" + ), + TickerTypes( + asset_class="stocks", code="UNIT", description="Unit", locale="us" + ), + TickerTypes( + asset_class="stocks", + code="LT", + description="Liquidating Trust", + locale="us", + ), + ] + + self.assertEqual(types, expected) diff --git a/tests/test_trades.py b/tests/test_trades.py new file mode 100644 index 00000000..3c7e9bbb --- /dev/null +++ b/tests/test_trades.py @@ -0,0 +1,82 @@ +from mocks import BaseTest +from polygon.rest.models import ( + Trade, + LastTrade, + Last, + LastTradeCrypto, +) + + +class TradesTest(BaseTest): + def test_get_last_trade(self): + last_trade = self.c.get_last_trade("AAPL") + expected = [ + LastTrade( + ticker="AAPL", + trf_timestamp=1651179319310588400, + sequence_number=7084210, + sip_timestamp=1651179319310617300, + participant_timestamp=1651179319308000000, + conditions=[12, 37], + correction=None, + id="237688", + price=166.25, + trf_id=202, + size=2, + exchange=4, + tape=3, + ) + ] + self.assertEqual(last_trade, expected) + + def test_get_last_trade_crypto(self): + last_trade_crypto = self.c.get_last_trade_crypto("BTC", "USD") + expected = [ + LastTradeCrypto( + last={ + "conditions": [2], + "exchange": 2, + "price": 39976.89682331, + "size": 0.005, + "timestamp": 1651180409688, + }, + ticker="BTC-USD", + status="success", + request_id="d67c9bfe1fa0c29db9177d78b3ab713c", + ) + ] + self.assertEqual(last_trade_crypto, expected) + + def test_trades(self): + trades = [t for t in self.c.list_trades(ticker="AAPL", limit=2)] + expected = [ + Trade( + conditions=[12, 37], + correction=1, + exchange=11, + id="183276", + participant_timestamp=1651181822461636600, + price=156.43, + sequence_number=7179341, + sip_timestamp=1651181822461979400, + size=10, + tape=3, + trf_id=3, + trf_timestamp=1651181557090806500, + ), + Trade( + conditions=[12, 37], + correction=1, + exchange=12, + id="183276", + participant_timestamp=1651181822461636600, + price=157.43, + sequence_number=7179341, + sip_timestamp=1651181822461979400, + size=10, + tape=3, + trf_id=3, + trf_timestamp=1651181557090806500, + ), + ] + self.assertEqual(trades, expected) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 8fa455ad..00000000 --- a/tox.ini +++ /dev/null @@ -1,7 +0,0 @@ -[tox] -envlist = py3 - -[testenv] -deps = -r requirements.txt -commands = pytest -passenv = API_KEY diff --git a/websocket_example/polygon.py b/websocket_example/polygon.py deleted file mode 100644 index 760a27c0..00000000 --- a/websocket_example/polygon.py +++ /dev/null @@ -1,32 +0,0 @@ -# Be sure to pip install polygon-api-client - -import time - -from polygon import WebSocketClient, STOCKS_CLUSTER - - -def my_custom_process_message(message): - print("this is my custom message processing", message) - - -def my_custom_error_handler(ws, error): - print("this is my custom error handler", error) - - -def my_custom_close_handler(ws): - print("this is my custom close handler") - - -def main(): - key = 'your api key' - my_client = WebSocketClient(STOCKS_CLUSTER, key, my_custom_process_message) - my_client.run_async() - - my_client.subscribe("T.MSFT", "T.AAPL", "T.AMD", "T.NVDA") - time.sleep(1) - - my_client.close_connection() - - -if __name__ == "__main__": - main()