Reality Modeling

Margin Calls

Introduction

If the value of your portfolio falls below the maintenance margin, you receive a margin call. If you receive a margin call, you either need to add more capital to your brokerage account or the brokerage will liquidate some of your holdings to reduce your exposure and their risk. A margin call model monitors the margin levels of your portfolio, issues margin call warnings, and submits orders when margin calls occur.

Set Models

To set the margin call model, set the MarginCallModel property of the Portfolioportfolio object.

// In Initialize
Portfolio.MarginCallModel = new DefaultMarginCallModel(Portfolio, DefaultOrderProperties);
# In Initialize
self.portfolio.margin_call_model = DefaultMarginCallModel(self.portfolio, self.default_order_properties)

Default Behavior

The brokerage model of your algorithm automatically sets the margin call model for the portfolio. The default brokerage model is the DefaultBrokerageModel, which sets the DefaultMarginCallModel. The DefaultMarginCallModel issues margin call warnings when the margin remaining in your portfolio is less than or equal to 5% of the total portfolio value. When a margin call occurs, this model sorts the generated margin call orders in ascending order by their unrealized profit and then executes each order synchronously until your portfolio is within the margin requirements.

Model Structure

Margin call models must extend the DefaultMarginCallModel class. Extensions of the DefaultMarginCallModel class can override the GetMarginCallOrders and ExecuteMarginCall methods.

The GetMarginCallOrders method scans the portfolio and the updated data for a potential margin call situation that may get the holdings below zero. The method must return a list of SubmitOrderRequest objects that represent the margin call orders. To issue a margin call warning during this method, set the issueMarginCallWarning argument of the method to true.

The ExecuteMarginCall method receives the list of SubmitOrderRequest objects from the GetMarginCallOrders method, executes some of them, and returns a list of OrderTicket objects.

// In the Initialize method, set the margin call model
Portfolio.MarginCallModel = new MyMarginCallModel(Portfolio, DefaultOrderProperties);

// Define the custom margin call model  
public class MyMarginCallModel : DefaultMarginCallModel
{
    public MyMarginCallModel(
        SecurityPortfolioManager portfolio,
        IOrderProperties defaultOrderProperties)
        : base(portfolio, defaultOrderProperties)
    {
    }

    public override List<OrderTicket> ExecuteMarginCall(
        IEnumerable<SubmitOrderRequest> generatedMarginCallOrders)
    {
        return base.ExecuteMarginCall(generatedMarginCallOrders);
    }

    public List<SubmitOrderRequest> GetMarginCallOrders(out bool issueMarginCallWarning)
    {
        return base.GetMarginCallOrders(out issueMarginCallWarning);
    }
}
# In the Initialize method, set the margin call model
self.Portfolio.MarginCallModel = MyMarginCallModel(self.Portfolio, self.DefaultOrderProperties)
        
# Define the custom margin call model        
class MyMarginCallModel(DefaultMarginCallModel):
    def __init__(self,
         portfolio: SecurityPortfolioManager,
         defaultOrderProperties: IOrderProperties):
        super().__init__(portfolio, defaultOrderProperties)

    def ExecuteMarginCall(self,
         generatedMarginCallOrders: List[SubmitOrderRequest]) -> List[OrderTicket]:
        return super().ExecuteMarginCall(generatedMarginCallOrders)

    def GetMarginCallOrders(self,
         issueMarginCallWarning: bool) -> List[SubmitOrderRequest]:
        return super().GetMarginCallOrders(issueMarginCallWarning)

For a full example algorithm, see this backtestthis backtest.

Disable Margin Calls

To disable margin calls, set the margin call model to the NullMarginCallModel.

Portfolio.MarginCallModel = MarginCallModel.Null;
self.portfolio.margin_call_model = MarginCallModel.NULL

Monitor Margin Call Events

When the margin call model of your portfolio issues a margin call warning, we notify your algorithm through the OnMarginCallWarningon_margin_call_warning event handler.

public override void OnMarginCallWarning()
{
    Debug("Warning: Close to margin call");
}
def on_margin_call_warning(self) -> None:
    self.debug(f"Warning: Close to margin call")

Before we send the orders that the margin call model produces, we notify your algorithm through the OnMarginCallon_margin_call event handler. This notification gives your algorithm a chance to liquidate some positions or modify the margin call orders. To modify the orders, adjust the list of SubmitOrderRequest objects the event handler receives.

public override void OnMarginCall(List<SubmitOrderRequest> requests)
{
    for (var i = 0; i < requests.Count; i++)
    {
        var order = requests[i];
        // liquidate an extra 10% each time you get a margin call to give yourself more padding
        var newQuantity = (int)(order.Quantity * 1.1m);
        requests[i] = new SubmitOrderRequest(order.OrderType, order.SecurityType, 
                                            order.Symbol, newQuantity, order.StopPrice, 
                                            order.LimitPrice, 0, Time, "OnMarginCall");
    }
}
def on_margin_call(self, requests: List[SubmitOrderRequest]) -> List[SubmitOrderRequest]:
    for i, order in enumerate(requests):
        # liquidate an extra 10% each time you get a margin call to give yourself more padding
        new_quantity = int(order.quantity * 1.1)
        requests[i] = SubmitOrderRequest(order.order_type, order.security_type, 
                                        order.symbol, new_quantity, order.stop_price, 
                                        order.limit_price, 0, self.time, "OnMarginCall")
    return requests

Submit Order Request

If you receive a margin call or create a margin call model, you'll need to work with SubmitOrderRequest objects. These objects have the following properties:

The following table describes the arguments of the SubmitOrderRequest constructor:

ArgumentData TypeDescriptionDefault Value
orderTypeOrderTypeThe order type to be submitted
securityTypeSecurityTypeThe security type of the asset
symbolSymbolThe symbol to be traded
quantitydecimalfloatThe number of units to order
stopPricedecimalfloatThe stop price for stop orders
limitPricedecimalfloatThe limit price for limit orders
triggerPricedecimalfloatThe trigger price for limit if touched orders
timeDateTimedatetimeThe time this request was created
tagstringstrA custom tag for this request
propertiesIOrderPropertiesThe order properties for this requestnullNone

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: