diff --git a/README.rst b/README.md similarity index 63% rename from README.rst rename to README.md index 639c069..1d2afe1 100644 --- a/README.rst +++ b/README.md @@ -1,122 +1,116 @@ -.. image:: https://readthedocs.org/projects/tastyworks-api/badge/?version=latest - :target: https://tastyworks-api.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status +[![Docs](https://readthedocs.org/projects/tastyworks-api/badge/?version=latest)](https://tastyworks-api.readthedocs.io/en/latest/?badge=latest) +[![PyPI](https://img.shields.io/pypi/v/tastytrade)](https://pypi.org/project/tastytrade) +[![Downloads](https://static.pepy.tech/badge/tastytrade)](https://pepy.tech/project/tastytrade) -.. image:: https://img.shields.io/pypi/v/tastytrade - :target: https://pypi.org/project/tastytrade - :alt: PyPI Package - -.. image:: https://static.pepy.tech/badge/tastytrade - :target: https://pepy.tech/project/tastytrade - :alt: PyPI Downloads - - -Tastytrade Python SDK -===================== +# 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. -Installation ------------- +> [!NOTE] +> Want to see the SDK in action? Check out [tastytrade-cli](https://github.com/tastyware/tastytrade-cli), a CLI for Tastytrade that showcases many of the SDK's features. -:: +## Installation - $ pip install tastytrade +```console +$ pip install tastytrade +``` -Creating a session ------------------- +## Creating a session A session object is required to authenticate your requests to the Tastytrade API. You can create a real session using your normal login, or a certification (test) session using your certification login. -.. code-block:: python +```python +from tastytrade import ProductionSession +session = ProductionSession('username', 'password') +``` - from tastytrade import ProductionSession - session = ProductionSession('username', 'password') - -Using the streamer ------------------- +## 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. -.. code-block:: python - - from tastytrade import DXLinkStreamer - from tastytrade.dxfeed import EventType +```python +from tastytrade import DXLinkStreamer +from tastytrade.dxfeed import EventType - async with DXLinkStreamer(session) as streamer: - subs_list = ['SPY'] # list of symbols to subscribe to - await streamer.subscribe(EventType.QUOTE, subs_list) - # this example fetches quotes once, then exits - quote = await streamer.get_event(EventType.QUOTE) - print(quote) +async with DXLinkStreamer(session) as streamer: + subs_list = ['SPY'] # list of symbols to subscribe to + await streamer.subscribe(EventType.QUOTE, subs_list) + # this example fetches quotes once, then exits + quote = await streamer.get_event(EventType.QUOTE) + print(quote) +``` +```python >>> [Quote(eventSymbol='SPY', eventTime=0, sequence=0, timeNanoPart=0, bidTime=0, bidExchangeCode='Q', bidPrice=411.58, bidSize=400.0, askTime=0, askExchangeCode='Q', askPrice=411.6, askSize=1313.0), Quote(eventSymbol='SPX', eventTime=0, sequence=0, timeNanoPart=0, bidTime=0, bidExchangeCode='\x00', bidPrice=4122.49, bidSize='NaN', askTime=0, askExchangeCode='\x00', askPrice=4123.65, askSize='NaN')] +``` Note that this is asynchronous code, so you can't run it as is unless you're using a Jupyter notebook or something similar. -Getting current positions -------------------------- +## Getting current positions -.. code-block:: python - - from tastytrade import Account +```python +from tastytrade import Account - account = Account.get_accounts(session)[0] - positions = account.get_positions(session) - print(positions[0]) +account = Account.get_accounts(session)[0] +positions = account.get_positions(session) +print(positions[0]) +``` +```python >>> CurrentPosition(account_number='5WX01234', symbol='IAU', instrument_type=, 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='Credit', is_suppressed=False, is_frozen=False, realized_day_gain=Decimal('7.888'), realized_day_gain_effect='Credit', realized_day_gain_date=datetime.date(2023, 5, 19), realized_today=Decimal('0.512'), realized_today_effect='Debit', 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 ----------------- - -.. code-block:: python - - from decimal import Decimal - from tastytrade import Account - from tastytrade.instruments import Equity - from tastytrade.order import NewOrder, OrderAction, OrderTimeInForce, OrderType, PriceEffect - - account = Account.get_account(session, '5WX01234') - symbol = Equity.get_equity(session, 'USO') - leg = symbol.build_leg(Decimal('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 for a total value of $50 - price_effect=PriceEffect.DEBIT - ) - response = account.place_order(session, order, dry_run=True) # a test order - print(response) - +``` + +## 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, PriceEffect + +account = Account.get_account(session, '5WX01234') +symbol = Equity.get_equity(session, 'USO') +leg = symbol.build_leg(Decimal('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 for a total value of $50 + price_effect=PriceEffect.DEBIT +) +response = 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_margin_requirement_effect=, change_in_buying_power=Decimal('125.004'), change_in_buying_power_effect=, current_buying_power=Decimal('1000.0'), current_buying_power_effect=, new_buying_power=Decimal('874.996'), new_buying_power_effect=, isolated_order_margin_requirement=Decimal('125.0'), isolated_order_margin_requirement_effect=, is_spread=False, impact=Decimal('125.004'), effect=), fee_calculation=FeeCalculation(regulatory_fees=Decimal('0.0'), regulatory_fees_effect=, clearing_fees=Decimal('0.004'), clearing_fees_effect=, commission=Decimal('0.0'), commission_effect=, proprietary_index_option_fees=Decimal('0.0'), proprietary_index_option_fees_effect=, total_fees=Decimal('0.004'), total_fees_effect=), order=PlacedOrder(account_number='5WV69754', time_in_force=, order_type=, size='5', underlying_symbol='USO', underlying_instrument_type=, status=, cancellable=True, editable=True, edited=False, updated_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), legs=[Leg(instrument_type=, symbol='USO', action=, quantity=Decimal('5'), remaining_quantity=Decimal('5'), fills=[])], id=None, price=Decimal('50.0'), price_effect=, gtc_date=None, value=None, value_effect=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 ------------------------------- - -.. code-block:: python +## Options chain/streaming greeks - from tastytrade import DXLinkStreamer - from tastytrade.instruments import get_option_chain - from tastytrade.utils import get_tasty_monthly +```python +from tastytrade import DXLinkStreamer +from tastytrade.instruments import get_option_chain +from tastytrade.utils import get_tasty_monthly - chain = get_option_chain(session, 'SPLG') - exp = get_tasty_monthly() # 45 DTE expiration! - subs_list = [chain[exp][0].streamer_symbol] +chain = 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(EventType.GREEKS, subs_list) - greeks = await streamer.get_event(EventType.GREEKS) - print(greeks) +async with DXLinkStreamer(session) as streamer: + await streamer.subscribe(EventType.GREEKS, subs_list) + greeks = await streamer.get_event(EventType.GREEKS) + print(greeks) +``` +```python >>> [Greeks(eventSymbol='.SPLG230616C23', eventTime=0, eventFlags=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 `_. +For more examples, check out the [documentation](https://tastyworks-api.readthedocs.io/en/latest/). -Disclaimer ----------- +## Disclaimer This is an unofficial SDK for Tastytrade. There is no implied warranty for any actions and results which arise from using it. diff --git a/docs/index.rst b/docs/index.rst index d713c8b..3d6cad9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,4 +1,22 @@ -.. include:: ../README.rst +.. image:: https://readthedocs.org/projects/tastyworks-api/badge/?version=latest + :target: https://tastyworks-api.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/pypi/v/tastytrade + :target: https://pypi.org/project/tastytrade + :alt: PyPI Package + +.. image:: https://static.pepy.tech/badge/tastytrade + :target: https://pepy.tech/project/tastytrade + :alt: PyPI Downloads + +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. + +.. tip:: + Want to see the SDK in action? Check out `tastytrade-cli `_, a CLI for Tastytrade that showcases many of the SDK's features. .. toctree:: :maxdepth: 2