Order Types

Stop Limit Orders

Introduction

Stop limit orders are instructions to place a limit order once an asset passes a specific price level. They are similar to stop market orders, but use limit orders instead of market orders to give you more control over the fill price. A buy stop limit order has a stop price above the current market price and a sell stop limit order has a stop price below the current market price. In effect, they are the opposite of limit if touched orders.

Place Orders

To send a stop limit order, call the StopLimitOrder method and provide a Symbol, quantity, stop price, and limit price. You can also provide a tag and order properties to the StopLimitOrder method. If you do not have sufficient capital for the order, it is rejected.

StopLimitOrder(symbol, quantity, stopPrice, limitPrice, tag, orderProperties);
self.stop_limit_order(symbol, quantity, stop_rice, limit_price, tag, order_properties)

To buy an asset with a stop limit order that has a marketable limit price, set the stop price above the current market price and set the limit price above the stop price.

// When Bitcoin trades up to $59,000, buy 1 Bitcoin with a limit order at $62,000
StopLimitOrder("BTCUSD", 1, 59000, 62000);
# When Bitcoin trades up to $59,000, buy 1 Bitcoin with a limit order at $62,000
self.stop_limit_order("BTCUSD", 1, 59000, 62000)
When the asset is trading at $46,000, place an unmarketable sell stop limit order with a stop at $59,000 and a limit at $62,000. The stop is hit, the limit is set, and the order fills when the asset trades up to $59,000.

To buy an asset with a stop limit order that has an unmarketable limit price, set the stop price above the current market price and set the limit price below the stop price.

// When Bitcoin trades up to $52,000, buy 1 Bitcoin with a limit order at $41,000
StopLimitOrder("BTCUSD", 1, 52000, 41000);
# When Bitcoin trades up to $52,000, buy 1 Bitcoin with a limit order at $41,000
self.stop_limit_order("BTCUSD", 1, 52000, 41000)
When the asset is trading at $37,000, place an unmarketable buy stop limit order with a stop at $52,500 and a limit at $41,000. The stop is hit and the limit is set when the asset trades up to $52,500. Then the stop limit order fills when the security trades down to $41,000.

To sell an asset with a stop limit order that has an unmarketable limit price, set the stop price below the current market price and set the limit price above the stop price.

// When Bitcoin trades down to $49,000, sell 1 Bitcoin with a limit order at $58,000
StopLimitOrder("BTCUSD", -1, 49000, 58000);
# When Bitcoin trades down to $49,000, sell 1 Bitcoin with a limit order at $58,000
self.stop_limit_order("BTCUSD", -1, 49000, 58000)
When the asset is trading at $57,000, place an unmarketable sell stop limit order with a stop at $49,000 and a limit at $58,000. The stop is hit and the limit is set when the asset trades down to $49,000. Then the stop limit order fills when the security trades up to $58,000.

To sell an asset with a stop limit order that has a marketable limit price, set the stop price below the current market price and set the limit price below the stop price.

// When Bitcoin trades down to $37,000, sell 1 Bitcoin with a limit order at $34,000
StopLimitOrder("BTCUSD", -1, 37000, 34000);
# When Bitcoin trades down to $37,000, sell 1 Bitcoin with a limit order at $34,000
self.stop_limit_order("BTCUSD", -1, 37000, 34000)
When the asset is trading at $57,000, place a marketable sell stop limit order with a stop at $37,000 and a limit at $34,000. The stop is hit, the limit is set, and the order fills when the asset trades down to $37,000.

Monitor Order Fills

Stop limit orders fill as limit orders when the security price passes the stop price. To monitor the fills of your order, save a reference to the order ticket.

// When GLD trades up to $200, buy 10 shares with a limit order at $205
var ticket = StopLimitOrder("GLD", 10, 200, 205);
Debug($"Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}");
# When GLD trades up to $200, buy 10 shares with a limit order at $205
ticket = self.stop_limit_order("GLD", 10, 200, 205)
self.debug(f"Quantity filled: {ticket.quantity_filled}; Fill price: {ticket.average_fill_price}")

For more information about how LEAN models order fills in backtests, see Trade Fills.

Update Orders

You can update the quantity, stop price, limit price, and tag of stop limit orders until the order fills or the brokerage prevents modifications. To update an order, pass an UpdateOrderFields object to the Updateupdate method on the OrderTicket. If you don't have the order ticket, get it from the transaction manager. The Updateupdate method returns an OrderResponse to signal the success or failure of the update request.

// Create a new order and save the order ticket
var ticket = StopLimitOrder("SPY", -10, 400, 390, tag: "original tag");

// Update the order
var response = ticket.Update(new UpdateOrderFields() { 
  Quantity = -15,
  StopPrice = 415,
  LimitPrice = 395,
  Tag = "new tag"
});

// Check if the update was successful
if (response.IsSuccess) { 
     Debug("Order updated successfully");
}
# Create a new order and save the order ticket
ticket = self.stop_limit_order("SPY", -10, 400, 390, tag="original tag")

# Update the order
update_settings = UpdateOrderFields()
update_settings.quantity = -15
update_settings.stop_price = 415
update_settings.limit_price = 395
update_settings.tag = "new tag"
response = ticket.update(update_settings)

# Check if the update was successful
if response.is_success:
     self.debug("Order updated successfully")

To update individual fields of an order, call any of the following methods:

  • UpdateLimitPrice
  • UpdateQuantity
  • UpdateStopPrice
  • UpdateTag
var limitResponse = ticket.UpdateLimitPrice(limitPrice, tag);

var quantityResponse = ticket.UpdateQuantity(quantity, tag);

var stopResponse = ticket.UpdateStopPrice(stopPrice, tag);

var tagResponse = ticket.UpdateTag(tag);

response = ticket.UpdateLimitPrice(limitPrice, tag)

response = ticket.UpdateQuantity(quantity, tag)

response = ticket.UpdateStopPrice(stopPrice, tag)

response = ticket.UpdateTag(tag)

When you update an order, LEAN creates an UpdateOrderRequest object, which have the following attributes:

To get a list of UpdateOrderRequest objects for an order, call the UpdateRequests method.

var updateRequests = ticket.UpdateRequests();
update_requests = ticket.update_requests()

Brokerage Support

Each brokerage has a set of assets and order types they support. To avoid issues with stop limit orders, set the brokerage model to a brokerage that supports them.

SetBrokerageModel(BrokerageName.QuantConnectBrokerage);
self.set_brokerage_model(BrokerageName.QuantConnectBrokerage)

To check if your brokerage has any special requirements for stop limit orders, see the Orders section of the brokerage model documentation.

Requirements

Stop limit orders can be submitted at any time for all security types.

If your algorithm subscribes to extended market hours, they can be filled outside regular trading hours.

Example

The following backtest verifies the StopLimitOrder behavior. The following table shows the trades in the backtest:

Submitted TimeFilled TimeSymbolStop PriceLimit PriceFilled PriceQuantityTypeStatusValueTag
2021-07-01T09:31:00Z2021-07-01T09:37:00ZSPY428.95429.00429.00-10Stop LimitFilled-4290.00Stop Price: ¤428.95 Limit Price: ¤429.00
2021-07-02T09:31:00Z2021-07-02T10:12:00ZSPY431.80431.75431.7510Stop LimitFilled4317.50Stop Price: ¤431.80 Limit Price: ¤431.75

On July 1, 2021 at 9:31 AM Eastern Time (ET), the algorithm places a stop limit order to sell SPY with a stop price of $428.95 and a limit price of $429. At the time of the order submission, the ask high price is $429.16 and the ask close price is $429.11. The order fills at 9:37 AM ET at a price of $429. The fill model triggers the stop for buy orders when the ask high price is greater than the stop price, fills the order when the ask close price is less than the limit price, and sets the fill price to the maximum of the ask high price and the limit price.

On July 2, 2021 at 9:31 AM ET, the algorithm places a stop limit order to buy SPY with a stop price of $431.80 and a limit price of $431.75. At the time of the order submissions, the bid low price is $431.49 and the bid close price is $431.54. The order fills at 10:12 AM ET at a price of $431.75. The fill model triggers the stop for sell orders when bid low price is less than the stop price, fills the order when the ask close price is less than the limit price, and sets the fill price to the minimum of the ask high price and the limit price.

To reproduce these results, backtest the following algorithm:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: