Trade Fills

Key Concepts

Introduction

A trade fill is the quantity and price at which your brokerage executes your order in the market. Fill models model how each type of order fills to accurately simulate the behavior of a real brokerage. Fill models determine the price and quantity of your fills, can incorporate spread costs, and work with the slippage model to add slippage into the fill price. If you trade US Equities, our built-in fill models can fill your orders at the official opening and closing auction prices.

Set Models

The brokerage model of your algorithm automatically sets the fill model for each security, but you can override it. To manually set the fill model of a security, call the SetFillModel method on the Security object.

// In Initialize
var security = AddEquity("SPY");
security.SetFillModel(new ImmediateFillModel());
# In Initialize
security = self.AddEquity("SPY")
security.SetFillModel(ImmediateFillModel())

You can also set the fill model in a security initializer. If your algorithm has a dynamic universe, use the security initializer technique. In order to initialize single security subscriptions with the security initializer, call SetSecurityInitializer before you create the subscriptions.

// In Initialize
SetSecurityInitializer(CustomSecurityInitializer);
AddEquity("SPY");

private void CustomSecurityInitializer(Security security)
{
    security.SetFillModel(new ImmediateFillModel());
}
# In Initialize
self.SetSecurityInitializer(self.CustomSecurityInitializer)
self.AddEquity("SPY")

def CustomSecurityInitializer(self, security: Security) -> None:
    security.SetFillModel(ImmediateFillModel())

To view all the pre-built fill models, see Supported Models.

Default Behavior

The brokerage model of your algorithm automatically sets the fill model of each security. The default brokerage model is the DefaultBrokerageModel, which sets the EquityFillModel for Equities and the ImmediateFillModel for all other asset classes.

Model Structure

Fill Models should extend the FillModel class. To implement your own fill model, override the methods in the FillModel class you wish to change. The class has a dedicated method for each order type. The method receives a Security and Order object and returns an OrderEvent object that contains information about the order status, fill quantity, and errors.

public class MyFillModel : FillModel {

    public override OrderEvent MarketFill(Security asset, MarketOrder order) {
        return base.MarketFill(asset, order);
    }

    public override OrderEvent LimitFill(Security asset, LimitOrder order) {
        return base.LimitFill(asset, order);
    }

    public override OrderEvent LimitIfTouchedFill(Security asset, LimitIfTouchOrder order) {
        return base.LimitIfTouchedFill(asset, order);
    }

    public override OrderEvent StopMarketFill(Security asset, StopMarketOrder order) {
        return base.StopMarketFill(asset, order);
    }

    public override OrderEvent StopLimitFill(Security asset, StopLimitOrder order) {
        return base.StopLimitFill(asset, order);
    }

    public override OrderEvent MarketOnOpenFill(Security asset, MarketOnOpenOrder order) {
        return base.MarketOnOpenFill(asset, order);
    }

    public override OrderEvent MarketOnCloseFill(Security asset, MarketOnCloseOrder order) {
        return base.MarketOnCloseFill(asset, order);
    }
}
class MyFillModel(FillModel):

    def MarketFill(self, asset: Security, order: MarketOrder) -> OrderEvent:
        return super().MarketFill(asset, order)

    def LimitFill(self, asse: Securityt, order: LimitOrder) -> OrderEvent:
        return super().LimitFill(asset, order)

    def LimitIfTouchedFill(self, asset: Security, order: LimitIfTouchOrder) -> OrderEvent:
        return super().LimitIfTouchedFill(asset, order)

    def StopMarketFill(self, asset: Security, order: StopMarketOrder) -> OrderEvent:
        return super().StopMarketFill(asset, order)

    def StopLimitFill(self, asset: Security, order: StopLimitOrder) -> OrderEvent:
        return super().StopLimitFill(asset, order)

    def MarketOnOpenFill(self, asset: Security, order: MarketOnOpenOrder) -> OrderEvent:
        return super().MarketOnOpenFill(asset, order)

    def MarketOnCloseFill(self, asset: Security, order: MarketOnCloseOrder) -> OrderEvent:
        return super().MarketOnCloseFill(asset, order)

Partial Fills

In live trading, your orders can partially fill. For example, if you have a buy limit order at the bid price for 100 shares and someone sells 10 shares with a market order, your order is partially filled. In backtests, the pre-built fill models assume orders completely fill. To simulate partial fills in backtests, create a custom fill model.

Stale Fills

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 setting.

Settings.StalePriceTimeSpan = TimeSpan.FromMinutes(10);
self.Settings.StalePriceTimeSpan = timedelta(minutes=10)

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: