diff --git a/tda/orders/equities.py b/tda/orders/equities.py index 248100d..46621bc 100644 --- a/tda/orders/equities.py +++ b/tda/orders/equities.py @@ -1,6 +1,13 @@ from enum import Enum -from tda.orders.common import Duration, Session +from tda.orders.common import ( + Duration, + StopType, + Session, + StopType, + StopPriceLinkBasis, + StopPriceLinkType, +) ########################################################################## @@ -154,3 +161,77 @@ def equity_buy_to_cover_limit(symbol, quantity, price): .set_duration(Duration.DAY) .set_order_strategy_type(OrderStrategyType.SINGLE) .add_equity_leg(EquityInstruction.BUY_TO_COVER, symbol, quantity)) + + +########################################################################## +# Stop orders + + +def equity_sell_stop_market( + symbol, quantity, stop_price, stop_type=StopType.MARK): + """ + Returns a pre-filled :class:`~tda.orders.generic.OrderBuilder` for an equity + sell stop order. + """ + from tda.orders.common import Duration, EquityInstruction + from tda.orders.common import OrderStrategyType, OrderType, Session + from tda.orders.generic import OrderBuilder + + return (OrderBuilder() + .set_order_type(OrderType.STOP) + .set_quantity(quantity) + .set_session(Session.NORMAL) + .set_stop_price(stop_price) + .set_stop_type(stop_type) + .set_duration(Duration.DAY) + .set_order_strategy_type(OrderStrategyType.SINGLE) + .add_equity_leg(EquityInstruction.SELL, symbol, quantity)) + + +def equity_sell_stop_limit(symbol, quantity, limit_price, stop_price, + stop_type=StopType.MARK): + """ + Returns a pre-filled :class:`~tda.orders.generic.OrderBuilder` for an equity + sell stop limit order. + """ + + from tda.orders.common import Duration, EquityInstruction + from tda.orders.common import OrderStrategyType, OrderType, Session + from tda.orders.generic import OrderBuilder + + return (OrderBuilder() + .set_order_type(OrderType.STOP_LIMIT) + .set_quantity(quantity) + .set_session(Session.NORMAL) + .set_price(limit_price) + .set_stop_price(stop_price) + .set_stop_type(stop_type) + .set_duration(Duration.DAY) + .set_order_strategy_type(OrderStrategyType.SINGLE) + .add_equity_leg(EquityInstruction.SELL, symbol, quantity)) + + +def equity_sell_trailing_stop_market( + symbol, quantity, trail_offset, + trail_offset_type=StopPriceLinkType.PERCENT, stop_type=StopType.MARK, + stop_price_link_basis=StopPriceLinkBasis.MARK): + """ + Returns a pre-filled :class:`~tda.orders.generic.OrderBuilder` for an equity + sell trailing stop order. + """ + + from tda.orders.common import Duration, EquityInstruction + from tda.orders.common import OrderStrategyType, OrderType, Session + from tda.orders.generic import OrderBuilder + + return (OrderBuilder() + .set_order_type(OrderType.TRAILING_STOP) + .set_quantity(quantity) + .set_session(Session.NORMAL) + .set_duration(Duration.DAY) + .set_stop_type(stop_type) + .set_stop_price_offset(trail_offset) + .set_stop_price_link_basis(stop_price_link_basis) + .set_stop_price_link_type(trail_offset_type) + .set_order_strategy_type(OrderStrategyType.SINGLE) + .add_equity_leg(EquityInstruction.SELL, symbol, quantity)) diff --git a/tests/orders_test.py b/tests/orders_test.py index 729f6a4..5704b5d 100644 --- a/tests/orders_test.py +++ b/tests/orders_test.py @@ -176,3 +176,63 @@ def test_equity_buy_to_cover_limit(self): } }] }, equity_buy_to_cover_limit('GOOG', 10, 199.99).build())) + + def test_equity_sell_stop_market(self): + self.assertFalse(has_diff({ + 'orderType': 'STOP', + 'quantity': 10, + 'session': 'NORMAL', + 'duration': 'DAY', + 'stopPrice': '199.99', + 'stopType': 'MARK', + 'orderStrategyType': 'SINGLE', + 'orderLegCollection': [{ + 'instruction': 'SELL', + 'quantity': 10, + 'instrument': { + 'symbol': 'GOOG', + 'assetType': 'EQUITY', + } + }] + }, equity_sell_stop_market('GOOG', 10, 199.99).build())) + + def test_equity_sell_stop_limit(self): + self.assertFalse(has_diff({ + 'orderType': 'STOP_LIMIT', + 'quantity': 10, + 'session': 'NORMAL', + 'duration': 'DAY', + 'price': '88.88', + 'stopPrice': '199.99', + 'stopType': 'MARK', + 'orderStrategyType': 'SINGLE', + 'orderLegCollection': [{ + 'instruction': 'SELL', + 'quantity': 10, + 'instrument': { + 'symbol': 'GOOG', + 'assetType': 'EQUITY', + } + }] + }, equity_sell_stop_limit('GOOG', 10, 88.88, 199.99).build())) + + def test_equity_sell_trailing_stop_market(self): + self.assertFalse(has_diff({ + 'orderType': 'TRAILING_STOP', + 'quantity': 10, + 'session': 'NORMAL', + 'duration': 'DAY', + 'stopType': 'MARK', + 'stopPriceOffset': 5, + 'stopPriceLinkBasis': 'MARK', + 'stopPriceLinkType': 'PERCENT', + 'orderStrategyType': 'SINGLE', + 'orderLegCollection': [{ + 'instruction': 'SELL', + 'quantity': 10, + 'instrument': { + 'symbol': 'GOOG', + 'assetType': 'EQUITY', + } + }] + }, equity_sell_trailing_stop_market('GOOG', 10, 5).build()))