Skip to content

Commit

Permalink
readme example, nested futures option chain (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
Graeme22 authored May 22, 2023
1 parent e347f77 commit 833ddb4
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 2 deletions.
16 changes: 16 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ Placing an order
>>> PlacedOrderResponse(buying_power_effect=BuyingPowerEffect(change_in_margin_requirement=Decimal('125.0'), change_in_margin_requirement_effect=<PriceEffect.DEBIT: 'Debit'>, change_in_buying_power=Decimal('125.004'), change_in_buying_power_effect=<PriceEffect.DEBIT: 'Debit'>, current_buying_power=Decimal('1000.0'), current_buying_power_effect=<PriceEffect.CREDIT: 'Credit'>, new_buying_power=Decimal('874.996'), new_buying_power_effect=<PriceEffect.CREDIT: 'Credit'>, isolated_order_margin_requirement=Decimal('125.0'), isolated_order_margin_requirement_effect=<PriceEffect.DEBIT: 'Debit'>, is_spread=False, impact=Decimal('125.004'), effect=<PriceEffect.DEBIT: 'Debit'>), fee_calculation=FeeCalculation(regulatory_fees=Decimal('0.0'), regulatory_fees_effect=<PriceEffect.NONE: 'None'>, clearing_fees=Decimal('0.004'), clearing_fees_effect=<PriceEffect.DEBIT: 'Debit'>, commission=Decimal('0.0'), commission_effect=<PriceEffect.NONE: 'None'>, proprietary_index_option_fees=Decimal('0.0'), proprietary_index_option_fees_effect=<PriceEffect.NONE: 'None'>, total_fees=Decimal('0.004'), total_fees_effect=<PriceEffect.DEBIT: 'Debit'>), 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('50.0'), price_effect=<PriceEffect.DEBIT: 'Debit'>, 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
from tastytrade.instruments import get_option_chain
from datetime import date
chain = get_option_chain(session, 'SPLG')
subs_list = [chain[date(2023, 6, 16)][0].streamer_symbol]
greeks = await streamer.oneshot(EventType.GREEKS, subs_list)
print(greeks)
>>> [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 <https://tastyworks-api.readthedocs.io/en/latest/>`_.

Disclaimer
Expand Down
86 changes: 84 additions & 2 deletions tastytrade/instruments.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,43 @@ class NestedOptionChainExpiration(TastytradeJsonDataclass):
strikes: list[Strike]


class NestedFutureOptionChainExpiration(TastytradeJsonDataclass):
"""
Dataclass representing an expiration in a nested future options chain.
"""
root_symbol: str
notional_value: Decimal
underlying_symbol: str
strike_factor: Decimal
days_to_expiration: int
option_root_symbol: str
expiration_date: date
expires_at: datetime
asset: str
expiration_type: str
display_factor: Decimal
option_contract_symbol: str
stops_trading_at: datetime
settlement_type: str
strikes: list[Strike]
tick_sizes: list[TickSize]


class NestedFutureOptionFuture(TastytradeJsonDataclass):
"""
Dataclass representing an underlying future in a nested future options chain.
"""
root_symbol: str
days_to_expiration: int
expiration_date: date
expires_at: datetime
next_active_month: bool
symbol: str
active_month: bool
stops_trading_at: datetime
maturity_date: Optional[date] = None


class FutureEtfEquivalent(TastytradeJsonDataclass):
"""
Dataclass that represents the ETF equivalent for a future (aka, the number
Expand Down Expand Up @@ -449,7 +486,7 @@ class NestedOptionChain(TastytradeJsonDataclass):
expirations: list[NestedOptionChainExpiration]

@classmethod
def get_nested_option_chain(cls, session: Session, symbol: str) -> 'NestedOptionChain':
def get_chain(cls, session: Session, symbol: str) -> 'NestedOptionChain':
"""
Gets the option chain for the given symbol in nested format.
Expand Down Expand Up @@ -830,6 +867,51 @@ def get_future_option(
return cls(**data)


class NestedFutureOptionSubchain(TastytradeJsonDataclass):
"""
Dataclass that represents a Tastytrade nested future option chain for a
specific futures underlying symbol.
"""
underlying_symbol: str
root_symbol: str
exercise_style: str
expirations: list[NestedFutureOptionChainExpiration]


class NestedFutureOptionChain(TastytradeJsonDataclass):
"""
Dataclass that represents a Tastytrade nested option chain object. Contains
information about the option chain and a method to fetch one for a symbol.
The nested option chain is a bit neater than calling :meth:`get_future_option_chain`
but if you want to create actual :class:`FutureOption` objects you'll need to make an
extra API request or two.
"""
futures: list[NestedFutureOptionFuture]
option_chains: list[NestedFutureOptionSubchain]

@classmethod
def get_chain(cls, session: Session, symbol: str) -> 'NestedFutureOptionChain':
"""
Gets the futures option chain for the given symbol in nested format.
:param session: the session to use for the request.
:param symbol: the symbol to get the option chain for.
:return: a :class:`NestedFutureOptionChain` object.
"""
symbol = symbol.replace('/', '')
response = requests.get(
f'{session.base_url}/futures-option-chains/{symbol}/nested',
headers=session.headers
)
validate_response(response)

data = response.json()['data']

return cls(**data)


class Warrant(TastytradeJsonDataclass):
"""
Dataclass that represents a Tastytrade warrant object. Contains
Expand Down Expand Up @@ -953,7 +1035,7 @@ def get_future_option_chain(session: Session, symbol: str) -> dict[date, list[Fu
:return: a dict mapping expiration date to a list of :class:`FutureOption` objects.
"""
symbol = symbol.replace('/', '%2F')
symbol = symbol.replace('/', '')
response = requests.get(
f'{session.base_url}/futures-option-chains/{symbol}',
headers=session.headers
Expand Down

0 comments on commit 833ddb4

Please sign in to comment.