Algorithm Reference

Trading and Orders


Algorithms can place an order through calling the appropriate method in the API. Going long is denoted with a ordering positive number, and short a negative one. LEAN does not support hedging (long and short at the same time).

Placing an order generates an OrderTicket which you can use to update, cancel or check the status of your order.

To update an order you can call the Update method on the OrderTicket. The Update method takes an UpdateOrderFields object which defines what properties of the order should be updated. In the same way you can cancel your order with the OrderTicket Cancel method.

The OrderTicket Status property can be used to determine if the order is filled. The OrderStatus has the values Submitted, PartiallyFilled, Filled, Cancelled or Invalid.

The Transactions property is a helper that provides easy access to current and past orders and order tickets.

// Popular Transactions methods:
            .CancelOpenOrders(Symbol symbol)
            .CancelOrder(int orderId, string orderTag = null)
            .GetOpenOrders(Symbol symbol)
            .GetOrderById(int orderId)
            .GetOrders(Funcfilter).GetOrderTicket(int orderId).GetOrderTickets(Funcfilter = null)
// Creating an Order:
OrderTicket limitOrderTicket = LimitOrder("SPY", 100, 205);

// Updating an Order:
limitOrderTicket.Update(new UpdateOrderFields{LimitPrice = 207.50};

// Cancel an Order:
# Creating an Order:
limitOrderTicket = self.LimitOrder("SPY", 100, 205)

# Updating an Order:
updateOrderFields = UpdateOrderFields()
updateOrderFields.LimitPrice = decimal.Decimal(207.50)

# Cancel an Order:
// Cancel all open orders from SPY
List cancelledOrders = Transactions.CancelOpenOrders("SPY")

// Cancel order #10
OrderTicket cancelledOrder = Transactions.CancelOrder(10);

// Get open orders
List openOrders = Transactions.GetOpenOrders();
List openOrders = Transactions
    .GetOrders(x => x.Status.IsOpen()).ToList();

// Get open orders from SPY
List openOrders = Transactions.GetOpenOrders("SPY");
List openOrders = Transactions
    .GetOrders(x => x.Status.IsOpen() && x.Symbol == "SPY").ToList();

// Get open order #10
Order openOrder = Transactions.GetOrderById(10);

// Get order ticket #10
OrderTicket orderTicket = Transactions.GetOrderTicket(10);

// Get open orders tickets from SPY
IEnumerable openOrderTickets = Transactions
    .GetOrderTickets(x => x.Status.IsOpen() && x.Symbol == "SPY");
# Cancel all open orders from SPY
cancelledOrders = self.Transactions.CancelOpenOrders("SPY")

# Cancel order #10
cancelledOrder = self.Transactions.CancelOrder(10)

# Get open orders
openOrders = self.Transactions.GetOpenOrders()

# Get open orders from SPY
openOrders = self.Transactions.GetOpenOrders("SPY")

# Get open order #10
openOrder = self.Transactions.GetOrderById(10)

# Get all orders
orders = self.Transactions.GetOrders()

# Get order ticket #10
orderTicket = self.Transactions.GetOrderTicket(10)

# Get all orders tickets
openOrderTickets = self.Transactions.GetOrderTickets()

Set Holdings Helper

Often portfolio based algorithms want to set the portfolio based on percentage weighting. We provide a helper method to perform this weighting for you called SetHoldings .

SetHoldings(Symbol symbol, double percentage, bool liquidateExistingHoldings = false)
self.SetHoldings(Symbol symbol, double percentage, bool liquidateExistingHoldings = false)

When liquidate existing holdings is set to true any existing holdings will first be sold. This may be useful when you're rebalancing to a new set of stocks. The Liquidate method can achieve the same affect.

Liquidate(Symbol symbolToLiquidate = null)
self.Liquidate(symbolToLiquidate=None) # set ticker to liquidate specific symbol

Liquidate sells all holdings in your portfolio, or just the ticker symbol if the parameter is specified.

SetHoldings sets a fraction of unlevered equity. e.g. If you have 2x available leverage, and SetHoldings to 1.0 the algorithm will use 1.0 of your available buying power. To maximize buying power in this case you would make the SetHoldings fractions total 2.0.

// Set fixed percentages of known tickers:
SetHoldings("IBM", 0.25);
SetHoldings("GOOG", 0.25);
SetHoldings("AAPL", 0.25);
SetHoldings("MSFT", 0.25);

// Or set portfolio to equal weighting of all securities:
var weighting = 1m / Securities.Count;
foreach(var security in Securities.Values) {
    SetHoldings(security.Symbol, weighting);
# Set fixed percentages of known tickers:
self.SetHoldings("IBM", 0.25)
self.SetHoldings("GOOG", 0.25)
self.SetHoldings("AAPL", 0.25)
self.SetHoldings("MSFT", 0.25)

# Or set portfolio to equal weighting of all securities:
weighting = 1.0 / self.Securities.Count
for security in self.Securities.Values:
    self.SetHoldings(security.Symbol, weighting)

Manually Applying Set Holdings

The method for calculating this order quantity is made available for your use. This is called CalculateOrderQuantity. The method accepts a Symbol and double target fraction of your portfolio. The return value is the ideal number of shares.

Order Types

We support many different order types. In live trading some of these order types may be simulated depending on your brokerage (for more information on this see Live Trading).

Order Type Method Signature
Market Order MarketOrder(Symbol symbol, decimal quantity, bool asynchronous=false, string tag="")
Asynchronous flag can be used to send the many orders and not wait for the fill response.
Market On Open MarketOnOpenOrder(Symbol symbol, decimalquantity, string tag="")
Fill an order at the market opening. Equity markets only.
Market On Close MarketOnCloseOrder(Symbol symbol, decimal quantity, string tag="")
Fill an order on market closing. Equity markets only. Orders must be submitted 15min before closing.
Stop Market StopMarketOrder(Symbol symbol, decimal quantity, decimal stopPrice, string tag="")
Submit a market order when the stop price is reached.
Limit Order LimitOrder(Symbol symbol, decimal quantity, decimal limitPrice, string tag="")
Fill order for the limit price or better.
Stop Limit Order StopLimitOrder(Symbol symbol, decimal quantity, decimal stopPrice, decimal limitPrice, string tag="")
Submit limit order when stop price is reached.

All order methods return an OrderTicket. The tag parameter can be used to send additional debugging information along with each order object.

// Various order types:
// Fill a market order immediately (before moving to next line of code)
var newTicket = MarketOrder("IBM", 100);

// Place a long limit order with limit price less than current price
var newTicket = LimitOrder("IBM", 100, lastClose * .999m);

// Closing out a short position; long stop above the last close price
var stopPrice = close * 1.0025m;
var newTicket = StopMarketOrder("IBM", 100, stopPrice);

// Closing out a long position on market drop
var stopPrice = close * .9975m;
var newTicket = StopMarketOrder("IBM", -100, stopPrice);

// Limit order trigger on reaching the stop price
var newTicket = StopLimitOrder("IBM", 100, stopPrice, limitPrice);

// Market on Open/Close:
var newTicket = MarketOnCloseOrder("IBM", 100);
var newTicket = MarketOnOpenOrder("IBM", 100);
# Various order types:
# Fill a market order immediately (before moving to next line of code)
newTicket = self.MarketOrder("IBM", 100)

# Place a long limit order with limit price less than current price
newTicket = self.LimitOrder("IBM", 100, lastClose * decimal.Decimal(.999))

# Closing out a short position; long stop above the last close price
stopPrice = close * decimal.Decimal(1.0025)
newTicket = self.StopMarketOrder("IBM", 100, stopPrice)

# Closing out a long position on market drop
stopPrice = close * decimal.Decimal(.9975)
newTicket = self.StopMarketOrder("IBM", -100, stopPrice)

# Limit order trigger on reaching the stop price
newTicket = self.StopLimitOrder("IBM", 100, stopPrice, limitPrice)

# Market on Open/Close:
newTicket = self.MarketOnCloseOrder("IBM", 100)
newTicket = self.MarketOnOpenOrder("IBM", 100)

Market Orders

When running an algorithm live, there are two ways of placing an order using the method MarketOrder: synchronous or asynchronous.

Synchronous Market Order

Market Orders are sent synchronously by default. This means the method call blocks and waits for an order-filled response from the broker. In highly liquid markets this fill response is ordinarily immediate; however some illiquid stocks or slow brokerages can take several seconds to fill a market order. By default, LEAN waits up to 5 seconds to fill a market order, before resuming normal algorithm execution.

The MarketOrderFillTimeOut can be adjusted if your algorithm requires a longer timeout. This is set via the Transactions Manager as shown below. Keep in mind this will result in blocking your algorithm for long fills.

self.Transactions.MarketOrderFillTimeout = TimeSpan.FromMinutes(2)
Transactions.MarketOrderFillTimeout = TimeSpan.FromMinutes(2);

Asynchronous Market Order

This type of market order is sent to a broker without waiting for a market order fill response from the broker. This is useful for when you are sending hundreds or thousands of orders such as for universe selection where doing it synchronously would take several minutes.

To send a market order asynchronously use the boolean flag on the market order arguement:

self.MarketOrder("SPY", 100, true, "Async Order")
MarketOrder("SPY", 100, asynchronous: true);

Time In Force

Time in force is a useful way for active traders to keep from accidentally executing trades. By setting time parameters, they don’t have to remember to cancel old trades. The TimeInForce property determines how long the order should remain open if unfilled.

Time In Force Method Signature
Good Until Canceled TimeInForce.GoodTilCanceled
Order is valid until filled -- default setting
Day TimeInForce.Day
Order is valid until filled or the market closes
Good Until Date TimeInForce.GoodTilDate(DateTime expiry)
Order is valid until filled or the specified expiration time

The default Time In Force is GoodTilCanceled. If assigning a different value, declare Time In Force before placing an order or orders. Specifying Time In Force can be done for one or more orders at a time, but doing so will change the default value for all future orders unless reassigned again.

    // Set Limit Order to be good until market close
    DefaultOrderProperties.TimeInForce = TimeInForce.Day;
    LimitOrder("IBM", 100, lastClose * .999m);

    // Set Market Order to be good until noon
    DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilDate(new DateTime(2019, 6, 19, 12, 0, 0));
    MarketOrder("IBM", 100);
    # Set Limit Order to be good until market close
    self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
    self.LimitOrder("IBM", 100, lastClose * decimal.Decimal(.999))

    # Set Market Order to be good until noon
    self.DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilDate(datetime(2019, 6, 19, 12, 0, 0))
    self.MarketOrder("IBM", 100)

Order Error Codes

When an order fails to process it is returned with a negative order code. These error codes mean different things as described below:

Error Code Interpretation
-1 ProcessingError - Unknown error.
-2 OrderAlreadyExists - Cannot submit because order already exists.
-3 InsufficientBuyingPower - Not enough money to to submit order.
-4 BrokerageModelRefusedToSubmitOrder - Internal logic invalidated submit order.
-5 BrokerageFailedToSubmitOrder - Brokerage rejected order.
-6 BrokerageFailedToUpdateOrder - Failed to update order.
-7 BrokerageHandlerRefusedToUpdateOrder - Brokerage rejected update request.
-8 BrokerageFailedToCancelOrder - Brokerage refused to cancel order.
-9 InvalidOrderStatus - Only pending orders can be cancelled
-10 UnableToFindOrder - Cannot find order with that id.
-11 OrderQuantityZero - Cannot submit or update orders with zero quantity.
-12 UnsupportedRequestType - This type of request is unsupported.
-13 PreOrderChecksError - Pre-placement order checks failed.
-14 MissingSecurity - Security is missing. Probably did not subscribe.
-15 ExchangeNotOpen - Some order types require open exchange.
-16 SecurityPriceZero - There isn't any market data yet for the security.
-17 ForexBaseAndQuoteCurrenciesRequired - Need both currencies in cashbook to trade a pair.
-18 ForexConversionRateZero - Need conversion rate to account currency.
-19 SecurityHasNoData - Should not attempt trading without at least one data point.
-20 ExceededMaximumOrders - Transaction manager's cache is full.
-21 MarketOnCloseOrderTooLate - Need to submit market on close orders at least 11 minutes before exchange close.
-22 InvalidRequest - Request is invalid or null.
-23 RequestCanceled - Request was canceled by user.
-24 AlgorithmWarmingUp - All orders are invalidated while algorithm is warming up.
-25 BrokerageModelRefusedToUpdateOrder - Internal logic invalidated update order.
-26 QuoteCurrencyRequired - Need quote currency in cashbook to trade.
-27 ConversionRateZero - Need conversion rate to account currency.
-28 NonTradableSecurity - The order's symbol references a non-tradable security.
-29 NonExercisableSecurity - The order's symbol references a non-exercisable security.

Order Events

Orders create lots of events you can use to track their status. These events are passed into the OnOrderEvent event handler with the relevant order.

// Override the base class event handler for order events
public override void OnOrderEvent(OrderEvent orderEvent)
    var order = Transactions.GetOrderById(orderEvent.OrderId);
    Console.WriteLine("{0}: {1}: {2}", Time, order.Type, orderEvent);
# Override the base class event handler for order events
def OnOrderEvent(self, orderEvent):
    order = self.Transactions.GetOrderById(orderEvent.OrderId)
    self.Debug("{0}: {1}: {2}".format(self.Time, order.Type, orderEvent))

You can also see our Tutorials and Videos. You can also get in touch with us via Chat.

Did you find this page Helpful ?