Supported Models

Equity Model

Introduction

The EquityFillModel is the default fill model if you trade Equity assets with the DefaultBrokerageModel. This fill model fills trades completely and immediately.

security.SetFillModel(new EquityFillModel());
security.set_fill_model(EquityFillModel())

The fill logic of each order depends on the order type, the data format of the security subscription, and the order direction. The following sections explain the fill logic of each order given these factors.

To view the implementation of this model, see the LEAN GitHub repository.

Market Orders

The model fills buy market orders at the best effort ask price plus slippage and fills sell market orders at the best effort bid price minus slippage.

To get the best effort bid price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a buy quote, use the bid price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing bid price of the most recent QuoteBar.

To get the best effort ask price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a sell quote, use the ask price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing ask price of the most recent QuoteBar.

If neither of the preceding procedures yield a result, the model uses the following procedure to get the best effort bid or ask price:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a tick of type TickType.Trade, use the last trade price.
  2. If the subscription provides TradeBar data, use the closing bid price of the most recent QuoteBar.

The model only fills market orders during regular trading hours.

Limit Orders

To fill limit orders, the model first gets the best effort TradeBar. To get the best effort TradeBar, the model checks the resolution of your security subscription. If your subscription provies Tick data, it gets the most recent batch of trade ticks and consolidates them to build a TradeBar. If your subscription provies TradeBar data, it gets the most recent TradeBar. If the EndTimeend_time of the best effort TradeBar is less than or equal to the time you placed the order, the model waits until the next best effort TradeBar to fill the order.

Once the model has a valid best effort TradeBar, it can fill the order. The following table shows the fill condition and fill price of limit orders. The model only fills the order once the fill condition is met.

Order DirectionFill ConditionFill Price
Buylow price < limit pricemin(open price, limit price)
Sellhigh price > limit pricemax(open price, limit price)

The model only fills limit orders when the exchange is open.

The model won't fill limit orders with stale data or data with the order timestamp to avoid look-ahead bias.

Limit if Touched Orders

To fill limit if touched orders, the model first gets the best effort TradeBar. To get the best effort TradeBar, the model checks the resolution of your security subscription. If your subscription provies Tick data, it gets the most recent batch of trade ticks and consolidates them to build a TradeBar. If your subscription provies TradeBar data, it gets the most recent TradeBar. If the EndTimeend_time of the best effort TradeBar is less than or equal to the time you placed the order, the model waits until the next best effort TradeBar to fill the order.

After the model has a valid best effort TradeBar, it can check if the trigger price has been touched. The following table describes the trigger condition of limit if touched orders for each order direction:

Order DirectionTrigger Condition
Buylow price <= trigger price
Sellhigh price >= trigger price

Once the limit if touched order triggers, the model starts to check if it should fill the order. The following table shows the fill condition and fill price of limit if touched orders. The model only fills the order once the fill condition is met

Order DirectionFill ConditionFill Price
BuyBest effort ask price <= limit price
min(best effort ask price, limit price)
SellBest effort bid price >= limit price
max(best effort bid price, limit price)

To get the best effort bid price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a buy quote, use the bid price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing bid price of the most recent QuoteBar.

To get the best effort ask price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a sell quote, use the ask price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing ask price of the most recent QuoteBar.

If neither of the preceding procedures yield a result, the model uses the following procedure to get the best effort bid or ask price:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a tick of type TickType.Trade, use the last trade price.
  2. If the subscription provides TradeBar data, use the closing bid price of the most recent QuoteBar.

The model only fills limit orders when the exchange is open.

The model won't trigger or fill limit if touched orders with stale data.

Stop Market Orders

To fill stop market orders, the model first gets the best effort TradeBar. To get the best effort TradeBar, the model checks the resolution of your security subscription. If your subscription provies Tick data, it gets the most recent batch of trade ticks and consolidates them to build a TradeBar. If your subscription provies TradeBar data, it gets the most recent TradeBar. If the EndTimeend_time of the best effort TradeBar is less than or equal to the time you placed the order, the model waits until the next best effort TradeBar to fill the order.

Once the stop condition is met, the model fills the orders and sets the fill price.

Once the model has a valid best effort TradeBar, it can fill the order. The following table shows the stop condition and fill price of stop market orders. The model only fills the order once the stop condition is met.

Order DirectionFill ConditionFill Price
Buyhigh price >= stop pricemax(open price, stop price) + slippage
Selllow price <= stop pricemin(open price, stop price) - slippage

The model only fills stop market orders during regular trading hours.

The model won't fill stop market orders with stale data or data with the order timestamp to avoid look-ahead bias.

Stop Limit Orders

The fill logic of stop limit orders depends on the data format of the security subscription and the order direction. The following table shows the fill price of stop limit orders given these factors. To determine the fill price of the order, the fill model first checks the most recent tick for the security. If your security subscription doesn't provide tick data, the fill model checks the most recent QuoteBar. If your security subscription doesn't provide quote data, the fill model checks the most recent TradeBar.

The following table describes how the fill model processes the order given the data format and order direction. Once the stop condition is met, the model starts to check the fill condition. Once the fill condition is met, the model fills the orders and sets the fill price.

