Problem Description
Solution
Based on the QuantConnect LEAN engine architecture, the processing order for a specific time slice is strictly defined.
The specific order for the events you requested is: Order Fills (for non-market orders) $\rightarrow$ Margin Checks $\rightarrow$ Data Events (OnData).
Detailed Event Flow Sequence
When LEAN synchronizes data to create a timeslice, it executes the following steps in this specific order:
- Data & State Updates: The engine updates
SecurityandCashobjects with the latest data prices. - Order Fills (Non-Market): The engine processes fill models for non-market orders (e.g., Limit, Stop). If a price target was hit during this slice, the order is filled here.
- Margin Checks: The engine processes margin calls. If the portfolio is below the maintenance margin, the
on_margin_call_warningoron_margin_callevents are triggered immediately. - Corporate Actions: Dividends, splits, and delistings are processed.
- Data Events: Finally, the
Sliceobject is passed to theon_datamethod in your algorithm.
Why This Order Matters
- Fills before Data: This ensures that if a Limit Order was filled by the price action in the current bar, your
on_datamethod sees the updated portfolio state (cash and holdings) immediately. - Margin before Data: The engine checks for solvency before allowing your strategy to make new decisions based on new data. This prevents an algorithm from opening new positions if it is already facing a margin call.
Full LEAN Event Loop
For a complete context, here is the relevant subset of the execution flow from the documentation:
- Update
Securityobjects with the latest data. - Update
Cashobjects in the CashBook. - Process fill models for non-market orders.
- Submit market-on-open orders for Equity Options (if applicable).
- Process margin calls.
- Perform cash settlement.
- Call
on_securities_changed. - Update consolidators.
- Pass
Dividends,Splits, andDelistingsto their respective event handlers. - Pass the
Sliceto theon_datamethod.
Q&A
When are market orders filled in this sequence?
In Backtesting, market orders are filled synchronously. If you place a market order inside on_data, it is processed immediately, and you will receive the on_order_event before the next line of code in on_data executes (assuming the market is open). In Live Trading, market orders are asynchronous; the fill event will arrive in a future execution loop.
Can I place trades inside on_margin_call?
No, you generally cannot place new entry trades inside on_margin_call. This method is specifically designed for you to return a list of SubmitOrderRequest objects to liquidate positions to satisfy the margin requirement.
Does on_data run if there is no new data?
Yes, if "Fill Forward" is enabled (which is the default setting). The on_data event handler will be triggered regularly with the previous data carried forward, ensuring your logic runs on a consistent heartbeat.