Order Types

Combo Market Orders

Introduction

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

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.

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

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

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) 
    {
        return;
    }

    // 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:
        return

    # 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)

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)

Example

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:

TimeSymbolPriceQuantityTypeStatusValueTag
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: