Transaction Fees

Key Concepts

Introduction

Your orders incur a transaction fee when a brokerage fills them in the market. LEAN uses transaction fee models in backtesting to model the live trading fees you would incur with the strategy. Transaction fee models make backtest results more realistic. To give your backtests the most accurate fees, LEAN contains transaction fee models that model the fee structure of many popular brokerages.

Set Models

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

// In Initialize
var security = AddEquity("SPY");
security.SetFeeModel(new ConstantFeeModel(0));
# In Initialize
security = self.add_equity("SPY")
security.set_fee_model(ConstantFeeModel(0))

You can also set the fee 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 SetSecurityInitializerset_security_initializer before you create the subscriptions.

// In Initialize
SetSecurityInitializer(new MySecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)));

// Outside of the algorithm class
class MySecurityInitializer : BrokerageModelSecurityInitializer
{
    public MySecurityInitializer(IBrokerageModel brokerageModel, ISecuritySeeder securitySeeder)
        : base(brokerageModel, securitySeeder) {}    
    
    public override void Initialize(Security security)
    {
        // First, call the superclass definition
        // This method sets the reality models of each security using the default reality models of the brokerage model
        base.Initialize(security);

        // Next, overwrite some of the reality models        
        security.SetFeeModel(new ConstantFeeModel(0));    
    }
}
# In Initialize
self.set_security_initializer(MySecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices)))

# Outside of the algorithm class
class MySecurityInitializer(BrokerageModelSecurityInitializer):

    def __init__(self, brokerage_model: IBrokerageModel, security_seeder: ISecuritySeeder) -> None:
        super().__init__(brokerage_model, security_seeder)
    def initialize(self, security: Security) -> None:
        # First, call the superclass definition
        # This method sets the reality models of each security using the default reality models of the brokerage model
        super().initialize(security)

        # Next, overwrite some of the reality models        
        security.SetFeeModel(ConstantFeeModel(0))

In live trading, the SetFeeModel method isn't ignored. If we use order helper methods like SetHoldings, the fee model helps to calculate the order quantity. However, the algorithm doesn't update the cash book with the fee from the fee model. The algorithm uses the actual fee from the brokerage to update the cash book.

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

Default Behavior

The brokerage model of your algorithm automatically sets the fill model for each security. The default brokerage model is the DefaultBrokerageModel, which set the ConstantFeeModel with no fees for Forex, CFD, and Crypto assets and sets the InteractiveBrokersFeeModel for the remaining asset classes.

Model Structure

Fee models should extend the FeeModel class. Extensions of the FeeModel class must implement the GetOrderFee method, which receives OrderFeeParameters and returns an OrderFee that represents a cash amount in a currency.

// In the Initialize method, set the fee model
security.SetFeeModel(new MyFeeModel());

// Define the custom fee model
public class MyFeeModel : FeeModel 
{
    public override OrderFee GetOrderFee(OrderFeeParameters parameters) 
    {
        return new OrderFee(new CashAmount(0.5m, "USD"));
    }
}
# In the Initialize method, set the fee model
security.set_fee_model(MyFeeModel())

# Define the custom fee model
class MyFeeModel(FeeModel):

    def get_order_fee(self, parameters: OrderFeeParameters) -> OrderFee:
        return OrderFee(CashAmount(0.5, 'USD'))

For a full example algorithm, see this backtestthis backtest.

The OrderFeeParameters object has the following members:

Negative Transaction Fees

If you short a security and receive interest payments, they are negative transaction fees.

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: