Order Types

Combo Market Orders


Combo market orders are individual orders that contain market orders for muliple securities. Combo market orders currently only work for trading Option contracts.

Place Orders

To send a combo market order, create multiple Leg objects to represent the legs of the combo order, then call the ComboMarketOrder method. At least one leg must have a positive quantity and at least one leg must have a negative quantity. The legs must each target a unique contract. If you don't have sufficient capital for the order, it's rejected. By default, combo market orders are synchronous and fill immediately.

foreach (var kvp in slice.OptionChains)
    // Select contracts
    var contracts = kvp.Value.Contracts.Values.ToList();
    if (contracts.Count < 2) 

    // Create order legs
    var legs = new List<Leg>()
        Leg.Create(contracts[0].Symbol, 1),
        Leg.Create(contracts[1].Symbol, -1)

    // Place order
    ComboMarketOrder(legs, 1);
for canonical_symbol, chain in slice.OptionChains.items():
    # Select contracts
    contracts = [c for c in chain][:2]
    if len(contracts) < 2:

    # Create order legs
    legs = []
    quantities = [1, -1]
    for i, contract in enumerate(contracts):
        legs.append(Leg.Create(contract.Symbol, quantities[i]))
    # Place order
    self.ComboMarketOrder(legs, 1)

The quantity of the legs sets the ratio of the leg orders while the quantity argument of the ComboMarketOrder method sets the combo order size and acts as a global multiplier. In the preceding example, if we set the global multiplier to two, then the algorithm buys two units of the first contract and sells two units of the second contract. The quantity argument of the ComboMarketOrder method also sets the order direction of the combo order, which affects how the fill model fills the order.

You can also provide a tag and order properties to the ComboMarketOrder method.

ComboMarketOrder(legs, quantity, tag: tag, orderProperties: orderProperties);
self.ComboMarketOrder(legs, quantity, tag=tag, orderProperties=order_properties)

Monitor Order Fills

If the brokerage has sufficient liquidity in their order book, combo market orders fill immediately. Otherwise, you get partial fills. To monitor the fills of your order, save a reference to the order tickets.

var tickets = ComboMarketOrder(legs, 1);
foreach (var ticket in tickets)
    Debug($"Symbol: {ticket.Symbol}; Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}");
ticket = self.ComboMarketOrder(legs, 1)
for ticket in tickets:
    self.Debug(f"Symbol: {ticket.Symbol}; Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}")

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

Synchronous Timeouts

Combo market orders are synchronous by default, so your algorithm waits for the order to fill before moving to the next line of code. If your order takes longer than five seconds to fill, your algorithm continues executing even if the trade isn't filled. To adjust the timeout period, set the Transactions.MarketOrderFillTimeout property.

// Adjust the market fill-timeout to 30 seconds.
Transactions.MarketOrderFillTimeout = TimeSpan.FromSeconds(30);
 # Adjust the market fill-timeout to 30 seconds.
self.Transactions.MarketOrderFillTimeout = timedelta(seconds=30)

Combo market orders may take a few minutes to fill for illiquid assets such as out-of-the-money Options.

Place Asynchronous Orders

When you trade a large portfolio of assets, you may want to send orders in batches and not wait for the response of each one. To send asynchronous orders, set the asynchronous argument to true.

ComboMarketOrder(legs, quantity, true);
self.ComboMarketOrder(legs, quantity, True)

Cancel Orders

To cancel a combo market order, call the Cancel method on the OrderTicket. If you don't have the order ticket, get it from the transaction manager. The Cancel method returns an OrderResponse object to signal the success or failure of the cancel request.

var response = ticket.Cancel("Cancelled trade");
if (response.IsSuccess)
    Debug("Order successfully cancelled");
response = ticket.Cancel("Cancelled Trade")
if response.IsSuccess:
    self.Debug("Order successfully cancelled")

When you cancel an order, LEAN creates a CancelOrderRequest, which have the following attributes:

To get the CancelOrderRequest for an order, call the CancelRequest method on the order ticket. The method returns nullNone if the order hasn't been cancelled.

var request = ticket.CancelOrderRequest();
request = ticket.CancelOrderRequest()

Brokerage Support

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


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


Combo market orders must be submitted during market hours for all security types.

If your algorithm place combo market orders at or after the last minute of regular market hours, they will be converted into market-on-open orders and will have to observe their for the following asset types:

  1. Equities
  2. Equity Options
  3. Forex
  4. CFDs
  5. Index Options

Combo market orders for Futures and Future Options can be submitted during extended market hours, or they will be invalid.


The following backtest verifies the ComboMarketOrder behavior. The algorithm buys one contract and sells one contract at the same time. The following table shows the two trades in the backtest:

2015-12-24T09:31:00ZGOOG 16011SC0074500016.901BuyFilled16.90
2015-12-24T09:31:00ZGOOG 160115C0074750014.20-1SellFilled-14.20

On December 24, 2015, the algorithm buys GOOG 16011SC00745000 at $16.90 and sells GOOG 160115C00747500 at $14.20. The fill model fills the buy order at the ask close price and fills the sell order at the bid close 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: