diff --git a/docs/conf.py b/docs/conf.py index 27ea038..903396a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,7 +13,7 @@ project = "tastytrade" copyright = "2024, Graeme Holliday" author = "Graeme Holliday" -release = "9.2" +release = "9.3" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/pyproject.toml b/pyproject.toml index b1a68c4..e9863db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "tastytrade" -version = "9.2" +version = "9.3" description = "An unofficial, sync/async SDK for Tastytrade!" readme = "README.md" requires-python = ">=3.8" diff --git a/tastytrade/__init__.py b/tastytrade/__init__.py index 61045d0..4e25c7c 100644 --- a/tastytrade/__init__.py +++ b/tastytrade/__init__.py @@ -4,7 +4,7 @@ BACKTEST_URL = "https://backtester.vast.tastyworks.com" CERT_URL = "https://api.cert.tastyworks.com" VAST_URL = "https://vast.tastyworks.com" -VERSION = "9.2" +VERSION = "9.3" logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) diff --git a/tastytrade/dxfeed/candle.py b/tastytrade/dxfeed/candle.py index e1c1f5e..7074600 100644 --- a/tastytrade/dxfeed/candle.py +++ b/tastytrade/dxfeed/candle.py @@ -26,13 +26,13 @@ class Candle(Event): #: total number of events in the candle count: int #: the first (open) price of the candle - open: Optional[Decimal] = None + open: Decimal #: the maximal (high) price of the candle - high: Optional[Decimal] = None + high: Decimal #: the minimal (low) price of the candle - low: Optional[Decimal] = None + low: Decimal #: the last (close) price of the candle - close: Optional[Decimal] = None + close: Decimal #: the total volume of the candle volume: Optional[Decimal] = None #: volume-weighted average price diff --git a/tastytrade/dxfeed/event.py b/tastytrade/dxfeed/event.py index cd8b5a9..030def9 100644 --- a/tastytrade/dxfeed/event.py +++ b/tastytrade/dxfeed/event.py @@ -1,7 +1,8 @@ from typing import Any, List -from pydantic import BaseModel, field_validator +from pydantic import BaseModel, ValidationError, field_validator +from tastytrade import logger from tastytrade.utils import TastytradeError @@ -27,12 +28,17 @@ def from_stream(cls, data: list) -> List["Event"]: size = len(cls.model_fields) multiples = len(data) / size if not multiples.is_integer(): - msg = "Mapper data input values are not a multiple of the key size" - raise TastytradeError(msg) + raise TastytradeError( + "Mapper data input values are not a multiple of the key size!" + ) keys = cls.model_fields.keys() for i in range(int(multiples)): offset = i * size local_values = data[offset : (i + 1) * size] event_dict = dict(zip(keys, local_values)) - objs.append(cls(**event_dict)) + try: + objs.append(cls(**event_dict)) + except ValidationError as e: + # we just skip these events as they're generally useless + logger.debug(e) return objs diff --git a/tastytrade/dxfeed/quote.py b/tastytrade/dxfeed/quote.py index e0eee3c..392e26e 100644 --- a/tastytrade/dxfeed/quote.py +++ b/tastytrade/dxfeed/quote.py @@ -27,9 +27,9 @@ class Quote(Event): #: ask exchange code askExchangeCode: str #: bid price - bidPrice: Optional[Decimal] = None + bidPrice: Decimal #: ask price - askPrice: Optional[Decimal] = None + askPrice: Decimal #: bid size as integer number (rounded toward zero) #: or decimal for cryptocurrencies bidSize: Optional[Decimal] = None diff --git a/tastytrade/dxfeed/trade.py b/tastytrade/dxfeed/trade.py index 5f75290..b03c068 100644 --- a/tastytrade/dxfeed/trade.py +++ b/tastytrade/dxfeed/trade.py @@ -33,7 +33,7 @@ class Trade(Event): #: whether the last trade was in extended trading hours extendedTradingHours: bool #: price of the last trade - price: Optional[Decimal] = None + price: Decimal #: change of the last trade change: Optional[Decimal] = None #: size of the last trade as integer number (rounded toward zero) diff --git a/tests/test_dxfeed.py b/tests/test_dxfeed.py index 2c3d694..26a2912 100644 --- a/tests/test_dxfeed.py +++ b/tests/test_dxfeed.py @@ -2,17 +2,31 @@ import pytest -from tastytrade.dxfeed import Quote +from tastytrade.dxfeed import Quote, Summary from tastytrade.utils import TastytradeError def test_parse_infinities_and_nan(): - quote_data = ["SPY", 0, 0, 0, 0, "Q", 0, "Q", "-Infinity", "Infinity", "NaN", "NaN"] - quote = Quote.from_stream(quote_data)[0] - quote = cast(Quote, quote) - assert quote.bidPrice is None - assert quote.askPrice is None - assert quote.bidSize is None + summary_data = [ + "SPY", + 0, + 0, + "foo", + 0, + "bar", + 0, + "-Infinity", + "Infinity", + "NaN", + "NaN", + "NaN", + "Infinity", + ] + summary = Summary.from_stream(summary_data)[0] + summary = cast(Summary, summary) + assert summary.dayOpenPrice is None + assert summary.dayClosePrice is None + assert summary.dayHighPrice is None def test_malformatted_data(): diff --git a/uv.lock b/uv.lock index b405720..66dd422 100644 --- a/uv.lock +++ b/uv.lock @@ -586,7 +586,7 @@ wheels = [ [[package]] name = "tastytrade" -version = "9.2" +version = "9.3" source = { editable = "." } dependencies = [ { name = "httpx" },