tastyware / tastytrade

An unofficial, sync/async Python SDK for Tastytrade!
https://tastyworks-api.rtfd.io
MIT License
127 stars 43 forks source link

Missing feature: Bracket Orders #63

Closed Graeme22 closed 1 year ago

Graeme22 commented 1 year ago

Currently the SDK doesn't support bracket orders as documented here: https://[developer.tastytrade.com/order-management/](https://developer.tastytrade.com/order-management/)

This is a feature I'd like to support at some point.

kaidaniel82 commented 1 year ago

Hi, is it still possible to use the OTOCO order to implement a Bracket order? The example on the Tasty website shows this, right? It would be great if you could post an example, as I'm having trouble understanding the process from the documentation.

https://developer.tastytrade.com/order-management/#submit-complex-order

{
    "type": "OTOCO",
    "trigger-order": {
        "order-type": "Limit",
        "price": 157.97,
        "price-effect": "Debit",
        "time-in-force": "Day",
        "legs": [{
            "instrument-type": "Equity",
            "symbol": "AAPL",
            "action": "Buy to Open",
            "quantity": 100
        }]
    },
    "orders": [
        {
            "order-type": "Limit",
            "price": 198.68,
            "price-effect": "Credit",
            "time-in-force": "GTC",
            "legs": [{
                "symbol": "AAPL",
                "instrument-type": "Equity",
                "action": "Sell to Close",
                "quantity": 100
            }]
        },
        {
            "order-type": "Stop",
            "time-in-force": "GTC",
            "stop-trigger": 143.06,
            "legs": [{
                "symbol": "AAPL",
                "instrument-type": "Equity",
                "action": "Sell to Close",
                "quantity": 100
            }]
        }
    ]
}
Graeme22 commented 1 year ago

Hi, this is still not implemented. If you'd like to create a PR to add it, feel welcome! It looks like it's a grouping of three orders: opening order, stop loss, and profit taking, all wrapped into one. The ComplexOrder class is a wrapper for one of these that's already placed, but in order to actually create one using the API you'd need to make a new class similar to NewOrder but with the OTOCO type and the relevant parts.

Quenos commented 1 year ago

Solved in PR #107

kaidaniel82 commented 1 year ago

When will it be merged to main?

Graeme22 commented 1 year ago

As soon as the tests are passing!

Graeme22 commented 1 year ago

This can now be done pretty easily:

symbol = Equity.get_equity(session, 'AAPL')
opening = symbol.build_leg(Decimal(1), OrderAction.BUY_TO_OPEN)
closing = symbol.build_leg(Decimal(1), OrderAction.SELL_TO_CLOSE)
otoco = NewComplexOrder(
    trigger_order=NewOrder(
        time_in_force=OrderTimeInForce.DAY,
        order_type=OrderType.LIMIT,
        legs=[opening],
        price=Decimal('180'),
        price_effect=PriceEffect.DEBIT
    ),
    orders=[
        NewOrder(
            time_in_force=OrderTimeInForce.GTC,
            order_type=OrderType.LIMIT,
            legs=[closing],
            price=Decimal('200'),  # take profits
            price_effect=PriceEffect.CREDIT
        ),
        NewOrder(
            time_in_force=OrderTimeInForce.GTC,
            order_type=OrderType.STOP,
            legs=[closing],
            stop_trigger=Decimal('160'),  # stop loss
            price_effect=PriceEffect.CREDIT
        )
    ]
)
resp = account.place_complex_order(session, otoco, dry_run=False)

For an OCO order, it's exactly the same, but without the trigger_order, and it only works for positions you already have open.

kaidaniel82 commented 1 year ago

Thats great. Thanks for developing this.