Order Types
Market On Close Orders
Place Orders
To send a MOC order, call the MarketOnCloseOrder
market_on_close_order
method with a Symbol
and quantity. If you don't have sufficient capital for the order, it is rejected.
// Buy 100 shares of AAPL at the market open MarketOnCloseOrder("AAPL", 100); // Sell 100 shares of AAPL at the market open MarketOnCloseOrder("AAPL", -100);
# Buy 100 shares of AAPL at the market open self.market_on_close_order("AAPL", 100) # Sell 100 shares of AAPL at the market open self.market_on_close_order("AAPL", -100)
You can provide a tag and order properties to the MarketOnCloseOrder
market_on_close_order
method.
MarketOnCloseOrder(symbol, quantity, tag: tag, orderProperties: orderProperties);
self.market_on_close_order(symbol, quantity, tag=tag, order_properties=order_properties)
By default, you must place MOC orders at least 15.5 minutes before the close, but some exchanges let you submit them closer to the market closing time. To adjust the buffer period that's required, set the MarketOnCloseOrder.SubmissionTimeBuffer
MarketOnCloseOrder.submission_time_buffer
property.
Orders.MarketOnCloseOrder.SubmissionTimeBuffer = TimeSpan.FromMinutes(10);
MarketOnCloseOrder.submission_time_buffer = timedelta(minutes=10)
You can also place MOC orders after the market close.
Monitor Order Fills
MOC orders fill at the closing auction. If the auction is heavily skewed to one side of the market, your MOC order may not fill. To monitor the fills of your order, save a reference to the order ticket.
// Buy 10 shares of SPY at the market close var ticket = MarketOnCloseOrder("SPY", 10); Debug($"Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}");
# Buy 10 shares of SPY at the market close ticket = self.market_on_close_order("SPY", 10) self.debug(f"Quantity filled: {ticket.quantity_filled}; Fill price: {ticket.average_fill_price}")
You won't know the fill price of the order until after the market closes. If the asset price moves before the market close to where you can't afford the quantity of the order, the brokerage rejects your order. To increase the probability of a successful trade, leave a sufficient buying power buffer to handle the price movements before the close.
For more information about how LEAN models order fills in backtests, see Trade Fills.
Update Orders
You can update the quantity and tag of MOC orders until the order fills or the brokerage prevents modifications. To update an order, pass an UpdateOrderFields
object to the Update
update
method on the OrderTicket
. If you don't have the order ticket, get it from the transaction manager. The Update
update
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 = MarketOnCloseOrder("SLV", 25, "original tag"); // Update the order var response = ticket.Update(new UpdateOrderFields() { Quantity = 50, 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.market_on_open_order("SLV", 25, "original tag") # Update the order update_settings = UpdateOrderFields() update_settings.quantity = 50 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:
UpdateQuantity
update_quantity
UpdateTag
update_tag
var quantityResponse = ticket.UpdateQuantity(quantity, tag); var tagResponse = ticket.UpdateTag(tag);
response = ticket.update_quantity(quantity, tag) response = ticket.update_tag(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
update_requests
method.
var updateRequests = ticket.UpdateRequests();
update_requests = ticket.update_requests()
Cancel Orders
To cancel a MOC 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 MOC 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 MOC orders, see the Orders section of the brokerage model documentation.
Requirements
By default, you must place MOC orders at least 15.5 minutes before the close, but some exchanges let you submit them closer to the market closing time. To adjust the buffer period that's required, set the MarketOnCloseOrder.SubmissionTimeBuffer
MarketOnCloseOrder.submission_time_buffer
property.
Orders.MarketOnCloseOrder.SubmissionTimeBuffer = TimeSpan.FromMinutes(10);
MarketOnCloseOrder.submission_time_buffer = timedelta(minutes=10)
Markets that operate 24/7 don't support MOC orders. The Forex market doesn't operate during the weekend.
MOC orders don't support the GoodTilDate
time in force. If you submit a MOC order with the GoodTilDate
time in force, LEAN automatically adjusts the time in force to be GoodTilCanceled
.
Example
The following backtest verifies the MarketOnCloseOrder
market_on_close_order
behavior. The following table shows the first trade in the backtest:
Submitted Time | Filled Time | Symbol | Price | Quantity | Type | Status | Value | Tag |
---|---|---|---|---|---|---|---|---|
2021-07-01T10:31:00Z | 2021-07-01T16:00:00Z | SPY | 430.43 | 10 | Market On Close | Filled | 4304.30 |
On July 1, 2021 at 10:31 AM Eastern Time (ET), the algorithm places a market on open order to buy SPY. The fill model fills the order on July 1, 2021 at 4:00 PM ET at a price of $430.43, which is the official closing auction price for July 1, 2021.
To reproduce these results, backtest the following algorithm: