Order Types
Market Orders
Introduction
Market orders are instructions to trade a specific number of units, regardless of the fill price. If your highest priority is to fill an order as fast as possible, use market orders. If the order book of the security you're trading has sufficient liquidity when the brokerage receives your order, it immediately fills. However, if there is not enough liquidity by the brokerage, you may need to wait a few minutes to fill the order, you may get partial fills, and you may incur additional costs from market impact.
Place Orders
To send a market order, call the MarketOrder
, Buy
, Sell
, or Order
market_order
, buy
, sell
, or order
method and provide a Symbol
and quantity. If you don't have sufficient capital for the order, it's rejected. By default, market orders are synchronous and fill immediately.
// Buy orders MarketOrder("IBM", 100); Buy("AAPL", 10); Order("SPY", 20); // Sell orders MarketOrder("AMZN", -15); Sell("TSLA", 25); Order("SPY", -20);
# Buy orders self.market_order("IBM", 100) self.buy("AAPL", 10) self.order("SPY", 20) # Sell orders self.market_order("AMZN", -15) self.sell("TSLA", 25) self.order("SPY", -20)
You can also provide a tag and order properties to the Order
and MarketOrder
order
and market_order
methods.
MarketOrder(symbol, quantity, tag: tag, orderProperties: orderProperties);
self.market_order(symbol, quantity, tag=tag, order_properties=order_properties)
If you place a market order during pre-market or post-market hours, LEAN converts your order to market on open order. To override this behavior, create a custom fill model. To be notified when the default fill model allows you to submit market orders outside of regular trading hours, subscribe to GitHub Issue #3947.
Monitor Order Fills
If the brokerage has sufficient liquidity in their order book, market orders fill immediately. Otherwise, you get partial fills. To monitor the fills of your order, save a reference to the order ticket.
var ticket = MarketOrder("XLK", 10); Debug($"Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}");
ticket = self.market_order("XLK", 10) 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.
Synchronous Timeouts
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
transactions.market_order_fill_timeout
property.
// Adjust the market fill-timeout to 30 seconds. Transactions.MarketOrderFillTimeout = TimeSpan.FromSeconds(30);
# Adjust the market fill-timeout to 30 seconds. self.transactions.market_order_fill_timeout = timedelta(seconds=30)
Market orders may take a few minutes to fill for illiquid assets such as out-of-the-money Options or penny stocks.
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.
MarketOrder("IBM", 100, asynchronous: true);
self.market_order("IBM", 100, True)
Cancel Orders
To cancel a market order, call the Cancel
cancel
method on the OrderTicket
. If you don't have the order ticket, get it from the transaction manager. The Cancel
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.is_success: 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
cancel_order_request
method on the order ticket. The method returns null
None
if the order hasn't been cancelled.
var request = ticket.cancel_order_request();
request = ticket.cancel_order_request()
Brokerage Support
Each brokerage has a set of assets and order types they support. To avoid issues with market orders, set the brokerage model to a brokerage that supports them.
SetBrokerageModel(BrokerageName.QuantConnectBrokerage);
self.set_brokerage_model(BrokerageName.QUANTCONNECT_BROKERAGE)
To check if your brokerage has any special requirements for market orders, see the Orders section of the brokerage model documentation.
Requirements
You can submit market orders during regular trading hours for all asset classes. For Futures and Future Options, you can place market orders during regular and extended market hours. For all other asset classes, if you place market orders at/after the last minute of regular market hours, LEAN converts the market orders into market-on-open orders as long as the asset class supports them. To view the trading hours of each asset class, follow these steps:
- Open the Asset Classes documentation.
- Click an asset class.
- Click .
Examples
The following backtest verifies the
MarketOrder
market_order
behavior. The algorithm buys SPY on the first day and liquidates the position on the second day. The following table shows the first two trades in the backtest:
Time | Symbol | Price | Quantity | Type | Status | Value | Tag |
---|---|---|---|---|---|---|---|
2021-07-01T09:31:00Z | SPY | 429.11 | 10 | Market | Filled | 4291.10 | |
2021-07-02T09:31:00Z | SPY | 431.54 | -10 | Market | Filled | -4315.40 |
On July 1, 2021, the algorithm buys SPY at $429.11. The
fill model
fills this order at the ask close price.
On July 2, 2021, the algorithm sells the SPY holdings at $431.54. The fill model fills this order at the bid close price.
To reproduce these results, backtest the following algorithm:
public class MarketOrderAlgorithm : QCAlgorithm { private Symbol _symbol; public override void Initialize() { SetStartDate(2021, 7, 1); SetEndDate(2021, 7, 4); SetCash(100000); UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw; _symbol = AddEquity("SPY").Symbol; } public override void OnData(Slice data) { if (!Portfolio.Invested && Time.Day == 1) { MarketOrder(_symbol, 10); } else if (Portfolio.Invested && Time.Day == 2) { MarketOrder(_symbol, -10); } } }
class MarketOrderAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2021, 7, 1) self.set_end_date(2021, 7, 3) self.set_cash(100000) self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW self.add_equity("SPY") def on_data(self, data): if not self.portfolio.invested and self.time.day == 1: self.market_order("SPY", 10) elif self.portfolio.invested and self.time.day != 1: self.market_order("SPY", -10)