QuantConnect/Lean · error · RegressionTestException
{Time} - Unexpected sell order event status: {orderEvent.Sta
Error message
{Time} - Unexpected sell order event status: {orderEvent.Status} What it means
The sell-leg invariant: a sell fill is only valid when a prior buy exists (_boughtQuantity > 0) and no sell has been recorded yet (_liquidatedQuantity == 0). If _boughtQuantity <= 0 and _liquidatedQuantity != 0, a sell fill arrived without a preceding buy or after liquidation already happened — an out-of-sequence or duplicate sell fill.
Source
Thrown at Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs:138
if (orderEvent.Direction == OrderDirection.Buy)
{
if (orderEvent.Status == OrderStatus.Filled)
{
if (_boughtQuantity != 0 && _liquidatedQuantity != 0)
{
throw new RegressionTestException($"{Time} - Unexpected buy order event status: {orderEvent.Status}");
}
_boughtQuantity = orderEvent.Quantity;
}
}
else if (orderEvent.Direction == OrderDirection.Sell)
{
if (orderEvent.Status == OrderStatus.Filled)
{
if (_boughtQuantity <= 0 && _liquidatedQuantity != 0)
{
throw new RegressionTestException($"{Time} - Unexpected sell order event status: {orderEvent.Status}");
}
_liquidatedQuantity = orderEvent.Quantity;
if (_liquidatedQuantity != -_boughtQuantity)
{
throw new RegressionTestException($"{Time} - Unexpected liquidated quantity: {_liquidatedQuantity}. Expected: {-_boughtQuantity}");
}
}
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
foreach (var addedSecurity in changes.AddedSecurities)
{
if (addedSecurity.Symbol.SecurityType == SecurityType.Future && addedSecurity.Symbol.IsCanonical())
{
_mappedSymbol = _continuousContract.Mapped;View on GitHub (pinned to d2c3659f87)
Solutions
- Verify the buy fill was recorded (_boughtQuantity > 0) before any sell is expected — check event ordering.
- Accumulate sell fills instead of treating each as the sole liquidation.
- Confirm delisting liquidation fires only once (no duplicate sell events).
- If using OnOrderEvent for a sell that can legitimately precede state, restructure the state machine to allow it.
Example fix
// before
if (_boughtQuantity <= 0 && _liquidatedQuantity != 0) { throw ...; }
// after: tolerate liquidation that arrives without a recorded buy (e.g. engine-forced)
_liquidatedQuantity += orderEvent.Quantity; Defensive patterns
Strategy: validation
Validate before calling
if (orderEvent.Direction == OrderDirection.Sell && orderEvent.Status == OrderStatus.Filled)
{
_liquidatedQuantity += orderEvent.Quantity;
} Prevention
- Verify a buy fill was recorded before expecting a sell.
- Accumulate sell fills into a running total.
- Confirm delisting liquidation fires once.
When it happens
Trigger: An OrderDirection.Sell with OrderStatus.Filled arrives while _boughtQuantity <= 0 and _liquidatedQuantity != 0 — e.g. a delisting liquidation sell when the buy was never recorded, or a second sell fill after liquidation.
Common situations: The buy fill event was missed/not recorded so _boughtQuantity stays 0 when the liquidation sell fires; delisting auto-liquidation emits a sell before the buy event was processed; a duplicate liquidation sell after the position is already closed.
Related errors
- {Time} - Unexpected buy order event status: {orderEvent.Stat
- {Time} - Unexpected liquidated quantity: {_liquidatedQuantit
- {Time} - Portfolio should not be invested after the traded c
- {Time} - Unexpected order event symbol: {orderEvent.Symbol}.
- Unexpected sold quantity: {_boughtQuantity} and liquidated q
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/7854bcee726f7f3c.
Report an issue: GitHub.