GitPedia

Tastytrade

An unofficial, typed, asynchronous Python SDK for Tastytrade!

From tastyware·Updated June 17, 2026·View on GitHub·

A simple, reverse-engineered SDK for Tastytrade built on their (now mostly public) API. This will allow you to create trading algorithms for whatever strategies you may have quickly and painlessly in Python. The project is written primarily in Python, distributed under the MIT License license, first published in 2022. Key topics include: asyncio, cli, options-trading, python, sdk.

Latest release: v12.4.1

Docs
PyPI
Downloads
Release)

Tastytrade Python SDK

A simple, reverse-engineered SDK for Tastytrade built on their (now mostly public) API. This will allow you to create trading algorithms for whatever strategies you may have quickly and painlessly in Python.

Features

  • Up to 10x less code than using the API directly
  • Powerful websocket implementation for account alerts and data streaming
  • 100% typed, with Pydantic models for all JSON responses from the API
  • 95%+ unit test coverage
  • Comprehensive documentation
  • Utility functions for timezone calculations, futures monthly expiration dates, and more
  • Proprietary paper API for reliable testing

[!TIP]
Want to see the SDK in action? Check out tastytrade-cli, a CLI for Tastytrade that showcases many of the SDK's features.

Installation

console
$ pip install tastytrade

Creating a session

A session object is required to authenticate your requests to the Tastytrade API. See here for information on how to set up an OAuth application.

python
from tastytrade import Session session = Session('client_secret', 'refresh_token')

Using the streamer

The streamer is a websocket connection to dxfeed (the Tastytrade data provider) that allows you to subscribe to real-time data for quotes, greeks, and more.

python
from tastytrade import DXLinkStreamer from tastytrade.dxfeed import Quote async with DXLinkStreamer(session) as streamer: subs_list = ['SPY'] # list of symbols to subscribe to await streamer.subscribe(Quote, subs_list) # fetch a single quote quote = await streamer.get_event(Quote) print(quote) # or multiple quotes... async for quote in streamer.listen(Quote): print(quote)
python
>>> Quote(event_symbol='SPY', event_time=0, sequence=0, time_nano_part=0, bid_time=0, bid_exchange_code='Q', bid_price=411.58, bid_size=400.0, ask_time=0, ask_exchange_code='Q', ask_price=411.6, ask_size=1313.0)

Getting current positions

python
from tastytrade import Account account = (await Account.get(session))[0] positions = await account.get_positions(session) print(positions[0])
python
>>> CurrentPosition(account_number='5WX01234', symbol='IAU', instrument_type=<InstrumentType.EQUITY: 'Equity'>, underlying_symbol='IAU', quantity=Decimal('20'), quantity_direction='Long', close_price=Decimal('37.09'), average_open_price=Decimal('37.51'), average_yearly_market_close_price=Decimal('37.51'), average_daily_market_close_price=Decimal('37.51'), multiplier=1, cost_effect=<PriceEffect.CREDIT: 'Credit'>, is_suppressed=False, is_frozen=False, realized_day_gain=Decimal('7.888'), realized_day_gain_date=datetime.date(2023, 5, 19), realized_today=Decimal('-0.512'), realized_today_date=datetime.date(2023, 5, 19), created_at=datetime.datetime(2023, 3, 31, 14, 38, 32, 58000, tzinfo=datetime.timezone.utc), updated_at=datetime.datetime(2023, 5, 19, 16, 56, 51, 920000, tzinfo=datetime.timezone.utc), mark=None, mark_price=None, restricted_quantity=Decimal('0'), expires_at=None, fixing_price=None, deliverable_type=None)

Placing an order

python
from decimal import Decimal from tastytrade import Account from tastytrade.instruments import Equity from tastytrade.order import NewOrder, OrderAction, OrderTimeInForce, OrderType account = await Account.get(session, '5WX01234') symbol = await Equity.get(session, 'USO') leg = symbol.build_leg(5, OrderAction.BUY_TO_OPEN) # buy to open 5 shares order = NewOrder( time_in_force=OrderTimeInForce.DAY, order_type=OrderType.LIMIT, legs=[leg], # you can have multiple legs in an order price=Decimal('-10') # limit price, $10/share debit for a total value of $50 ) response = await account.place_order(session, order, dry_run=True) # a test order print(response)
python
>>> PlacedOrderResponse(buying_power_effect=BuyingPowerEffect(change_in_margin_requirement=Decimal('-125.0'), change_in_buying_power=Decimal('-125.004'), current_buying_power=Decimal('1000.0'), new_buying_power=Decimal('874.996'), isolated_order_margin_requirement=Decimal('-125.0'), is_spread=False, impact=Decimal('125.004'), effect=<PriceEffect.DEBIT: 'Debit'>), fee_calculation=FeeCalculation(regulatory_fees=Decimal('0.0'), clearing_fees=Decimal('-0.004'), commission=Decimal('0.0'), proprietary_index_option_fees=Decimal('0.0'), total_fees=Decimal('-0.004'), order=PlacedOrder(account_number='5WV69754', time_in_force=<OrderTimeInForce.DAY: 'Day'>, order_type=<OrderType.LIMIT: 'Limit'>, size='5', underlying_symbol='USO', underlying_instrument_type=<InstrumentType.EQUITY: 'Equity'>, status=<OrderStatus.RECEIVED: 'Received'>, cancellable=True, editable=True, edited=False, updated_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), legs=[Leg(instrument_type=<InstrumentType.EQUITY: 'Equity'>, symbol='USO', action=<OrderAction.BUY_TO_OPEN: 'Buy to Open'>, quantity=Decimal('5'), remaining_quantity=Decimal('5'), fills=[])], id=None, price=Decimal('-10.0'), gtc_date=None, value=None, stop_trigger=None, contingent_status=None, confirmation_status=None, cancelled_at=None, cancel_user_id=None, cancel_username=None, replacing_order_id=None, replaces_order_id=None, in_flight_at=None, live_at=None, received_at=None, reject_reason=None, user_id=None, username=None, terminal_at=None, complex_order_id=None, complex_order_tag=None, preflight_id=None, order_rule=None), complex_order=None, warnings=[Message(code='tif_next_valid_sesssion', message='Your order will begin working during next valid session.', preflight_id=None)], errors=None)

Options chain/streaming greeks

python
from tastytrade import DXLinkStreamer from tastytrade.dxfeed import Greeks from tastytrade.instruments import get_option_chain from tastytrade.utils import get_tasty_monthly chain = await get_option_chain(session, 'SPLG') exp = get_tasty_monthly() # 45 DTE expiration! subs_list = [chain[exp][0].streamer_symbol] async with DXLinkStreamer(session) as streamer: await streamer.subscribe(Greeks, subs_list) greeks = await streamer.get_event(Greeks) print(greeks)
python
>>> Greeks(event_symbol='.SPLG230616C23', event_time=0, event_flags=0, index=7235129486797176832, time=1684559855338, sequence=0, price=26.3380972233688, volatility=0.396983376650804, delta=0.999999999996191, gamma=4.81989763184255e-12, theta=-2.5212017514875e-12, rho=0.01834504287973133, vega=3.7003015672215e-12)

For more examples, check out the documentation.

Disclaimer

This is an unofficial SDK for Tastytrade. There is no implied warranty for any actions and results which arise from using it.

Contributors

Showing top 12 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from tastyware/tastytrade via the GitHub API.Last fetched: 6/23/2026