Trading and Orders
Order Errors
Types of Order Errors
Errors at Order Submission
The following errors can occur when you submit an order:
AlgorithmWarmingUp
BrokerageFailedToSubmitOrder
BrokerageModelRefusedToSubmitOrder
ConversionRateZero
EuropeanOptionNotExpiredOnExercise
ExceededMaximumOrders
ExceedsShortableQuantity
ExchangeNotOpen
ForexBaseAndQuoteCurrenciesRequired
ForexConversionRateZero
InsufficientBuyingPower
MarketOnCloseOrderTooLate
MissingSecurity
NonExercisableSecurity
NonTradableSecurity
OptionOrderOnStockSplit
OrderAlreadyExisits
OrderQuantityLessThanLotSize
OrderQuantityZero
PreOrderChecksError
QuoteCurrencyRequired
SecurityHasNoData
UnsupportedRequestType
ALGORITHM_WARMING_UP
BROKERAGE_FAILED_TO_SUBMIT_ORDER
BROKERAGE_MODEL_REFUSED_TO_UPDATE_ORDER
CONVERSION_RATE_ZERO
EUROPEAN_OPTION_NOT_EXPIRED_ON_EXERCISE
EXCEEDED_MAXIMUM_ORDERS
EXCEEDS_SHORTABLE_QUANTITY
EXCHANGE_NOT_OPEN
FOREX_BASE_AND_QUOTE_CURRENCIES_REQUIRED
FOREX_CONVERSION_RATE_ZERO
INSUFFICIENT_BUYING_POWER
MARKET_ON_CLOSE_ORDER_TOO_LATE
MISSING_SECURITY
NON_EXERCISABLE_SECURITY
NON_TRADABLE_SECURITY
OPTION_ORDER_ON_STOCK_SPLIT
ORDER_ALREADY_EXISTS
ORDER_QUANTITY_LESS_THAN_LOT_SIZE
ORDER_QUANTITY_ZERO
PRE_ORDER_CHECKS_ERROR
QUOTE_CURRENCY_REQUIRED
SECURITY_HAS_NO_DATA
UNSUPPORTED_REQUEST_TYPE
Errors After Order Submission
The following errors can occur for active orders:
BrokerageFailedToUpdateOrder
BrokerageModelRefusedToUpdateOrder
InvalidNewOrderStatus
InvalidOrderStatus
InvalidRequest
RequestCanceled
UnableToFindOrder
BROKERAGE_FAILED_TO_UPDATE_ORDER
BROKERAGE_MODEL_REFUSED_TO_SUBMIT_ORDER
INVALID_NEW_ORDER_STATUS
INVALID_ORDER_STATUS
INVALID_REQUEST
REQUEST_CANCELED
UNABLE_TO_FIND_ORDER
Common Errors
There are a few common order errors you may experience.
Why is my order converted to a market on open order?
If you place a market order when the market is closed, LEAN automatically converts the order into market on open order. This most commonly happens when you use daily or hourly data, which your algorithm can receive when the market is closed. With the DailyPreciseEndTime
daily_precise_end_time
setting enabled, your algorithm receives daily bars and the last hourly bar of each day at 4 PM Eastern Time (ET). To avoid LEAN from converting your market order to market on open orders, submit your market orders when the market is open. To check if the market is open, call the IsMarketOpen
is_market_open
method.
// Check the market status before placing an order to avoid unintended market-on-open trades if (IsMarketOpen(_symbol)) { MarketOrder(symbol, quantity); }
# Check the market status before placing an order to avoid unintended market-on-open trades. if self.is_market_open(self._symbol): self.market_order(self._symbol, quantity)
Why am I seeing the "stale price" warning?
Stale fills occur when you fill an order with price data that is timestamped an hour or more into the past. Stale fills usually only occur if you trade illiquid assets or if your algorithm uses daily data but you trade intraday with Scheduled Events. If your order is filled with stale data, the fill price may not be realistic. The pre-built fill models can only fill market orders with stale data. To adjust the length of time that needs to pass before an order is considered stale, set the StalePriceTimeSpan
stale_price_time_span
setting.
public override void Initialize() { // Adjust the stale price time span to be 10 minutes. Settings.StalePriceTimeSpan = TimeSpan.FromMinutes(10); }
def initialize(self) -> None: # Adjust the stale price time span to be 10 minutes. self.settings.stale_price_time_span = timedelta(minutes=10)
Why do I get "Backtest Handled Error: The security with symbol '/ES' is marked as non-tradable"?
This error occurs when you place an order for a continuous Futures contract, which isn't a tradable security. To fix the issue, place the order for a specific Futures contract. To access the currently selected contract in the continuous contract series, use the Mapped
mapped
property of the Future
object.
Why do I get "Backtest Handled Error: Order Error: ids: [1], Insufficient buying power to complete orders" from a Crypto order?
When you place Crypto trades, ensure you have a sufficient balance of the base or quote currency before each trade. If you hold multiple assets and you want to put all of your capital into BTCUSDT, you need to first convert all your non-BTC assets into USDT and then purchase BTCUSDT.
By default, the account currency is USD and your starting cash is $100,000. Some Crypto exchanges don't support fiat currencies, which means you can't convert the $100,000 USD to the pair's quote currency. In this case, set your account currency to the quote currency with a positive quantity.
SetAccountCurrency("USDT", 1000); // Set the account currency to Tether and its quantity to 1,000 USDT
self.set_account_currency("USDT", 1000) # Set the account currency to Tether and its quantity to 1,000 USDT
Order Response Error Reference
The following sections explain why each OrderResponseErrorCode
occurs and how to avoid it.
None
The OrderResponseErrorCode.None
OrderResponseErrorCode.NONE
(0) error means there is no order response error.
Processing Error
The OrderResponseErrorCode.ProcessingError
OrderResponseErrorCode.PROCESSING_ERROR
(-1) error occurs in the following situations:
- When you submit a new order, but LEAN throws an exception while checking if you have sufficient buying power for the order.
- When you try to update or cancel an order, but LEAN throws an exception.
To investigate this order response error further, see the HandleSubmitOrderRequest
, UpdateOrder
, and CancelOrder
methods of the BrokerageTransactionHandler in the LEAN GitHub repository.
Order Already Exists
The OrderResponseErrorCode.OrderAlreadyExists
OrderResponseErrorCode.ORDER_ALREADY_EXISTS
(-2) error occurs when you submit a new order but you already have an open order or a completed order with the same order ID. This order response error usually comes from a concurrency issue.
To avoid this order response, don't place two asynchronous orders at the same time.
Insufficient Buying Power
The OrderResponseErrorCode.InsufficientBuyingPower
OrderResponseErrorCode.INSUFFICIENT_BUYING_POWER
(-3) error occurs when you place an order but the buying power model determines you can't afford it.
To avoid this order response error for non-Option trades, ensure you have enough margin remaining to cover the initial margin requirements of the order before placing it.
This error also commonly occurs when you place a market on open order with daily data. If you place the order with SetHoldings
set_holdings
or use CalculateOrderQuantity
calculate_order_quantity
to determine the order quantity, LEAN calculates the order quantity based on the market close price. If the open price on the following day makes your order more expensive, then you may have insufficient buying power. To avoid the order response error in this case, either use intraday data and place trades when the market is open or adjust your buying power buffer.
Settings.FreePortfolioValuePercentage = 0.05m;
self.settings.free_portfolio_value_percentage = 0.05
Brokerage Model Refused to Submit Order
The OrderResponseErrorCode.BrokerageModelRefusedToSubmitOrder
OrderResponseErrorCode.BROKERAGE_MODEL_REFUSED_TO_SUBMIT_ORDER
(-4) error occurs when you place an order but the brokerage model determines it's invalid. The brokerage model usually checks your order meets the following requirements before sending it to the brokerage:
- Supported security types
- Supported order types and their respective requirements
- Supported time in force options
- The order size is larger than the minimum order size
Each brokerage model can have additional order requirements that the brokerage declares. To avoid this order response error, see the Orders section of the brokerage model documentation.
To investigate this order response error further, see the CanSubmitOrder
method definition of your brokerage model. This order response error occurs when the CanSubmitOrder
method returns false
False
.
Brokerage Failed to Submit Order
The OrderResponseErrorCode.BrokerageFailedToSubmitOrder
OrderResponseErrorCode.BROKERAGE_FAILED_TO_SUBMIT_ORDER
(-5) error occurs when you place an order but the brokerage implementation fails to submit the order to your brokerage.
To investigate this order response error further, see the PlaceOrder
method definition of your brokerage or the BacktestingBrokerage in the LEAN GitHub repository. This order response error occurs when the PlaceOrder
method throws an error or returns false
.
Brokerage Failed to Update Order
The OrderResponseErrorCode.BrokerageFailedToUpdateOrder
OrderResponseErrorCode.BROKERAGE_FAILED_TO_UPDATE_ORDER
(-6) error occurs when you try to update an order but the brokerage implementation fails to submit the order update request to your brokerage.
To avoid this order response error, see the Orders section of the brokerage model documentation.
To investigate this order response error further, see the UpdateOrder
method definition of your brokerage or the BacktestingBrokerage in the LEAN GitHub repository. This order response error occurs when the UpdateOrder
method throws an error or returns false
.
Brokerage Failed to Cancel Order
The OrderResponseErrorCode.BrokerageFailedToCancelOrder
OrderResponseErrorCode.BROKERAGE_FAILED_TO_CANCEL_ORDER
(-8) error occurs when you try to cancel an order but the brokerage implementation fails to submit the cancel request to your brokerage.
To investigate this order response error further, see the CancelOrder
method definition of your brokerage or the BacktestingBrokerage in the LEAN GitHub repository. This order response error occurs when CancelOrder
method throws an error or returns false
.
Invalid Order Status
The OrderResponseErrorCode.InvalidOrderStatus
OrderResponseErrorCode.INVALID_ORDER_STATUS
(-9) error occurs when you try to update or cancel an order but the order is already complete. An order is complete if it has OrderStatus.Filled
OrderStatus.FILLED
, OrderStatus.Canceled
OrderStatus.CANCELED
, or OrderStatus.Invalid
OrderStatus.INVALID
.
To avoid this order response error, check Status
of an order ticket or order event before you update or cancel the order.
if (!_orderTicket.Status.IsClosed()) { _orderTicket.Cancel(); }
if not OrderExtensions.is_closed(order_ticket.status): order_ticket.cancel()
Unable to Find Order
The OrderResponseErrorCode.UnableToFindOrder
OrderResponseErrorCode.UNABLE_TO_FIND_ORDER
(-10) error occurs when you try to place, update, or cancel an order, but the BrokerageTransactionHandler
doesn't have a record of the order ID.
To investigate this order response error further, see BrokerageTransactionHandler.cs in the LEAN GitHub repository. This order response error occurs when the BrokerageTransactionHandler
can't find the order ID in it's _completeOrders
or _completeOrderTickets
dictionaries.
Order Quantity Zero
The OrderResponseErrorCode.OrderQuantityZero
OrderResponseErrorCode.ORDER_QUANTITY_ZERO
(-11) error occurs when you place an order that has zero quantity or when you update an order to have a zero quantity. This error commonly occurs if you use the SetHoldings method but the portfolio weight you provide to the method is too small to translate into a non-zero order quantity.
To avoid this order response error, check if the quantity of the order is non-zero before you place the order. If you use the SetHoldings
set_holdings
method, replace it with a combination of the CalculateOrderQuantity and MarketOrder methods.
var quantity = CalculateOrderQuantity(_symbol, 0.05); if (quantity != 0) { MarketOrder(_symbol, quantity); }
quantity = self.calculate_order_quantity(self._symbol, 0.05) if quantity: self.market_order(self._symbol, quantity)
Unsupported Request Type
The OrderResponseErrorCode.UnsupportedRequestType
OrderResponseErrorCode.UNSUPPORTED_REQUEST_TYPE
(-12) error occurs in the following situations:
- When you try to exercise an Option contract for which you hold a short position
- When you try to exercise more Option contracts than you hold
To avoid this order response error, check the quantity of your holdings before you try to exercise an Option contract.
var holdingQuantity = Portfolio[_contractSymbol].Quantity; if (holdingQuantity > 0) { ExerciseOption(_contractSymbol, Math.Max(holdingQuantity, exerciseQuantity)); }
holding_quantity = self.Portfolio[self.contract_symbol].Quantity if holding_quantity > 0: self.ExerciseOption(self.contract_symbol, max(holding_quantity, exercise_quantity))
Missing Security
The OrderResponseErrorCode.MissingSecurity
OrderResponseErrorCode.MISSING_SECURITY
(-14) error occurs when you place an order for a security but you don't have a subscription for the security in your algorithm.
To avoid this order response error, create a subscription for each security you want to trade. To create subscriptions, see the Requesting Data page of the documentation for each asset class.
Exchange Not Open
The OrderResponseErrorCode.ExchangeNotOpen
OrderResponseErrorCode.EXCHANGE_NOT_OPEN
(-15) error occurs in the following situations:
- When you try to exercise an Option while the exchange is not open
- When you try to place a market on open order for a Futures contract or a Future Option contract
To avoid the order response error in this case, check if the exchange is open before you exercise an Option contract.
if (IsMarketOpen(_contractSymbol)) { ExerciseOption(_contractSymbol, quantity); }
if self.is_market_open(self.contract_symbol): self.exercise_option(self.contract_symbol, quantity)
Security Price Zero
The OrderResponseErrorCode.SecurityPriceZero
OrderResponseErrorCode.SECURITY_PRICE_ZERO
(-16) error occurs when you place an order or exercise an Option contract while the security price is $0. The security price can be $0 for the following reasons:
- The data is missing
- The algorithm hasn't received data for the security yet
Investigate if it's a data issue. If it is a data issue, report it.
If you subscribe to a security and place an order for the security in the same time step, you'll get this error. To avoid this order response error, initialize the security price with the last known price.
SetSecurityInitializer(new BrokerageModelSecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));
self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices)))
Forex Base and Quote Currencies Required
The OrderResponseErrorCode.ForexBaseAndQuoteCurrenciesRequired
OrderResponseErrorCode.FOREX_BASE_AND_QUOTE_CURRENCIES_REQUIRED
(-17) error occurs when you place a trade for a Forex or Crypto pair but you don't have the base currency and quote currency in your cash book. This error should never occur. If it does, create a bug report.
Forex Conversion Rate Zero
The OrderResponseErrorCode.ForexConversionRateZero
OrderResponseErrorCode.FOREX_CONVERSION_RATE_ZERO
(-18) error occurs when you place a trade for a Forex or Crypto pair and LEAN can't convert the value of the base currency to your account currency. This error usually indicates a lack of data. Investigate the data and if there is some missing, report it.
Security Has No Data
The OrderResponseErrorCode.SecurityHasNoData
OrderResponseErrorCode.SECURITY_HAS_NO_DATA
(-19) error occurs when you place an order for a security before your algorithm receives any data for it. If you subscribe to a security and place an order for the security in the same time step, you'll get this error. To avoid this order response error, initialize the security price with the last known price.
SetSecurityInitializer(new BrokerageModelSecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));
self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices)))
Exceeded Maximum Orders
The OrderResponseErrorCode.ExceededMaximumOrders
OrderResponseErrorCode.EXCEEDED_MAXIMUM_ORDERS
(-20) error occurs when exceed your order quota in a backtest. The number of orders you can place in a single backtest depends on the tier of your organization. The following table shows the number of orders you can place on each tier:
Tier | Orders Quota |
---|---|
Free | 10K |
Quant Researcher | 10M |
Team | Unlimited |
Trading Firm | Unlimited |
Institution | Unlimited |
To avoid this order response error, reduce the number of orders in your backtest or upgrade your organization.
Market on Close Order Too Late
The OrderResponseErrorCode.MarketOnCloseOrderTooLate
OrderResponseErrorCode.MARKET_ON_CLOSE_ORDER_TOO_LATE
(-21) error occurs when you try to place a market on close (MOC) order too early in the trading day.
To avoid this order response error, place the MOC order closer to the market close or adjust the submission time buffer. 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)
Invalid Request
The OrderResponseErrorCode.InvalidRequest
OrderResponseErrorCode.INVALID_REQUEST
(-22) error occurs when you try to cancel an order multiple times.
To avoid this order response error, only try to cancel an order one time.
Request Canceled
The OrderResponseErrorCode.RequestCanceled
OrderResponseErrorCode.REQUEST_CANCELED
(-23) error occurs when you try to cancel an order multiple times.
To avoid this order response error, only try to cancel an order one time.
Algorithm Warming Up
The OrderResponseErrorCode.AlgorithmWarmingUp
OrderResponseErrorCode.ALGORITHM_WARMING_UP
(-24) error occurs in the following situations:
- When you try to place, update, or cancel an order during the warm-up period
- When the Option assignment simulator assigns you to an Option during the warm-up period
To avoid this order response error, only manage orders after the warm-up period ends. To avoid trading during the warm-up period, add an IsWarmingUp
is_warming_up
guard to the top of the OnData
on_data
method.
if (IsWarmingUp) return;
if self.is_warming_up: return
Brokerage Model Refused to Update Order
The OrderResponseErrorCode.BrokerageModelRefusedToUpdateOrder
OrderResponseErrorCode.BROKERAGE_MODEL_REFUSED_TO_UPDATE_ORDER
(-25) error occurs in backtests when you try to update an order in a way that the brokerage model doesn't support.
To avoid this issue, see the Orders section of the brokerage model documentation to check its order requirements.
To investigate this order response error further, see the CanUpdateOrder
method definition of your brokerage model.
Quote Currency Required
The OrderResponseErrorCode.QuoteCurrencyRequired
OrderResponseErrorCode.QUOTE_CURRENCY_REQUIRED
(-26) error occurs when you place an order for a Forex or Crypto pair and don't have the quote currency of the pair in your cash book. This error should never occur. If it does, create a bug report.
Conversion Rate Zero
The OrderResponseErrorCode.ConversionRateZero
OrderResponseErrorCode.CONVERSION_RATE_ZERO
(-27) error occurs when you place an order for a Forex or Crypto pair and LEAN can't convert the value of the quote currency in the pair to your account currency. This order response error usually indicates a lack of data. Investigate the data and if there is data missing, report it.
Non-Tradable Security
The OrderResponseErrorCode.NonTradableSecurity
OrderResponseErrorCode.NON_TRADABLE_SECURITY
(-28) error occurs when you place an order for a security that's not tradable. To avoid this order response error, check if a security is tradable before you trade it.
if (Securities[_symbol].IsTradable) { MarketOrder(_symbol, quantity); }
if self.securities[self._symbol].is_tradable: self.market_order(self._symbol, quantity)
Non-Exercisable Security
The OrderResponseErrorCode.NonExercisableSecurity
OrderResponseErrorCode.NON_EXERCISABLE_SECURITY
(-29) error occurs when you call the ExerciseOption method with a Symbol
that doesn't reference an Option contract.
Order Quantity Less Than Lot Size
The OrderResponseErrorCode.OrderQuantityLessThanLotSize
OrderResponseErrorCode.ORDER_QUANTITY_LESS_THAN_LOT_SIZE
(-30) error occurs when you place an order with a quantity that's less than the lot size of the security.
To avoid this order response error, check if the order quantity is greater than or equal to the security lot size before you place an order.
var lotSize = Securities[_symbol].SymbolProperties.LotSize; if (quantity >= lotSize) { MarketOrder(_symbol, quantity); }
lot_size = self.Securities[self._symbol].SymbolProperties.LotSize if quantity >= lot_size: self.MarketOrder(self._symbol, quantity)
Exceeds Shortable Quantity
The OrderResponseErrorCode.ExceedsShortableQuantity
OrderResponseErrorCode.EXCEEDS_SHORTABLE_QUANTITY
(-31) error occurs when you place an order to short a security but the shortable provider of the brokerage model states there isn't enough shares to borrow. For a full example of this error, clone and run this backtest.
To avoid this order response error, check if there are enough shares available before you place an order to short a security.
var availableToBorrow = BrokerageModel.GetShortableProvider().ShortableQuantity(_symbol, Time); if (availableToBorrow == null || quantityToBorrow <= availableToBorrow) { MarketOrder(_symbol, -quantityToBorrow); }
available_to_borrow = self.BrokerageModel.GetShortableProvider().ShortableQuantity(self._symbol, self.Time) if available_to_borrow == None or quantity_to_borrow <= available_to_borrow: self.MarketOrder(self._symbol, -quantity_to_borrow)
Invalid New Order Status
The OrderResponseErrorCode.InvalidNewOrderStatus
OrderResponseErrorCode.INVALID_NEW_ORDER_STATUS
(-32) error occurs in live trading when you try to update or cancel an order while it still has OrderStatus.New
OrderStatus.NEW
status.
To avoid this order response error, check the Status
status
property of the order ticket or order event before you update or cancel an order.
if (_orderTicket.Status != OrderStatus.New) { _orderTicket.Cancel(); }
if self.order_ticket.status != OrderStatus.NEW: self.order_ticket.cancel()
European Option Not Expired on Exercise
The OrderResponseErrorCode.EuropeanOptionNotExpiredOnExercise
OrderResponseErrorCode.EUROPEAN_OPTION_NOT_EXPIRED_ON_EXERCISE
(-33) error occurs when you try to exercise a European Option contract before its expiry date.
To avoid this order response error, check the type and expiry date of the contract before you exercise it.
if (_contractSymbol.ID.OptionStyle == OptionStyle.European && _contractSymbol.ID.Date == Time.Date) { ExerciseOption(_contractSymbol, quantity); }
if self.contract_symbol.ID.OptionStyle == OptionStyle.European && self.contract_symbol.ID.Date == self.Time.Date: self.ExerciseOption(self.contract_symbol, quantity)
Option Order on Stock Split
The OrderResponseErrorCode.OptionOrderOnStockSplit
OrderResponseErrorCode.OPTION_ORDER_ON_STOCK_SPLIT
(-34) error occurs when you try to submit an order for an Equity Option contract when the current time slice contains a split for the underlying Equity.
To avoid this order response error, check if the time slice has a split event for the underlying Equity of the contract before you place an order for the contract.
if (!slice.Splits.ContainsKey(_contractSymbol.Underlying)) { MarketOrder(_contractSymbol, quantity); }
if self.contract_symbol.underlying not in slice.splits: self.market_order(self.contract_symbol, quantity)