Problem Description
Solution
To handle margin warnings in QuantConnect, you utilize the on_margin_call_warning event handler. This method is triggered when your algorithm's remaining margin drops below 5%.
This gives you a specific window of opportunity to reduce leverage (liquidate positions) manually before the brokerage model steps in to force liquidation via the on_margin_call event.
Implementation Strategy
on_margin_call_warning: This is your proactive defense. Inside this method, you should identify positions to close or reduce.on_margin_call: This is the reactive defense (the actual call). It receives a list of orders the broker intends to execute. You can override this to choose specific assets to liquidate, though usually, if you handled the warning correctly, this might not trigger.
Python Code Example
The following algorithm demonstrates how to listen for the warning and liquidate 50% of all positions to restore margin health.
# region imports
from AlgorithmImports import *
# endregion
class MarginManagementAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2020, 1, 1)
self.set_end_date(2021, 1, 1)
self.set_cash(100000)
# Add a security
self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol
# Set leverage high to simulate potential margin issues
self.securities[self.spy].set_leverage(2.0)
def on_data(self, data: Slice):
# Enter a highly leveraged position
if not self.portfolio.invested:
self.set_holdings(self.spy, 2.0)
def on_margin_call_warning(self):
"""
This method is called when there is less than 5% margin remaining.
We use this opportunity to reduce leverage before a forced liquidation.
"""
self.error(f"Margin Warning at {self.time}: Margin remaining < 5%. Reducing positions.")
# Strategy: Liquidate 50% of all currently invested positions to free up buying power
for symbol, holding in self.portfolio.items():
if holding.invested:
# Calculate half of the current quantity (preserving direction)
new_quantity = holding.quantity * 0.5
self.market_order(symbol, -new_quantity)
self.debug(f"Reduced position in {symbol} by 50% to avoid margin call.")
def on_margin_call(self, requests: List[SubmitOrderRequest]) -> List[SubmitOrderRequest]:
"""
This event triggers if the warning action wasn't enough and the broker
needs to force liquidation.
"""
self.debug(f"Official Margin Call at {self.time}. Executing broker requests.")
# You can return 'requests' as is to accept broker's decision,
# or modify them to choose which specific assets to sell.
return requests
Key Components
- Trigger Condition: The
on_margin_call_warningis automatically called by the LEAN engine whenPortfolio.MarginRemainingdrops to a critical level (typically < 5% of total portfolio value). - Execution: Inside the warning, we use
self.market_orderorself.set_holdingsto reduce exposure. In the example above, we reduce the quantity of every holding by half. - Logging: It is best practice to use
self.errororself.loginside this handler so you can see exactly when your strategy came close to blowing up in the backtest logs.
Q&A: Margin Management in QuantConnect
Q: What happens if I don't implement on_margin_call_warning?
A: If you do not implement this method, the algorithm will do nothing when margin gets low. Once the margin requirement is breached, the on_margin_call event will trigger, and the LEAN engine (acting as the broker) will automatically liquidate positions to satisfy the margin requirement, often closing the most losing positions or those with the highest margin usage first.
Q: Can I choose which specific stocks to sell during the actual on_margin_call?
A: Yes. The on_margin_call method receives a list of SubmitOrderRequest objects. You can modify this list (e.g., remove orders for stocks you want to keep and increase the quantity of orders for stocks you want to dump) and return the modified list. However, the total value liquidated must still satisfy the margin deficit.
Q: Does on_margin_call_warning work in Live Trading?
A: Yes, it works in Live Trading exactly as it does in backtesting. However, in live trading, market volatility can be instant. There is a chance the market moves so fast that the account goes from >5% margin to negative margin immediately, skipping the warning and going straight to the margin call.
Q: How is Buying Power calculated for the warning?
A: LEAN models buying power based on the specific brokerage model selected (e.g., Interactive Brokers, Bitfinex). It tracks the maintenance margin requirement of every asset. The warning triggers based on the Portfolio.MarginRemaining property relative to the Portfolio.TotalPortfolioValue.