Settlement
Key Concepts
Introduction
After you trade an asset, the brokerage needs to settle the funds in your account. The most common type of settlement is immediate, where the funds are immediately available for trading after the transaction. In some cases, you may have delayed settlement, where you sell an asset and need to wait a few days to spend the cash you receive from the sale. A settlement model simulates these settlement rules.
Set Models
The brokerage model of your algorithm automatically sets the settlement model for each security, but you can override it. To manually set the settlement model of a security, call the SetSettlementModel
set_settlement_model
method on the Security
object.
public override void Initialize() { var security = AddEquity("SPY"); // Set a delayed settlement model that settles 7 days after the trade at 8 AM // This can better mimic actual settlement of some brokerage, providing more realistic fund and margin available security.SetSettlementModel(new DelayedSettlementModel(7, TimeSpan.FromHours(8))); }
def initialize(self) -> None: security = self.add_equity("SPY") # Set a delayed settlement model that settles 7 days after the trade at 8 AM # This can better mimic actual settlement of some brokerage, providing more realistic fund and margin available security.set_settlement_model(DelayedSettlementModel(7, timedelta(hours=8)))
You can also set the settlement model in a security initializer. If your algorithm has a universe, use the security initializer technique. In order to initialize single security subscriptions with the security initializer, call SetSecurityInitializer
set_security_initializer
before you create the subscriptions.
public class BrokerageModelExampleAlgorithm : QCAlgorithm { public override void Initialize() { // In the Initialize method, set the security initializer to seed initial the prices and models of assets. SetSecurityInitializer(new MySecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices))); } } public 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.SetSettlementModel(new DelayedSettlementModel(7, TimeSpan.FromHours(8))); } }
class BrokerageModelExampleAlgorithm(QCAlgorithm): def initialize(self) -> None: # In the Initialize method, set the security initializer to seed initial the prices and models of assets. 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.set_settlement_model(DelayedSettlementModel(7, timedelta(hours=8)))
To view all the pre-built settlement models, see Supported Models.
Default Behavior
The brokerage model of your algorithm automatically sets the settlement model for each security. The default brokerage model is the DefaultBrokerageModel
, which sets the settlement model based on the security type and your account type. The following table shows how it sets the settlement models:
Security Type | Account Type | Settlement Model |
---|---|---|
Equity | Cash | DelayedSettlementModel with the default settlement rules |
Option | Cash | DelayedSettlementModel with the default settlement rules |
Future | Any | FutureSettlementModel |
For all other cases, the DefaultBrokerageModel
uses the ImmediateSettlementModel.
The default delayed settlement rule for US Equity trades is T+2 at 8 AM Eastern Time (ET). For example, if you sell on Monday, the trade settles on Wednesday at 8 AM. The default delayed settlement rule for Future and Option contracts is T+1 at 8 AM.
Model Structure
Settlement models must extend the ISettlementModel
interface. Extensions of the ISettlementModel
interface must implement the Scan
scan
and ApplyFunds
apply_funds
methods. The Scan
scan
method is automatically called at the top of each hour and it receives a ScanSettlementModelParameters
object. The ApplyFunds
apply_funds
method receives an ApplyFundsSettlementModelParameters
object and applies the settlement rules. The ApplyFunds
apply_funds
method is also automatically called, but its frequency depends on the security type. The ApplyFunds
apply_funds
method is automatically called when you fill an order for the following security types:
- Equity
- Equity Options
- Crypto
- Forex
- Future Options
- Index Options
The ApplyFunds
apply_funds
method is automatically called when you close a position for the following security types:
- Futures
- Crypto Futures
- CFD
public class CustomSettlementModelExampleAlgorithm : QCAlgorithm { public override void Initialize() { var security = AddEquity("SPY"); // Set the custom settlement model of the selected security to reflect actual scenario for more realistic margin available security.SetSettlementModel(new MySettlementModel()); } } // Define the custom settlement model outside of the algorithm public class MySettlementModel : ISettlementModel { public void ApplyFunds(ApplyFundsSettlementModelParameters applyFundsParameters) { var currency = applyFundsParameters.CashAmount.Currency; var amount = applyFundsParameters.CashAmount.Amount; applyFundsParameters.Portfolio.CashBook[currency].AddAmount(amount); } public void Scan(ScanSettlementModelParameters settlementParameters) { } public CashAmount GetUnsettledCash() { return new CashAmount(0, "USD"); } }
class CustomSettlementModelExampleAlgorithm(QCAlgorithm): def initialize(self) -> None: security = self.add_equity("SPY") # Set the custom settlement model of the selected security to reflect actual scenario for more realistic margin available security.set_settlement_model(MySettlementModel()) # Define the custom settlement model outside of the algorithm class MySettlementModel: def apply_funds(self, applyFundsParameters: ApplyFundsSettlementModelParameters) -> None: currency = applyFundsParameters.cash_amount.currency amount = applyFundsParameters.cash_amount.amount applyFundsParameters.portfolio.cash_book[currency].add_amount(amount) def scan(self, settlementParameters: ScanSettlementModelParameters) -> None: pass def get_unsettled_cash(self) -> CashAmount: return CashAmount(0, 'USD')
For a full example algorithm, see this backtestthis backtest.
ApplyFundsSettlementModelParameters
objects have the following properties:
ScanSettlementModelParameters
objects have the following properties:
You likely don't need to create a custom settlement model because the supported models already implement immediate and delayed settlement rules.