Data FormatTickTypeOrder DirectionStop ConditionFill ConditionFill Price
TickQuoteBuyquote price > stop pricequote price < limit pricemin(quote price, limit price)
TickQuoteSellquote price < stop pricequote price > limit pricemax(quote price, limit price)
TickTradeBuytrade price > stop pricetrade price < limit pricemin(trade price, limit price)
TickTradeSelltrade price < stop pricetrade price > limit pricemax(trade price, limit price)
QuoteBar
Buyask high price > stop priceask close price < limit pricemin(ask high price, limit price)
QuoteBar
Sellbid low price < stop pricebid close price > limit pricemax(bid low price, limit price)
TradeBar
Buyhigh price > stop priceclose price < limit pricemin(high price, limit price)
TradeBar
Selllow price < stop priceclose price > limit pricemax(low price, limit price)

The model won't fill stop limit orders with stale data or data with the order timestamp to avoid look-ahead bias.

The model only fills stop limit orders when the exchange is open.

Trailing Stop Orders

To fill trailing stop orders, the model first gets the best effort TradeBar. To get the best effort TradeBar, the model checks the resolution of your security subscription. If your subscription provies Tick data, it gets the most recent batch of trade ticks and consolidates them to build a TradeBar. If your subscription provies TradeBar data, it gets the most recent TradeBar. If the EndTimeend_time of the best effort TradeBar is less than or equal to the time you placed the order, the model waits until the next best effort TradeBar to fill the order.

Once the stop condition is met, the model fills the orders and sets the fill price.

Once the model has a valid best effort TradeBar, it can fill the order. The following table shows the stop condition and fill price of trailing stop orders. The model only fills the order once the stop condition is met.

Order DirectionFill ConditionFill Price
Buyhigh price >= stop pricemax(open price, stop price) + slippage
Selllow price <= stop pricemin(open price, stop price) - slippage

While the stop condition is not met, the model updates the stop price under certain conditions. The following table shows the update condition and stop price value for currency-based trailing amounts:

Order DirectionUpdate ConditionStop Price
Buystop price - low price <= trailing amountlow price + trailing amount
Sellhigh price - stop price <= trailing amounthigh price - trailing amount

The following table shows the update condition and stop price value for percentage-based trailing amounts:

Order DirectionUpdate ConditionStop Price
Buystop price - low price <= low price * trailing amountlow price * (1 + trailing amount)
Sellhigh price - stop price <= high price * trailing amounthigh price * (1 - trailing amount)

The model only fills trailing stop orders during regular trading hours.

The model won't fill trailing stop orders with stale data or data with the order timestamp to avoid look-ahead bias.

Market on Open Orders

The following table describes the fill price of market on open orders for each data format and order direction:

Data FormatOrder DirectionFill Price
TickBuyIf the model receives the official opening auction price within one minute, the order fills at official open price + slippage. After one minute, the order fills at the most recent trade price + slippage. If the security doesn't trade within the first two minutes, the order fills at the best effort ask price + slippage.
TickSellIf the model receives the official opening auction price within one minute, the order fills at the official open price - slippage. After one minute, the order fills at the most recent trade price - slippage. If the security doesn't trade within the first two minutes, the order fills at the best effort bid price - slippage.
TradeBarBuyOpen price + slippage
TradeBarSellOpen price - slippage
QuoteBarBuyBest effort ask price + slippage
QuoteBarSellBest effort bid price - slippage

The model checks the data format in the following order:

  1. Tick
  2. TradeBar
  3. QuoteBar

To get the best effort bid price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a buy quote, use the bid price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing bid price of the most recent QuoteBar.

To get the best effort ask price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a sell quote, use the ask price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing ask price of the most recent QuoteBar.

If neither of the preceding procedures yield a result, the model uses the following procedure to get the best effort bid or ask price:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a tick of type TickType.Trade, use the last trade price.
  2. If the subscription provides TradeBar data, use the closing bid price of the most recent QuoteBar.

Market on Close Orders

The following table describes the fill price of market on close orders for each data format and order direction:

Data FormatOrder DirectionFill Price
TickBuyIf the model receives the official closing auction price within one minute after the close, the order fills at official close price + slippage. After one minute, the order fills at the most recent trade price + slippage. If the security doesn't trade within the first two minutes, the order fills at the best effort ask price + slippage.
TickSellIf the model receives the official closing auction price within one minute after the close, the order fills at the official close price - slippage. After one minute, the order fills at the most recent trade price - slippage. If the security doesn't trade within the first two minutes after the close, the order fills at the best effort bid price - slippage.
TradeBarBuyOpen price + slippage
TradeBarSellOpen price - slippage
QuoteBarBuyBest effort ask price + slippage
QuoteBarSellBest effort bid price - slippage

The model checks the data format in the following order:

  1. Tick
  2. TradeBar
  3. QuoteBar

To get the best effort bid price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a buy quote, use the bid price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing bid price of the most recent QuoteBar.

To get the best effort ask price, the model uses the following procedure:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a sell quote, use the ask price of the most recent quote tick.
  2. If the subscription provides QuoteBar data, use the closing ask price of the most recent QuoteBar.

If neither of the preceding procedures yield a result, the model uses the following procedure to get the best effort bid or ask price:

  1. If the subscription provides Tick data and the most recent batch of ticks contains a tick of type TickType.Trade, use the last trade price.
  2. If the subscription provides TradeBar data, use the closing bid price of the most recent QuoteBar.

Combo Market Orders

The fill logic of combo market orders depends on the data format of the security subscription and the order direction. The following table shows the fill price of combo market orders given these factors. To determine the fill price of the order, the fill model first checks the most recent tick for the security. If your security subscription doesn't provide tick data, the fill model checks the most recent QuoteBar. If your security subscription doesn't provide quote data, the fill model checks the most recent TradeBar.

Data FormatTickTypeOrder DirectionFill Price
TickQuoteBuyAsk quote price + slippage
TickQuoteSellBid quote price - slippage
TickTradeBuyTrade price + slippage
TickTradeSellTrade price - slippage
QuoteBar
BuyAsk close price + slippage
QuoteBar
SellBid close price - slippage
TradeBar
BuyClose price + slippage
TradeBar
SellClose price - slippage

The model only fills combo market orders if all the following conditions are met:

  • The exchange is open
  • The data isn't stale
  • All the legs can fill in the same time step after the order time step

The fill quantity of each leg is the product of the leg order quantity and the combo market order quantity.

Combo Limit Orders

The fill logic of combo limit orders depends on the data format of the security subscription and the order direction. To determine the fill price of the order, the fill model first checks the most recent tick for the security. If your security subscription doesn't provide tick data, the fill model checks the most recent QuoteBar. If your security subscription doesn't provide quote data, the fill model checks the most recent TradeBar.

To fill combo limit orders, the fill model calculates the aggregate price of the combo order, which is the sum of prices for each security in the order legs. The price of each security is a function of the data format and order direction. Legs with a positive order quantity increase the aggregate price and legs with a negative quantity decrease the aggregate price. The following table shows how the fill model calculates the security prices.

Data FormatTickTypeCombo Order DirectionLeg Order DirectionPrice
TickQuoteBuy or sellBuyAsk price
TickQuoteBuy or sellSellBid price
TickTradeBuy or sellBuy or sellTrade price
QuoteBarBuyBuyAsk low price
QuoteBarBuySellBid low price
QuoteBarSellBuyAsk high price
QuoteBarSellSellBid high price
TradeBarBuyBuy or sellLow price
TradeBarSellBuy or sellHigh price

After the fill model calculates the aggregate price of the combo order, it checks if it should fill the order. The following table describes the fill condition of the combo order and the fill price price of each leg:

Data FormatTickTypeCombo Order DirectionFill ConditionLeg Order DirectionFill Price
TickQuoteBuyAggregate price < combo limit priceBuy or sellQuote price
TickQuoteSellAggregate price > combo limit priceBuy or sellQuote price
TickTradeBuyAggregate price < combo limit priceBuy or sellTrade price
TickTradeSellAggregate price > combo limit priceBuy or sellTrade price
QuoteBar
BuyAggregate price < combo limit priceBuyAsk low price
QuoteBar
BuyAggregate price < combo limit priceSellBid low price
QuoteBar
SellAggregate price > combo limit priceBuyAsk high price
QuoteBar
SellAggregate price > combo limit priceSellBid high price
TradeBar
BuyAggregate price < combo limit priceBuy or sellLow price
TradeBar
SellAggregate price > combo limit priceBuy or sellHigh price

The model only fills combo limit orders if the data isn't stale and all the legs can fill in the same time step after the order time step. The fill quantity of each leg is the product of the leg order quantity and the combo order quantity.

Combo Leg Limit Orders

The fill logic of combo leg limit orders depends on the data format of the security subscription and the order direction. The following table shows the fill price of combo leg limit orders given these factors. To determine the fill price of the order, the fill model first checks the most recent tick for the security. If your security subscription doesn't provide tick data, the fill model checks the most recent QuoteBar. If your security subscription doesn't provide quote data, the fill model checks the most recent TradeBar.

The order direction in the table represents the order direction of the order leg, not the order direction of the combo order.

Data FormatTickTypeOrder DirectionFill ConditionFill Price
TickQuoteBuyAsk price < limit pricemin(ask price, limit price)
TickQuoteSellBid price > limit pricemax(bid price, limit price)
TickTradeBuyTrade price < limit pricemin(trade price, limit price)
TickTradeSellTrade price > limit pricemax(trade price, limit price)
QuoteBar
BuyAsk low price < limit pricemin(ask high price, limit price)
QuoteBar
SellBid high price > limit pricemax(bid low price, limit price)
TradeBar
BuyLow price < limit pricemin(high price, limit price)
TradeBar
SellHigh price > limit pricemax(low price, limit price)

The model only fills combo leg limit orders if all the following conditions are met:

  • The exchange is open
  • The data isn't stale
  • All the legs can fill in the same time step after the order time step

The fill quantity is the product of the leg order quantity and the combo order quantity.

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: