diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1ae9ada..8c42050c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - python-version: ['3.10', '3.11'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] runs-on: ${{ matrix.os }} name: ${{ matrix.os }} Unit test ${{ matrix.python-version }} steps: @@ -32,3 +32,23 @@ jobs: run: poetry install - name: Unit tests run: make test + test-free-threaded: + runs-on: ubuntu-latest + name: ubuntu-latest Unit test 3.14t (PYTHON_GIL=0) + env: + PYTHON_GIL: '0' + steps: + - uses: actions/checkout@v3 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.14t' + - name: Install pypi deps + # the tests need only the package and pook, not the dev tools + run: pip install -e . pook + - name: Check that the GIL is off + run: python -c "import sys; assert not sys._is_gil_enabled(), sys.version" + - name: Unit tests + run: | + python -m unittest discover -s test_rest + python -m unittest discover -s test_websocket diff --git a/AGENTS.md b/AGENTS.md index 7da1d1bf..4431e94f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,6 +51,7 @@ The OpenAPI spec at https://api.massive.com/openapi is the source of truth for p - Single-object endpoints are named `get_<...>` and call `self._get(...)`. - Every query param is a keyword argument defaulting to `None`. Write range filters as `x_gt`, `x_gte`, `x_lt`, `x_lte`, `x_any_of`; `_get_params` turns them into `x.gt` and so on. - Always end the signature with `params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None`. + - Precede the method with three `@overload`s that copy its signature, so callers get the precise type for each value of `raw`: `raw: Literal[False] = False` returns the model type (`Iterator[Model]`, `List[Model]` or `Model`); `*, raw: Literal[True]` (keyword-only) returns `HTTPResponse`; and `raw: bool = False` returns the full `Union`. Copy an existing method, such as `list_aggs` in `massive/rest/aggs.py`. 4. **New domain only.** Create a `BaseClient` subclass and add it to `RESTClient`'s bases in `massive/rest/__init__.py`. 5. **Tests, examples, docs.** For core endpoints, add a fixture under `test_rest/mocks/.json`, a test in `test_rest/test_.py`, an example in `examples/rest/`, and an `automethod` entry in `docs/source/*.rst`. 6. Run `make lint` and `make test`. diff --git a/Makefile b/Makefile index b3732930..9173bef6 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,9 @@ style: ## Check static types static: poetry run mypy massive test_* examples + @# From test_rest/, massive resolves to the installed package, as it does + @# for users, so this also fails if the package stops shipping py.typed. + cd test_rest && poetry run mypy --strict typing_consumer.py ## Check code style and static types lint: style static diff --git a/docs/source/Aggs.rst b/docs/source/Aggs.rst index b8e3fcc8..45fccd7c 100644 --- a/docs/source/Aggs.rst +++ b/docs/source/Aggs.rst @@ -41,10 +41,17 @@ Get daily open close agg - `Stocks daily open/close agg`_ - `Options daily open/close agg`_ -- `Crypto daily open/close agg`_ .. automethod:: massive.RESTClient.get_daily_open_close_agg +============================ +Get daily open close crypto +============================ + +- `Crypto daily open/close agg`_ + +.. automethod:: massive.RESTClient.get_daily_open_close_crypto + ============================ Get previous close agg ============================ diff --git a/docs/source/WebSocket.rst b/docs/source/WebSocket.rst index c624d9d2..1a366bbb 100644 --- a/docs/source/WebSocket.rst +++ b/docs/source/WebSocket.rst @@ -34,11 +34,26 @@ Unsubscribe ============================ .. automethod:: massive.WebSocketClient.unsubscribe +============================ +Set subscriptions +============================ +.. automethod:: massive.WebSocketClient.set_subscriptions + +============================ +Resubscribe +============================ +.. automethod:: massive.WebSocketClient.resubscribe + ============================ Close ============================ .. automethod:: massive.WebSocketClient.close +============================ +Request close +============================ +.. automethod:: massive.WebSocketClient.request_close + .. _Stocks getting started: https://massive.com/docs/stocks/ws_getting-started .. _Options getting started: https://massive.com/docs/options/ws_getting-started .. _Forex getting started: https://massive.com/docs/forex/ws_getting-started diff --git a/examples/rest/crypto-daily_open_close.py b/examples/rest/crypto-daily_open_close.py index 5c29db0c..41971796 100644 --- a/examples/rest/crypto-daily_open_close.py +++ b/examples/rest/crypto-daily_open_close.py @@ -2,14 +2,15 @@ # docs # https://massive.com/docs/crypto/get_v1_open-close_crypto__from___to___date -# https://massive-api-client.readthedocs.io/en/latest/Aggs.html#get-daily-open-close-agg +# https://massive-api-client.readthedocs.io/en/latest/Aggs.html#get-daily-open-close-crypto # client = RESTClient("XXXXXX") # hardcoded api_key is used client = RESTClient() # MASSIVE_API_KEY environment variable is used # make request -request = client.get_daily_open_close_agg( - "X:BTCUSD", +request = client.get_daily_open_close_crypto( + "BTC", + "USD", "2023-01-09", ) diff --git a/examples/rest/economy-funding_conditions.py b/examples/rest/economy-funding_conditions.py new file mode 100644 index 00000000..4dc948d2 --- /dev/null +++ b/examples/rest/economy-funding_conditions.py @@ -0,0 +1,13 @@ +from massive import RESTClient + +# docs +# https://massive.com/docs/rest/economy/funding-conditions + +# client = RESTClient("XXXXXX") # hardcoded api_key is used +client = RESTClient() # MASSIVE_API_KEY environment variable is used + +conditions = [] +for day in client.list_funding_conditions(date_gte="2025-06-01", sort="date.asc"): + conditions.append(day) + +print(conditions) diff --git a/massive/__init__.py b/massive/__init__.py index da6c5136..04f41281 100644 --- a/massive/__init__.py +++ b/massive/__init__.py @@ -1,6 +1,6 @@ -from .rest import RESTClient +from .rest import RESTClient as RESTClient from .rest.base import version -from .websocket import WebSocketClient +from .websocket import WebSocketClient as WebSocketClient from .exceptions import * __version__ = version diff --git a/massive/exceptions.py b/massive/exceptions.py index b8960763..d5b1c40b 100644 --- a/massive/exceptions.py +++ b/massive/exceptions.py @@ -1,3 +1,9 @@ +from typing import Optional + +# the package star-imports this module; keep Optional out of its namespace +__all__ = ["AuthError", "BadResponse"] + + class AuthError(Exception): """ Empty or invalid API key @@ -9,6 +15,11 @@ class AuthError(Exception): class BadResponse(Exception): """ Non-200 response from API + + The message is the response body. ``status`` is the HTTP status code, or + None if not given. """ - pass + def __init__(self, *args: object, status: Optional[int] = None): + super().__init__(*args) + self.status = status diff --git a/massive/modelclass.py b/massive/modelclass.py index 117f7910..0605180a 100644 --- a/massive/modelclass.py +++ b/massive/modelclass.py @@ -1,10 +1,23 @@ import inspect +import sys import typing from dataclasses import dataclass +if typing.TYPE_CHECKING: + if sys.version_info >= (3, 11): + from typing import dataclass_transform + else: + from typing_extensions import dataclass_transform +else: + + def dataclass_transform(**kwargs): + return lambda f: f + + _T = typing.TypeVar("_T") +@dataclass_transform() def modelclass(cls: typing.Type[_T]) -> typing.Type[_T]: cls = dataclass(cls) type_hints = typing.get_type_hints(cls) diff --git a/massive/py.typed b/massive/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/massive/rest/__init__.py b/massive/rest/__init__.py index 237ab84c..5fe653a3 100644 --- a/massive/rest/__init__.py +++ b/massive/rest/__init__.py @@ -66,6 +66,7 @@ def __init__( ca_certs: Optional[str] = None, proxy: Optional[str] = None, connection_pool_kw: Optional[Dict[str, Any]] = None, + raise_on_status: bool = True, ): """ :param maxsize: Connections kept open per host, for reuse across threads. @@ -75,6 +76,9 @@ def __init__( Environment proxy variables (HTTPS_PROXY etc.) are not used. :param connection_pool_kw: Other urllib3 PoolManager options. They override the client's defaults. + :param raise_on_status: When a retried status (413, 429, 499, 500, 502, 503, + 504) is still returned after the last retry: if True, urllib3 raises + MaxRetryError; if False, the client raises BadResponse with that status. """ # resolve once, so the main and vx clients share it and warn only once ca_certs = ca_certs or ca_bundle_path(logger) @@ -93,6 +97,7 @@ def __init__( ca_certs=ca_certs, proxy=proxy, connection_pool_kw=connection_pool_kw, + raise_on_status=raise_on_status, ) self.vx = VXClient( api_key=api_key, @@ -109,4 +114,5 @@ def __init__( ca_certs=ca_certs, proxy=proxy, connection_pool_kw=connection_pool_kw, + raise_on_status=raise_on_status, ) diff --git a/massive/rest/aggs.py b/massive/rest/aggs.py index cb874fac..7f823e04 100644 --- a/massive/rest/aggs.py +++ b/massive/rest/aggs.py @@ -1,6 +1,13 @@ from .base import BaseClient -from typing import Optional, Any, Dict, List, Union, Iterator -from .models import Agg, GroupedDailyAgg, DailyOpenCloseAgg, PreviousCloseAgg, Sort +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload +from .models import ( + Agg, + GroupedDailyAgg, + DailyOpenCloseAgg, + DailyOpenCloseCrypto, + PreviousCloseAgg, + Sort, +) from urllib3 import HTTPResponse from datetime import datetime, date @@ -8,6 +15,52 @@ class AggsClient(BaseClient): + @overload + def list_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Agg]: ... + @overload + def list_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Agg], HTTPResponse]: ... def list_aggs( self, ticker: str, @@ -53,6 +106,52 @@ def list_aggs( options=options, ) + @overload + def get_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[Agg]: ... + @overload + def get_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_aggs( + self, + ticker: str, + multiplier: int, + timespan: str, + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[Agg], HTTPResponse]: ... def get_aggs( self, ticker: str, @@ -99,6 +198,44 @@ def get_aggs( options=options, ) + @overload + def get_grouped_daily_aggs( + self, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + locale: str = "us", + market_type: str = "stocks", + include_otc: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[GroupedDailyAgg]: ... + @overload + def get_grouped_daily_aggs( + self, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + locale: str = "us", + market_type: str = "stocks", + include_otc: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_grouped_daily_aggs( + self, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + locale: str = "us", + market_type: str = "stocks", + include_otc: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[GroupedDailyAgg], HTTPResponse]: ... + # TODO: next breaking change release move "market_type" to be 2nd mandatory # param def get_grouped_daily_aggs( @@ -132,6 +269,37 @@ def get_grouped_daily_aggs( options=options, ) + @overload + def get_daily_open_close_agg( + self, + ticker: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> DailyOpenCloseAgg: ... + @overload + def get_daily_open_close_agg( + self, + ticker: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_daily_open_close_agg( + self, + ticker: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[DailyOpenCloseAgg, HTTPResponse]: ... def get_daily_open_close_agg( self, ticker: str, @@ -161,6 +329,100 @@ def get_daily_open_close_agg( options=options, ) + @overload + def get_daily_open_close_crypto( + self, + from_: str, + to: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> DailyOpenCloseCrypto: ... + @overload + def get_daily_open_close_crypto( + self, + from_: str, + to: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_daily_open_close_crypto( + self, + from_: str, + to: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[DailyOpenCloseCrypto, HTTPResponse]: ... + def get_daily_open_close_crypto( + self, + # "from" is a keyword in python https://www.w3schools.com/python/python_ref_keywords.asp + from_: str, + to: str, + date: Union[str, date], + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[DailyOpenCloseCrypto, HTTPResponse]: + """ + Get the open and close prices of a cryptocurrency pair on a certain day, along with the opening and closing trades. + + :param from_: The "from" symbol of the pair (e.g. "BTC"). + :param to: The "to" symbol of the pair (e.g. "USD"). + :param date: The date of the requested open/close in the format YYYY-MM-DD. + :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 for the crypto pair + """ + url = f"/v1/open-close/crypto/{from_}/{to}/{date}" + + return self._get( + path=url, + params=self._get_params(self.get_daily_open_close_crypto, locals()), + deserializer=DailyOpenCloseCrypto.from_dict, + raw=raw, + options=options, + ) + + @overload + def get_previous_close_agg( + self, + ticker: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[PreviousCloseAgg]: ... + @overload + def get_previous_close_agg( + self, + ticker: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_previous_close_agg( + self, + ticker: str, + adjusted: Optional[bool] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[PreviousCloseAgg], HTTPResponse]: ... def get_previous_close_agg( self, ticker: str, @@ -168,7 +430,7 @@ def get_previous_close_agg( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[PreviousCloseAgg, HTTPResponse]: + ) -> Union[List[PreviousCloseAgg], HTTPResponse]: """ Get the previous day's open, high, low, and close (OHLC) for the specified stock ticker. @@ -176,7 +438,7 @@ def get_previous_close_agg( :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 + :return: List of previous close aggregates (the API returns a one-element list) """ url = f"/v2/aggs/ticker/{ticker}/prev" diff --git a/massive/rest/base.py b/massive/rest/base.py index 294dd482..d8564dc9 100644 --- a/massive/rest/base.py +++ b/massive/rest/base.py @@ -38,6 +38,7 @@ def __init__( ca_certs: Optional[str] = None, proxy: Optional[str] = None, connection_pool_kw: Optional[Dict[str, Any]] = None, + raise_on_status: bool = True, ): if api_key is None: raise AuthError( @@ -70,6 +71,8 @@ def __init__( 504, ], # default 413, 429, 503 backoff_factor=0.1, # [0.0s, 0.2s, 0.4s, 0.8s, 1.6s, ...] + # if False, return the last response so that _get raises BadResponse + raise_on_status=raise_on_status, ) # https://urllib3.readthedocs.io/en/stable/reference/urllib3.util.html#urllib3.util.Timeout @@ -152,7 +155,7 @@ def _get( ) if resp.status != 200: - raise BadResponse(resp.data.decode("utf-8")) + raise BadResponse(resp.data.decode("utf-8"), status=resp.status) if raw: return resp @@ -196,7 +199,8 @@ def _get_params( # https://docs.python.org/3.8/library/inspect.html#inspect.Signature for argname, v in inspect.signature(fn).parameters.items(): # https://docs.python.org/3.8/library/inspect.html#inspect.Parameter - if argname in ["params", "raw"]: + # these configure the request itself and are never query params + if argname in ["params", "raw", "options"]: continue if v.default != v.empty: # timestamp_lt -> timestamp.lt diff --git a/massive/rest/benzinga.py b/massive/rest/benzinga.py index fdd9d0b0..0e08d3e7 100644 --- a/massive/rest/benzinga.py +++ b/massive/rest/benzinga.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -24,6 +24,160 @@ class BenzingaClient(BaseClient): (aligned with the paths from /benzinga/v1/...) """ + @overload + def list_benzinga_analyst_insights( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + firm: Optional[str] = None, + firm_any_of: Optional[str] = None, + firm_gt: Optional[str] = None, + firm_gte: Optional[str] = None, + firm_lt: Optional[str] = None, + firm_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + benzinga_rating_id: Optional[str] = None, + benzinga_rating_id_any_of: Optional[str] = None, + benzinga_rating_id_gt: Optional[str] = None, + benzinga_rating_id_gte: Optional[str] = None, + benzinga_rating_id_lt: Optional[str] = None, + benzinga_rating_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaAnalystInsight]: ... + @overload + def list_benzinga_analyst_insights( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + firm: Optional[str] = None, + firm_any_of: Optional[str] = None, + firm_gt: Optional[str] = None, + firm_gte: Optional[str] = None, + firm_lt: Optional[str] = None, + firm_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + benzinga_rating_id: Optional[str] = None, + benzinga_rating_id_any_of: Optional[str] = None, + benzinga_rating_id_gt: Optional[str] = None, + benzinga_rating_id_gte: Optional[str] = None, + benzinga_rating_id_lt: Optional[str] = None, + benzinga_rating_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_analyst_insights( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + firm: Optional[str] = None, + firm_any_of: Optional[str] = None, + firm_gt: Optional[str] = None, + firm_gte: Optional[str] = None, + firm_lt: Optional[str] = None, + firm_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + benzinga_rating_id: Optional[str] = None, + benzinga_rating_id_any_of: Optional[str] = None, + benzinga_rating_id_gt: Optional[str] = None, + benzinga_rating_id_gte: Optional[str] = None, + benzinga_rating_id_lt: Optional[str] = None, + benzinga_rating_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaAnalystInsight], HTTPResponse]: ... def list_benzinga_analyst_insights( self, date: Optional[Union[str, date]] = None, @@ -86,6 +240,106 @@ def list_benzinga_analyst_insights( options=options, ) + @overload + def list_benzinga_analysts( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + firm_name: Optional[str] = None, + firm_name_any_of: Optional[str] = None, + firm_name_gt: Optional[str] = None, + firm_name_gte: Optional[str] = None, + firm_name_lt: Optional[str] = None, + firm_name_lte: Optional[str] = None, + full_name: Optional[str] = None, + full_name_any_of: Optional[str] = None, + full_name_gt: Optional[str] = None, + full_name_gte: Optional[str] = None, + full_name_lt: Optional[str] = None, + full_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaAnalyst]: ... + @overload + def list_benzinga_analysts( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + firm_name: Optional[str] = None, + firm_name_any_of: Optional[str] = None, + firm_name_gt: Optional[str] = None, + firm_name_gte: Optional[str] = None, + firm_name_lt: Optional[str] = None, + firm_name_lte: Optional[str] = None, + full_name: Optional[str] = None, + full_name_any_of: Optional[str] = None, + full_name_gt: Optional[str] = None, + full_name_gte: Optional[str] = None, + full_name_lt: Optional[str] = None, + full_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_analysts( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + firm_name: Optional[str] = None, + firm_name_any_of: Optional[str] = None, + firm_name_gt: Optional[str] = None, + firm_name_gte: Optional[str] = None, + firm_name_lt: Optional[str] = None, + firm_name_lte: Optional[str] = None, + full_name: Optional[str] = None, + full_name_any_of: Optional[str] = None, + full_name_gt: Optional[str] = None, + full_name_gte: Optional[str] = None, + full_name_lt: Optional[str] = None, + full_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaAnalyst], HTTPResponse]: ... def list_benzinga_analysts( self, benzinga_id: Optional[str] = None, @@ -130,6 +384,7 @@ def list_benzinga_analysts( options=options, ) + @overload def list_benzinga_consensus_ratings( self, ticker: str, @@ -140,22 +395,504 @@ def list_benzinga_consensus_ratings( date_lte: Optional[Union[str, date]] = None, limit: Optional[int] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False, + raw: Literal[False] = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[BenzingaConsensusRating], HTTPResponse]: - """ - Endpoint: GET /benzinga/v1/consensus-ratings/{ticker} - """ - url = f"/benzinga/v1/consensus-ratings/{ticker}" - return self._paginate( - path=url, - params=self._get_params(self.list_benzinga_consensus_ratings, locals()), - raw=raw, - deserializer=BenzingaConsensusRating.from_dict, - options=options, - ) - - def list_benzinga_earnings( + ) -> Iterator[BenzingaConsensusRating]: ... + @overload + def list_benzinga_consensus_ratings( + self, + ticker: str, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_consensus_ratings( + self, + ticker: str, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaConsensusRating], HTTPResponse]: ... + def list_benzinga_consensus_ratings( + self, + ticker: str, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaConsensusRating], HTTPResponse]: + """ + Endpoint: GET /benzinga/v1/consensus-ratings/{ticker} + """ + url = f"/benzinga/v1/consensus-ratings/{ticker}" + return self._paginate( + path=url, + params=self._get_params(self.list_benzinga_consensus_ratings, locals()), + raw=raw, + deserializer=BenzingaConsensusRating.from_dict, + options=options, + ) + + @overload + def list_benzinga_earnings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + date_status: Optional[str] = None, + date_status_any_of: Optional[str] = None, + date_status_gt: Optional[str] = None, + date_status_gte: Optional[str] = None, + date_status_lt: Optional[str] = None, + date_status_lte: Optional[str] = None, + eps_surprise_percent: Optional[float] = None, + eps_surprise_percent_any_of: Optional[str] = None, + eps_surprise_percent_gt: Optional[float] = None, + eps_surprise_percent_gte: Optional[float] = None, + eps_surprise_percent_lt: Optional[float] = None, + eps_surprise_percent_lte: Optional[float] = None, + revenue_surprise_percent: Optional[float] = None, + revenue_surprise_percent_any_of: Optional[str] = None, + revenue_surprise_percent_gt: Optional[float] = None, + revenue_surprise_percent_gte: Optional[float] = None, + revenue_surprise_percent_lt: Optional[float] = None, + revenue_surprise_percent_lte: Optional[float] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaEarning]: ... + @overload + def list_benzinga_earnings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + date_status: Optional[str] = None, + date_status_any_of: Optional[str] = None, + date_status_gt: Optional[str] = None, + date_status_gte: Optional[str] = None, + date_status_lt: Optional[str] = None, + date_status_lte: Optional[str] = None, + eps_surprise_percent: Optional[float] = None, + eps_surprise_percent_any_of: Optional[str] = None, + eps_surprise_percent_gt: Optional[float] = None, + eps_surprise_percent_gte: Optional[float] = None, + eps_surprise_percent_lt: Optional[float] = None, + eps_surprise_percent_lte: Optional[float] = None, + revenue_surprise_percent: Optional[float] = None, + revenue_surprise_percent_any_of: Optional[str] = None, + revenue_surprise_percent_gt: Optional[float] = None, + revenue_surprise_percent_gte: Optional[float] = None, + revenue_surprise_percent_lt: Optional[float] = None, + revenue_surprise_percent_lte: Optional[float] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_earnings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + date_status: Optional[str] = None, + date_status_any_of: Optional[str] = None, + date_status_gt: Optional[str] = None, + date_status_gte: Optional[str] = None, + date_status_lt: Optional[str] = None, + date_status_lte: Optional[str] = None, + eps_surprise_percent: Optional[float] = None, + eps_surprise_percent_any_of: Optional[str] = None, + eps_surprise_percent_gt: Optional[float] = None, + eps_surprise_percent_gte: Optional[float] = None, + eps_surprise_percent_lt: Optional[float] = None, + eps_surprise_percent_lte: Optional[float] = None, + revenue_surprise_percent: Optional[float] = None, + revenue_surprise_percent_any_of: Optional[str] = None, + revenue_surprise_percent_gt: Optional[float] = None, + revenue_surprise_percent_gte: Optional[float] = None, + revenue_surprise_percent_lt: Optional[float] = None, + revenue_surprise_percent_lte: Optional[float] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaEarning], HTTPResponse]: ... + def list_benzinga_earnings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + date_status: Optional[str] = None, + date_status_any_of: Optional[str] = None, + date_status_gt: Optional[str] = None, + date_status_gte: Optional[str] = None, + date_status_lt: Optional[str] = None, + date_status_lte: Optional[str] = None, + eps_surprise_percent: Optional[float] = None, + eps_surprise_percent_any_of: Optional[str] = None, + eps_surprise_percent_gt: Optional[float] = None, + eps_surprise_percent_gte: Optional[float] = None, + eps_surprise_percent_lt: Optional[float] = None, + eps_surprise_percent_lte: Optional[float] = None, + revenue_surprise_percent: Optional[float] = None, + revenue_surprise_percent_any_of: Optional[str] = None, + revenue_surprise_percent_gt: Optional[float] = None, + revenue_surprise_percent_gte: Optional[float] = None, + revenue_surprise_percent_lt: Optional[float] = None, + revenue_surprise_percent_lte: Optional[float] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaEarning], HTTPResponse]: + """ + Endpoint: GET /benzinga/v1/earnings + """ + url = "/benzinga/v1/earnings" + return self._paginate( + path=url, + params=self._get_params(self.list_benzinga_earnings, locals()), + raw=raw, + deserializer=BenzingaEarning.from_dict, + options=options, + ) + + @overload + def list_benzinga_firms( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaFirm]: ... + @overload + def list_benzinga_firms( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_firms( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaFirm], HTTPResponse]: ... + def list_benzinga_firms( + self, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaFirm], HTTPResponse]: + """ + Endpoint: GET /benzinga/v1/firms + """ + url = "/benzinga/v1/firms" + return self._paginate( + path=url, + params=self._get_params(self.list_benzinga_firms, locals()), + raw=raw, + deserializer=BenzingaFirm.from_dict, + options=options, + ) + + @overload + def list_benzinga_guidance( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + positioning: Optional[str] = None, + positioning_any_of: Optional[str] = None, + positioning_gt: Optional[str] = None, + positioning_gte: Optional[str] = None, + positioning_lt: Optional[str] = None, + positioning_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaGuidance]: ... + @overload + def list_benzinga_guidance( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + positioning: Optional[str] = None, + positioning_any_of: Optional[str] = None, + positioning_gt: Optional[str] = None, + positioning_gte: Optional[str] = None, + positioning_lt: Optional[str] = None, + positioning_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + fiscal_year: Optional[int] = None, + fiscal_year_any_of: Optional[str] = None, + fiscal_year_gt: Optional[int] = None, + fiscal_year_gte: Optional[int] = None, + fiscal_year_lt: Optional[int] = None, + fiscal_year_lte: Optional[int] = None, + fiscal_period: Optional[str] = None, + fiscal_period_any_of: Optional[str] = None, + fiscal_period_gt: Optional[str] = None, + fiscal_period_gte: Optional[str] = None, + fiscal_period_lt: Optional[str] = None, + fiscal_period_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_guidance( self, date: Optional[Union[str, date]] = None, date_any_of: Optional[str] = None, @@ -169,6 +906,12 @@ def list_benzinga_earnings( ticker_gte: Optional[str] = None, ticker_lt: Optional[str] = None, ticker_lte: Optional[str] = None, + positioning: Optional[str] = None, + positioning_any_of: Optional[str] = None, + positioning_gt: Optional[str] = None, + positioning_gte: Optional[str] = None, + positioning_lt: Optional[str] = None, + positioning_lte: Optional[str] = None, importance: Optional[int] = None, importance_any_of: Optional[str] = None, importance_gt: Optional[int] = None, @@ -181,24 +924,6 @@ def list_benzinga_earnings( last_updated_gte: Optional[str] = None, last_updated_lt: Optional[str] = None, last_updated_lte: Optional[str] = None, - date_status: Optional[str] = None, - date_status_any_of: Optional[str] = None, - date_status_gt: Optional[str] = None, - date_status_gte: Optional[str] = None, - date_status_lt: Optional[str] = None, - date_status_lte: Optional[str] = None, - eps_surprise_percent: Optional[float] = None, - eps_surprise_percent_any_of: Optional[str] = None, - eps_surprise_percent_gt: Optional[float] = None, - eps_surprise_percent_gte: Optional[float] = None, - eps_surprise_percent_lt: Optional[float] = None, - eps_surprise_percent_lte: Optional[float] = None, - revenue_surprise_percent: Optional[float] = None, - revenue_surprise_percent_any_of: Optional[str] = None, - revenue_surprise_percent_gt: Optional[float] = None, - revenue_surprise_percent_gte: Optional[float] = None, - revenue_surprise_percent_lt: Optional[float] = None, - revenue_surprise_percent_lte: Optional[float] = None, fiscal_year: Optional[int] = None, fiscal_year_any_of: Optional[str] = None, fiscal_year_gt: Optional[int] = None, @@ -216,45 +941,7 @@ def list_benzinga_earnings( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[BenzingaEarning], HTTPResponse]: - """ - Endpoint: GET /benzinga/v1/earnings - """ - url = "/benzinga/v1/earnings" - return self._paginate( - path=url, - params=self._get_params(self.list_benzinga_earnings, locals()), - raw=raw, - deserializer=BenzingaEarning.from_dict, - options=options, - ) - - def list_benzinga_firms( - self, - benzinga_id: Optional[str] = None, - benzinga_id_any_of: Optional[str] = None, - benzinga_id_gt: Optional[str] = None, - benzinga_id_gte: Optional[str] = None, - benzinga_id_lt: Optional[str] = None, - benzinga_id_lte: Optional[str] = None, - limit: Optional[int] = None, - sort: Optional[Union[str, Sort]] = None, - params: Optional[Dict[str, Any]] = None, - raw: bool = False, - options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[BenzingaFirm], HTTPResponse]: - """ - Endpoint: GET /benzinga/v1/firms - """ - url = "/benzinga/v1/firms" - return self._paginate( - path=url, - params=self._get_params(self.list_benzinga_firms, locals()), - raw=raw, - deserializer=BenzingaFirm.from_dict, - options=options, - ) - + ) -> Union[Iterator[BenzingaGuidance], HTTPResponse]: ... def list_benzinga_guidance( self, date: Optional[Union[str, date]] = None, @@ -317,6 +1004,115 @@ def list_benzinga_guidance( options=options, ) + @overload + def list_benzinga_news( + self, + published: Optional[str] = None, + published_any_of: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaNews]: ... + @overload + def list_benzinga_news( + self, + published: Optional[str] = None, + published_any_of: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_news( + self, + published: Optional[str] = None, + published_any_of: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaNews], HTTPResponse]: ... def list_benzinga_news( self, published: Optional[str] = None, @@ -364,6 +1160,103 @@ def list_benzinga_news( options=options, ) + @overload + def list_benzinga_news_v2( + self, + published: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + stocks: Optional[str] = None, + stocks_all_of: Optional[str] = None, + stocks_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaNews]: ... + @overload + def list_benzinga_news_v2( + self, + published: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + stocks: Optional[str] = None, + stocks_all_of: Optional[str] = None, + stocks_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_news_v2( + self, + published: Optional[str] = None, + published_gt: Optional[str] = None, + published_gte: Optional[str] = None, + published_lt: Optional[str] = None, + published_lte: Optional[str] = None, + channels: Optional[str] = None, + channels_all_of: Optional[str] = None, + channels_any_of: Optional[str] = None, + tags: Optional[str] = None, + tags_all_of: Optional[str] = None, + tags_any_of: Optional[str] = None, + author: Optional[str] = None, + author_any_of: Optional[str] = None, + author_gt: Optional[str] = None, + author_gte: Optional[str] = None, + author_lt: Optional[str] = None, + author_lte: Optional[str] = None, + stocks: Optional[str] = None, + stocks_all_of: Optional[str] = None, + stocks_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaNews], HTTPResponse]: ... def list_benzinga_news_v2( self, published: Optional[str] = None, @@ -407,6 +1300,196 @@ def list_benzinga_news_v2( options=options, ) + @overload + def list_benzinga_ratings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + price_target_action: Optional[str] = None, + price_target_action_any_of: Optional[str] = None, + price_target_action_gt: Optional[str] = None, + price_target_action_gte: Optional[str] = None, + price_target_action_lt: Optional[str] = None, + price_target_action_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_analyst_id: Optional[str] = None, + benzinga_analyst_id_any_of: Optional[str] = None, + benzinga_analyst_id_gt: Optional[str] = None, + benzinga_analyst_id_gte: Optional[str] = None, + benzinga_analyst_id_lt: Optional[str] = None, + benzinga_analyst_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaRating]: ... + @overload + def list_benzinga_ratings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + price_target_action: Optional[str] = None, + price_target_action_any_of: Optional[str] = None, + price_target_action_gt: Optional[str] = None, + price_target_action_gte: Optional[str] = None, + price_target_action_lt: Optional[str] = None, + price_target_action_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_analyst_id: Optional[str] = None, + benzinga_analyst_id_any_of: Optional[str] = None, + benzinga_analyst_id_gt: Optional[str] = None, + benzinga_analyst_id_gte: Optional[str] = None, + benzinga_analyst_id_lt: Optional[str] = None, + benzinga_analyst_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_ratings( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + importance: Optional[int] = None, + importance_any_of: Optional[str] = None, + importance_gt: Optional[int] = None, + importance_gte: Optional[int] = None, + importance_lt: Optional[int] = None, + importance_lte: Optional[int] = None, + last_updated: Optional[str] = None, + last_updated_any_of: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + rating_action: Optional[str] = None, + rating_action_any_of: Optional[str] = None, + rating_action_gt: Optional[str] = None, + rating_action_gte: Optional[str] = None, + rating_action_lt: Optional[str] = None, + rating_action_lte: Optional[str] = None, + price_target_action: Optional[str] = None, + price_target_action_any_of: Optional[str] = None, + price_target_action_gt: Optional[str] = None, + price_target_action_gte: Optional[str] = None, + price_target_action_lt: Optional[str] = None, + price_target_action_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + benzinga_analyst_id: Optional[str] = None, + benzinga_analyst_id_any_of: Optional[str] = None, + benzinga_analyst_id_gt: Optional[str] = None, + benzinga_analyst_id_gte: Optional[str] = None, + benzinga_analyst_id_lt: Optional[str] = None, + benzinga_analyst_id_lte: Optional[str] = None, + benzinga_firm_id: Optional[str] = None, + benzinga_firm_id_any_of: Optional[str] = None, + benzinga_firm_id_gt: Optional[str] = None, + benzinga_firm_id_gte: Optional[str] = None, + benzinga_firm_id_lt: Optional[str] = None, + benzinga_firm_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaRating], HTTPResponse]: ... def list_benzinga_ratings( self, date: Optional[Union[str, date]] = None, @@ -481,6 +1564,85 @@ def list_benzinga_ratings( options=options, ) + @overload + def list_benzinga_bulls_bears_say( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[BenzingaBullsBearsSay]: ... + @overload + def list_benzinga_bulls_bears_say( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_benzinga_bulls_bears_say( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + benzinga_id: Optional[str] = None, + benzinga_id_any_of: Optional[str] = None, + benzinga_id_gt: Optional[str] = None, + benzinga_id_gte: Optional[str] = None, + benzinga_id_lt: Optional[str] = None, + benzinga_id_lte: Optional[str] = None, + last_updated: Optional[str] = None, + last_updated_gt: Optional[str] = None, + last_updated_gte: Optional[str] = None, + last_updated_lt: Optional[str] = None, + last_updated_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[BenzingaBullsBearsSay], HTTPResponse]: ... def list_benzinga_bulls_bears_say( self, ticker: Optional[str] = None, diff --git a/massive/rest/economy.py b/massive/rest/economy.py index 4c4b251f..2ad06852 100644 --- a/massive/rest/economy.py +++ b/massive/rest/economy.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -8,6 +8,7 @@ TreasuryYield, FedInflationExpectations, FedLaborMarket, + FedFundingConditions, EUMerchantAggregate, EUMerchantHierarchy, ) @@ -21,6 +22,55 @@ class EconomyClient(BaseClient): (aligned with the paths from /fed/v1/...) """ + @overload + def list_treasury_yields( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[TreasuryYield]: ... + @overload + def list_treasury_yields( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: 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: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_treasury_yields( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[TreasuryYield], HTTPResponse]: ... def list_treasury_yields( self, date: Optional[str] = None, @@ -35,7 +85,7 @@ def list_treasury_yields( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[List[TreasuryYield], HTTPResponse]: + ) -> Union[Iterator[TreasuryYield], HTTPResponse]: """ Retrieve treasury yield data. @@ -51,7 +101,7 @@ def list_treasury_yields( :param params: Additional query parameters. :param raw: Return raw HTTPResponse object if True, else return List[TreasuryYield]. :param options: RequestOptionBuilder for additional headers or params. - :return: A list of TreasuryYield objects or HTTPResponse if raw=True. + :return: An iterator of TreasuryYield objects or HTTPResponse if raw=True. """ url = "/fed/v1/treasury-yields" @@ -64,6 +114,52 @@ def list_treasury_yields( options=options, ) + @overload + def list_inflation( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FedInflation]: ... + @overload + def list_inflation( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_inflation( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FedInflation], HTTPResponse]: ... def list_inflation( self, date: Optional[Union[str, date]] = None, @@ -90,6 +186,52 @@ def list_inflation( options=options, ) + @overload + def list_inflation_expectations( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FedInflationExpectations]: ... + @overload + def list_inflation_expectations( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_inflation_expectations( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FedInflationExpectations], HTTPResponse]: ... def list_inflation_expectations( self, date: Optional[Union[str, date]] = None, @@ -131,6 +273,52 @@ def list_inflation_expectations( options=options, ) + @overload + def list_labor_market_indicators( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FedLaborMarket]: ... + @overload + def list_labor_market_indicators( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_labor_market_indicators( + self, + date: Optional[str] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FedLaborMarket], HTTPResponse]: ... def list_labor_market_indicators( self, date: Optional[str] = None, @@ -171,6 +359,185 @@ def list_labor_market_indicators( options=options, ) + @overload + def list_funding_conditions( + self, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FedFundingConditions]: ... + @overload + def list_funding_conditions( + self, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_funding_conditions( + self, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FedFundingConditions], HTTPResponse]: ... + def list_funding_conditions( + self, + date: Optional[Union[str, date]] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FedFundingConditions], HTTPResponse]: + """ + Daily U.S. money-market funding conditions from the Federal Reserve and the Federal Reserve Bank of New York, including the Federal Funds Effective Rate, SOFR, OBFR, tri-party general collateral repo rates, Treasury-collateralized overnight reverse repo and repo operation amounts, and commercial paper rates. + + :param date: Calendar date of the observation (YYYY-MM-DD). + :param date_gt: Filter greater than the value. + :param date_gte: Filter greater than or equal to the value. + :param date_lt: Filter less than the value. + :param date_lte: Filter less than or equal to the value. + :param limit: Limit the maximum number of results returned. Defaults to '100' if not specified. The maximum allowed limit is '50000'. + :param sort: A comma separated list of sort columns. For each column, append '.asc' or '.desc' to specify the sort direction, e.g. "date.desc". The sort column defaults to 'date' if not specified. The sort order defaults to 'asc' if not specified. The value is sent as given. + :param params: Additional query parameters. + :param raw: Return raw HTTPResponse object if True, else return Iterator[FedFundingConditions]. + :param options: RequestOptionBuilder for additional headers or params. + :return: An iterator of FedFundingConditions objects or HTTPResponse if raw=True. + """ + url = "/fed/v1/funding-conditions" + + return self._paginate( + path=url, + params=self._get_params(self.list_funding_conditions, locals()), + deserializer=FedFundingConditions.from_dict, + raw=raw, + result_key="results", + options=options, + ) + + @overload + def list_eu_merchant_aggregates( + self, + transaction_date: Optional[Union[str, date]] = None, + transaction_date_gt: Optional[Union[str, date]] = None, + transaction_date_gte: Optional[Union[str, date]] = None, + transaction_date_lt: Optional[Union[str, date]] = None, + transaction_date_lte: Optional[Union[str, date]] = None, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + user_country: Optional[str] = None, + user_country_any_of: Optional[str] = None, + channel: Optional[str] = None, + channel_any_of: Optional[str] = None, + consumer_type: Optional[str] = None, + consumer_type_any_of: Optional[str] = None, + parent_name: Optional[str] = None, + parent_name_any_of: Optional[str] = None, + parent_name_gt: Optional[str] = None, + parent_name_gte: Optional[str] = None, + parent_name_lt: Optional[str] = None, + parent_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EUMerchantAggregate]: ... + @overload + def list_eu_merchant_aggregates( + self, + transaction_date: Optional[Union[str, date]] = None, + transaction_date_gt: Optional[Union[str, date]] = None, + transaction_date_gte: Optional[Union[str, date]] = None, + transaction_date_lt: Optional[Union[str, date]] = None, + transaction_date_lte: Optional[Union[str, date]] = None, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + user_country: Optional[str] = None, + user_country_any_of: Optional[str] = None, + channel: Optional[str] = None, + channel_any_of: Optional[str] = None, + consumer_type: Optional[str] = None, + consumer_type_any_of: Optional[str] = None, + parent_name: Optional[str] = None, + parent_name_any_of: Optional[str] = None, + parent_name_gt: Optional[str] = None, + parent_name_gte: Optional[str] = None, + parent_name_lt: Optional[str] = None, + parent_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_eu_merchant_aggregates( + self, + transaction_date: Optional[Union[str, date]] = None, + transaction_date_gt: Optional[Union[str, date]] = None, + transaction_date_gte: Optional[Union[str, date]] = None, + transaction_date_lt: Optional[Union[str, date]] = None, + transaction_date_lte: Optional[Union[str, date]] = None, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + user_country: Optional[str] = None, + user_country_any_of: Optional[str] = None, + channel: Optional[str] = None, + channel_any_of: Optional[str] = None, + consumer_type: Optional[str] = None, + consumer_type_any_of: Optional[str] = None, + parent_name: Optional[str] = None, + parent_name_any_of: Optional[str] = None, + parent_name_gt: Optional[str] = None, + parent_name_gte: Optional[str] = None, + parent_name_lt: Optional[str] = None, + parent_name_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EUMerchantAggregate], HTTPResponse]: ... def list_eu_merchant_aggregates( self, transaction_date: Optional[Union[str, date]] = None, @@ -221,6 +588,106 @@ def list_eu_merchant_aggregates( options=options, ) + @overload + def list_eu_merchant_hierarchy( + self, + lookup_name: Optional[str] = None, + lookup_name_any_of: Optional[str] = None, + lookup_name_gt: Optional[str] = None, + lookup_name_gte: Optional[str] = None, + lookup_name_lt: Optional[str] = None, + lookup_name_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + listing_status: Optional[str] = None, + listing_status_any_of: Optional[str] = None, + active_from: Optional[Union[str, date]] = None, + active_from_gt: Optional[Union[str, date]] = None, + active_from_gte: Optional[Union[str, date]] = None, + active_from_lt: Optional[Union[str, date]] = None, + active_from_lte: Optional[Union[str, date]] = None, + active_to: Optional[Union[str, date]] = None, + active_to_gt: Optional[Union[str, date]] = None, + active_to_gte: Optional[Union[str, date]] = None, + active_to_lt: Optional[Union[str, date]] = None, + active_to_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EUMerchantHierarchy]: ... + @overload + def list_eu_merchant_hierarchy( + self, + lookup_name: Optional[str] = None, + lookup_name_any_of: Optional[str] = None, + lookup_name_gt: Optional[str] = None, + lookup_name_gte: Optional[str] = None, + lookup_name_lt: Optional[str] = None, + lookup_name_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + listing_status: Optional[str] = None, + listing_status_any_of: Optional[str] = None, + active_from: Optional[Union[str, date]] = None, + active_from_gt: Optional[Union[str, date]] = None, + active_from_gte: Optional[Union[str, date]] = None, + active_from_lt: Optional[Union[str, date]] = None, + active_from_lte: Optional[Union[str, date]] = None, + active_to: Optional[Union[str, date]] = None, + active_to_gt: Optional[Union[str, date]] = None, + active_to_gte: Optional[Union[str, date]] = None, + active_to_lt: Optional[Union[str, date]] = None, + active_to_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_eu_merchant_hierarchy( + self, + lookup_name: Optional[str] = None, + lookup_name_any_of: Optional[str] = None, + lookup_name_gt: Optional[str] = None, + lookup_name_gte: Optional[str] = None, + lookup_name_lt: Optional[str] = None, + lookup_name_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + listing_status: Optional[str] = None, + listing_status_any_of: Optional[str] = None, + active_from: Optional[Union[str, date]] = None, + active_from_gt: Optional[Union[str, date]] = None, + active_from_gte: Optional[Union[str, date]] = None, + active_from_lt: Optional[Union[str, date]] = None, + active_from_lte: Optional[Union[str, date]] = None, + active_to: Optional[Union[str, date]] = None, + active_to_gt: Optional[Union[str, date]] = None, + active_to_gte: Optional[Union[str, date]] = None, + active_to_lt: Optional[Union[str, date]] = None, + active_to_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EUMerchantHierarchy], HTTPResponse]: ... def list_eu_merchant_hierarchy( self, lookup_name: Optional[str] = None, diff --git a/massive/rest/etf_global.py b/massive/rest/etf_global.py index 9da19539..ac3360a7 100644 --- a/massive/rest/etf_global.py +++ b/massive/rest/etf_global.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -20,6 +20,7 @@ class EtfGlobalClient(BaseClient): (aligned with the paths from /etf-global/v1/...) """ + @overload def get_etf_global_analytics( self, composite_ticker: Optional[str] = None, @@ -92,21 +93,415 @@ def get_etf_global_analytics( limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EtfGlobalAnalytics]: ... + @overload + def get_etf_global_analytics( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + risk_total_score: Optional[float] = None, + risk_total_score_gt: Optional[float] = None, + risk_total_score_gte: Optional[float] = None, + risk_total_score_lt: Optional[float] = None, + risk_total_score_lte: Optional[float] = None, + reward_score: Optional[float] = None, + reward_score_gt: Optional[float] = None, + reward_score_gte: Optional[float] = None, + reward_score_lt: Optional[float] = None, + reward_score_lte: Optional[float] = None, + quant_total_score: Optional[float] = None, + quant_total_score_gt: Optional[float] = None, + quant_total_score_gte: Optional[float] = None, + quant_total_score_lt: Optional[float] = None, + quant_total_score_lte: Optional[float] = None, + quant_grade: Optional[str] = None, + quant_grade_any_of: Optional[str] = None, + quant_grade_gt: Optional[str] = None, + quant_grade_gte: Optional[str] = None, + quant_grade_lt: Optional[str] = None, + quant_grade_lte: Optional[str] = None, + quant_composite_technical: Optional[float] = None, + quant_composite_technical_gt: Optional[float] = None, + quant_composite_technical_gte: Optional[float] = None, + quant_composite_technical_lt: Optional[float] = None, + quant_composite_technical_lte: Optional[float] = None, + quant_composite_sentiment: Optional[float] = None, + quant_composite_sentiment_gt: Optional[float] = None, + quant_composite_sentiment_gte: Optional[float] = None, + quant_composite_sentiment_lt: Optional[float] = None, + quant_composite_sentiment_lte: Optional[float] = None, + quant_composite_behavioral: Optional[float] = None, + quant_composite_behavioral_gt: Optional[float] = None, + quant_composite_behavioral_gte: Optional[float] = None, + quant_composite_behavioral_lt: Optional[float] = None, + quant_composite_behavioral_lte: Optional[float] = None, + quant_composite_fundamental: Optional[float] = None, + quant_composite_fundamental_gt: Optional[float] = None, + quant_composite_fundamental_gte: Optional[float] = None, + quant_composite_fundamental_lt: Optional[float] = None, + quant_composite_fundamental_lte: Optional[float] = None, + quant_composite_global: Optional[float] = None, + quant_composite_global_gt: Optional[float] = None, + quant_composite_global_gte: Optional[float] = None, + quant_composite_global_lt: Optional[float] = None, + quant_composite_global_lte: Optional[float] = None, + quant_composite_quality: Optional[float] = None, + quant_composite_quality_gt: Optional[float] = None, + quant_composite_quality_gte: Optional[float] = None, + quant_composite_quality_lt: Optional[float] = None, + quant_composite_quality_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def get_etf_global_analytics( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + risk_total_score: Optional[float] = None, + risk_total_score_gt: Optional[float] = None, + risk_total_score_gte: Optional[float] = None, + risk_total_score_lt: Optional[float] = None, + risk_total_score_lte: Optional[float] = None, + reward_score: Optional[float] = None, + reward_score_gt: Optional[float] = None, + reward_score_gte: Optional[float] = None, + reward_score_lt: Optional[float] = None, + reward_score_lte: Optional[float] = None, + quant_total_score: Optional[float] = None, + quant_total_score_gt: Optional[float] = None, + quant_total_score_gte: Optional[float] = None, + quant_total_score_lt: Optional[float] = None, + quant_total_score_lte: Optional[float] = None, + quant_grade: Optional[str] = None, + quant_grade_any_of: Optional[str] = None, + quant_grade_gt: Optional[str] = None, + quant_grade_gte: Optional[str] = None, + quant_grade_lt: Optional[str] = None, + quant_grade_lte: Optional[str] = None, + quant_composite_technical: Optional[float] = None, + quant_composite_technical_gt: Optional[float] = None, + quant_composite_technical_gte: Optional[float] = None, + quant_composite_technical_lt: Optional[float] = None, + quant_composite_technical_lte: Optional[float] = None, + quant_composite_sentiment: Optional[float] = None, + quant_composite_sentiment_gt: Optional[float] = None, + quant_composite_sentiment_gte: Optional[float] = None, + quant_composite_sentiment_lt: Optional[float] = None, + quant_composite_sentiment_lte: Optional[float] = None, + quant_composite_behavioral: Optional[float] = None, + quant_composite_behavioral_gt: Optional[float] = None, + quant_composite_behavioral_gte: Optional[float] = None, + quant_composite_behavioral_lt: Optional[float] = None, + quant_composite_behavioral_lte: Optional[float] = None, + quant_composite_fundamental: Optional[float] = None, + quant_composite_fundamental_gt: Optional[float] = None, + quant_composite_fundamental_gte: Optional[float] = None, + quant_composite_fundamental_lt: Optional[float] = None, + quant_composite_fundamental_lte: Optional[float] = None, + quant_composite_global: Optional[float] = None, + quant_composite_global_gt: Optional[float] = None, + quant_composite_global_gte: Optional[float] = None, + quant_composite_global_lt: Optional[float] = None, + quant_composite_global_lte: Optional[float] = None, + quant_composite_quality: Optional[float] = None, + quant_composite_quality_gt: Optional[float] = None, + quant_composite_quality_gte: Optional[float] = None, + quant_composite_quality_lt: Optional[float] = None, + quant_composite_quality_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EtfGlobalAnalytics], HTTPResponse]: ... + def get_etf_global_analytics( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + risk_total_score: Optional[float] = None, + risk_total_score_gt: Optional[float] = None, + risk_total_score_gte: Optional[float] = None, + risk_total_score_lt: Optional[float] = None, + risk_total_score_lte: Optional[float] = None, + reward_score: Optional[float] = None, + reward_score_gt: Optional[float] = None, + reward_score_gte: Optional[float] = None, + reward_score_lt: Optional[float] = None, + reward_score_lte: Optional[float] = None, + quant_total_score: Optional[float] = None, + quant_total_score_gt: Optional[float] = None, + quant_total_score_gte: Optional[float] = None, + quant_total_score_lt: Optional[float] = None, + quant_total_score_lte: Optional[float] = None, + quant_grade: Optional[str] = None, + quant_grade_any_of: Optional[str] = None, + quant_grade_gt: Optional[str] = None, + quant_grade_gte: Optional[str] = None, + quant_grade_lt: Optional[str] = None, + quant_grade_lte: Optional[str] = None, + quant_composite_technical: Optional[float] = None, + quant_composite_technical_gt: Optional[float] = None, + quant_composite_technical_gte: Optional[float] = None, + quant_composite_technical_lt: Optional[float] = None, + quant_composite_technical_lte: Optional[float] = None, + quant_composite_sentiment: Optional[float] = None, + quant_composite_sentiment_gt: Optional[float] = None, + quant_composite_sentiment_gte: Optional[float] = None, + quant_composite_sentiment_lt: Optional[float] = None, + quant_composite_sentiment_lte: Optional[float] = None, + quant_composite_behavioral: Optional[float] = None, + quant_composite_behavioral_gt: Optional[float] = None, + quant_composite_behavioral_gte: Optional[float] = None, + quant_composite_behavioral_lt: Optional[float] = None, + quant_composite_behavioral_lte: Optional[float] = None, + quant_composite_fundamental: Optional[float] = None, + quant_composite_fundamental_gt: Optional[float] = None, + quant_composite_fundamental_gte: Optional[float] = None, + quant_composite_fundamental_lt: Optional[float] = None, + quant_composite_fundamental_lte: Optional[float] = None, + quant_composite_global: Optional[float] = None, + quant_composite_global_gt: Optional[float] = None, + quant_composite_global_gte: Optional[float] = None, + quant_composite_global_lt: Optional[float] = None, + quant_composite_global_lte: Optional[float] = None, + quant_composite_quality: Optional[float] = None, + quant_composite_quality_gt: Optional[float] = None, + quant_composite_quality_gte: Optional[float] = None, + quant_composite_quality_lt: Optional[float] = None, + quant_composite_quality_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EtfGlobalAnalytics], HTTPResponse]: + """ + Endpoint: GET /etf-global/v1/analytics + """ + url = "/etf-global/v1/analytics" + return self._paginate( + path=url, + params=self._get_params(self.get_etf_global_analytics, locals()), + raw=raw, + deserializer=EtfGlobalAnalytics.from_dict, + options=options, + ) + + @overload + def get_etf_global_constituents( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + constituent_ticker: Optional[str] = None, + constituent_ticker_any_of: Optional[str] = None, + constituent_ticker_gt: Optional[str] = None, + constituent_ticker_gte: Optional[str] = None, + constituent_ticker_lt: Optional[str] = None, + constituent_ticker_lte: Optional[str] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + us_code: Optional[str] = None, + us_code_any_of: Optional[str] = None, + us_code_gt: Optional[str] = None, + us_code_gte: Optional[str] = None, + us_code_lt: Optional[str] = None, + us_code_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + figi: Optional[str] = None, + figi_any_of: Optional[str] = None, + figi_gt: Optional[str] = None, + figi_gte: Optional[str] = None, + figi_lt: Optional[str] = None, + figi_lte: Optional[str] = None, + sedol: Optional[str] = None, + sedol_any_of: Optional[str] = None, + sedol_gt: Optional[str] = None, + sedol_gte: Optional[str] = None, + sedol_lt: Optional[str] = None, + sedol_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EtfGlobalConstituent]: ... + @overload + def get_etf_global_constituents( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + constituent_ticker: Optional[str] = None, + constituent_ticker_any_of: Optional[str] = None, + constituent_ticker_gt: Optional[str] = None, + constituent_ticker_gte: Optional[str] = None, + constituent_ticker_lt: Optional[str] = None, + constituent_ticker_lte: Optional[str] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + us_code: Optional[str] = None, + us_code_any_of: Optional[str] = None, + us_code_gt: Optional[str] = None, + us_code_gte: Optional[str] = None, + us_code_lt: Optional[str] = None, + us_code_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + figi: Optional[str] = None, + figi_any_of: Optional[str] = None, + figi_gt: Optional[str] = None, + figi_gte: Optional[str] = None, + figi_lt: Optional[str] = None, + figi_lte: Optional[str] = None, + sedol: Optional[str] = None, + sedol_any_of: Optional[str] = None, + sedol_gt: Optional[str] = None, + sedol_gte: Optional[str] = None, + sedol_lt: Optional[str] = None, + sedol_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def get_etf_global_constituents( + self, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + constituent_ticker: Optional[str] = None, + constituent_ticker_any_of: Optional[str] = None, + constituent_ticker_gt: Optional[str] = None, + constituent_ticker_gte: Optional[str] = None, + constituent_ticker_lt: Optional[str] = None, + constituent_ticker_lte: Optional[str] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + us_code: Optional[str] = None, + us_code_any_of: Optional[str] = None, + us_code_gt: Optional[str] = None, + us_code_gte: Optional[str] = None, + us_code_lt: Optional[str] = None, + us_code_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + figi: Optional[str] = None, + figi_any_of: Optional[str] = None, + figi_gt: Optional[str] = None, + figi_gte: Optional[str] = None, + figi_lt: Optional[str] = None, + figi_lte: Optional[str] = None, + sedol: Optional[str] = None, + sedol_any_of: Optional[str] = None, + sedol_gt: Optional[str] = None, + sedol_gte: Optional[str] = None, + sedol_lt: Optional[str] = None, + sedol_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[EtfGlobalAnalytics], HTTPResponse]: - """ - Endpoint: GET /etf-global/v1/analytics - """ - url = "/etf-global/v1/analytics" - return self._paginate( - path=url, - params=self._get_params(self.get_etf_global_analytics, locals()), - raw=raw, - deserializer=EtfGlobalAnalytics.from_dict, - options=options, - ) - + ) -> Union[Iterator[EtfGlobalConstituent], HTTPResponse]: ... def get_etf_global_constituents( self, composite_ticker: Optional[str] = None, @@ -173,6 +568,82 @@ def get_etf_global_constituents( options=options, ) + @overload + def get_etf_global_fund_flows( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EtfGlobalFundFlow]: ... + @overload + def get_etf_global_fund_flows( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def get_etf_global_fund_flows( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EtfGlobalFundFlow], HTTPResponse]: ... def get_etf_global_fund_flows( self, processed_date: Optional[Union[str, date]] = None, @@ -209,6 +680,82 @@ def get_etf_global_fund_flows( options=options, ) + @overload + def get_etf_global_profiles( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EtfGlobalProfile]: ... + @overload + def get_etf_global_profiles( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def get_etf_global_profiles( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EtfGlobalProfile], HTTPResponse]: ... def get_etf_global_profiles( self, processed_date: Optional[Union[str, date]] = None, @@ -245,6 +792,82 @@ def get_etf_global_profiles( options=options, ) + @overload + def get_etf_global_taxonomies( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[EtfGlobalTaxonomy]: ... + @overload + def get_etf_global_taxonomies( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def get_etf_global_taxonomies( + self, + processed_date: Optional[Union[str, date]] = None, + processed_date_gt: Optional[Union[str, date]] = None, + processed_date_gte: Optional[Union[str, date]] = None, + processed_date_lt: Optional[Union[str, date]] = None, + processed_date_lte: Optional[Union[str, date]] = None, + effective_date: Optional[Union[str, date]] = None, + effective_date_gt: Optional[Union[str, date]] = None, + effective_date_gte: Optional[Union[str, date]] = None, + effective_date_lt: Optional[Union[str, date]] = None, + effective_date_lte: Optional[Union[str, date]] = None, + composite_ticker: Optional[str] = None, + composite_ticker_any_of: Optional[str] = None, + composite_ticker_gt: Optional[str] = None, + composite_ticker_gte: Optional[str] = None, + composite_ticker_lt: Optional[str] = None, + composite_ticker_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[EtfGlobalTaxonomy], HTTPResponse]: ... def get_etf_global_taxonomies( self, processed_date: Optional[Union[str, date]] = None, diff --git a/massive/rest/financials.py b/massive/rest/financials.py index 6138258a..9c6475ec 100644 --- a/massive/rest/financials.py +++ b/massive/rest/financials.py @@ -1,5 +1,5 @@ # financials.py -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -21,6 +21,139 @@ class FinancialsClient(BaseClient): (aligned with the paths from /stocks/financials/v1/...) """ + @overload + def list_financials_balance_sheets( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FinancialBalanceSheet]: ... + @overload + def list_financials_balance_sheets( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_financials_balance_sheets( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialBalanceSheet], HTTPResponse]: ... def list_financials_balance_sheets( self, cik: Optional[str] = None, @@ -76,6 +209,139 @@ def list_financials_balance_sheets( options=options, ) + @overload + def list_financials_cash_flow_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FinancialCashFlowStatement]: ... + @overload + def list_financials_cash_flow_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_financials_cash_flow_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialCashFlowStatement], HTTPResponse]: ... def list_financials_cash_flow_statements( self, cik: Optional[str] = None, @@ -116,78 +382,575 @@ def list_financials_cash_flow_statements( limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False, - options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[FinancialCashFlowStatement], HTTPResponse]: - """ - Endpoint: GET /stocks/financials/v1/cash-flow-statements - """ - url = "/stocks/financials/v1/cash-flow-statements" - return self._paginate( - path=url, - params=self._get_params( - self.list_financials_cash_flow_statements, locals() - ), - raw=raw, - deserializer=FinancialCashFlowStatement.from_dict, - options=options, - ) - - def list_financials_income_statements( + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialCashFlowStatement], HTTPResponse]: + """ + Endpoint: GET /stocks/financials/v1/cash-flow-statements + """ + url = "/stocks/financials/v1/cash-flow-statements" + return self._paginate( + path=url, + params=self._get_params( + self.list_financials_cash_flow_statements, locals() + ), + raw=raw, + deserializer=FinancialCashFlowStatement.from_dict, + options=options, + ) + + @overload + def list_financials_income_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FinancialIncomeStatement]: ... + @overload + def list_financials_income_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_financials_income_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialIncomeStatement], HTTPResponse]: ... + def list_financials_income_statements( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + fiscal_year: Optional[float] = None, + fiscal_year_gt: Optional[float] = None, + fiscal_year_gte: Optional[float] = None, + fiscal_year_lt: Optional[float] = None, + fiscal_year_lte: Optional[float] = None, + fiscal_quarter: Optional[float] = None, + fiscal_quarter_gt: Optional[float] = None, + fiscal_quarter_gte: Optional[float] = None, + fiscal_quarter_lt: Optional[float] = None, + fiscal_quarter_lte: Optional[float] = None, + timeframe: Optional[str] = None, + timeframe_any_of: Optional[str] = None, + timeframe_gt: Optional[str] = None, + timeframe_gte: Optional[str] = None, + timeframe_lt: Optional[str] = None, + timeframe_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialIncomeStatement], HTTPResponse]: + """ + Endpoint: GET /stocks/financials/v1/income-statements + """ + url = "/stocks/financials/v1/income-statements" + return self._paginate( + path=url, + params=self._get_params(self.list_financials_income_statements, locals()), + raw=raw, + deserializer=FinancialIncomeStatement.from_dict, + options=options, + ) + + @overload + def list_financials_ratios( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + price: Optional[float] = None, + price_gt: Optional[float] = None, + price_gte: Optional[float] = None, + price_lt: Optional[float] = None, + price_lte: Optional[float] = None, + average_volume: Optional[float] = None, + average_volume_gt: Optional[float] = None, + average_volume_gte: Optional[float] = None, + average_volume_lt: Optional[float] = None, + average_volume_lte: Optional[float] = None, + market_cap: Optional[float] = None, + market_cap_gt: Optional[float] = None, + market_cap_gte: Optional[float] = None, + market_cap_lt: Optional[float] = None, + market_cap_lte: Optional[float] = None, + earnings_per_share: Optional[float] = None, + earnings_per_share_gt: Optional[float] = None, + earnings_per_share_gte: Optional[float] = None, + earnings_per_share_lt: Optional[float] = None, + earnings_per_share_lte: Optional[float] = None, + price_to_earnings: Optional[float] = None, + price_to_earnings_gt: Optional[float] = None, + price_to_earnings_gte: Optional[float] = None, + price_to_earnings_lt: Optional[float] = None, + price_to_earnings_lte: Optional[float] = None, + price_to_book: Optional[float] = None, + price_to_book_gt: Optional[float] = None, + price_to_book_gte: Optional[float] = None, + price_to_book_lt: Optional[float] = None, + price_to_book_lte: Optional[float] = None, + price_to_sales: Optional[float] = None, + price_to_sales_gt: Optional[float] = None, + price_to_sales_gte: Optional[float] = None, + price_to_sales_lt: Optional[float] = None, + price_to_sales_lte: Optional[float] = None, + price_to_cash_flow: Optional[float] = None, + price_to_cash_flow_gt: Optional[float] = None, + price_to_cash_flow_gte: Optional[float] = None, + price_to_cash_flow_lt: Optional[float] = None, + price_to_cash_flow_lte: Optional[float] = None, + price_to_free_cash_flow: Optional[float] = None, + price_to_free_cash_flow_gt: Optional[float] = None, + price_to_free_cash_flow_gte: Optional[float] = None, + price_to_free_cash_flow_lt: Optional[float] = None, + price_to_free_cash_flow_lte: Optional[float] = None, + dividend_yield: Optional[float] = None, + dividend_yield_gt: Optional[float] = None, + dividend_yield_gte: Optional[float] = None, + dividend_yield_lt: Optional[float] = None, + dividend_yield_lte: Optional[float] = None, + return_on_assets: Optional[float] = None, + return_on_assets_gt: Optional[float] = None, + return_on_assets_gte: Optional[float] = None, + return_on_assets_lt: Optional[float] = None, + return_on_assets_lte: Optional[float] = None, + return_on_equity: Optional[float] = None, + return_on_equity_gt: Optional[float] = None, + return_on_equity_gte: Optional[float] = None, + return_on_equity_lt: Optional[float] = None, + return_on_equity_lte: Optional[float] = None, + debt_to_equity: Optional[float] = None, + debt_to_equity_gt: Optional[float] = None, + debt_to_equity_gte: Optional[float] = None, + debt_to_equity_lt: Optional[float] = None, + debt_to_equity_lte: Optional[float] = None, + current: Optional[float] = None, + current_gt: Optional[float] = None, + current_gte: Optional[float] = None, + current_lt: Optional[float] = None, + current_lte: Optional[float] = None, + quick: Optional[float] = None, + quick_gt: Optional[float] = None, + quick_gte: Optional[float] = None, + quick_lt: Optional[float] = None, + quick_lte: Optional[float] = None, + cash: Optional[float] = None, + cash_gt: Optional[float] = None, + cash_gte: Optional[float] = None, + cash_lt: Optional[float] = None, + cash_lte: Optional[float] = None, + ev_to_sales: Optional[float] = None, + ev_to_sales_gt: Optional[float] = None, + ev_to_sales_gte: Optional[float] = None, + ev_to_sales_lt: Optional[float] = None, + ev_to_sales_lte: Optional[float] = None, + ev_to_ebitda: Optional[float] = None, + ev_to_ebitda_gt: Optional[float] = None, + ev_to_ebitda_gte: Optional[float] = None, + ev_to_ebitda_lt: Optional[float] = None, + ev_to_ebitda_lte: Optional[float] = None, + enterprise_value: Optional[float] = None, + enterprise_value_gt: Optional[float] = None, + enterprise_value_gte: Optional[float] = None, + enterprise_value_lt: Optional[float] = None, + enterprise_value_lte: Optional[float] = None, + free_cash_flow: Optional[float] = None, + free_cash_flow_gt: Optional[float] = None, + free_cash_flow_gte: Optional[float] = None, + free_cash_flow_lt: Optional[float] = None, + free_cash_flow_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FinancialRatio]: ... + @overload + def list_financials_ratios( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + price: Optional[float] = None, + price_gt: Optional[float] = None, + price_gte: Optional[float] = None, + price_lt: Optional[float] = None, + price_lte: Optional[float] = None, + average_volume: Optional[float] = None, + average_volume_gt: Optional[float] = None, + average_volume_gte: Optional[float] = None, + average_volume_lt: Optional[float] = None, + average_volume_lte: Optional[float] = None, + market_cap: Optional[float] = None, + market_cap_gt: Optional[float] = None, + market_cap_gte: Optional[float] = None, + market_cap_lt: Optional[float] = None, + market_cap_lte: Optional[float] = None, + earnings_per_share: Optional[float] = None, + earnings_per_share_gt: Optional[float] = None, + earnings_per_share_gte: Optional[float] = None, + earnings_per_share_lt: Optional[float] = None, + earnings_per_share_lte: Optional[float] = None, + price_to_earnings: Optional[float] = None, + price_to_earnings_gt: Optional[float] = None, + price_to_earnings_gte: Optional[float] = None, + price_to_earnings_lt: Optional[float] = None, + price_to_earnings_lte: Optional[float] = None, + price_to_book: Optional[float] = None, + price_to_book_gt: Optional[float] = None, + price_to_book_gte: Optional[float] = None, + price_to_book_lt: Optional[float] = None, + price_to_book_lte: Optional[float] = None, + price_to_sales: Optional[float] = None, + price_to_sales_gt: Optional[float] = None, + price_to_sales_gte: Optional[float] = None, + price_to_sales_lt: Optional[float] = None, + price_to_sales_lte: Optional[float] = None, + price_to_cash_flow: Optional[float] = None, + price_to_cash_flow_gt: Optional[float] = None, + price_to_cash_flow_gte: Optional[float] = None, + price_to_cash_flow_lt: Optional[float] = None, + price_to_cash_flow_lte: Optional[float] = None, + price_to_free_cash_flow: Optional[float] = None, + price_to_free_cash_flow_gt: Optional[float] = None, + price_to_free_cash_flow_gte: Optional[float] = None, + price_to_free_cash_flow_lt: Optional[float] = None, + price_to_free_cash_flow_lte: Optional[float] = None, + dividend_yield: Optional[float] = None, + dividend_yield_gt: Optional[float] = None, + dividend_yield_gte: Optional[float] = None, + dividend_yield_lt: Optional[float] = None, + dividend_yield_lte: Optional[float] = None, + return_on_assets: Optional[float] = None, + return_on_assets_gt: Optional[float] = None, + return_on_assets_gte: Optional[float] = None, + return_on_assets_lt: Optional[float] = None, + return_on_assets_lte: Optional[float] = None, + return_on_equity: Optional[float] = None, + return_on_equity_gt: Optional[float] = None, + return_on_equity_gte: Optional[float] = None, + return_on_equity_lt: Optional[float] = None, + return_on_equity_lte: Optional[float] = None, + debt_to_equity: Optional[float] = None, + debt_to_equity_gt: Optional[float] = None, + debt_to_equity_gte: Optional[float] = None, + debt_to_equity_lt: Optional[float] = None, + debt_to_equity_lte: Optional[float] = None, + current: Optional[float] = None, + current_gt: Optional[float] = None, + current_gte: Optional[float] = None, + current_lt: Optional[float] = None, + current_lte: Optional[float] = None, + quick: Optional[float] = None, + quick_gt: Optional[float] = None, + quick_gte: Optional[float] = None, + quick_lt: Optional[float] = None, + quick_lte: Optional[float] = None, + cash: Optional[float] = None, + cash_gt: Optional[float] = None, + cash_gte: Optional[float] = None, + cash_lt: Optional[float] = None, + cash_lte: Optional[float] = None, + ev_to_sales: Optional[float] = None, + ev_to_sales_gt: Optional[float] = None, + ev_to_sales_gte: Optional[float] = None, + ev_to_sales_lt: Optional[float] = None, + ev_to_sales_lte: Optional[float] = None, + ev_to_ebitda: Optional[float] = None, + ev_to_ebitda_gt: Optional[float] = None, + ev_to_ebitda_gte: Optional[float] = None, + ev_to_ebitda_lt: Optional[float] = None, + ev_to_ebitda_lte: Optional[float] = None, + enterprise_value: Optional[float] = None, + enterprise_value_gt: Optional[float] = None, + enterprise_value_gte: Optional[float] = None, + enterprise_value_lt: Optional[float] = None, + enterprise_value_lte: Optional[float] = None, + free_cash_flow: Optional[float] = None, + free_cash_flow_gt: Optional[float] = None, + free_cash_flow_gte: Optional[float] = None, + free_cash_flow_lt: Optional[float] = None, + free_cash_flow_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_financials_ratios( self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, cik: Optional[str] = None, cik_any_of: Optional[str] = None, cik_gt: Optional[str] = None, cik_gte: Optional[str] = None, cik_lt: Optional[str] = None, cik_lte: Optional[str] = None, - tickers: Optional[str] = None, - tickers_all_of: Optional[str] = None, - tickers_any_of: Optional[str] = None, - period_end: Optional[Union[str, date]] = None, - period_end_gt: Optional[Union[str, date]] = None, - period_end_gte: Optional[Union[str, date]] = None, - period_end_lt: Optional[Union[str, date]] = None, - period_end_lte: Optional[Union[str, date]] = None, - filing_date: Optional[Union[str, date]] = None, - filing_date_gt: Optional[Union[str, date]] = None, - filing_date_gte: Optional[Union[str, date]] = None, - filing_date_lt: Optional[Union[str, date]] = None, - filing_date_lte: Optional[Union[str, date]] = None, - fiscal_year: Optional[float] = None, - fiscal_year_gt: Optional[float] = None, - fiscal_year_gte: Optional[float] = None, - fiscal_year_lt: Optional[float] = None, - fiscal_year_lte: Optional[float] = None, - fiscal_quarter: Optional[float] = None, - fiscal_quarter_gt: Optional[float] = None, - fiscal_quarter_gte: Optional[float] = None, - fiscal_quarter_lt: Optional[float] = None, - fiscal_quarter_lte: Optional[float] = None, - timeframe: Optional[str] = None, - timeframe_any_of: Optional[str] = None, - timeframe_gt: Optional[str] = None, - timeframe_gte: Optional[str] = None, - timeframe_lt: Optional[str] = None, - timeframe_lte: Optional[str] = None, + price: Optional[float] = None, + price_gt: Optional[float] = None, + price_gte: Optional[float] = None, + price_lt: Optional[float] = None, + price_lte: Optional[float] = None, + average_volume: Optional[float] = None, + average_volume_gt: Optional[float] = None, + average_volume_gte: Optional[float] = None, + average_volume_lt: Optional[float] = None, + average_volume_lte: Optional[float] = None, + market_cap: Optional[float] = None, + market_cap_gt: Optional[float] = None, + market_cap_gte: Optional[float] = None, + market_cap_lt: Optional[float] = None, + market_cap_lte: Optional[float] = None, + earnings_per_share: Optional[float] = None, + earnings_per_share_gt: Optional[float] = None, + earnings_per_share_gte: Optional[float] = None, + earnings_per_share_lt: Optional[float] = None, + earnings_per_share_lte: Optional[float] = None, + price_to_earnings: Optional[float] = None, + price_to_earnings_gt: Optional[float] = None, + price_to_earnings_gte: Optional[float] = None, + price_to_earnings_lt: Optional[float] = None, + price_to_earnings_lte: Optional[float] = None, + price_to_book: Optional[float] = None, + price_to_book_gt: Optional[float] = None, + price_to_book_gte: Optional[float] = None, + price_to_book_lt: Optional[float] = None, + price_to_book_lte: Optional[float] = None, + price_to_sales: Optional[float] = None, + price_to_sales_gt: Optional[float] = None, + price_to_sales_gte: Optional[float] = None, + price_to_sales_lt: Optional[float] = None, + price_to_sales_lte: Optional[float] = None, + price_to_cash_flow: Optional[float] = None, + price_to_cash_flow_gt: Optional[float] = None, + price_to_cash_flow_gte: Optional[float] = None, + price_to_cash_flow_lt: Optional[float] = None, + price_to_cash_flow_lte: Optional[float] = None, + price_to_free_cash_flow: Optional[float] = None, + price_to_free_cash_flow_gt: Optional[float] = None, + price_to_free_cash_flow_gte: Optional[float] = None, + price_to_free_cash_flow_lt: Optional[float] = None, + price_to_free_cash_flow_lte: Optional[float] = None, + dividend_yield: Optional[float] = None, + dividend_yield_gt: Optional[float] = None, + dividend_yield_gte: Optional[float] = None, + dividend_yield_lt: Optional[float] = None, + dividend_yield_lte: Optional[float] = None, + return_on_assets: Optional[float] = None, + return_on_assets_gt: Optional[float] = None, + return_on_assets_gte: Optional[float] = None, + return_on_assets_lt: Optional[float] = None, + return_on_assets_lte: Optional[float] = None, + return_on_equity: Optional[float] = None, + return_on_equity_gt: Optional[float] = None, + return_on_equity_gte: Optional[float] = None, + return_on_equity_lt: Optional[float] = None, + return_on_equity_lte: Optional[float] = None, + debt_to_equity: Optional[float] = None, + debt_to_equity_gt: Optional[float] = None, + debt_to_equity_gte: Optional[float] = None, + debt_to_equity_lt: Optional[float] = None, + debt_to_equity_lte: Optional[float] = None, + current: Optional[float] = None, + current_gt: Optional[float] = None, + current_gte: Optional[float] = None, + current_lt: Optional[float] = None, + current_lte: Optional[float] = None, + quick: Optional[float] = None, + quick_gt: Optional[float] = None, + quick_gte: Optional[float] = None, + quick_lt: Optional[float] = None, + quick_lte: Optional[float] = None, + cash: Optional[float] = None, + cash_gt: Optional[float] = None, + cash_gte: Optional[float] = None, + cash_lt: Optional[float] = None, + cash_lte: Optional[float] = None, + ev_to_sales: Optional[float] = None, + ev_to_sales_gt: Optional[float] = None, + ev_to_sales_gte: Optional[float] = None, + ev_to_sales_lt: Optional[float] = None, + ev_to_sales_lte: Optional[float] = None, + ev_to_ebitda: Optional[float] = None, + ev_to_ebitda_gt: Optional[float] = None, + ev_to_ebitda_gte: Optional[float] = None, + ev_to_ebitda_lt: Optional[float] = None, + ev_to_ebitda_lte: Optional[float] = None, + enterprise_value: Optional[float] = None, + enterprise_value_gt: Optional[float] = None, + enterprise_value_gte: Optional[float] = None, + enterprise_value_lt: Optional[float] = None, + enterprise_value_lte: Optional[float] = None, + free_cash_flow: Optional[float] = None, + free_cash_flow_gt: Optional[float] = None, + free_cash_flow_gte: Optional[float] = None, + free_cash_flow_lt: Optional[float] = None, + free_cash_flow_lte: Optional[float] = None, limit: Optional[int] = None, sort: Optional[Union[str, Sort]] = None, params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[FinancialIncomeStatement], HTTPResponse]: - """ - Endpoint: GET /stocks/financials/v1/income-statements - """ - url = "/stocks/financials/v1/income-statements" - return self._paginate( - path=url, - params=self._get_params(self.list_financials_income_statements, locals()), - raw=raw, - deserializer=FinancialIncomeStatement.from_dict, - options=options, - ) - + ) -> Union[Iterator[FinancialRatio], HTTPResponse]: ... def list_financials_ratios( self, ticker: Optional[str] = None, @@ -320,6 +1083,67 @@ def list_financials_ratios( options=options, ) + @overload + def list_stocks_floats( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + free_float_percent: Optional[float] = None, + free_float_percent_gt: Optional[float] = None, + free_float_percent_gte: Optional[float] = None, + free_float_percent_lt: Optional[float] = None, + free_float_percent_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FinancialFloat]: ... + @overload + def list_stocks_floats( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + free_float_percent: Optional[float] = None, + free_float_percent_gt: Optional[float] = None, + free_float_percent_gte: Optional[float] = None, + free_float_percent_lt: Optional[float] = None, + free_float_percent_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_stocks_floats( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + free_float_percent: Optional[float] = None, + free_float_percent_gt: Optional[float] = None, + free_float_percent_gte: Optional[float] = None, + free_float_percent_lt: Optional[float] = None, + free_float_percent_lte: Optional[float] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FinancialFloat], HTTPResponse]: ... def list_stocks_floats( self, ticker: Optional[str] = None, diff --git a/massive/rest/futures.py b/massive/rest/futures.py index 8973c7af..6d6e9d90 100644 --- a/massive/rest/futures.py +++ b/massive/rest/futures.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -24,6 +24,55 @@ class FuturesClient(BaseClient): (aligned with the paths from /futures/v1/...) """ + @overload + def list_futures_aggregates( + self, + ticker: str, + resolution: Optional[str] = None, + window_start: Optional[str] = None, + window_start_lt: Optional[str] = None, + window_start_lte: Optional[str] = None, + window_start_gt: Optional[str] = None, + window_start_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesAgg]: ... + @overload + def list_futures_aggregates( + self, + ticker: str, + resolution: Optional[str] = None, + window_start: Optional[str] = None, + window_start_lt: Optional[str] = None, + window_start_lte: Optional[str] = None, + window_start_gt: Optional[str] = None, + window_start_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_aggregates( + self, + ticker: str, + resolution: Optional[str] = None, + window_start: Optional[str] = None, + window_start_lt: Optional[str] = None, + window_start_lte: Optional[str] = None, + window_start_gt: Optional[str] = None, + window_start_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesAgg], HTTPResponse]: ... def list_futures_aggregates( self, ticker: str, @@ -57,6 +106,124 @@ def list_futures_aggregates( options=options, ) + @overload + def list_futures_contracts( + self, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + active: Optional[bool] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + first_trade_date: Optional[str] = None, + first_trade_date_gt: Optional[str] = None, + first_trade_date_gte: Optional[str] = None, + first_trade_date_lt: Optional[str] = None, + first_trade_date_lte: Optional[str] = None, + last_trade_date: Optional[str] = None, + last_trade_date_gt: Optional[str] = None, + last_trade_date_gte: Optional[str] = None, + last_trade_date_lt: Optional[str] = None, + last_trade_date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesContract]: ... + @overload + def list_futures_contracts( + self, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + active: Optional[bool] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + first_trade_date: Optional[str] = None, + first_trade_date_gt: Optional[str] = None, + first_trade_date_gte: Optional[str] = None, + first_trade_date_lt: Optional[str] = None, + first_trade_date_lte: Optional[str] = None, + last_trade_date: Optional[str] = None, + last_trade_date_gt: Optional[str] = None, + last_trade_date_gte: Optional[str] = None, + last_trade_date_lt: Optional[str] = None, + last_trade_date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_contracts( + self, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + active: Optional[bool] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + first_trade_date: Optional[str] = None, + first_trade_date_gt: Optional[str] = None, + first_trade_date_gte: Optional[str] = None, + first_trade_date_lt: Optional[str] = None, + first_trade_date_lte: Optional[str] = None, + last_trade_date: Optional[str] = None, + last_trade_date_gt: Optional[str] = None, + last_trade_date_gte: Optional[str] = None, + last_trade_date_lt: Optional[str] = None, + last_trade_date_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesContract], HTTPResponse]: ... def list_futures_contracts( self, date: Optional[str] = None, @@ -109,6 +276,49 @@ def list_futures_contracts( options=options, ) + @overload + def list_futures_products( + self, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + sector: Optional[str] = None, + sector_any_of: Optional[str] = None, + sub_sector: Optional[str] = None, + sub_sector_any_of: Optional[str] = None, + asset_class: Optional[str] = None, + asset_class_any_of: Optional[str] = None, + asset_sub_class: Optional[str] = None, + asset_sub_class_any_of: Optional[str] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesProduct]: ... + @overload def list_futures_products( self, name: Optional[str] = None, @@ -145,25 +355,170 @@ def list_futures_products( type: Optional[str] = None, type_any_of: Optional[str] = None, limit: Optional[int] = None, - sort: Optional[str] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_products( + self, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + sector: Optional[str] = None, + sector_any_of: Optional[str] = None, + sub_sector: Optional[str] = None, + sub_sector_any_of: Optional[str] = None, + asset_class: Optional[str] = None, + asset_class_any_of: Optional[str] = None, + asset_sub_class: Optional[str] = None, + asset_sub_class_any_of: Optional[str] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesProduct], HTTPResponse]: ... + def list_futures_products( + self, + name: Optional[str] = None, + name_any_of: Optional[str] = None, + name_gt: Optional[str] = None, + name_gte: Optional[str] = None, + name_lt: Optional[str] = None, + name_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + date: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + sector: Optional[str] = None, + sector_any_of: Optional[str] = None, + sub_sector: Optional[str] = None, + sub_sector_any_of: Optional[str] = None, + asset_class: Optional[str] = None, + asset_class_any_of: Optional[str] = None, + asset_sub_class: Optional[str] = None, + asset_sub_class_any_of: Optional[str] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesProduct], HTTPResponse]: + """ + Endpoint: GET /futures/v1/products + + Returns a list of futures products (including combos). + """ + url = "/futures/v1/products" + return self._paginate( + path=url, + params=self._get_params(self.list_futures_products, locals()), + raw=raw, + deserializer=FuturesProduct.from_dict, + options=options, + ) + + @overload + def list_futures_quotes( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesQuote]: ... + @overload + def list_futures_quotes( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_quotes( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[FuturesProduct], HTTPResponse]: - """ - Endpoint: GET /futures/v1/products - - Returns a list of futures products (including combos). - """ - url = "/futures/v1/products" - return self._paginate( - path=url, - params=self._get_params(self.list_futures_products, locals()), - raw=raw, - deserializer=FuturesProduct.from_dict, - options=options, - ) - + ) -> Union[Iterator[FuturesQuote], HTTPResponse]: ... def list_futures_quotes( self, ticker: str, @@ -197,6 +552,67 @@ def list_futures_quotes( options=options, ) + @overload + def list_futures_trades( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesTrade]: ... + @overload + def list_futures_trades( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_trades( + self, + ticker: str, + timestamp: Optional[str] = None, + timestamp_lt: Optional[str] = None, + timestamp_lte: Optional[str] = None, + timestamp_gt: Optional[str] = None, + timestamp_gte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesTrade], HTTPResponse]: ... def list_futures_trades( self, ticker: str, @@ -230,6 +646,85 @@ def list_futures_trades( options=options, ) + @overload + def list_futures_schedules( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesSchedule]: ... + @overload + def list_futures_schedules( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_schedules( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + session_end_date: Optional[str] = None, + session_end_date_gt: Optional[str] = None, + session_end_date_gte: Optional[str] = None, + session_end_date_lt: Optional[str] = None, + session_end_date_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesSchedule], HTTPResponse]: ... def list_futures_schedules( self, product_code: Optional[str] = None, @@ -270,6 +765,49 @@ def list_futures_schedules( options=options, ) + @overload + def list_futures_market_statuses( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesMarketStatus]: ... + @overload + def list_futures_market_statuses( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_market_statuses( + self, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesMarketStatus], HTTPResponse]: ... def list_futures_market_statuses( self, product_code: Optional[str] = None, @@ -292,6 +830,70 @@ def list_futures_market_statuses( options=options, ) + @overload + def get_futures_snapshot( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesSnapshot]: ... + @overload + def get_futures_snapshot( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_futures_snapshot( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + product_code: Optional[str] = None, + product_code_any_of: Optional[str] = None, + product_code_gt: Optional[str] = None, + product_code_gte: Optional[str] = None, + product_code_lt: Optional[str] = None, + product_code_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesSnapshot], HTTPResponse]: ... def get_futures_snapshot( self, ticker: Optional[str] = None, @@ -321,6 +923,31 @@ def get_futures_snapshot( options=options, ) + @overload + def list_futures_exchanges( + self, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FuturesExchange]: ... + @overload + def list_futures_exchanges( + self, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_futures_exchanges( + self, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FuturesExchange], HTTPResponse]: ... def list_futures_exchanges( self, limit: Optional[int] = None, diff --git a/massive/rest/indicators.py b/massive/rest/indicators.py index 88746f62..bdc392b0 100644 --- a/massive/rest/indicators.py +++ b/massive/rest/indicators.py @@ -6,7 +6,7 @@ MACDIndicatorResults, ) from .base import BaseClient -from typing import Optional, Any, Dict, List, Union +from typing import Optional, Any, Dict, List, Union, Literal, overload from .models import Order from urllib3 import HTTPResponse from datetime import datetime, date @@ -15,6 +15,67 @@ class IndicatorsClient(BaseClient): + @overload + def get_sma( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> SMAIndicatorResults: ... + @overload + def get_sma( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_sma( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[SMAIndicatorResults, HTTPResponse]: ... def get_sma( self, ticker: str, @@ -70,6 +131,67 @@ def get_sma( options=options, ) + @overload + def get_ema( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> EMAIndicatorResults: ... + @overload + def get_ema( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_ema( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[EMAIndicatorResults, HTTPResponse]: ... def get_ema( self, ticker: str, @@ -125,6 +247,67 @@ def get_ema( options=options, ) + @overload + def get_rsi( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> RSIIndicatorResults: ... + @overload + def get_rsi( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_rsi( + 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, + timespan: Optional[str] = None, + window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[RSIIndicatorResults, HTTPResponse]: ... def get_rsi( self, ticker: str, @@ -180,6 +363,73 @@ def get_rsi( options=options, ) + @overload + def get_macd( + 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, + timespan: Optional[str] = None, + short_window: Optional[int] = None, + long_window: Optional[int] = None, + signal_window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> MACDIndicatorResults: ... + @overload + def get_macd( + 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, + timespan: Optional[str] = None, + short_window: Optional[int] = None, + long_window: Optional[int] = None, + signal_window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_macd( + 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, + timespan: Optional[str] = None, + short_window: Optional[int] = None, + long_window: Optional[int] = None, + signal_window: Optional[int] = None, + adjusted: Optional[bool] = None, + expand_underlying: Optional[bool] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + params: Optional[Dict[str, Any]] = None, + series_type: Optional[Union[str, SeriesType]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[MACDIndicatorResults, HTTPResponse]: ... def get_macd( self, ticker: str, diff --git a/massive/rest/models/aggs.py b/massive/rest/models/aggs.py index 49bba680..7315237e 100644 --- a/massive/rest/models/aggs.py +++ b/massive/rest/models/aggs.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import List, Optional from ...modelclass import modelclass @@ -95,6 +95,64 @@ def from_dict(d): ) +@modelclass +class DailyOpenCloseCryptoTrade: + "Contains data for one of the opening or closing trades of a crypto pair on a specified date." + + conditions: Optional[List[int]] = None + id: Optional[str] = None + price: Optional[float] = None + size: Optional[float] = None + timestamp: Optional[int] = None + exchange: Optional[int] = None + + @staticmethod + def from_dict(d): + return DailyOpenCloseCryptoTrade( + conditions=d.get("c", None), + id=d.get("i", None), + price=d.get("p", None), + size=d.get("s", None), + timestamp=d.get("t", None), + exchange=d.get("x", None), + ) + + +@modelclass +class DailyOpenCloseCrypto: + "Contains data for open and close prices, and the opening and closing trades, of a crypto pair on a specified date." + + symbol: Optional[str] = None + is_utc: Optional[bool] = None + day: Optional[str] = None + open: Optional[float] = None + close: Optional[float] = None + open_trades: Optional[List[DailyOpenCloseCryptoTrade]] = None + closing_trades: Optional[List[DailyOpenCloseCryptoTrade]] = None + + @staticmethod + def from_dict(d): + return DailyOpenCloseCrypto( + symbol=d.get("symbol", None), + is_utc=d.get("isUTC", None), + day=d.get("day", None), + open=d.get("open", None), + close=d.get("close", None), + open_trades=( + None + if "openTrades" not in d + else [DailyOpenCloseCryptoTrade.from_dict(t) for t in d["openTrades"]] + ), + closing_trades=( + None + if "closingTrades" not in d + else [ + DailyOpenCloseCryptoTrade.from_dict(t) for t in d["closingTrades"] + ] + ), + ) + + @modelclass class PreviousCloseAgg: "Contains data for the previous day's open, high, low, and close (OHLC) of the specified stock ticker." diff --git a/massive/rest/models/economy.py b/massive/rest/models/economy.py index 97386235..d0636f56 100644 --- a/massive/rest/models/economy.py +++ b/massive/rest/models/economy.py @@ -106,6 +106,76 @@ def from_dict(d): ) +@modelclass +class FedFundingConditions: + """ + Daily U.S. money-market funding conditions for a specific date. Rates are + percentages; volumes and operation amounts are in billions of U.S. dollars. + """ + + date: Optional[str] = None + effective_fed_funds_rate: Optional[float] = None + effective_fed_funds_volume: Optional[float] = None + fed_funds_target_lower: Optional[float] = None + fed_funds_target_upper: Optional[float] = None + fed_overnight_repo_treasury_amount: Optional[float] = None + fed_overnight_reverse_repo_treasury_amount: Optional[float] = None + financial_commercial_paper_90d_rate: Optional[float] = None + interest_on_reserve_balances: Optional[float] = None + nonfinancial_commercial_paper_90d_rate: Optional[float] = None + obfr_25th_percentile: Optional[float] = None + obfr_75th_percentile: Optional[float] = None + obfr_volume: Optional[float] = None + overnight_bank_funding_rate: Optional[float] = None + secured_overnight_financing_rate: Optional[float] = None + sofr_25th_percentile: Optional[float] = None + sofr_75th_percentile: Optional[float] = None + sofr_volume: Optional[float] = None + tgcr_25th_percentile: Optional[float] = None + tgcr_75th_percentile: Optional[float] = None + tri_party_general_collateral_rate: Optional[float] = None + tri_party_general_collateral_volume: Optional[float] = None + + @staticmethod + def from_dict(d): + return FedFundingConditions( + date=d.get("date"), + effective_fed_funds_rate=d.get("effective_fed_funds_rate"), + effective_fed_funds_volume=d.get("effective_fed_funds_volume"), + fed_funds_target_lower=d.get("fed_funds_target_lower"), + fed_funds_target_upper=d.get("fed_funds_target_upper"), + fed_overnight_repo_treasury_amount=d.get( + "fed_overnight_repo_treasury_amount" + ), + fed_overnight_reverse_repo_treasury_amount=d.get( + "fed_overnight_reverse_repo_treasury_amount" + ), + financial_commercial_paper_90d_rate=d.get( + "financial_commercial_paper_90d_rate" + ), + interest_on_reserve_balances=d.get("interest_on_reserve_balances"), + nonfinancial_commercial_paper_90d_rate=d.get( + "nonfinancial_commercial_paper_90d_rate" + ), + obfr_25th_percentile=d.get("obfr_25th_percentile"), + obfr_75th_percentile=d.get("obfr_75th_percentile"), + obfr_volume=d.get("obfr_volume"), + overnight_bank_funding_rate=d.get("overnight_bank_funding_rate"), + secured_overnight_financing_rate=d.get("secured_overnight_financing_rate"), + sofr_25th_percentile=d.get("sofr_25th_percentile"), + sofr_75th_percentile=d.get("sofr_75th_percentile"), + sofr_volume=d.get("sofr_volume"), + tgcr_25th_percentile=d.get("tgcr_25th_percentile"), + tgcr_75th_percentile=d.get("tgcr_75th_percentile"), + tri_party_general_collateral_rate=d.get( + "tri_party_general_collateral_rate" + ), + tri_party_general_collateral_volume=d.get( + "tri_party_general_collateral_volume" + ), + ) + + @modelclass class EUMerchantAggregate: """ diff --git a/massive/rest/quotes.py b/massive/rest/quotes.py index 353c21e1..48285aeb 100644 --- a/massive/rest/quotes.py +++ b/massive/rest/quotes.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, Union, Iterator +from typing import Optional, Any, Dict, Union, Iterator, Literal, overload from .models import ( Quote, LastQuote, @@ -17,6 +17,55 @@ # https://massive.com/docs/stocks class QuotesClient(BaseClient): + @overload + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Quote]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Quote], HTTPResponse]: ... def list_quotes( self, ticker: str, @@ -58,6 +107,31 @@ def list_quotes( options=options, ) + @overload + def get_last_quote( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> LastQuote: ... + @overload + def get_last_quote( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_last_quote( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[LastQuote, HTTPResponse]: ... def get_last_quote( self, ticker: str, @@ -84,6 +158,34 @@ def get_last_quote( options=options, ) + @overload + def get_last_forex_quote( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> LastForexQuote: ... + @overload + def get_last_forex_quote( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_last_forex_quote( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[LastForexQuote, HTTPResponse]: ... def get_last_forex_quote( self, from_: str, @@ -111,6 +213,40 @@ def get_last_forex_quote( options=options, ) + @overload + def get_real_time_currency_conversion( + self, + from_: str, + to: str, + amount: Optional[float] = None, + precision: Union[int, Precision] = 2, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> RealTimeCurrencyConversion: ... + @overload + def get_real_time_currency_conversion( + self, + from_: str, + to: str, + amount: Optional[float] = None, + precision: Union[int, Precision] = 2, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_real_time_currency_conversion( + self, + from_: str, + to: str, + amount: Optional[float] = None, + precision: Union[int, Precision] = 2, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[RealTimeCurrencyConversion, HTTPResponse]: ... def get_real_time_currency_conversion( self, from_: str, diff --git a/massive/rest/reference.py b/massive/rest/reference.py index b6886c55..c31a8cdc 100644 --- a/massive/rest/reference.py +++ b/massive/rest/reference.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from .models import ( MarketHoliday, MarketStatus, @@ -44,6 +44,18 @@ class MarketsClient(BaseClient): + @overload + def get_market_holidays( + self, params: Optional[Dict[str, Any]] = None, raw: Literal[False] = False + ) -> List[MarketHoliday]: ... + @overload + def get_market_holidays( + self, params: Optional[Dict[str, Any]] = None, *, raw: Literal[True] + ) -> HTTPResponse: ... + @overload + def get_market_holidays( + self, params: Optional[Dict[str, Any]] = None, raw: bool = False + ) -> Union[List[MarketHoliday], HTTPResponse]: ... def get_market_holidays( self, params: Optional[Dict[str, Any]] = None, raw: bool = False ) -> Union[List[MarketHoliday], HTTPResponse]: @@ -64,6 +76,18 @@ def get_market_holidays( result_key="", ) + @overload + def get_market_status( + self, params: Optional[Dict[str, Any]] = None, raw: Literal[False] = False + ) -> MarketStatus: ... + @overload + def get_market_status( + self, params: Optional[Dict[str, Any]] = None, *, raw: Literal[True] + ) -> HTTPResponse: ... + @overload + def get_market_status( + self, params: Optional[Dict[str, Any]] = None, raw: bool = False + ) -> Union[MarketStatus, HTTPResponse]: ... def get_market_status( self, params: Optional[Dict[str, Any]] = None, raw: bool = False ) -> Union[MarketStatus, HTTPResponse]: @@ -82,6 +106,76 @@ def get_market_status( class TickersClient(BaseClient): + @overload + 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[Union[int, str]] = None, + cik: Optional[int] = None, + date: Optional[str] = None, + active: Optional[bool] = None, + search: Optional[str] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = "ticker", + order: Optional[Union[str, Order]] = "asc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Ticker]: ... + @overload + 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[Union[int, str]] = None, + cik: Optional[int] = None, + date: Optional[str] = None, + active: Optional[bool] = None, + search: Optional[str] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = "ticker", + order: Optional[Union[str, Order]] = "asc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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[Union[int, str]] = None, + cik: Optional[int] = None, + date: Optional[str] = None, + active: Optional[bool] = None, + search: Optional[str] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = "ticker", + order: Optional[Union[str, Order]] = "asc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Ticker], HTTPResponse]: ... def list_tickers( self, ticker: Optional[str] = None, @@ -92,7 +186,7 @@ def list_tickers( type: Optional[str] = None, market: Optional[str] = None, exchange: Optional[str] = None, - cusip: Optional[int] = None, + cusip: Optional[Union[int, str]] = None, cik: Optional[int] = None, date: Optional[str] = None, active: Optional[bool] = None, @@ -115,7 +209,7 @@ def list_tickers( :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 assets primary exchange Market Identifier Code (MIC) according to ISO 10383. 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 cusip: Specify the CUSIP code of the asset you want to search for. The API treats a CUSIP as a string, so pass a string such as "037833100": an int drops leading zeros and cannot hold the letters some CUSIPs contain. An int is still accepted for backward compatibility. 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. @@ -137,6 +231,34 @@ def list_tickers( options=options, ) + @overload + def get_ticker_details( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> TickerDetails: ... + @overload + def get_ticker_details( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_ticker_details( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[TickerDetails, HTTPResponse]: ... def get_ticker_details( self, ticker: Optional[str] = None, @@ -165,6 +287,34 @@ def get_ticker_details( options=options, ) + @overload + def get_ticker_events( + self, + ticker: str, + types: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> TickerChangeResults: ... + @overload + def get_ticker_events( + self, + ticker: str, + types: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_ticker_events( + self, + ticker: str, + types: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[TickerChangeResults, HTTPResponse]: ... def get_ticker_events( self, ticker: str, @@ -191,6 +341,67 @@ def get_ticker_events( options=options, ) + @overload + 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, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[TickerNews]: ... + @overload + 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, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[TickerNews], HTTPResponse]: ... def list_ticker_news( self, ticker: Optional[str] = None, @@ -232,6 +443,34 @@ def list_ticker_news( options=options, ) + @overload + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[TickerTypes]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[TickerTypes], HTTPResponse]: ... def get_ticker_types( self, asset_class: Optional[Union[str, AssetClass]] = None, @@ -260,6 +499,31 @@ def get_ticker_types( options=options, ) + @overload + def get_related_companies( + self, + ticker: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> RelatedCompany: ... + @overload + def get_related_companies( + self, + ticker: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_related_companies( + self, + ticker: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[RelatedCompany, HTTPResponse]: ... def get_related_companies( self, ticker: Optional[str] = None, @@ -288,6 +552,70 @@ def get_related_companies( class SplitsClient(BaseClient): + @overload + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Split]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Split], HTTPResponse]: ... def list_splits( self, ticker: Optional[str] = None, @@ -341,6 +669,7 @@ def list_splits( class DividendsClient(BaseClient): + @overload def list_dividends( self, ticker: Optional[str] = None, @@ -379,17 +708,143 @@ def list_dividends( sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False, + raw: Literal[False] = False, options: Optional[RequestOptionBuilder] = None, - ) -> 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. + ) -> Iterator[Dividend]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Dividend], HTTPResponse]: ... + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> 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. @@ -432,6 +887,49 @@ def list_dividends( class ConditionsClient(BaseClient): + @overload + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Condition]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Condition], HTTPResponse]: ... def list_conditions( self, asset_class: Optional[Union[str, AssetClass]] = None, @@ -471,6 +969,34 @@ def list_conditions( class ExchangesClient(BaseClient): + @overload + def get_exchanges( + self, + asset_class: Optional[Union[str, AssetClass]] = None, + locale: Optional[Union[str, Locale]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[Exchange]: ... + @overload + def get_exchanges( + self, + asset_class: Optional[Union[str, AssetClass]] = None, + locale: Optional[Union[str, Locale]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[Exchange], HTTPResponse]: ... def get_exchanges( self, asset_class: Optional[Union[str, AssetClass]] = None, @@ -501,6 +1027,34 @@ def get_exchanges( class ContractsClient(BaseClient): + @overload + def get_options_contract( + self, + ticker: str, + as_of: Optional[Union[str, date]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> OptionsContract: ... + @overload + def get_options_contract( + self, + ticker: str, + as_of: Optional[Union[str, date]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_options_contract( + self, + ticker: str, + as_of: Optional[Union[str, date]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[OptionsContract, HTTPResponse]: ... def get_options_contract( self, ticker: str, @@ -529,6 +1083,7 @@ def get_options_contract( options=options, ) + @overload def list_options_contracts( self, underlying_ticker: Optional[str] = None, @@ -553,64 +1108,227 @@ def list_options_contracts( sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False, + raw: Literal[False] = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[OptionsContract], HTTPResponse]: - """ - List historical options contracts. - - :param underlying_ticker: Query for contracts relating to an underlying stock ticker. - :param contract_type: Query by the type of contract. - :param expiration_date: Query by contract expiration with date format YYYY-MM-DD. - :param as_of: Specify a point in time for contracts as of this date with format YYYY-MM-DD. - :param strike_price: Query by strike price of a contract. - :param expired: Query for expired contracts. - :param limit: Limit the number of results returned per-page, 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 options contracts. - """ - url = "/v3/reference/options/contracts" - - return self._paginate( - path=url, - params=self._get_params(self.list_options_contracts, locals()), - raw=raw, - deserializer=OptionsContract.from_dict, - options=options, - ) - - def list_short_interest( + ) -> Iterator[OptionsContract]: ... + @overload + def list_options_contracts( self, - ticker: Optional[str] = None, - days_to_cover: Optional[str] = None, - days_to_cover_lt: Optional[str] = None, - days_to_cover_lte: Optional[str] = None, - days_to_cover_gt: Optional[str] = None, - days_to_cover_gte: Optional[str] = None, - settlement_date: Optional[str] = None, - settlement_date_lt: Optional[str] = None, - settlement_date_lte: Optional[str] = None, - settlement_date_gt: Optional[str] = None, - settlement_date_gte: Optional[str] = None, - avg_daily_volume: Optional[str] = None, - avg_daily_volume_lt: Optional[str] = None, - avg_daily_volume_lte: Optional[str] = None, - avg_daily_volume_gt: Optional[str] = None, - avg_daily_volume_gte: Optional[str] = None, - limit: Optional[int] = None, - sort: Optional[Union[str, Sort]] = None, - order: Optional[Union[str, Order]] = None, - params: Optional[Dict[str, Any]] = None, - raw: bool = False, - options: Optional[RequestOptionBuilder] = None, - ) -> Union[List[ShortInterest], HTTPResponse]: - """ - Retrieve short interest data for stocks. - - :param ticker: Filter by the primary ticker symbol. + underlying_ticker: Optional[str] = None, + underlying_ticker_lt: Optional[str] = None, + underlying_ticker_lte: Optional[str] = None, + underlying_ticker_gt: Optional[str] = None, + underlying_ticker_gte: Optional[str] = None, + contract_type: Optional[str] = None, + expiration_date: Optional[Union[str, date]] = None, + expiration_date_lt: Optional[Union[str, date]] = None, + expiration_date_lte: Optional[Union[str, date]] = None, + expiration_date_gt: Optional[Union[str, date]] = None, + expiration_date_gte: Optional[Union[str, date]] = None, + as_of: Optional[Union[str, date]] = None, + strike_price: Optional[float] = None, + strike_price_lt: Optional[float] = None, + strike_price_lte: Optional[float] = None, + strike_price_gt: Optional[float] = None, + strike_price_gte: Optional[float] = None, + expired: 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_options_contracts( + self, + underlying_ticker: Optional[str] = None, + underlying_ticker_lt: Optional[str] = None, + underlying_ticker_lte: Optional[str] = None, + underlying_ticker_gt: Optional[str] = None, + underlying_ticker_gte: Optional[str] = None, + contract_type: Optional[str] = None, + expiration_date: Optional[Union[str, date]] = None, + expiration_date_lt: Optional[Union[str, date]] = None, + expiration_date_lte: Optional[Union[str, date]] = None, + expiration_date_gt: Optional[Union[str, date]] = None, + expiration_date_gte: Optional[Union[str, date]] = None, + as_of: Optional[Union[str, date]] = None, + strike_price: Optional[float] = None, + strike_price_lt: Optional[float] = None, + strike_price_lte: Optional[float] = None, + strike_price_gt: Optional[float] = None, + strike_price_gte: Optional[float] = None, + expired: 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[OptionsContract], HTTPResponse]: ... + def list_options_contracts( + self, + underlying_ticker: Optional[str] = None, + underlying_ticker_lt: Optional[str] = None, + underlying_ticker_lte: Optional[str] = None, + underlying_ticker_gt: Optional[str] = None, + underlying_ticker_gte: Optional[str] = None, + contract_type: Optional[str] = None, + expiration_date: Optional[Union[str, date]] = None, + expiration_date_lt: Optional[Union[str, date]] = None, + expiration_date_lte: Optional[Union[str, date]] = None, + expiration_date_gt: Optional[Union[str, date]] = None, + expiration_date_gte: Optional[Union[str, date]] = None, + as_of: Optional[Union[str, date]] = None, + strike_price: Optional[float] = None, + strike_price_lt: Optional[float] = None, + strike_price_lte: Optional[float] = None, + strike_price_gt: Optional[float] = None, + strike_price_gte: Optional[float] = None, + expired: 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[OptionsContract], HTTPResponse]: + """ + List historical options contracts. + + :param underlying_ticker: Query for contracts relating to an underlying stock ticker. + :param contract_type: Query by the type of contract. + :param expiration_date: Query by contract expiration with date format YYYY-MM-DD. + :param as_of: Specify a point in time for contracts as of this date with format YYYY-MM-DD. + :param strike_price: Query by strike price of a contract. + :param expired: Query for expired contracts. + :param limit: Limit the number of results returned per-page, 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 options contracts. + """ + url = "/v3/reference/options/contracts" + + return self._paginate( + path=url, + params=self._get_params(self.list_options_contracts, locals()), + raw=raw, + deserializer=OptionsContract.from_dict, + options=options, + ) + + @overload + def list_short_interest( + self, + ticker: Optional[str] = None, + days_to_cover: Optional[str] = None, + days_to_cover_lt: Optional[str] = None, + days_to_cover_lte: Optional[str] = None, + days_to_cover_gt: Optional[str] = None, + days_to_cover_gte: Optional[str] = None, + settlement_date: Optional[str] = None, + settlement_date_lt: Optional[str] = None, + settlement_date_lte: Optional[str] = None, + settlement_date_gt: Optional[str] = None, + settlement_date_gte: Optional[str] = None, + avg_daily_volume: Optional[str] = None, + avg_daily_volume_lt: Optional[str] = None, + avg_daily_volume_lte: Optional[str] = None, + avg_daily_volume_gt: Optional[str] = None, + avg_daily_volume_gte: 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[ShortInterest]: ... + @overload + def list_short_interest( + self, + ticker: Optional[str] = None, + days_to_cover: Optional[str] = None, + days_to_cover_lt: Optional[str] = None, + days_to_cover_lte: Optional[str] = None, + days_to_cover_gt: Optional[str] = None, + days_to_cover_gte: Optional[str] = None, + settlement_date: Optional[str] = None, + settlement_date_lt: Optional[str] = None, + settlement_date_lte: Optional[str] = None, + settlement_date_gt: Optional[str] = None, + settlement_date_gte: Optional[str] = None, + avg_daily_volume: Optional[str] = None, + avg_daily_volume_lt: Optional[str] = None, + avg_daily_volume_lte: Optional[str] = None, + avg_daily_volume_gt: Optional[str] = None, + avg_daily_volume_gte: 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_short_interest( + self, + ticker: Optional[str] = None, + days_to_cover: Optional[str] = None, + days_to_cover_lt: Optional[str] = None, + days_to_cover_lte: Optional[str] = None, + days_to_cover_gt: Optional[str] = None, + days_to_cover_gte: Optional[str] = None, + settlement_date: Optional[str] = None, + settlement_date_lt: Optional[str] = None, + settlement_date_lte: Optional[str] = None, + settlement_date_gt: Optional[str] = None, + settlement_date_gte: Optional[str] = None, + avg_daily_volume: Optional[str] = None, + avg_daily_volume_lt: Optional[str] = None, + avg_daily_volume_lte: Optional[str] = None, + avg_daily_volume_gt: Optional[str] = None, + avg_daily_volume_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[ShortInterest], HTTPResponse]: ... + def list_short_interest( + self, + ticker: Optional[str] = None, + days_to_cover: Optional[str] = None, + days_to_cover_lt: Optional[str] = None, + days_to_cover_lte: Optional[str] = None, + days_to_cover_gt: Optional[str] = None, + days_to_cover_gte: Optional[str] = None, + settlement_date: Optional[str] = None, + settlement_date_lt: Optional[str] = None, + settlement_date_lte: Optional[str] = None, + settlement_date_gt: Optional[str] = None, + settlement_date_gte: Optional[str] = None, + avg_daily_volume: Optional[str] = None, + avg_daily_volume_lt: Optional[str] = None, + avg_daily_volume_lte: Optional[str] = None, + avg_daily_volume_gt: Optional[str] = None, + avg_daily_volume_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[ShortInterest], HTTPResponse]: + """ + Retrieve short interest data for stocks. + + :param ticker: Filter by the primary ticker symbol. :param days_to_cover: Filter by the days to cover value. :param days_to_cover_lt: Filter for days to cover dates less than the provided date. :param days_to_cover_lte: Filter for days to cover dates less than or equal to the provided date. @@ -632,7 +1350,7 @@ def list_short_interest( :param params: Additional query parameters. :param raw: Return raw HTTPResponse object if True, else return List[ShortInterest]. :param options: RequestOptionBuilder for additional headers or params. - :return: A list of ShortInterest objects or HTTPResponse if raw=True. + :return: An iterator of ShortInterest objects or HTTPResponse if raw=True. """ url = "/stocks/v1/short-interest" @@ -645,6 +1363,7 @@ def list_short_interest( options=options, ) + @overload def list_short_volume( self, ticker: Optional[str] = None, @@ -667,66 +1386,211 @@ def list_short_volume( sort: Optional[Union[str, Sort]] = None, order: Optional[Union[str, Order]] = None, params: Optional[Dict[str, Any]] = None, - raw: bool = False, + raw: Literal[False] = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[List[ShortVolume], HTTPResponse]: - """ - Retrieve short volume data for stocks. - - :param ticker: Filter by the primary ticker symbol. - :param date: Filter by the date of trade activity (YYYY-MM-DD). - :param date_lt: Filter for dates less than the provided date. - :param date_lte: Filter for dates less than or equal to the provided date. - :param date_gt: Filter for dates greater than the provided date. - :param date_gte: Filter for dates greater than or equal to the provided date. - :param short_volume_ratio: Filter by short volume ratio. - :param short_volume_ratio_lt: Filter for short volume ratio less than the provided date. - :param short_volume_ratio_lte: Filter for short volume ratio less than or equal to the provided date. - :param short_volume_ratio_gt: Filter for short volume ratio greater than the provided date. - :param short_volume_ratio_gte: Filter for short volume ratio greater than or equal to the provided date. - :param total_volume: Filter by total volume. - :param total_volume_lt: Filter for total volume less than the provided date. - :param total_volume_lte: Filter for total volume less than or equal to the provided date. - :param total_volume_gt: Filter for total volume greater than the provided date. - :param total_volume_gte: Filter for total volume greater than or equal to the provided date. - :param limit: Limit the number of results returned. Default 10, max 50000. - :param sort: Field to sort by (e.g., "ticker"). - :param order: Order results based on the sort field ("asc" or "desc"). Default "desc". - :param params: Additional query parameters. - :param raw: Return raw HTTPResponse object if True, else return List[ShortVolume]. - :param options: RequestOptionBuilder for additional headers or params. - :return: A list of ShortVolume objects or HTTPResponse if raw=True. - """ - url = "/stocks/v1/short-volume" - - return self._paginate( - path=url, - params=self._get_params(self.list_short_volume, locals()), - deserializer=ShortVolume.from_dict, - raw=raw, - result_key="results", - options=options, - ) - - # Add these functions to financials.py in the FinancialsClient class - - def list_stocks_splits( + ) -> Iterator[ShortVolume]: ... + @overload + def list_short_volume( self, ticker: Optional[str] = None, - ticker_any_of: Optional[str] = None, - ticker_gt: Optional[str] = None, - ticker_gte: Optional[str] = None, - ticker_lt: Optional[str] = None, - ticker_lte: Optional[str] = None, - execution_date: Optional[Union[str, date]] = None, - execution_date_gt: Optional[Union[str, date]] = None, - execution_date_gte: Optional[Union[str, date]] = None, - execution_date_lt: Optional[Union[str, date]] = None, - execution_date_lte: Optional[Union[str, date]] = None, - adjustment_type: Optional[str] = None, - adjustment_type_any_of: Optional[str] = None, - limit: Optional[int] = None, - sort: Optional[Union[str, Sort]] = None, + date: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + short_volume_ratio: Optional[str] = None, + short_volume_ratio_lt: Optional[str] = None, + short_volume_ratio_lte: Optional[str] = None, + short_volume_ratio_gt: Optional[str] = None, + short_volume_ratio_gte: Optional[str] = None, + total_volume: Optional[str] = None, + total_volume_lt: Optional[str] = None, + total_volume_lte: Optional[str] = None, + total_volume_gt: Optional[str] = None, + total_volume_gte: 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_short_volume( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + short_volume_ratio: Optional[str] = None, + short_volume_ratio_lt: Optional[str] = None, + short_volume_ratio_lte: Optional[str] = None, + short_volume_ratio_gt: Optional[str] = None, + short_volume_ratio_gte: Optional[str] = None, + total_volume: Optional[str] = None, + total_volume_lt: Optional[str] = None, + total_volume_lte: Optional[str] = None, + total_volume_gt: Optional[str] = None, + total_volume_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[ShortVolume], HTTPResponse]: ... + def list_short_volume( + self, + ticker: Optional[str] = None, + date: Optional[str] = None, + date_lt: Optional[str] = None, + date_lte: Optional[str] = None, + date_gt: Optional[str] = None, + date_gte: Optional[str] = None, + short_volume_ratio: Optional[str] = None, + short_volume_ratio_lt: Optional[str] = None, + short_volume_ratio_lte: Optional[str] = None, + short_volume_ratio_gt: Optional[str] = None, + short_volume_ratio_gte: Optional[str] = None, + total_volume: Optional[str] = None, + total_volume_lt: Optional[str] = None, + total_volume_lte: Optional[str] = None, + total_volume_gt: Optional[str] = None, + total_volume_gte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[ShortVolume], HTTPResponse]: + """ + Retrieve short volume data for stocks. + + :param ticker: Filter by the primary ticker symbol. + :param date: Filter by the date of trade activity (YYYY-MM-DD). + :param date_lt: Filter for dates less than the provided date. + :param date_lte: Filter for dates less than or equal to the provided date. + :param date_gt: Filter for dates greater than the provided date. + :param date_gte: Filter for dates greater than or equal to the provided date. + :param short_volume_ratio: Filter by short volume ratio. + :param short_volume_ratio_lt: Filter for short volume ratio less than the provided date. + :param short_volume_ratio_lte: Filter for short volume ratio less than or equal to the provided date. + :param short_volume_ratio_gt: Filter for short volume ratio greater than the provided date. + :param short_volume_ratio_gte: Filter for short volume ratio greater than or equal to the provided date. + :param total_volume: Filter by total volume. + :param total_volume_lt: Filter for total volume less than the provided date. + :param total_volume_lte: Filter for total volume less than or equal to the provided date. + :param total_volume_gt: Filter for total volume greater than the provided date. + :param total_volume_gte: Filter for total volume greater than or equal to the provided date. + :param limit: Limit the number of results returned. Default 10, max 50000. + :param sort: Field to sort by (e.g., "ticker"). + :param order: Order results based on the sort field ("asc" or "desc"). Default "desc". + :param params: Additional query parameters. + :param raw: Return raw HTTPResponse object if True, else return List[ShortVolume]. + :param options: RequestOptionBuilder for additional headers or params. + :return: An iterator of ShortVolume objects or HTTPResponse if raw=True. + """ + url = "/stocks/v1/short-volume" + + return self._paginate( + path=url, + params=self._get_params(self.list_short_volume, locals()), + deserializer=ShortVolume.from_dict, + raw=raw, + result_key="results", + options=options, + ) + + # Add these functions to financials.py in the FinancialsClient class + + @overload + def list_stocks_splits( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + execution_date: Optional[Union[str, date]] = None, + execution_date_gt: Optional[Union[str, date]] = None, + execution_date_gte: Optional[Union[str, date]] = None, + execution_date_lt: Optional[Union[str, date]] = None, + execution_date_lte: Optional[Union[str, date]] = None, + adjustment_type: Optional[str] = None, + adjustment_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[StockSplit]: ... + @overload + def list_stocks_splits( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + execution_date: Optional[Union[str, date]] = None, + execution_date_gt: Optional[Union[str, date]] = None, + execution_date_gte: Optional[Union[str, date]] = None, + execution_date_lt: Optional[Union[str, date]] = None, + execution_date_lte: Optional[Union[str, date]] = None, + adjustment_type: Optional[str] = None, + adjustment_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_splits( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + execution_date: Optional[Union[str, date]] = None, + execution_date_gt: Optional[Union[str, date]] = None, + execution_date_gte: Optional[Union[str, date]] = None, + execution_date_lt: Optional[Union[str, date]] = None, + execution_date_lte: Optional[Union[str, date]] = None, + adjustment_type: Optional[str] = None, + adjustment_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[StockSplit], HTTPResponse]: ... + def list_stocks_splits( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + execution_date: Optional[Union[str, date]] = None, + execution_date_gt: Optional[Union[str, date]] = None, + execution_date_gte: Optional[Union[str, date]] = None, + execution_date_lt: Optional[Union[str, date]] = None, + execution_date_lte: Optional[Union[str, date]] = None, + adjustment_type: Optional[str] = None, + adjustment_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, @@ -743,6 +1607,88 @@ def list_stocks_splits( options=options, ) + @overload + def list_stocks_dividends( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ex_dividend_date: Optional[Union[str, date]] = None, + ex_dividend_date_gt: Optional[Union[str, date]] = None, + ex_dividend_date_gte: Optional[Union[str, date]] = None, + ex_dividend_date_lt: Optional[Union[str, date]] = None, + ex_dividend_date_lte: Optional[Union[str, date]] = None, + frequency: Optional[int] = None, + frequency_gt: Optional[int] = None, + frequency_gte: Optional[int] = None, + frequency_lt: Optional[int] = None, + frequency_lte: Optional[int] = None, + distribution_type: Optional[str] = None, + distribution_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[StockDividend]: ... + @overload + def list_stocks_dividends( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ex_dividend_date: Optional[Union[str, date]] = None, + ex_dividend_date_gt: Optional[Union[str, date]] = None, + ex_dividend_date_gte: Optional[Union[str, date]] = None, + ex_dividend_date_lt: Optional[Union[str, date]] = None, + ex_dividend_date_lte: Optional[Union[str, date]] = None, + frequency: Optional[int] = None, + frequency_gt: Optional[int] = None, + frequency_gte: Optional[int] = None, + frequency_lt: Optional[int] = None, + frequency_lte: Optional[int] = None, + distribution_type: Optional[str] = None, + distribution_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_dividends( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ex_dividend_date: Optional[Union[str, date]] = None, + ex_dividend_date_gt: Optional[Union[str, date]] = None, + ex_dividend_date_gte: Optional[Union[str, date]] = None, + ex_dividend_date_lt: Optional[Union[str, date]] = None, + ex_dividend_date_lte: Optional[Union[str, date]] = None, + frequency: Optional[int] = None, + frequency_gt: Optional[int] = None, + frequency_gte: Optional[int] = None, + frequency_lt: Optional[int] = None, + frequency_lte: Optional[int] = None, + distribution_type: Optional[str] = None, + distribution_type_any_of: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[StockDividend], HTTPResponse]: ... def list_stocks_dividends( self, ticker: Optional[str] = None, @@ -781,172 +1727,802 @@ def list_stocks_dividends( options=options, ) + @overload def list_stocks_filings_risk_factors( self, filing_date: Optional[Union[str, date]] = None, - filing_date_any_of: Optional[str] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[RiskFactor]: ... + @overload + def list_stocks_filings_risk_factors( + self, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_risk_factors( + self, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[RiskFactor], HTTPResponse]: ... + def list_stocks_filings_risk_factors( + self, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[RiskFactor], HTTPResponse]: + """ + Get categorized risk factors extracted from 10-K filings (with supporting_text). + """ + url = "/stocks/filings/vX/risk-factors" + return self._paginate( + path=url, + params=self._get_params(self.list_stocks_filings_risk_factors, locals()), + result_key="results", + deserializer=RiskFactor.from_dict, + raw=raw, + options=options, + ) + + @overload + def list_stocks_taxonomies_risk_factors( + self, + taxonomy: Optional[float] = None, + taxonomy_gt: Optional[float] = None, + taxonomy_gte: Optional[float] = None, + taxonomy_lt: Optional[float] = None, + taxonomy_lte: Optional[float] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[RiskFactorTaxonomy]: ... + @overload + def list_stocks_taxonomies_risk_factors( + self, + taxonomy: Optional[float] = None, + taxonomy_gt: Optional[float] = None, + taxonomy_gte: Optional[float] = None, + taxonomy_lt: Optional[float] = None, + taxonomy_lte: Optional[float] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_taxonomies_risk_factors( + self, + taxonomy: Optional[float] = None, + taxonomy_gt: Optional[float] = None, + taxonomy_gte: Optional[float] = None, + taxonomy_lt: Optional[float] = None, + taxonomy_lte: Optional[float] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[RiskFactorTaxonomy], HTTPResponse]: ... + def list_stocks_taxonomies_risk_factors( + self, + taxonomy: Optional[float] = None, + taxonomy_gt: Optional[float] = None, + taxonomy_gte: Optional[float] = None, + taxonomy_lt: Optional[float] = None, + taxonomy_lte: Optional[float] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[RiskFactorTaxonomy], HTTPResponse]: + """ + Get the taxonomy/categories used to classify risk factors (kept old name for backward compatibility). + """ + url = "/stocks/taxonomies/vX/risk-factors" + return self._paginate( + path=url, + params=self._get_params(self.list_stocks_taxonomies_risk_factors, locals()), + result_key="results", + deserializer=RiskFactorTaxonomy.from_dict, + raw=raw, + options=options, + ) + + @overload + def list_stocks_filings_8k_disclosures( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tertiary_category: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Disclosure]: ... + @overload + def list_stocks_filings_8k_disclosures( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tertiary_category: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_8k_disclosures( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tertiary_category: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Disclosure], HTTPResponse]: ... + def list_stocks_filings_8k_disclosures( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_any_of: Optional[str] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + tertiary_category: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Disclosure], HTTPResponse]: + """ + SEC 8-K filing disclosure categorization. A single 8-K filing can produce + multiple rows when it covers multiple disclosure types, each classified into + primary, secondary, and tertiary categories with a supporting text excerpt. + The full classification list is available at /stocks/taxonomies/vX/disclosures. + """ + url = "/stocks/filings/8-K/vX/disclosures" + return self._paginate( + path=url, + params=self._get_params(self.list_stocks_filings_8k_disclosures, locals()), + result_key="results", + deserializer=Disclosure.from_dict, + raw=raw, + options=options, + ) + + @overload + def list_stocks_taxonomies_disclosures( + self, + taxonomy: Optional[str] = None, + taxonomy_any_of: Optional[str] = None, + taxonomy_gt: Optional[str] = None, + taxonomy_gte: Optional[str] = None, + taxonomy_lt: Optional[str] = None, + taxonomy_lte: Optional[str] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[DisclosureTaxonomy]: ... + @overload + def list_stocks_taxonomies_disclosures( + self, + taxonomy: Optional[str] = None, + taxonomy_any_of: Optional[str] = None, + taxonomy_gt: Optional[str] = None, + taxonomy_gte: Optional[str] = None, + taxonomy_lt: Optional[str] = None, + taxonomy_lte: Optional[str] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_taxonomies_disclosures( + self, + taxonomy: Optional[str] = None, + taxonomy_any_of: Optional[str] = None, + taxonomy_gt: Optional[str] = None, + taxonomy_gte: Optional[str] = None, + taxonomy_lt: Optional[str] = None, + taxonomy_lte: Optional[str] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[DisclosureTaxonomy], HTTPResponse]: ... + def list_stocks_taxonomies_disclosures( + self, + taxonomy: Optional[str] = None, + taxonomy_any_of: Optional[str] = None, + taxonomy_gt: Optional[str] = None, + taxonomy_gte: Optional[str] = None, + taxonomy_lt: Optional[str] = None, + taxonomy_lte: Optional[str] = None, + primary_category: Optional[str] = None, + primary_category_any_of: Optional[str] = None, + primary_category_gt: Optional[str] = None, + primary_category_gte: Optional[str] = None, + primary_category_lt: Optional[str] = None, + primary_category_lte: Optional[str] = None, + secondary_category: Optional[str] = None, + secondary_category_any_of: Optional[str] = None, + secondary_category_gt: Optional[str] = None, + secondary_category_gte: Optional[str] = None, + secondary_category_lt: Optional[str] = None, + secondary_category_lte: Optional[str] = None, + tertiary_category: Optional[str] = None, + tertiary_category_any_of: Optional[str] = None, + tertiary_category_gt: Optional[str] = None, + tertiary_category_gte: Optional[str] = None, + tertiary_category_lt: Optional[str] = None, + tertiary_category_lte: Optional[str] = None, + limit: Optional[int] = 200, + sort: Optional[Union[str, Sort]] = "taxonomy.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[DisclosureTaxonomy], HTTPResponse]: + """ + The complete list of 8-K disclosure classifications used in the 8-K + disclosures endpoint. + """ + url = "/stocks/taxonomies/vX/disclosures" + return self._paginate( + path=url, + params=self._get_params(self.list_stocks_taxonomies_disclosures, locals()), + result_key="results", + deserializer=DisclosureTaxonomy.from_dict, + raw=raw, + options=options, + ) + + @overload + def list_stocks_filings_10k_sections( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + section: Optional[str] = None, + section_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "period_end.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FilingSection]: ... + @overload + def list_stocks_filings_10k_sections( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + section: Optional[str] = None, + section_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "period_end.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_10k_sections( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + section: Optional[str] = None, + section_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "period_end.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FilingSection], HTTPResponse]: ... + def list_stocks_filings_10k_sections( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + section: Optional[str] = None, + section_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + period_end: Optional[Union[str, date]] = None, + period_end_gt: Optional[Union[str, date]] = None, + period_end_gte: Optional[Union[str, date]] = None, + period_end_lt: Optional[Union[str, date]] = None, + period_end_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "period_end.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FilingSection], HTTPResponse]: + """ + Get raw text sections from 10-K/10-Q filings (business, risk_factors, etc.). + """ + url = "/stocks/filings/10-K/vX/sections" + return self._paginate( + path=url, + params=self._get_params(self.list_stocks_filings_10k_sections, locals()), + result_key="results", + deserializer=FilingSection.from_dict, + raw=raw, + options=options, + ) + + @overload + def list_stocks_filings_8k_text( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, filing_date_gt: Optional[Union[str, date]] = None, filing_date_gte: Optional[Union[str, date]] = None, filing_date_lt: Optional[Union[str, date]] = None, filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Filing8K]: ... + @overload + def list_stocks_filings_8k_text( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, ticker: Optional[str] = None, ticker_any_of: Optional[str] = None, ticker_gt: Optional[str] = None, ticker_gte: Optional[str] = None, ticker_lt: Optional[str] = None, ticker_lte: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_8k_text( + self, cik: Optional[str] = None, cik_any_of: Optional[str] = None, cik_gt: Optional[str] = None, cik_gte: Optional[str] = None, cik_lt: Optional[str] = None, cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, limit: Optional[int] = 100, sort: Optional[Union[str, Sort]] = "filing_date.desc", params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[RiskFactor], HTTPResponse]: - """ - Get categorized risk factors extracted from 10-K filings (with supporting_text). - """ - url = "/stocks/filings/vX/risk-factors" - return self._paginate( - path=url, - params=self._get_params(self.list_stocks_filings_risk_factors, locals()), - result_key="results", - deserializer=RiskFactor.from_dict, - raw=raw, - options=options, - ) - - def list_stocks_taxonomies_risk_factors( - self, - taxonomy: Optional[float] = None, - taxonomy_gt: Optional[float] = None, - taxonomy_gte: Optional[float] = None, - taxonomy_lt: Optional[float] = None, - taxonomy_lte: Optional[float] = None, - primary_category: Optional[str] = None, - primary_category_any_of: Optional[str] = None, - primary_category_gt: Optional[str] = None, - primary_category_gte: Optional[str] = None, - primary_category_lt: Optional[str] = None, - primary_category_lte: Optional[str] = None, - secondary_category: Optional[str] = None, - secondary_category_any_of: Optional[str] = None, - secondary_category_gt: Optional[str] = None, - secondary_category_gte: Optional[str] = None, - secondary_category_lt: Optional[str] = None, - secondary_category_lte: Optional[str] = None, - tertiary_category: Optional[str] = None, - tertiary_category_any_of: Optional[str] = None, - tertiary_category_gt: Optional[str] = None, - tertiary_category_gte: Optional[str] = None, - tertiary_category_lt: Optional[str] = None, - tertiary_category_lte: Optional[str] = None, - limit: Optional[int] = 200, - sort: Optional[Union[str, Sort]] = "taxonomy.desc", - params: Optional[Dict[str, Any]] = None, - raw: bool = False, - options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[RiskFactorTaxonomy], HTTPResponse]: - """ - Get the taxonomy/categories used to classify risk factors (kept old name for backward compatibility). - """ - url = "/stocks/taxonomies/vX/risk-factors" - return self._paginate( - path=url, - params=self._get_params(self.list_stocks_taxonomies_risk_factors, locals()), - result_key="results", - deserializer=RiskFactorTaxonomy.from_dict, - raw=raw, - options=options, - ) - - def list_stocks_filings_8k_disclosures( + ) -> Union[Iterator[Filing8K], HTTPResponse]: ... + def list_stocks_filings_8k_text( self, cik: Optional[str] = None, cik_any_of: Optional[str] = None, - tickers: Optional[str] = None, - tickers_all_of: Optional[str] = None, - tickers_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, filing_date: Optional[Union[str, date]] = None, - filing_date_any_of: Optional[str] = None, filing_date_gt: Optional[Union[str, date]] = None, filing_date_gte: Optional[Union[str, date]] = None, filing_date_lt: Optional[Union[str, date]] = None, filing_date_lte: Optional[Union[str, date]] = None, - tertiary_category: Optional[str] = None, limit: Optional[int] = 100, sort: Optional[Union[str, Sort]] = "filing_date.desc", params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[Disclosure], HTTPResponse]: - """ - SEC 8-K filing disclosure categorization. A single 8-K filing can produce - multiple rows when it covers multiple disclosure types, each classified into - primary, secondary, and tertiary categories with a supporting text excerpt. - The full classification list is available at /stocks/taxonomies/vX/disclosures. - """ - url = "/stocks/filings/8-K/vX/disclosures" - return self._paginate( - path=url, - params=self._get_params(self.list_stocks_filings_8k_disclosures, locals()), - result_key="results", - deserializer=Disclosure.from_dict, - raw=raw, - options=options, - ) - - def list_stocks_taxonomies_disclosures( - self, - taxonomy: Optional[str] = None, - taxonomy_any_of: Optional[str] = None, - taxonomy_gt: Optional[str] = None, - taxonomy_gte: Optional[str] = None, - taxonomy_lt: Optional[str] = None, - taxonomy_lte: Optional[str] = None, - primary_category: Optional[str] = None, - primary_category_any_of: Optional[str] = None, - primary_category_gt: Optional[str] = None, - primary_category_gte: Optional[str] = None, - primary_category_lt: Optional[str] = None, - primary_category_lte: Optional[str] = None, - secondary_category: Optional[str] = None, - secondary_category_any_of: Optional[str] = None, - secondary_category_gt: Optional[str] = None, - secondary_category_gte: Optional[str] = None, - secondary_category_lt: Optional[str] = None, - secondary_category_lte: Optional[str] = None, - tertiary_category: Optional[str] = None, - tertiary_category_any_of: Optional[str] = None, - tertiary_category_gt: Optional[str] = None, - tertiary_category_gte: Optional[str] = None, - tertiary_category_lt: Optional[str] = None, - tertiary_category_lte: Optional[str] = None, - limit: Optional[int] = 200, - sort: Optional[Union[str, Sort]] = "taxonomy.desc", - params: Optional[Dict[str, Any]] = None, - raw: bool = False, - options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[DisclosureTaxonomy], HTTPResponse]: + ) -> Union[Iterator[Filing8K], HTTPResponse]: """ - The complete list of 8-K disclosure classifications used in the 8-K - disclosures endpoint. + Get parsed 8-K filings (earnings, acquisitions, executive changes, etc.). """ - url = "/stocks/taxonomies/vX/disclosures" + url = "/stocks/filings/8-K/vX/text" return self._paginate( path=url, - params=self._get_params(self.list_stocks_taxonomies_disclosures, locals()), + params=self._get_params(self.list_stocks_filings_8k_text, locals()), result_key="results", - deserializer=DisclosureTaxonomy.from_dict, + deserializer=Filing8K.from_dict, raw=raw, options=options, ) - def list_stocks_filings_10k_sections( + @overload + def list_stocks_filings_index( self, cik: Optional[str] = None, cik_any_of: Optional[str] = None, @@ -960,38 +2536,58 @@ def list_stocks_filings_10k_sections( ticker_gte: Optional[str] = None, ticker_lt: Optional[str] = None, ticker_lte: Optional[str] = None, - section: Optional[str] = None, - section_any_of: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, filing_date: Optional[Union[str, date]] = None, filing_date_gt: Optional[Union[str, date]] = None, filing_date_gte: Optional[Union[str, date]] = None, filing_date_lt: Optional[Union[str, date]] = None, filing_date_lte: Optional[Union[str, date]] = None, - period_end: Optional[Union[str, date]] = None, - period_end_gt: Optional[Union[str, date]] = None, - period_end_gte: Optional[Union[str, date]] = None, - period_end_lt: Optional[Union[str, date]] = None, - period_end_lte: Optional[Union[str, date]] = None, - limit: Optional[int] = 100, - sort: Optional[Union[str, Sort]] = "period_end.desc", + limit: Optional[int] = 1000, + sort: Optional[Union[str, Sort]] = "filing_date.desc", params: Optional[Dict[str, Any]] = None, - raw: bool = False, + raw: Literal[False] = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[FilingSection], HTTPResponse]: - """ - Get raw text sections from 10-K/10-Q filings (business, risk_factors, etc.). - """ - url = "/stocks/filings/10-K/vX/sections" - return self._paginate( - path=url, - params=self._get_params(self.list_stocks_filings_10k_sections, locals()), - result_key="results", - deserializer=FilingSection.from_dict, - raw=raw, - options=options, - ) - - def list_stocks_filings_8k_text( + ) -> Iterator[FilingIndex]: ... + @overload + def list_stocks_filings_index( + self, + cik: Optional[str] = None, + cik_any_of: Optional[str] = None, + cik_gt: Optional[str] = None, + cik_gte: Optional[str] = None, + cik_lt: Optional[str] = None, + cik_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + form_type: Optional[str] = None, + form_type_any_of: Optional[str] = None, + form_type_gt: Optional[str] = None, + form_type_gte: Optional[str] = None, + form_type_lt: Optional[str] = None, + form_type_lte: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 1000, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_index( self, cik: Optional[str] = None, cik_any_of: Optional[str] = None, @@ -1016,25 +2612,12 @@ def list_stocks_filings_8k_text( filing_date_gte: Optional[Union[str, date]] = None, filing_date_lt: Optional[Union[str, date]] = None, filing_date_lte: Optional[Union[str, date]] = None, - limit: Optional[int] = 100, + limit: Optional[int] = 1000, sort: Optional[Union[str, Sort]] = "filing_date.desc", params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[Iterator[Filing8K], HTTPResponse]: - """ - Get parsed 8-K filings (earnings, acquisitions, executive changes, etc.). - """ - url = "/stocks/filings/8-K/vX/text" - return self._paginate( - path=url, - params=self._get_params(self.list_stocks_filings_8k_text, locals()), - result_key="results", - deserializer=Filing8K.from_dict, - raw=raw, - options=options, - ) - + ) -> Union[Iterator[FilingIndex], HTTPResponse]: ... def list_stocks_filings_index( self, cik: Optional[str] = None, @@ -1079,6 +2662,55 @@ def list_stocks_filings_index( options=options, ) + @overload + def list_stocks_filings_13f( + self, + filer_cik: Optional[str] = None, + filer_cik_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Filing13F]: ... + @overload + def list_stocks_filings_13f( + self, + filer_cik: Optional[str] = None, + filer_cik_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_13f( + self, + filer_cik: Optional[str] = None, + filer_cik_any_of: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Filing13F], HTTPResponse]: ... def list_stocks_filings_13f( self, filer_cik: Optional[str] = None, @@ -1110,6 +2742,109 @@ def list_stocks_filings_13f( options=options, ) + @overload + def list_stocks_filings_form_3( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FilingForm3]: ... + @overload + def list_stocks_filings_form_3( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_form_3( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FilingForm3], HTTPResponse]: ... def list_stocks_filings_form_3( self, issuer_cik: Optional[str] = None, @@ -1158,6 +2893,112 @@ def list_stocks_filings_form_3( options=options, ) + @overload + def list_stocks_filings_form_4( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + transaction_code: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[FilingForm4]: ... + @overload + def list_stocks_filings_form_4( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + transaction_code: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_stocks_filings_form_4( + self, + issuer_cik: Optional[str] = None, + issuer_cik_any_of: Optional[str] = None, + owner_cik: Optional[str] = None, + owner_cik_any_of: Optional[str] = None, + tickers: Optional[str] = None, + tickers_all_of: Optional[str] = None, + tickers_any_of: Optional[str] = None, + form_type: Optional[str] = None, + transaction_code: Optional[str] = None, + filing_date: Optional[Union[str, date]] = None, + filing_date_gt: Optional[Union[str, date]] = None, + filing_date_gte: Optional[Union[str, date]] = None, + filing_date_lt: Optional[Union[str, date]] = None, + filing_date_lte: Optional[Union[str, date]] = None, + max_ticker: Optional[str] = None, + max_ticker_any_of: Optional[str] = None, + max_ticker_gt: Optional[str] = None, + max_ticker_gte: Optional[str] = None, + max_ticker_lt: Optional[str] = None, + max_ticker_lte: Optional[str] = None, + min_ticker: Optional[str] = None, + min_ticker_any_of: Optional[str] = None, + min_ticker_gt: Optional[str] = None, + min_ticker_gte: Optional[str] = None, + min_ticker_lt: Optional[str] = None, + min_ticker_lte: Optional[str] = None, + limit: Optional[int] = 100, + sort: Optional[Union[str, Sort]] = "filing_date.desc", + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[FilingForm4], HTTPResponse]: ... def list_stocks_filings_form_4( self, issuer_cik: Optional[str] = None, diff --git a/massive/rest/snapshot.py b/massive/rest/snapshot.py index 1cf4e368..da1f7483 100644 --- a/massive/rest/snapshot.py +++ b/massive/rest/snapshot.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from .models import ( TickerSnapshot, Direction, @@ -24,6 +24,55 @@ def get_locale(market_type: Union[SnapshotMarketType, str]): class SnapshotClient(BaseClient): + @overload + def list_universal_snapshots( + self, + type: Optional[Union[str, SnapshotMarketType]] = None, + ticker_any_of: Optional[List[str]] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[UniversalSnapshot]: ... + @overload + def list_universal_snapshots( + self, + type: Optional[Union[str, SnapshotMarketType]] = None, + ticker_any_of: Optional[List[str]] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_universal_snapshots( + self, + type: Optional[Union[str, SnapshotMarketType]] = None, + ticker_any_of: Optional[List[str]] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = 10, + sort: Optional[Union[str, Sort]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[UniversalSnapshot], HTTPResponse]: ... def list_universal_snapshots( self, type: Optional[Union[str, SnapshotMarketType]] = None, @@ -72,6 +121,37 @@ def list_universal_snapshots( options=options, ) + @overload + def get_snapshot_all( + self, + market_type: Union[str, SnapshotMarketType], + tickers: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + include_otc: Optional[bool] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[TickerSnapshot]: ... + @overload + def get_snapshot_all( + self, + market_type: Union[str, SnapshotMarketType], + tickers: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + include_otc: Optional[bool] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_all( + self, + market_type: Union[str, SnapshotMarketType], + tickers: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + include_otc: Optional[bool] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[TickerSnapshot], HTTPResponse]: ... def get_snapshot_all( self, market_type: Union[str, SnapshotMarketType], @@ -104,6 +184,37 @@ def get_snapshot_all( options=options, ) + @overload + def get_snapshot_direction( + self, + market_type: Union[str, SnapshotMarketType], + direction: Union[str, Direction], + params: Optional[Dict[str, Any]] = None, + include_otc: Optional[bool] = False, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[TickerSnapshot]: ... + @overload + def get_snapshot_direction( + self, + market_type: Union[str, SnapshotMarketType], + direction: Union[str, Direction], + params: Optional[Dict[str, Any]] = None, + include_otc: Optional[bool] = False, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_direction( + self, + market_type: Union[str, SnapshotMarketType], + direction: Union[str, Direction], + params: Optional[Dict[str, Any]] = None, + include_otc: Optional[bool] = False, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[TickerSnapshot], HTTPResponse]: ... def get_snapshot_direction( self, market_type: Union[str, SnapshotMarketType], @@ -136,6 +247,34 @@ def get_snapshot_direction( options=options, ) + @overload + def get_snapshot_ticker( + self, + market_type: Union[str, SnapshotMarketType], + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> TickerSnapshot: ... + @overload + def get_snapshot_ticker( + self, + market_type: Union[str, SnapshotMarketType], + ticker: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_ticker( + self, + market_type: Union[str, SnapshotMarketType], + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[TickerSnapshot, HTTPResponse]: ... def get_snapshot_ticker( self, market_type: Union[str, SnapshotMarketType], @@ -164,6 +303,34 @@ def get_snapshot_ticker( options=options, ) + @overload + def get_snapshot_option( + self, + underlying_asset: str, + option_contract: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> OptionContractSnapshot: ... + @overload + def get_snapshot_option( + self, + underlying_asset: str, + option_contract: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_option( + self, + underlying_asset: str, + option_contract: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[OptionContractSnapshot, HTTPResponse]: ... def get_snapshot_option( self, underlying_asset: str, @@ -189,6 +356,31 @@ def get_snapshot_option( options=options, ) + @overload + def list_snapshot_options_chain( + self, + underlying_asset: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[OptionContractSnapshot]: ... + @overload + def list_snapshot_options_chain( + self, + underlying_asset: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_snapshot_options_chain( + self, + underlying_asset: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[OptionContractSnapshot], HTTPResponse]: ... def list_snapshot_options_chain( self, underlying_asset: str, @@ -212,6 +404,31 @@ def list_snapshot_options_chain( options=options, ) + @overload + def get_snapshot_crypto_book( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> SnapshotTickerFullBook: ... + @overload + def get_snapshot_crypto_book( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_crypto_book( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[SnapshotTickerFullBook, HTTPResponse]: ... def get_snapshot_crypto_book( self, ticker: str, @@ -237,6 +454,31 @@ def get_snapshot_crypto_book( options=options, ) + @overload + def get_snapshot_indices( + self, + ticker_any_of: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[IndicesSnapshot]: ... + @overload + def get_snapshot_indices( + self, + ticker_any_of: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_snapshot_indices( + self, + ticker_any_of: Optional[Union[str, List[str]]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[IndicesSnapshot], HTTPResponse]: ... def get_snapshot_indices( self, ticker_any_of: Optional[Union[str, List[str]]] = None, @@ -266,6 +508,55 @@ def get_snapshot_indices( options=options, ) + @overload + def list_snapshot_indices( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[Union[str, List[str]]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[IndicesSnapshot]: ... + @overload + def list_snapshot_indices( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[Union[str, List[str]]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def list_snapshot_indices( + self, + ticker: Optional[str] = None, + ticker_any_of: Optional[Union[str, List[str]]] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + order: Optional[Union[str, Order]] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[IndicesSnapshot], HTTPResponse]: ... def list_snapshot_indices( self, ticker: Optional[str] = None, diff --git a/massive/rest/summaries.py b/massive/rest/summaries.py index 6af960eb..33ed7ee7 100644 --- a/massive/rest/summaries.py +++ b/massive/rest/summaries.py @@ -1,12 +1,37 @@ from massive.rest.models.summaries import SummaryResult from .base import BaseClient -from typing import Optional, Any, Dict, List, Union +from typing import Optional, Any, Dict, List, Union, Literal, overload from urllib3 import HTTPResponse from .models.request import RequestOptionBuilder class SummariesClient(BaseClient): + @overload + def get_summaries( + self, + ticker_any_of: Optional[List[str]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> List[SummaryResult]: ... + @overload + def get_summaries( + self, + ticker_any_of: Optional[List[str]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_summaries( + self, + ticker_any_of: Optional[List[str]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[List[SummaryResult], HTTPResponse]: ... def get_summaries( self, ticker_any_of: Optional[List[str]] = None, diff --git a/massive/rest/tmx.py b/massive/rest/tmx.py index dd5687cd..bda13ea1 100644 --- a/massive/rest/tmx.py +++ b/massive/rest/tmx.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from urllib3 import HTTPResponse from datetime import datetime, date @@ -16,6 +16,178 @@ class TmxClient(BaseClient): (aligned with the paths from /tmx/v1/...) """ + @overload + def list_tmx_corporate_events( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + type_gt: Optional[str] = None, + type_gte: Optional[str] = None, + type_lt: Optional[str] = None, + type_lte: Optional[str] = None, + status: Optional[str] = None, + status_any_of: Optional[str] = None, + status_gt: Optional[str] = None, + status_gte: Optional[str] = None, + status_lt: Optional[str] = None, + status_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + tmx_company_id: Optional[int] = None, + tmx_company_id_any_of: Optional[str] = None, + tmx_company_id_gt: Optional[int] = None, + tmx_company_id_gte: Optional[int] = None, + tmx_company_id_lt: Optional[int] = None, + tmx_company_id_lte: Optional[int] = None, + tmx_record_id: Optional[str] = None, + tmx_record_id_any_of: Optional[str] = None, + tmx_record_id_gt: Optional[str] = None, + tmx_record_id_gte: Optional[str] = None, + tmx_record_id_lt: Optional[str] = None, + tmx_record_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[TmxCorporateEvent]: ... + @overload + def list_tmx_corporate_events( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + type_gt: Optional[str] = None, + type_gte: Optional[str] = None, + type_lt: Optional[str] = None, + type_lte: Optional[str] = None, + status: Optional[str] = None, + status_any_of: Optional[str] = None, + status_gt: Optional[str] = None, + status_gte: Optional[str] = None, + status_lt: Optional[str] = None, + status_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + tmx_company_id: Optional[int] = None, + tmx_company_id_any_of: Optional[str] = None, + tmx_company_id_gt: Optional[int] = None, + tmx_company_id_gte: Optional[int] = None, + tmx_company_id_lt: Optional[int] = None, + tmx_company_id_lte: Optional[int] = None, + tmx_record_id: Optional[str] = None, + tmx_record_id_any_of: Optional[str] = None, + tmx_record_id_gt: Optional[str] = None, + tmx_record_id_gte: Optional[str] = None, + tmx_record_id_lt: Optional[str] = None, + tmx_record_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_tmx_corporate_events( + self, + date: Optional[Union[str, date]] = None, + date_any_of: Optional[str] = None, + date_gt: Optional[Union[str, date]] = None, + date_gte: Optional[Union[str, date]] = None, + date_lt: Optional[Union[str, date]] = None, + date_lte: Optional[Union[str, date]] = None, + type: Optional[str] = None, + type_any_of: Optional[str] = None, + type_gt: Optional[str] = None, + type_gte: Optional[str] = None, + type_lt: Optional[str] = None, + type_lte: Optional[str] = None, + status: Optional[str] = None, + status_any_of: Optional[str] = None, + status_gt: Optional[str] = None, + status_gte: Optional[str] = None, + status_lt: Optional[str] = None, + status_lte: Optional[str] = None, + ticker: Optional[str] = None, + ticker_any_of: Optional[str] = None, + ticker_gt: Optional[str] = None, + ticker_gte: Optional[str] = None, + ticker_lt: Optional[str] = None, + ticker_lte: Optional[str] = None, + isin: Optional[str] = None, + isin_any_of: Optional[str] = None, + isin_gt: Optional[str] = None, + isin_gte: Optional[str] = None, + isin_lt: Optional[str] = None, + isin_lte: Optional[str] = None, + trading_venue: Optional[str] = None, + trading_venue_any_of: Optional[str] = None, + trading_venue_gt: Optional[str] = None, + trading_venue_gte: Optional[str] = None, + trading_venue_lt: Optional[str] = None, + trading_venue_lte: Optional[str] = None, + tmx_company_id: Optional[int] = None, + tmx_company_id_any_of: Optional[str] = None, + tmx_company_id_gt: Optional[int] = None, + tmx_company_id_gte: Optional[int] = None, + tmx_company_id_lt: Optional[int] = None, + tmx_company_id_lte: Optional[int] = None, + tmx_record_id: Optional[str] = None, + tmx_record_id_any_of: Optional[str] = None, + tmx_record_id_gt: Optional[str] = None, + tmx_record_id_gte: Optional[str] = None, + tmx_record_id_lt: Optional[str] = None, + tmx_record_id_lte: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[TmxCorporateEvent], HTTPResponse]: ... def list_tmx_corporate_events( self, date: Optional[Union[str, date]] = None, diff --git a/massive/rest/trades.py b/massive/rest/trades.py index 3aad1d0e..e6bf2d9b 100644 --- a/massive/rest/trades.py +++ b/massive/rest/trades.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, Union, Iterator +from typing import Optional, Any, Dict, Union, Iterator, Literal, overload from .models import Trade, LastTrade, CryptoTrade, Sort, Order from urllib3 import HTTPResponse from datetime import datetime, date @@ -8,6 +8,55 @@ class TradesClient(BaseClient): + @overload + 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[Trade]: ... + @overload + 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: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[Trade], HTTPResponse]: ... def list_trades( self, ticker: str, @@ -49,6 +98,31 @@ def list_trades( options=options, ) + @overload + def get_last_trade( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> LastTrade: ... + @overload + def get_last_trade( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_last_trade( + self, + ticker: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[LastTrade, HTTPResponse]: ... def get_last_trade( self, ticker: str, @@ -75,6 +149,34 @@ def get_last_trade( options=options, ) + @overload + def get_last_crypto_trade( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> CryptoTrade: ... + @overload + def get_last_crypto_trade( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None, + ) -> HTTPResponse: ... + @overload + def get_last_crypto_trade( + self, + from_: str, + to: str, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[CryptoTrade, HTTPResponse]: ... def get_last_crypto_trade( self, from_: str, diff --git a/massive/rest/vX.py b/massive/rest/vX.py index ebd95a1a..dbedad1e 100644 --- a/massive/rest/vX.py +++ b/massive/rest/vX.py @@ -1,5 +1,5 @@ from .base import BaseClient -from typing import Optional, Any, Dict, List, Union, Iterator +from typing import Optional, Any, Dict, List, Union, Iterator, Literal, overload from .models import ( StockFinancial, IPOListing, @@ -13,6 +13,88 @@ class VXClient(BaseClient): + @overload + def list_stock_financials( + self, + ticker: Optional[str] = None, + cik: Optional[str] = None, + company_name: Optional[str] = None, + company_name_search: Optional[str] = None, + sic: Optional[str] = None, + filing_date: Optional[Union[str, int, datetime, date]] = None, + filing_date_lt: Optional[Union[str, int, datetime, date]] = None, + filing_date_lte: Optional[Union[str, int, datetime, date]] = None, + filing_date_gt: Optional[Union[str, int, datetime, date]] = None, + filing_date_gte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gte: Optional[Union[str, int, datetime, date]] = None, + timeframe: Optional[Union[str, Timeframe]] = None, + include_sources: 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: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[StockFinancial]: ... + @overload + def list_stock_financials( + self, + ticker: Optional[str] = None, + cik: Optional[str] = None, + company_name: Optional[str] = None, + company_name_search: Optional[str] = None, + sic: Optional[str] = None, + filing_date: Optional[Union[str, int, datetime, date]] = None, + filing_date_lt: Optional[Union[str, int, datetime, date]] = None, + filing_date_lte: Optional[Union[str, int, datetime, date]] = None, + filing_date_gt: Optional[Union[str, int, datetime, date]] = None, + filing_date_gte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gte: Optional[Union[str, int, datetime, date]] = None, + timeframe: Optional[Union[str, Timeframe]] = None, + include_sources: 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: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_stock_financials( + self, + ticker: Optional[str] = None, + cik: Optional[str] = None, + company_name: Optional[str] = None, + company_name_search: Optional[str] = None, + sic: Optional[str] = None, + filing_date: Optional[Union[str, int, datetime, date]] = None, + filing_date_lt: Optional[Union[str, int, datetime, date]] = None, + filing_date_lte: Optional[Union[str, int, datetime, date]] = None, + filing_date_gt: Optional[Union[str, int, datetime, date]] = None, + filing_date_gte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_lte: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gt: Optional[Union[str, int, datetime, date]] = None, + period_of_report_date_gte: Optional[Union[str, int, datetime, date]] = None, + timeframe: Optional[Union[str, Timeframe]] = None, + include_sources: 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, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[StockFinancial], HTTPResponse]: ... def list_stock_financials( self, ticker: Optional[str] = None, @@ -76,6 +158,64 @@ def list_stock_financials( options=options, ) + @overload + def list_ipos( + self, + ticker: Optional[str] = None, + us_code: Optional[str] = None, + isin: Optional[str] = None, + listing_date: Optional[str] = None, + listing_date_lt: Optional[str] = None, + listing_date_lte: Optional[str] = None, + listing_date_gt: Optional[str] = None, + listing_date_gte: Optional[str] = None, + ipo_status: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: Literal[False] = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Iterator[IPOListing]: ... + @overload + def list_ipos( + self, + ticker: Optional[str] = None, + us_code: Optional[str] = None, + isin: Optional[str] = None, + listing_date: Optional[str] = None, + listing_date_lt: Optional[str] = None, + listing_date_lte: Optional[str] = None, + listing_date_gt: Optional[str] = None, + listing_date_gte: Optional[str] = None, + ipo_status: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + *, + raw: Literal[True], + options: Optional[RequestOptionBuilder] = None + ) -> HTTPResponse: ... + @overload + def list_ipos( + self, + ticker: Optional[str] = None, + us_code: Optional[str] = None, + isin: Optional[str] = None, + listing_date: Optional[str] = None, + listing_date_lt: Optional[str] = None, + listing_date_lte: Optional[str] = None, + listing_date_gt: Optional[str] = None, + listing_date_gte: Optional[str] = None, + ipo_status: Optional[str] = None, + limit: Optional[int] = None, + sort: Optional[Union[str, Sort]] = None, + order: Optional[Union[str, Order]] = None, + params: Optional[Dict[str, Any]] = None, + raw: bool = False, + options: Optional[RequestOptionBuilder] = None, + ) -> Union[Iterator[IPOListing], HTTPResponse]: ... def list_ipos( self, ticker: Optional[str] = None, @@ -93,7 +233,7 @@ def list_ipos( params: Optional[Dict[str, Any]] = None, raw: bool = False, options: Optional[RequestOptionBuilder] = None, - ) -> Union[List[IPOListing], HTTPResponse]: + ) -> Union[Iterator[IPOListing], HTTPResponse]: """ Retrieve upcoming or historical IPOs. @@ -108,7 +248,7 @@ def list_ipos( :param params: Additional query params. :param raw: Return raw HTTPResponse object if True, else return List[IPOListing]. :param options: RequestOptionBuilder for additional headers or params. - :return: A list of IPOListing objects or HTTPResponse if raw=True. + :return: An iterator of IPOListing objects or HTTPResponse if raw=True. """ url = "/vX/reference/ipos" diff --git a/massive/websocket/__init__.py b/massive/websocket/__init__.py index 7463b4cb..b3dd0a70 100644 --- a/massive/websocket/__init__.py +++ b/massive/websocket/__init__.py @@ -1,14 +1,29 @@ import os from collections import Counter from enum import Enum -from typing import Optional, Union, List, Set, Callable, Awaitable, Any +from typing import ( + Optional, + Union, + List, + Set, + Callable, + Awaitable, + Any, + Tuple, + TypeVar, + cast, + Iterable, +) import logging import json +import functools import asyncio +import random import ssl +import threading import time from .models import * -from websockets.asyncio.client import connect, ClientConnection +from websockets.asyncio.client import connect, ClientConnection, process_exception from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError from ..certs import ca_bundle_path from ..logging import get_logger @@ -22,6 +37,22 @@ # "max_connections", "slow_consumer", "force_disconnect") is logged as a warning. OK_STATUSES = {"connected", "auth_success", "success"} +_F = TypeVar("_F", bound=Callable[..., Any]) + + +def _changes_subscriptions(method: _F) -> _F: + # runs a WebSocketClient method that changes scheduled_subs under the + # client's lock, so it is safe to call from any thread, then wakes the + # task that sends the change + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + with self._subs_lock: + result = method(self, *args, **kwargs) + self._notify() + return result + + return cast(_F, wrapper) + class WebSocketClient: def __init__( @@ -36,6 +67,12 @@ def __init__( secure: bool = True, custom_json: Optional[Any] = None, ca_certs: Optional[str] = None, + reconnect_backoff: float = 0.0, + max_reconnect_backoff: float = 120.0, + reconnect_on_close: bool = False, + max_consecutive_failures: Optional[int] = None, + stable_uptime: float = 60.0, + raise_fatal_errors: bool = False, **kwargs, ): """ @@ -49,8 +86,20 @@ def __init__( :param max_reconnects: How many times to reconnect on network outage before ending .connect event loop. :param custom_json: Optional module exposing loads/dumps functions (similar to Python's json module) to be used for JSON conversions. :param ca_certs: Path to a CA bundle to verify TLS with. Defaults to the SSL_CERT_FILE or REQUESTS_CA_BUNDLE environment variable, then certifi. + :param reconnect_backoff: Seconds to wait before reconnecting after an open connection closes. The wait doubles with each consecutive failure, up to max_reconnect_backoff, with random jitter. 0 (the default) reconnects at once. + :param max_reconnect_backoff: The longest wait before reconnecting, in seconds. + :param reconnect_on_close: Also reconnect when the server closes the connection normally (e.g. code 1000), counting toward max_reconnects. By default, .connect returns then. + :param max_consecutive_failures: How many failures in a row .connect allows before it raises the last error. A failure is a connection attempt that fails, or a connection that closes before it has been open for stable_uptime seconds. None (the default) allows any number. max_reconnects applies too. + :param stable_uptime: Seconds a connection must stay open to reset the failure count and the backoff. + :param raise_fatal_errors: Raise connection errors that retrying will not fix, such as an HTTP 404 during the handshake, instead of retrying them forever. Uses websockets' default process_exception. + :raises ValueError: If reconnect_backoff is negative or greater than max_reconnect_backoff. :return: A client. """ + if not 0 <= reconnect_backoff <= max_reconnect_backoff: + raise ValueError( + "need 0 <= reconnect_backoff <= max_reconnect_backoff, got " + f"{reconnect_backoff} and {max_reconnect_backoff}" + ) if api_key is None: raise AuthError( f"Must specify env var {env_key} or pass api_key in constructor" @@ -73,11 +122,31 @@ def __init__( self.subscribed = False self.subs: Set[str] = set() self.max_reconnects = max_reconnects + self.reconnect_backoff = reconnect_backoff + self.max_reconnect_backoff = max_reconnect_backoff + self.reconnect_on_close = reconnect_on_close + self.max_consecutive_failures = max_consecutive_failures + self.stable_uptime = stable_uptime + self.raise_fatal_errors = raise_fatal_errors + # whether the server sent a max_connections status during the last + # handshake: the account has too many connections open + self.max_connections_reached = False self.websocket: Optional[ClientConnection] = None if subscriptions is None: subscriptions = [] self.scheduled_subs: Set[str] = set(subscriptions) self.schedule_resub = True + # guards scheduled_subs and schedule_resub, which subscribe() and + # friends change on the caller's thread while connect() reads them + self._subs_lock = threading.Lock() + # set_subscriptions() was called since the last update was sent, so + # send removals first; guarded by _subs_lock + self._removals_first = False + # topics resubscribe() asked to send again; guarded by _subs_lock + self._resend: Set[str] = set() + # while a connection is open: its loop, and the event that wakes its + # sender task (see _start_sender) + self._wake: Optional[Tuple[asyncio.AbstractEventLoop, asyncio.Event]] = None self._server_errors: Counter = Counter() self._server_errors_since = 0.0 self.ca_certs = ca_certs @@ -85,6 +154,11 @@ def __init__( self.json = custom_json else: self.json = json + # set by request_close(); connect() returns instead of reconnecting + self._close_requested = threading.Event() + # the event loop connect() runs on, while it runs + self._loop: Optional[asyncio.AbstractEventLoop] = None + self._closing: Optional[asyncio.Future] = None # https://websockets.readthedocs.io/en/stable/reference/client.html#opening-a-connection async def connect( @@ -101,25 +175,66 @@ async def connect( :param processor: The callback to process messages. :param close_timeout: How long to wait for handshake when calling .close. + :param kwargs: Passed to websockets' connect(), e.g. process_exception. :raises AuthError: If invalid API key is supplied. """ + self._loop = asyncio.get_running_loop() + try: + await self._connect(processor, close_timeout, **kwargs) + finally: + self._loop = None + self._close_requested.clear() + + async def _connect( + self, + processor: Union[ + Callable[[List[WebSocketMessage]], Awaitable], + Callable[[Union[str, bytes]], Awaitable], + ], + close_timeout: int, + **kwargs, + ): + if self._close_requested.is_set(): + return + # a new connection has no subscriptions, whatever an earlier call left + self.subs = set() + self.schedule_resub = True reconnects = 0 + # failed attempts and short-lived connections in a row + failures = 0 logger.debug("connect: %s", self.url) ssl_context = self._ssl_context() - last_exc = None + retry_or_raise = kwargs.pop( + "process_exception", + process_exception if self.raise_fatal_errors else lambda exc: None, + ) + + def on_connect_error(exc: Exception) -> Optional[Exception]: + nonlocal failures + failures += 1 + if self._too_many(failures, self.max_consecutive_failures): + return exc + return retry_or_raise(exc) + + last_exc: Optional[Exception] = None async for s in connect( self.url, close_timeout=close_timeout, ssl=ssl_context, - process_exception=lambda exc: None, + process_exception=on_connect_error, **kwargs, ): + if self._close_requested.is_set(): + await s.close() # requested while connecting + return self.websocket = s + connected_at = None try: msg = await s.recv() logger.debug("connected: %s", msg) - self._log_server_statuses(self.json.loads(msg)) + msg_parsed = self.json.loads(msg) + self._log_server_statuses(msg_parsed) logger.debug("authing...") await s.send( self.json.dumps({"action": "auth", "params": self.api_key}) @@ -129,66 +244,98 @@ async def connect( logger.debug("authed: %s", auth_msg) if auth_msg_parsed[0]["status"] == "auth_failed": raise AuthError(auth_msg_parsed[0]["message"]) + self.max_connections_reached = any( + m.get("status") == "max_connections" + for m in msg_parsed + auth_msg_parsed + ) + connected_at = time.monotonic() # e.g. max_connections, which the server sends before closing self._log_server_statuses(auth_msg_parsed) self._flush_server_errors(force=True) - while True: - if self.schedule_resub: - logger.debug( - "reconciling: %s %s", self.subs, self.scheduled_subs - ) - new_subs = self.scheduled_subs.difference(self.subs) - await self._subscribe(new_subs) - old_subs = self.subs.difference(self.scheduled_subs) - await self._unsubscribe(old_subs) - self.subs = self.scheduled_subs - self.subs = set(self.scheduled_subs) - self.schedule_resub = False - - try: - cmsg: Union[List[WebSocketMessage], Union[str, bytes]] = ( - await asyncio.wait_for(s.recv(), timeout=1) - ) - except asyncio.TimeoutError: + # subscription changes go out from a task of their own, + # starting with the whole scheduled set + sender, wake = self._start_sender() + try: + while True: + if sender.done(): + self._check_sender(sender) + if self.schedule_resub: + # e.g. set by code that changed scheduled_subs itself + wake.set() + + try: + cmsg: Union[List[WebSocketMessage], Union[str, bytes]] = ( + await asyncio.wait_for(s.recv(), timeout=1) + ) + except asyncio.TimeoutError: + self._flush_server_errors() + continue + + if not self.raw: + # we know cmsg is Data + msgJson = self.json.loads(cmsg) # type: ignore + for m in msgJson: + if m["ev"] == "status": + logger.debug("status: %s", m["message"]) + self._log_server_statuses(msgJson) + cmsg = parse(msgJson, logger, self.market) self._flush_server_errors() - continue - - if not self.raw: - # we know cmsg is Data - msgJson = self.json.loads(cmsg) # type: ignore - for m in msgJson: - if m["ev"] == "status": - logger.debug("status: %s", m["message"]) - self._log_server_statuses(msgJson) - cmsg = parse(msgJson, logger, self.market) - self._flush_server_errors() - - if len(cmsg) > 0: - await processor(cmsg) # type: ignore + + if len(cmsg) > 0: + await processor(cmsg) # type: ignore + finally: + await self._stop_sender(sender) except ConnectionClosedOK as e: logger.debug("connection closed (OK): %s", e) # the server sends a status (e.g. slow_consumer) before closing self._flush_server_errors(force=True) - return + # rcvd_then_sent: the server closed it, rather than close() + if not (self.reconnect_on_close and e.rcvd_then_sent): + return + last_exc = e except ConnectionClosedError as e: last_exc = e logger.debug("connection closed (ERR): %s", e) self._flush_server_errors(force=True) - reconnects += 1 - self.scheduled_subs = set(self.subs) - self.subs = set() - self.schedule_resub = True - if self.max_reconnects is not None and reconnects > self.max_reconnects: - break - continue - - if ( - last_exc - and self.max_reconnects is not None - and reconnects > self.max_reconnects - ): + if self._close_requested.is_set(): + return + reconnects += 1 + # keep scheduled_subs, which may hold changes not sent yet, + # and subscribe to all of it on the next connection + self.subs = set() + self.schedule_resub = True + if ( + connected_at is not None + and time.monotonic() - connected_at >= self.stable_uptime + ): + failures = 0 + else: + failures += 1 + if self._too_many(reconnects, self.max_reconnects) or self._too_many( + failures, self.max_consecutive_failures + ): + break + if self.reconnect_backoff > 0: + delay = self._reconnect_delay(failures) + logger.debug("reconnecting in %.1f s", delay) + await asyncio.sleep(delay) + + if last_exc is not None: raise last_exc + @staticmethod + def _too_many(count: int, limit: Optional[int]) -> bool: + return limit is not None and count > limit + + def _reconnect_delay(self, failures: int) -> float: + # doubles with each failure in a row, up to the cap; jitter adds up + # to 20%, and at the cap draws from [cap / 1.2, cap] instead + base, cap = self.reconnect_backoff, self.max_reconnect_backoff + delay = min(base * 2.0 ** min(max(failures - 1, 0), 64), cap) + if delay < cap: + return random.uniform(delay, min(delay * 1.2, cap)) + return random.uniform(max(base, cap / 1.2), cap) + def _ssl_context(self) -> Optional[ssl.SSLContext]: # darwin needs some extra <3 if not self.url.startswith("wss://"): @@ -260,19 +407,90 @@ async def _unsubscribe(self, topics: Union[List[str], Set[str]]): self.json.dumps({"action": "unsubscribe", "params": subs}) ) + def _start_sender(self) -> Tuple["asyncio.Task[None]", asyncio.Event]: + """Start the task that sends subscription changes; see _notify.""" + wake = asyncio.Event() + wake.set() # first, the whole scheduled set + self._wake = (asyncio.get_running_loop(), wake) + return asyncio.ensure_future(self._send_changes(wake)), wake + + async def _send_changes(self, wake: asyncio.Event): + # The only sender of subscription messages, so messages for two + # changes never interleave. Sending while connect() waits in recv() is + # safe: in websockets, only two concurrent recv() calls conflict. + while True: + await wake.wait() + wake.clear() + await self._reconcile() + + def _check_sender(self, sender: "asyncio.Task[None]"): + # raise what ended the sender, unless the connection closed: then + # recv() raises too, once the messages already received are read + if sender.cancelled(): + return + exc = sender.exception() + if exc is not None and not isinstance( + exc, (ConnectionClosedOK, ConnectionClosedError) + ): + raise exc + + async def _stop_sender(self, sender: "asyncio.Task[None]"): + self._wake = None + sender.cancel() + await asyncio.wait({sender}) # does not raise + self._check_sender(sender) + + def _notify(self): + """Wake the sender, if a connection is open. Safe from any thread.""" + waker = self._wake + if waker is None: + return + loop, wake = waker + try: + loop.call_soon_threadsafe(wake.set) + except RuntimeError: + pass # the loop is closed + + async def _reconcile(self): + """Send the changes that move the server from subs to scheduled_subs.""" + with self._subs_lock: + if not self.schedule_resub: + return + desired = set(self.scheduled_subs) + removals_first, self._removals_first = self._removals_first, False + resend, self._resend = self._resend, set() + self.schedule_resub = False + logger.debug("reconciling: %s %s", self.subs, desired) + added = desired.difference(self.subs) | resend.intersection(desired) + removed = self.subs.difference(desired) + try: + if removals_first: + await self._unsubscribe(removed) + await self._subscribe(added) + else: + await self._subscribe(added) + await self._unsubscribe(removed) + except BaseException: + # e.g. the connection closed: send it all on the next connection + with self._subs_lock: + self.schedule_resub = True + raise + self.subs = desired + @staticmethod def _parse_subscription(s: str): s = s.strip() split = s.split(".", 1) # Split at the first period if len(split) != 2: - logger.warning("invalid subscription:", s) + logger.warning("invalid subscription: %s", s) return [None, None] return split + @_changes_subscriptions def subscribe(self, *subscriptions: str): """ - Subscribe to given subscriptions. + Subscribe to given subscriptions. Safe to call from any thread. :param subscriptions: Subscriptions (args) """ @@ -285,14 +503,15 @@ def subscribe(self, *subscriptions: str): # If user subs to X.*, remove other X.\w+ if sym == "*": for t in list(self.subs): - if t.startswith(topic): + if t != s and t.strip().split(".", 1)[0] == topic: self.scheduled_subs.discard(t) self.schedule_resub = True + @_changes_subscriptions def unsubscribe(self, *subscriptions: str): """ - Unsubscribe from given subscriptions. + Unsubscribe from given subscriptions. Safe to call from any thread. :param subscriptions: Subscriptions (args) """ @@ -306,18 +525,59 @@ def unsubscribe(self, *subscriptions: str): # If user unsubs to X.*, remove other X.\w+ if sym == "*": for t in list(self.subs): - if t.startswith(topic): + if t.strip().split(".", 1)[0] == topic: self.scheduled_subs.discard(t) self.schedule_resub = True + @_changes_subscriptions def unsubscribe_all(self): """ - Unsubscribe from all subscriptions. + Unsubscribe from all subscriptions. Safe to call from any thread. """ self.scheduled_subs = set() self.schedule_resub = True + @_changes_subscriptions + def set_subscriptions(self, desired: Iterable[str]): + """ + Replace all subscriptions with ``desired``, in one step. Safe to call + from any thread. + + The client sends one unsubscribe message for the topics no longer + desired, then one subscribe message for the new ones, together with + any changes from ``subscribe()`` or ``unsubscribe()`` not sent yet. + Removals go first, so a client at the server's subscription limit + can swap topics; data that a removed and an added topic both cover + (e.g. ``T.AAPL`` replaced by ``T.*``) is not delivered in between. + Wildcards such as ``T.*`` are ordinary topics here. + + :param desired: Every topic to be subscribed to afterwards. Malformed + topics are logged and skipped. + """ + topics = {s for s in desired if self._parse_subscription(s)[0] is not None} + self.scheduled_subs = topics + self._removals_first = True + self.schedule_resub = True + + @_changes_subscriptions + def resubscribe(self, *topics: str): + """ + Send a subscribe message again for topics already subscribed, e.g. + ones the server never acknowledged. Safe to call from any thread. + + :param topics: Topics to send again (args). Malformed topics are + logged and skipped. + :raises ValueError: If a topic is not subscribed or scheduled to be; + nothing is sent then. + """ + again = {s for s in topics if self._parse_subscription(s)[0] is not None} + unknown = again.difference(self.scheduled_subs) + if unknown: + raise ValueError(f"not subscribed: {sorted(unknown)}") + self._resend |= again + self.schedule_resub = True + async def close(self): """ Close the websocket connection. @@ -330,3 +590,28 @@ async def close(self): self.websocket = None else: logger.warning("no websocket open to close") + + def request_close(self): + """ + Close the websocket connection and make ``connect()`` return instead + of reconnecting. Unlike ``close()``, this is safe to call from any + thread, e.g. to stop ``run()``, and it does not wait. + + An attempt to connect, or a wait before reconnecting, is not + interrupted: ``connect()`` returns once it ends. If ``connect()`` is + not running, the next call returns at once. + """ + logger.debug("close requested") + self._close_requested.set() + loop = self._loop + if loop is None: + return + try: + loop.call_soon_threadsafe(self._close_soon) + except RuntimeError: + pass # the loop is closed, so connect() has returned + + def _close_soon(self): + # on connect()'s loop; recv() then raises and connect() returns + if self.websocket is not None: + self._closing = asyncio.ensure_future(self.websocket.close()) diff --git a/massive/websocket/models/models.py b/massive/websocket/models/models.py index 6b3acd90..d3711e57 100644 --- a/massive/websocket/models/models.py +++ b/massive/websocket/models/models.py @@ -217,10 +217,10 @@ class CryptoQuote: event_type: Optional[Union[str, EventType]] = None pair: Optional[str] = None - bid_price: Optional[int] = None + bid_price: Optional[float] = None bid_size: Optional[float] = None - ask_price: Optional[int] = None - ask_size: Optional[int] = None + ask_price: Optional[float] = None + ask_size: Optional[float] = None timestamp: Optional[float] = None exchange_id: Optional[int] = None received_timestamp: Optional[int] = None @@ -328,7 +328,7 @@ class IndexValue: event_type: Optional[Union[str, EventType]] = None value: Optional[float] = None ticker: Optional[str] = None - timestamp: Optional[str] = None + timestamp: Optional[int] = None @staticmethod def from_dict(d): diff --git a/test_rest/base.py b/test_rest/base.py index 40854146..41b652d4 100644 --- a/test_rest/base.py +++ b/test_rest/base.py @@ -3,6 +3,7 @@ import os import re import unittest +from typing import Set import pook # type: ignore # mocks are stored in file tree @@ -32,6 +33,10 @@ class BaseTest(unittest.TestCase): + # mocks that answer more than once, for tests that repeat a request; + # others answer once, which the pagination tests rely on + persistent_mocks: Set[str] = set() + @classmethod def setUpClass(cls): cls.maxDiff = None @@ -40,4 +45,14 @@ def setUpClass(cls): for m in mocks: url = cls.c.BASE + m[0] # print("register", url) - pook.get(url, reply=200, response_body=m[1]) + pook.get( + url, + reply=200, + response_body=m[1], + persist=m[0] in cls.persistent_mocks, + ) + + @classmethod + def tearDownClass(cls): + # stop pook and drop the mocks, so they don't leak into later classes + pook.off() diff --git a/test_rest/mocks/fed/v1/funding-conditions&cursor=ZGF0ZS5ndGU9MjAyNS0wNi0wMSZsaW1pdD0x.json b/test_rest/mocks/fed/v1/funding-conditions&cursor=ZGF0ZS5ndGU9MjAyNS0wNi0wMSZsaW1pdD0x.json new file mode 100644 index 00000000..1f20e1b3 --- /dev/null +++ b/test_rest/mocks/fed/v1/funding-conditions&cursor=ZGF0ZS5ndGU9MjAyNS0wNi0wMSZsaW1pdD0x.json @@ -0,0 +1,31 @@ +{ + "status": "OK", + "request_id": "b2170df985474b6d21a6eeccfb6bee67", + "count": 1, + "results": [ + { + "date": "2025-06-02", + "effective_fed_funds_rate": 4.33, + "effective_fed_funds_volume": 98, + "fed_funds_target_lower": 4.25, + "fed_funds_target_upper": 4.5, + "fed_overnight_repo_treasury_amount": 0, + "fed_overnight_reverse_repo_treasury_amount": 214.5, + "financial_commercial_paper_90d_rate": 4.35, + "interest_on_reserve_balances": 4.4, + "nonfinancial_commercial_paper_90d_rate": 4.34, + "obfr_25th_percentile": 4.3, + "obfr_75th_percentile": 4.33, + "obfr_volume": 305, + "overnight_bank_funding_rate": 4.32, + "secured_overnight_financing_rate": 4.31, + "sofr_25th_percentile": 4.28, + "sofr_75th_percentile": 4.32, + "sofr_volume": 2214, + "tgcr_25th_percentile": 4.27, + "tgcr_75th_percentile": 4.31, + "tri_party_general_collateral_rate": 4.3, + "tri_party_general_collateral_volume": 1876 + } + ] +} diff --git a/test_rest/mocks/fed/v1/funding-conditions&date.gte=2025-06-01&limit=1.json b/test_rest/mocks/fed/v1/funding-conditions&date.gte=2025-06-01&limit=1.json new file mode 100644 index 00000000..f294c384 --- /dev/null +++ b/test_rest/mocks/fed/v1/funding-conditions&date.gte=2025-06-01&limit=1.json @@ -0,0 +1,32 @@ +{ + "status": "OK", + "request_id": "6a7e466379af0a71039d60cc78e72282", + "count": 1, + "next_url": "https://api.massive.com/fed/v1/funding-conditions?cursor=ZGF0ZS5ndGU9MjAyNS0wNi0wMSZsaW1pdD0x", + "results": [ + { + "date": "2025-06-01", + "effective_fed_funds_rate": 4.33, + "effective_fed_funds_volume": null, + "fed_funds_target_lower": 4.25, + "fed_funds_target_upper": 4.5, + "fed_overnight_repo_treasury_amount": null, + "fed_overnight_reverse_repo_treasury_amount": null, + "financial_commercial_paper_90d_rate": null, + "interest_on_reserve_balances": 4.4, + "nonfinancial_commercial_paper_90d_rate": null, + "obfr_25th_percentile": null, + "obfr_75th_percentile": null, + "obfr_volume": null, + "overnight_bank_funding_rate": null, + "secured_overnight_financing_rate": null, + "sofr_25th_percentile": null, + "sofr_75th_percentile": null, + "sofr_volume": null, + "tgcr_25th_percentile": null, + "tgcr_75th_percentile": null, + "tri_party_general_collateral_rate": null, + "tri_party_general_collateral_volume": null + } + ] +} diff --git a/test_rest/mocks/v1/open-close/crypto/BTC/USD/2020-10-09&adjusted=true.json b/test_rest/mocks/v1/open-close/crypto/BTC/USD/2020-10-09&adjusted=true.json new file mode 100644 index 00000000..b3338177 --- /dev/null +++ b/test_rest/mocks/v1/open-close/crypto/BTC/USD/2020-10-09&adjusted=true.json @@ -0,0 +1,51 @@ +{ + "symbol": "BTC-USD", + "isUTC": true, + "day": "2020-10-09T00:00:00.000Z", + "open": 10932.44, + "close": 11050.64, + "openTrades": [ + { + "s": 0.002, + "p": 10932.44, + "x": 1, + "t": 1602201600056, + "c": [ + 2 + ], + "i": "511235746" + }, + { + "s": 0.02, + "p": 10923.76, + "x": 4, + "t": 1602201600141, + "c": [ + 2 + ], + "i": "511235751" + } + ], + "closingTrades": [ + { + "s": 0.006128, + "p": 11050.64, + "x": 4, + "t": 1602287999795, + "c": [ + 2 + ], + "i": "973323250" + }, + { + "s": 0.014, + "p": 11049.4, + "x": 17, + "t": 1602287999659, + "c": [ + 1 + ], + "i": "105717893" + } + ] +} diff --git a/test_rest/test_aggs.py b/test_rest/test_aggs.py index 850a00da..c58cdf62 100644 --- a/test_rest/test_aggs.py +++ b/test_rest/test_aggs.py @@ -3,6 +3,8 @@ Agg, GroupedDailyAgg, DailyOpenCloseAgg, + DailyOpenCloseCrypto, + DailyOpenCloseCryptoTrade, PreviousCloseAgg, ) @@ -96,8 +98,59 @@ def test_get_daily_open_close_agg(self): self.assertEqual(aggs, expected) + def test_get_daily_open_close_crypto(self): + aggs = self.c.get_daily_open_close_crypto( + "BTC", "USD", "2020-10-09", adjusted=True + ) + expected = DailyOpenCloseCrypto( + symbol="BTC-USD", + is_utc=True, + day="2020-10-09T00:00:00.000Z", + open=10932.44, + close=11050.64, + open_trades=[ + DailyOpenCloseCryptoTrade( + conditions=[2], + id="511235746", + price=10932.44, + size=0.002, + timestamp=1602201600056, + exchange=1, + ), + DailyOpenCloseCryptoTrade( + conditions=[2], + id="511235751", + price=10923.76, + size=0.02, + timestamp=1602201600141, + exchange=4, + ), + ], + closing_trades=[ + DailyOpenCloseCryptoTrade( + conditions=[2], + id="973323250", + price=11050.64, + size=0.006128, + timestamp=1602287999795, + exchange=4, + ), + DailyOpenCloseCryptoTrade( + conditions=[1], + id="105717893", + price=11049.4, + size=0.014, + timestamp=1602287999659, + exchange=17, + ), + ], + ) + + self.assertEqual(aggs, expected) + def test_get_previous_close_agg(self): aggs = self.c.get_previous_close_agg("AAPL") + self.assertIsInstance(aggs, list) expected = [ PreviousCloseAgg( ticker="AAPL", diff --git a/test_rest/test_bad_response.py b/test_rest/test_bad_response.py new file mode 100644 index 00000000..9509f5f3 --- /dev/null +++ b/test_rest/test_bad_response.py @@ -0,0 +1,111 @@ +from http.server import BaseHTTPRequestHandler, HTTPServer +from unittest import mock +import threading +import unittest + +from urllib3.exceptions import MaxRetryError +from urllib3.util.retry import Retry + +from massive import RESTClient +from massive.exceptions import BadResponse +from base import BaseTest + +import pook # type: ignore + + +class BadResponseTest(BaseTest): + def test_status_is_set(self): + cases = [ + (403, '{"status":"NOT_AUTHORIZED","message":"not entitled"}'), + (404, '{"status":"NOT_FOUND","message":"not found"}'), + ] + for status, body in cases: + with self.subTest(status=status): + ticker = f"ERR{status}" # not covered by the fixture mocks + pook.get( + self.c.BASE + "/v3/reference/tickers/" + ticker, + reply=status, + response_body=body, + ) + with self.assertRaises(BadResponse) as ctx: + self.c.get_ticker_details(ticker) + self.assertEqual(ctx.exception.status, status) + self.assertEqual(ctx.exception.args, (body,)) + self.assertEqual(str(ctx.exception), body) + + def test_status_defaults_to_none(self): + for args in [(), ("boom",), ("boom", 1)]: + with self.subTest(args=args): + exc = BadResponse(*args) + self.assertEqual(exc.args, args) + self.assertIsNone(exc.status) + + def test_status_does_not_change_message(self): + exc = BadResponse("boom", status=500) + self.assertEqual(exc.args, ("boom",)) + self.assertEqual(str(exc), "boom") + self.assertEqual(exc.status, 500) + + +class StatusServer(HTTPServer): + """Answers every GET with a 429 and counts the requests. + + pook replaces urllib3's urlopen, which is where retries happen, so the + raise_on_status tests need a real server. + """ + + def __init__(self): + self.requests = 0 + super().__init__(("127.0.0.1", 0), StatusHandler) + + +class StatusHandler(BaseHTTPRequestHandler): + server: StatusServer + + def do_GET(self): + self.server.requests += 1 + self.send_response(429) + self.send_header("Content-Length", "4") + self.end_headers() + self.wfile.write(b"slow") + + def log_message(self, format, *args): + pass + + +class RaiseOnStatusTest(unittest.TestCase): + def setUp(self): + # BaseTest leaves pook on for the rest of the run + if pook.isactive(): + pook.disable() + self.addCleanup(pook.activate) + self.server = StatusServer() + threading.Thread( + target=self.server.serve_forever, + kwargs={"poll_interval": 0.01}, + daemon=True, + ).start() + self.addCleanup(self.server.server_close) + self.addCleanup(self.server.shutdown) + + def get_error(self, error, **kwargs): + base = f"http://127.0.0.1:{self.server.server_port}" + c = RESTClient("key", base=base, retries=2, **kwargs) + with mock.patch.object(Retry, "sleep"): # skip the backoff + with self.assertRaises(error) as ctx: + c.get_market_status() + self.assertEqual(self.server.requests, 3) # first attempt + 2 retries + return ctx.exception + + def test_default_raises_max_retry_error(self): + self.get_error(MaxRetryError) + + def test_false_raises_bad_response(self): + exc = self.get_error(BadResponse, raise_on_status=False) + self.assertEqual(exc.status, 429) + self.assertEqual(str(exc), "slow") + + def test_reaches_vx_client(self): + c = RESTClient("key", raise_on_status=False) + for pool in (c.client, c.vx.client): + self.assertFalse(pool.connection_pool_kw["retries"].raise_on_status) diff --git a/test_rest/test_concurrency.py b/test_rest/test_concurrency.py new file mode 100644 index 00000000..9f4e9aa7 --- /dev/null +++ b/test_rest/test_concurrency.py @@ -0,0 +1,76 @@ +import json +import threading +import unittest +from concurrent.futures import ThreadPoolExecutor +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer + +from massive import RESTClient +from massive.rest.models.request import RequestOptionBuilder, X_MASSIVE_EDGE_ID + + +class EchoServer(ThreadingHTTPServer): + "Echoes each request back, and records the most requests in flight at once." + + daemon_threads = True + + def __init__(self): + super().__init__(("127.0.0.1", 0), EchoHandler) + self.lock = threading.Lock() + self.in_flight = 0 + self.peak = 0 + + +class EchoHandler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" # keep-alive, so pooled connections are reused + server: EchoServer + + def do_GET(self): + with self.server.lock: + self.server.in_flight += 1 + self.server.peak = max(self.server.peak, self.server.in_flight) + body = json.dumps([self.path, self.headers.get(X_MASSIVE_EDGE_ID)]).encode() + self.send_response(200) + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + with self.server.lock: + self.server.in_flight -= 1 + + def log_message(self, format, *args): + pass + + +class ConcurrencyTest(unittest.TestCase): + threads = 16 + calls = 64 + + def test_shared_client(self): + httpd = EchoServer() + threading.Thread(target=httpd.serve_forever, daemon=True).start() + self.addCleanup(httpd.server_close) + self.addCleanup(httpd.shutdown) + host, port = httpd.server_address[:2] + c = RESTClient("key", base=f"http://{host!s}:{port}", maxsize=self.threads) + headers_before = list(c.headers.items()) + barrier = threading.Barrier(self.threads, timeout=10) + + def run(t): + barrier.wait() # start together, so the requests overlap + for i in range(self.calls): + path = f"/v3/reference/tickers/T{t}N{i}" + # odd calls send per-request headers, even calls send none + edge_id = f"edge-{t}-{i}" if i % 2 else None + options = RequestOptionBuilder(edge_id, "10.0.0.1") if edge_id else None + # _get, which every endpoint calls; endpoint methods currently + # also copy `options` into the query string + resp = c._get(path=path, params={"n": i}, raw=True, options=options) + # the response answers this call's request, not another thread's + self.assertEqual(json.loads(resp.data), [f"{path}?n={i}", edge_id]) + + with ThreadPoolExecutor(self.threads) as pool: + for f in [pool.submit(run, t) for t in range(self.threads)]: + f.result() + + self.assertGreater(httpd.peak, 1) # the threads really overlapped + # per-request headers never leak into the client's default headers + self.assertEqual(list(c.headers.items()), headers_before) diff --git a/test_rest/test_dividends.py b/test_rest/test_dividends.py index 7b6575d0..8549df9d 100644 --- a/test_rest/test_dividends.py +++ b/test_rest/test_dividends.py @@ -3,6 +3,9 @@ class DividendsTest(BaseTest): + # test_list_stocks_dividends_ticker_any_of requests this twice + persistent_mocks = {"/stocks/v1/dividends?ticker.any_of=AAPL%2CVZ"} + def test_list_dividends(self): dividends = [d for d in self.c.list_dividends()] expected = [ diff --git a/test_rest/test_economy.py b/test_rest/test_economy.py new file mode 100644 index 00000000..223475f1 --- /dev/null +++ b/test_rest/test_economy.py @@ -0,0 +1,89 @@ +import pook # type: ignore + +from base import BaseTest +from massive.rest.models.economy import FedFundingConditions + + +class EconomyTest(BaseTest): + def test_list_funding_conditions(self): + conditions = [ + c for c in self.c.list_funding_conditions(date_gte="2025-06-01", limit=1) + ] + expected = [ + FedFundingConditions( + date="2025-06-01", + effective_fed_funds_rate=4.33, + fed_funds_target_lower=4.25, + fed_funds_target_upper=4.5, + interest_on_reserve_balances=4.4, + ), + FedFundingConditions( + date="2025-06-02", + effective_fed_funds_rate=4.33, + effective_fed_funds_volume=98, + fed_funds_target_lower=4.25, + fed_funds_target_upper=4.5, + fed_overnight_repo_treasury_amount=0, + fed_overnight_reverse_repo_treasury_amount=214.5, + financial_commercial_paper_90d_rate=4.35, + interest_on_reserve_balances=4.4, + nonfinancial_commercial_paper_90d_rate=4.34, + obfr_25th_percentile=4.3, + obfr_75th_percentile=4.33, + obfr_volume=305, + overnight_bank_funding_rate=4.32, + secured_overnight_financing_rate=4.31, + sofr_25th_percentile=4.28, + sofr_75th_percentile=4.32, + sofr_volume=2214, + tgcr_25th_percentile=4.27, + tgcr_75th_percentile=4.31, + tri_party_general_collateral_rate=4.3, + tri_party_general_collateral_volume=1876, + ), + ] + self.assertEqual(conditions, expected) + + def test_list_funding_conditions_query_params(self): + # each documented parameter is sent under its API name (date.gt, not date_gt) + params = { + "date": "2025-06-02", + "date.gt": "2025-06-01", + "date.gte": "2025-06-01", + "date.lt": "2025-06-03", + "date.lte": "2025-06-03", + "limit": "10", + "sort": "date.desc", + } + mock = pook.get( + self.c.BASE + "/fed/v1/funding-conditions", + params=params, + reply=200, + response_json={"results": []}, + ) + conditions = self.c.list_funding_conditions( + date="2025-06-02", + date_gt="2025-06-01", + date_gte="2025-06-01", + date_lt="2025-06-03", + date_lte="2025-06-03", + limit=10, + sort="date.desc", + ) + self.assertEqual(list(conditions), []) + self.assertEqual(mock.calls, 1) + self.assertEqual(mock.matches[0].query, {k: [v] for k, v in params.items()}) + + def test_list_funding_conditions_sort_is_sent_as_given(self): + # sort takes "." values, comma separated, not a + # bare direction, so the client must send the string unchanged. + sort = "date.desc,effective_fed_funds_rate.asc" + mock = pook.get( + self.c.BASE + "/fed/v1/funding-conditions", + params={"sort": sort}, + reply=200, + response_json={"results": []}, + ) + self.assertEqual(list(self.c.list_funding_conditions(sort=sort)), []) + self.assertEqual(mock.calls, 1) + self.assertEqual(mock.matches[0].query, {"sort": [sort]}) diff --git a/test_rest/test_exports.py b/test_rest/test_exports.py new file mode 100644 index 00000000..3c3c40bc --- /dev/null +++ b/test_rest/test_exports.py @@ -0,0 +1,9 @@ +import unittest + + +class ExportsTest(unittest.TestCase): + def test_star_import(self): + ns = {} + exec("from massive import *", ns) + for name in ("RESTClient", "WebSocketClient", "AuthError", "BadResponse"): + self.assertIn(name, ns) diff --git a/test_rest/test_pagination.py b/test_rest/test_pagination.py new file mode 100644 index 00000000..f0f86aa2 --- /dev/null +++ b/test_rest/test_pagination.py @@ -0,0 +1,15 @@ +import types + +from base import BaseTest + + +class PaginationTest(BaseTest): + def test_list_methods_return_iterators(self): + # The iterators are lazy, so no request is sent. + for result in ( + self.c.list_treasury_yields(), + self.c.list_short_interest(), + self.c.list_short_volume(), + self.c.vx.list_ipos(), + ): + self.assertIsInstance(result, types.GeneratorType) diff --git a/test_rest/test_request_options.py b/test_rest/test_request_options.py new file mode 100644 index 00000000..805b2255 --- /dev/null +++ b/test_rest/test_request_options.py @@ -0,0 +1,35 @@ +from massive.rest.models.request import RequestOptionBuilder +from base import BaseTest + +import pook # type: ignore + + +class RequestOptionsTest(BaseTest): + """`options` sets headers; it must not leak into the query string.""" + + def options(self): + return RequestOptionBuilder(edge_id="test-edge", edge_ip_address="1.2.3.4") + + def assert_no_options_in_query(self, mock): + self.assertEqual(len(mock.matches), 1) + self.assertNotIn("options", mock.matches[0].query or {}) + + def test_get_with_options(self): + mock = pook.get( + self.c.BASE + "/v3/reference/tickers/OPTS", + reply=200, + response_body='{"results": {"ticker": "OPTS"}}', + ) + details = self.c.get_ticker_details("OPTS", options=self.options()) + self.assertEqual(details.ticker, "OPTS") + self.assert_no_options_in_query(mock) + + def test_paginate_with_options(self): + mock = pook.get( + self.c.BASE + "/v3/trades/OPTS", + reply=200, + response_body='{"results": []}', + ) + trades = list(self.c.list_trades("OPTS", options=self.options())) + self.assertEqual(trades, []) + self.assert_no_options_in_query(mock) diff --git a/test_rest/test_snapshots.py b/test_rest/test_snapshots.py index 3ead4e15..4472970a 100644 --- a/test_rest/test_snapshots.py +++ b/test_rest/test_snapshots.py @@ -26,6 +26,9 @@ class SnapshotsTest(BaseTest): + # test_get_snapshot_indices requests this twice + persistent_mocks = {"/v3/snapshot/indices?ticker.any_of=SPX%2CAPx%2CAPy"} + def test_list_universal_snapshots(self): expected = [ UniversalSnapshot( diff --git a/test_rest/typing_consumer.py b/test_rest/typing_consumer.py new file mode 100644 index 00000000..32feb51e --- /dev/null +++ b/test_rest/typing_consumer.py @@ -0,0 +1,152 @@ +"""Typical user code, checked with ``mypy --strict`` but never run. + +``make static`` checks this file from inside ``test_rest/``, so ``massive`` +resolves to the installed package, as it does for a user. The check fails if: + +- the package stops shipping ``py.typed`` or re-exporting a public name; +- a default call stops returning the model type, so using the result + needs an ``isinstance`` check; +- ``raw=True`` stops returning ``HTTPResponse``; +- a model constructor stops accepting its fields as keywords; +- a corrected hint regresses (``assert_type`` checks the exact type); +- code written for earlier releases, which narrows each result with + ``isinstance`` and passes an ``int`` CUSIP, stops type-checking. + +The file is named so that unittest discovery does not import it. +""" + +import sys +from typing import Iterator, List, Optional, Union + +from urllib3 import HTTPResponse + +if sys.version_info >= (3, 11): + from typing import assert_type +else: + from typing_extensions import assert_type + +from massive import AuthError, BadResponse, RESTClient, WebSocketClient +from massive.rest.models import ( + Agg, + IPOListing, + LastTrade, + PreviousCloseAgg, + ShortInterest, + ShortVolume, + Ticker, +) +from massive.rest.models.economy import TreasuryYield +from massive.websocket.models import CryptoQuote, IndexValue, WebSocketMessage + + +def ticker_symbols(client: RESTClient) -> List[str]: + # list_* yields models; no isinstance check is needed to read them. + return [t.ticker for t in client.list_tickers(market="stocks") if t.ticker] + + +def apple_tickers(client: RESTClient) -> List[Ticker]: + # A CUSIP is a string; an int is still accepted for backward compatibility. + return list(client.list_tickers(cusip="037833100")) + list( + client.list_tickers(cusip=37833100) + ) + + +def first_close(client: RESTClient) -> Optional[float]: + # get_* list endpoints can be indexed directly. + bars = client.get_aggs("AAPL", 1, "day", "2024-01-02", "2024-01-31") + assert_type(bars, List[Agg]) + return bars[0].close if bars else None + + +def previous_close(client: RESTClient) -> Optional[float]: + aggs = client.get_previous_close_agg("AAPL") + assert_type(aggs, List[PreviousCloseAgg]) + return aggs[0].close if aggs else None + + +def last_price(client: RESTClient) -> Optional[float]: + trade = client.get_last_trade("AAPL") + assert_type(trade, LastTrade) + return trade.price + + +def paginated(client: RESTClient) -> None: + assert_type( + client.list_aggs("AAPL", 1, "day", "2024-01-02", "2024-01-31"), Iterator[Agg] + ) + assert_type(client.list_treasury_yields(), Iterator[TreasuryYield]) + assert_type(client.list_short_interest(ticker="AAPL"), Iterator[ShortInterest]) + assert_type(client.list_short_volume(ticker="AAPL"), Iterator[ShortVolume]) + assert_type(client.vx.list_ipos(), Iterator[IPOListing]) + + +def raw_status(client: RESTClient) -> int: + resp = client.get_aggs("AAPL", 1, "day", "2024-01-02", "2024-01-31", raw=True) + assert_type(resp, HTTPResponse) + assert_type(client.list_tickers(raw=True), HTTPResponse) + assert_type(client.get_last_trade("AAPL", raw=True), HTTPResponse) + return resp.status + + +def raw_flag(client: RESTClient, raw: bool) -> None: + # A non-literal flag gets the full union, as before. + assert_type(client.get_last_trade("AAPL", raw=raw), Union[LastTrade, HTTPResponse]) + assert_type(client.list_tickers(raw=raw), Union[Iterator[Ticker], HTTPResponse]) + + +def ticker_symbols_or_none(client: RESTClient) -> Optional[List[str]]: + try: + return ticker_symbols(client) + except (AuthError, BadResponse): + return None + + +def spread(q: CryptoQuote) -> Optional[float]: + assert_type(q.bid_price, Optional[float]) + assert_type(q.ask_price, Optional[float]) + assert_type(q.ask_size, Optional[float]) + if q.ask_price is None or q.bid_price is None: + return None + return q.ask_price - q.bid_price + + +def index_time_ms(v: IndexValue) -> Optional[int]: + assert_type(v.timestamp, Optional[int]) + return v.timestamp + + +def handle(msgs: List[WebSocketMessage]) -> None: + for m in msgs: + if isinstance(m, CryptoQuote): + spread(m) + elif isinstance(m, IndexValue): + index_time_ms(m) + + +def make_ws_client() -> WebSocketClient: + return WebSocketClient(api_key="key", subscriptions=["XQ.BTC-USD"]) + + +def build_models() -> List[object]: + # Model constructors accept their fields as keywords. + quote = CryptoQuote(pair="BTC-USD", bid_price=33052.79, ask_size=0.601) + value = IndexValue(ticker="I:SPX", value=3988.5, timestamp=1678220098130) + trade = LastTrade(ticker="AAPL", sequence_number=3135876) + return [quote, value, trade] + + +def written_for_earlier_releases(client: RESTClient, raw: bool) -> None: + # Code written when every REST method returned Union[Model, HTTPResponse] + # narrows the result itself. It must keep type-checking. + trade = client.get_last_trade("AAPL") + if isinstance(trade, LastTrade): + print(trade.price) + for t in client.list_tickers(cusip=37833100): + if isinstance(t, Ticker): + print(t.ticker) + resp = client.get_last_trade("AAPL", raw=True) + if isinstance(resp, HTTPResponse): + print(resp.status) + either: Union[LastTrade, HTTPResponse] = client.get_last_trade("AAPL", raw=raw) + tickers: Union[Iterator[Ticker], HTTPResponse] = client.list_tickers() + print(either, tickers) diff --git a/test_websocket/base_ws.py b/test_websocket/base_ws.py index a21bc4d8..e041839a 100644 --- a/test_websocket/base_ws.py +++ b/test_websocket/base_ws.py @@ -1,8 +1,9 @@ import unittest import asyncio -from mock_server import run_mock_server +from mock_server import run_mock_server, inbox, port from typing import List from massive.websocket import WebSocketMessage +from websockets.asyncio.client import connect unittest.util._MAX_LENGTH = 30000 # type: ignore @@ -23,6 +24,30 @@ async def asyncSetUp(self): self.maxDiff = None loop = asyncio.get_event_loop() self.task = loop.create_task(run_mock_server()) + # wait until the mock server is accepting connections + for _ in range(100): + try: + async with connect(f"ws://localhost:{port}"): + break + except OSError: + await asyncio.sleep(0.05) + else: + self.fail("mock server did not start") + await self.until(lambda: inbox) # the connection above + inbox.clear() async def asyncTearDown(self): + # wait for the server to shut down so the next test can bind the port self.task.cancel() + try: + await self.task + except asyncio.CancelledError: + pass + + async def until(self, condition): + # wait for condition() to hold, checking every 10 ms for up to 5 s + for _ in range(500): + if condition(): + return + await asyncio.sleep(0.01) + self.fail("timed out") diff --git a/test_websocket/mock_server.py b/test_websocket/mock_server.py index a3e4b294..882bb4ec 100644 --- a/test_websocket/mock_server.py +++ b/test_websocket/mock_server.py @@ -1,18 +1,23 @@ from websockets import serve # type: ignore import asyncio import json -from typing import Set +from typing import Any, List, Set port = 8765 subs: Set[str] = set() +# the messages each connection received, in order; one list per connection +inbox: List[List[Any]] = [] async def mock_server(websocket): + received: List[Any] = [] + inbox.append(received) await websocket.send( '[{"ev":"status","status":"connected","message":"Connected Successfully"}]' ) async for message in websocket: message = json.loads(message) + received.append(message) if "action" not in message: continue if message["action"] == "auth" and message["params"] == "MAX-CONNECTIONS": @@ -35,6 +40,13 @@ async def mock_server(websocket): await websocket.close(code=1000) return for p in message["params"].split(","): + if p == "DROP.X": + # emulate the connection failing, right after a trade + await websocket.send( + '[{"ev":"T","sym":"X","i":"1","x":1,"p":1,"s":1,"t":1,"q":1}]' + ) + await websocket.close(code=1011) + return if p.startswith("ERR."): # emulate the server rejecting a subscription await websocket.send( @@ -125,8 +137,14 @@ async def mock_server(websocket): ) +def process_request(connection, request): + if request.path.startswith("/404/"): + # emulate the server refusing the handshake + return connection.respond(404, "Not Found\n") + + async def run_mock_server(): - async with serve(mock_server, "localhost", port): + async with serve(mock_server, "localhost", port, process_request=process_request): await asyncio.Future() # run forever diff --git a/test_websocket/test_reconnect.py b/test_websocket/test_reconnect.py new file mode 100644 index 00000000..f7299c0a --- /dev/null +++ b/test_websocket/test_reconnect.py @@ -0,0 +1,45 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +import asyncio + + +def sent(conn, action): + # the topics in each `action` message one connection received + return [set(m["params"].split(",")) for m in conn if m.get("action") == action] + + +class ReconnectTest(BaseTest): + async def test_changes_made_before_a_drop_are_kept(self): + c = WebSocketClient( + api_key="", + feed=f"localhost:{port}", + secure=False, + subscriptions=["T.AAPL", "T.MSFT", "DROP.X"], + ) + + async def processor(msgs): + if len(inbox) == 1: + # DROP.X makes the server drop the connection; change the + # subscriptions before the client sends anything else + await c.websocket.wait_closed() + c.unsubscribe("T.MSFT", "DROP.X") + c.subscribe("T.NVDA") + + task = asyncio.create_task(c.connect(processor)) + await self.until(lambda: len(inbox) == 2 and sent(inbox[1], "subscribe")) + self.assertEqual(sent(inbox[1], "subscribe"), [{"T.AAPL", "T.NVDA"}]) + await c.close() + await task + + async def test_connect_again_subscribes_again(self): + # SLOW.X makes the server close the connection, so connect() returns + c = WebSocketClient( + api_key="", feed=f"localhost:{port}", secure=False, subscriptions=["SLOW.X"] + ) + with self.assertLogs("WebSocketClient", level="WARNING"): + for _ in range(2): + await asyncio.wait_for(c.connect(lambda msgs: asyncio.sleep(0)), 5) + self.assertEqual( + [sent(conn, "subscribe") for conn in inbox], [[{"SLOW.X"}], [{"SLOW.X"}]] + ) diff --git a/test_websocket/test_reconnect_options.py b/test_websocket/test_reconnect_options.py new file mode 100644 index 00000000..32b4989a --- /dev/null +++ b/test_websocket/test_reconnect_options.py @@ -0,0 +1,119 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +from unittest import mock +from websockets.exceptions import ( + ConnectionClosedError, + ConnectionClosedOK, + InvalidStatus, +) +import asyncio + + +class RecordSleeps: + # asyncio, except that sleep() records the delay and returns at once + def __init__(self): + self.delays = [] + + def __getattr__(self, name): + return getattr(asyncio, name) + + async def sleep(self, delay): + self.delays.append(delay) + + +async def ignore(msgs): + pass + + +class ReconnectOptionsTest(BaseTest): + def client(self, *subscriptions, **kwargs): + return WebSocketClient( + api_key=kwargs.pop("api_key", ""), + feed=kwargs.pop("feed", f"localhost:{port}"), + secure=False, + subscriptions=list(subscriptions), + **kwargs, + ) + + async def drop_until_raised(self, c, exc=ConnectionClosedError): + # DROP.X makes the server drop every connection right away + sleeps = RecordSleeps() + with mock.patch("massive.websocket.asyncio", sleeps), mock.patch( + "massive.websocket.random" + ) as rnd: + rnd.uniform.side_effect = lambda a, b: a + with self.assertRaises(exc): + await asyncio.wait_for(c.connect(ignore), 5) + return sleeps.delays, rnd.uniform.call_args_list + + async def test_reconnects_at_once_by_default(self): + c = self.client("DROP.X", max_reconnects=2) + delays, _ = await self.drop_until_raised(c) + self.assertEqual(delays, []) + self.assertEqual(len(inbox), 3) + + async def test_backoff_doubles_up_to_the_cap(self): + c = self.client( + "DROP.X", max_reconnects=4, reconnect_backoff=1, max_reconnect_backoff=4 + ) + delays, uniform = await self.drop_until_raised(c) + at_cap = mock.call(4 / 1.2, 4) + self.assertEqual( + uniform, [mock.call(1, 1.2), mock.call(2, 2.4), at_cap, at_cap] + ) + self.assertEqual(delays, [1, 2, 4 / 1.2, 4 / 1.2]) + + async def test_consecutive_failures_are_limited(self): + c = self.client("DROP.X", max_reconnects=None, max_consecutive_failures=2) + await self.drop_until_raised(c) + self.assertEqual(len(inbox), 3) + + async def test_stable_connection_resets_failures(self): + c = self.client( + "DROP.X", max_reconnects=3, max_consecutive_failures=0, stable_uptime=0 + ) + await self.drop_until_raised(c) + self.assertEqual(len(inbox), 4) + + async def test_reconnect_on_close(self): + # SLOW.X makes the server close every connection normally + c = self.client("SLOW.X", max_reconnects=2, reconnect_on_close=True) + with self.assertLogs("WebSocketClient", level="WARNING"): + await self.drop_until_raised(c, ConnectionClosedOK) + self.assertEqual(len(inbox), 3) + + async def test_close_still_returns_with_reconnect_on_close(self): + c = self.client("T.AAPL", reconnect_on_close=True) + task = asyncio.create_task(c.connect(ignore)) + await self.until(lambda: inbox and len(inbox[0]) == 2) + await c.close() + await asyncio.wait_for(task, 5) + self.assertEqual(len(inbox), 1) + + async def test_raise_fatal_errors(self): + c = self.client(feed=f"localhost:{port}/404", raise_fatal_errors=True) + with self.assertRaises(InvalidStatus): + await asyncio.wait_for(c.connect(ignore), 5) + + async def test_handshake_failures_count(self): + c = self.client(feed=f"localhost:{port}/404", max_consecutive_failures=0) + with self.assertRaises(InvalidStatus): + await asyncio.wait_for(c.connect(ignore), 5) + + async def test_process_exception_is_passed_to_websockets(self): + c = self.client(feed=f"localhost:{port}/404") + with self.assertRaises(InvalidStatus): + await asyncio.wait_for( + c.connect(ignore, process_exception=lambda exc: exc), 5 + ) + + async def test_max_connections_reached(self): + processor = mock.AsyncMock() + c = self.client(api_key="MAX-CONNECTIONS", raw=True, max_reconnects=0) + self.assertFalse(c.max_connections_reached) + with self.assertLogs("WebSocketClient", level="WARNING"): + with self.assertRaises(ConnectionClosedError): + await asyncio.wait_for(c.connect(processor), 5) + self.assertTrue(c.max_connections_reached) + processor.assert_not_called() diff --git a/test_websocket/test_request_close.py b/test_websocket/test_request_close.py new file mode 100644 index 00000000..324187ea --- /dev/null +++ b/test_websocket/test_request_close.py @@ -0,0 +1,47 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +import asyncio +import threading + + +class RequestCloseTest(BaseTest): + def client(self, *subscriptions, **kwargs): + return WebSocketClient( + api_key="", + feed=f"localhost:{port}", + secure=False, + subscriptions=list(subscriptions), + **kwargs, + ) + + async def test_stops_run_from_another_thread(self): + c = self.client("T.AAPL", reconnect_on_close=True) + thread = threading.Thread(target=c.run, args=(lambda msgs: None,)) + thread.start() + await self.until(lambda: inbox and len(inbox[0]) == 2) + c.request_close() + await asyncio.to_thread(thread.join, 5) + self.assertFalse(thread.is_alive()) + self.assertEqual(len(inbox), 1) + + async def test_stops_reconnecting(self): + # DROP.X makes the server drop the connection + c = self.client("DROP.X", max_reconnects=None) + + async def processor(msgs): + c.request_close() + + await asyncio.wait_for(c.connect(processor), 5) + self.assertEqual(len(inbox), 1) + + async def test_before_connect(self): + c = self.client("T.AAPL") + c.request_close() + await asyncio.wait_for(c.connect(lambda msgs: asyncio.sleep(0)), 5) + self.assertEqual(inbox, []) + # the request is used up + task = asyncio.create_task(c.connect(lambda msgs: asyncio.sleep(0))) + await self.until(lambda: inbox and len(inbox[0]) == 2) + await c.close() + await task diff --git a/test_websocket/test_sender.py b/test_websocket/test_sender.py new file mode 100644 index 00000000..71cb2898 --- /dev/null +++ b/test_websocket/test_sender.py @@ -0,0 +1,61 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +from unittest import mock +import asyncio + + +class NoRecvTimeout: + # asyncio, except that connect() waits in recv() until a message arrives + def __getattr__(self, name): + return getattr(asyncio, name) + + @staticmethod + def wait_for(aw, timeout): + return asyncio.wait_for(aw, None) + + +def sent(conn, action): + # the topics in each `action` message one connection received + return [set(m["params"].split(",")) for m in conn if m.get("action") == action] + + +class SenderTest(BaseTest): + async def connected(self, *subscriptions): + # a client whose receive loop has handled every message so far + c = WebSocketClient( + api_key="", + feed=f"localhost:{port}", + secure=False, + subscriptions=list(subscriptions), + ) + received = [] + + async def processor(msgs): + received.append(msgs) + + task = asyncio.create_task(c.connect(processor)) + # each subscribed topic gets two trade messages + await self.until(lambda: len(received) == 2 * len(subscriptions)) + return c, task + + async def test_change_is_sent_while_waiting_for_a_message(self): + with mock.patch("massive.websocket.asyncio", NoRecvTimeout()): + c, task = await self.connected("T.AAPL") + await asyncio.to_thread(c.subscribe, "T.MSFT") + await self.until(lambda: len(sent(inbox[0], "subscribe")) == 2) + await asyncio.to_thread(c.unsubscribe, "T.AAPL") + await self.until(lambda: sent(inbox[0], "unsubscribe")) + self.assertEqual(sent(inbox[0], "subscribe"), [{"T.AAPL"}, {"T.MSFT"}]) + self.assertEqual(sent(inbox[0], "unsubscribe"), [{"T.AAPL"}]) + await c.close() + await task + + async def test_scheduled_subs_can_still_be_changed_directly(self): + c, task = await self.connected("T.AAPL") + c.scheduled_subs.add("T.MSFT") + c.schedule_resub = True + await self.until(lambda: len(sent(inbox[0], "subscribe")) == 2) + self.assertEqual(sent(inbox[0], "subscribe")[1], {"T.MSFT"}) + await c.close() + await task diff --git a/test_websocket/test_set_subscriptions.py b/test_websocket/test_set_subscriptions.py new file mode 100644 index 00000000..3d4cbc21 --- /dev/null +++ b/test_websocket/test_set_subscriptions.py @@ -0,0 +1,55 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +import asyncio + + +def sent(conn): + # the subscribe and unsubscribe messages one connection received + return [ + (m["action"], set(m["params"].split(","))) + for m in conn + if m.get("action") in ("subscribe", "unsubscribe") + ] + + +class SetSubscriptionsTest(BaseTest): + async def connected(self, *subscriptions): + c = WebSocketClient( + api_key="", + feed=f"localhost:{port}", + secure=False, + subscriptions=list(subscriptions), + ) + task = asyncio.create_task(c.connect(lambda msgs: asyncio.sleep(0))) + await self.until(lambda: inbox and sent(inbox[0])) + return c, task + + async def test_set_subscriptions_sends_removals_first(self): + c, task = await self.connected("T.AAPL", "T.MSFT") + c.set_subscriptions(["T.AAPL", "T.NVDA"]) + await self.until(lambda: len(sent(inbox[0])) == 3) + self.assertEqual( + sent(inbox[0])[1:], + [("unsubscribe", {"T.MSFT"}), ("subscribe", {"T.NVDA"})], + ) + await c.close() + await task + + async def test_resubscribe_sends_again(self): + c, task = await self.connected("T.AAPL") + c.resubscribe("T.AAPL") + await self.until(lambda: len(sent(inbox[0])) == 2) + self.assertEqual(sent(inbox[0])[1], ("subscribe", {"T.AAPL"})) + await c.close() + await task + + async def test_resubscribe_unknown_topic_sends_nothing(self): + c, task = await self.connected("T.AAPL") + with self.assertRaises(ValueError): + c.resubscribe("T.AAPL", "T.MSFT") + c.subscribe("T.NVDA") + await self.until(lambda: len(sent(inbox[0])) == 2) + self.assertEqual(sent(inbox[0])[1], ("subscribe", {"T.NVDA"})) + await c.close() + await task diff --git a/test_websocket/test_status.py b/test_websocket/test_status.py index d333c9c8..c02a1cc5 100644 --- a/test_websocket/test_status.py +++ b/test_websocket/test_status.py @@ -2,30 +2,10 @@ from massive.websocket import logger from base_ws import BaseTest from mock_server import port -from websockets.asyncio.client import connect import asyncio class StatusTest(BaseTest): - async def asyncSetUp(self): - await super().asyncSetUp() - # wait until the mock server is accepting connections - for _ in range(100): - try: - async with connect(f"ws://localhost:{port}"): - return - except OSError: - await asyncio.sleep(0.05) - self.fail("mock server did not start") - - async def asyncTearDown(self): - # wait for the server to shut down so the next test can bind the port - self.task.cancel() - try: - await self.task - except asyncio.CancelledError: - pass - async def run_client(self, *subscriptions): c = WebSocketClient(api_key="", feed=f"localhost:{port}", secure=False) c.subscribe(*subscriptions) @@ -95,3 +75,13 @@ async def test_auth_reply_status_is_logged(self): "Maximum number of websocket connections exceeded." ], ) + + async def test_invalid_subscription_is_logged(self): + # a topic without a channel prefix is skipped with a warning + c = WebSocketClient(api_key="") + with self.assertLogs("WebSocketClient", level="WARNING") as logs: + c.subscribe("AAPL") + self.assertEqual( + logs.output, ["WARNING:WebSocketClient:invalid subscription: AAPL"] + ) + self.assertEqual(c.scheduled_subs, set()) diff --git a/test_websocket/test_threads.py b/test_websocket/test_threads.py new file mode 100644 index 00000000..e10394ee --- /dev/null +++ b/test_websocket/test_threads.py @@ -0,0 +1,44 @@ +from massive import WebSocketClient +from base_ws import BaseTest +from mock_server import inbox, port +import asyncio +import random +import threading +import time + + +def streamed(conn): + # the topics one connection was asked to stream + topics = set() + for m in conn: + if m.get("action") == "subscribe": + topics |= set(m["params"].split(",")) + elif m.get("action") == "unsubscribe": + topics -= set(m["params"].split(",")) + return topics + + +class ThreadTest(BaseTest): + async def test_changes_from_many_threads_all_reach_the_server(self): + c = WebSocketClient(api_key="", feed=f"localhost:{port}", secure=False) + task = asyncio.create_task(c.connect(lambda msgs: asyncio.sleep(0))) + await self.until(lambda: inbox) + + def churn(seed): + rng = random.Random(seed) + for _ in range(250): + topic = f"T.S{rng.randrange(20)}" + if rng.random() < 0.5: + c.subscribe(topic) + else: + c.unsubscribe(topic) + time.sleep(0.001) # let the event loop run in between + + threads = [threading.Thread(target=churn, args=(i,)) for i in range(4)] + for t in threads: + t.start() + await asyncio.to_thread(lambda: [t.join() for t in threads]) + + await self.until(lambda: streamed(inbox[0]) == c.scheduled_subs == c.subs) + await c.close() + await task diff --git a/test_websocket/test_wildcard.py b/test_websocket/test_wildcard.py new file mode 100644 index 00000000..9224a165 --- /dev/null +++ b/test_websocket/test_wildcard.py @@ -0,0 +1,28 @@ +import unittest +from massive import WebSocketClient + + +class WildcardTest(unittest.TestCase): + def client(self, *subs): + c = WebSocketClient(api_key="", subscriptions=list(subs)) + c.subs = set(subs) # as if connect() had sent them + return c + + def test_subscribe_wildcard_keeps_other_channels(self): + c = self.client("A.MSFT", "AM.AAPL") + c.subscribe("A.*") + self.assertEqual(c.scheduled_subs, {"A.*", "AM.AAPL"}) + + def test_subscribe_wildcard_twice_keeps_it(self): + c = self.client("A.*") + c.subscribe("A.*") + self.assertEqual(c.scheduled_subs, {"A.*"}) + + def test_unsubscribe_wildcard_keeps_other_channels(self): + c = self.client("A.*", "A.MSFT", "AM.AAPL") + c.unsubscribe("A.*") + self.assertEqual(c.scheduled_subs, {"AM.AAPL"}) + + +if __name__ == "__main__": + unittest.main()