tastyware/tastytrade:v9.4
What's Changed
The datetime-related utilities in tastytrade.utils
suffered from a hard-to-detect bug related to variable Python default arguments. These utilities will work correctly now, whereas previously something like this:
from tastytrade.utils import is_market_open_on
print(is_market_open_on())
# 5 hours later...
print(is_market_open_on())
could potentially yield incorrect results in long-running programs. This now behaves as expected, and no code changes are required.
This partially reverts the changes in v9.3 which excluded all Candle
events without OHLC fields. @JBlohm brought to attention that these "empty" candles can still contain important information in the event_flags
field. This was solved by re-allowing the empty candles (while still ensuring None
values provided will be set to 0, which allows for filtering them out without messing with the types), and as a bonus a new class, tastytrade.dxfeed.IndexedEvent
, was added which allows for easily parsing the event_flags
field, which otherwise required some bitwise math. So upgrading will look something like this:
candles = []
async for candle in streamer.listen(Candle):
if not Decimal.is_zero(candle.open): # filter out invalid candles
candles.append(candle)
else:
print(candle.snapshot_end) # handle event flags
This updates the websockets
dependency to >=14.1
and uses the new async websockets features to implement auto-reconnect functionality upon certain connection errors. This takes effect automatically and doesn't require any code changes. However, the reconnection algorithm's behavior can be modified through environment variables, documented here.
Building on the auto-reconnection functionality, this PR introduces callback functions that can be ran upon reconnection to handle common tasks, for example, re-subscribing to alerts or events. Here's how this looks:
async def callback(streamer: DXLinkStreamer, arg1, arg2):
await streamer.subscribe(Trade, ["SPX"])
print(arg1 + arg2)
async with DXLinkStreamer(session, reconnect_args=(arg1, arg2), reconnect_fn=callback) as streamer:
pass
The first argument for the callback will always be the streamer itself; after that, the number and type of arguments is determined by your use case.
Additionally, a small change was made to the existing AlertStreamer.create
and DXLinkStreamer.create
functions. They have been switched to a simpler syntax that allows you to await
the constructor directly. So this code:
streamer = await AlertStreamer.create(session)
becomes:
streamer = await AlertStreamer(session)
Full Changelog: v9.3...v9.4