QuantConnect/Lean · error · RegressionTestException

{Time} - Unexpected buy order event status: {orderEvent.Stat

Error message

{Time} - Unexpected buy order event status: {orderEvent.Status}

What it means

The order-event handler is a small state machine: a buy fill is only valid as the FIRST fill (when neither a buy nor a sell has been recorded). If _boughtQuantity != 0 AND _liquidatedQuantity != 0, a second buy fill arrived after both legs completed — a duplicate or unexpected re-entry fill that violates the single-buy/single-sell lifecycle.

Source

Thrown at Algorithm.CSharp/BasicTemplateEurexFuturesAlgorithm.cs:127

                    }
                }
            }
        }

        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            if (orderEvent.Symbol != _contractToTrade)
            {
                throw new RegressionTestException($"{Time} - Unexpected order event symbol: {orderEvent.Symbol}. Expected {_contractToTrade}");
            }

            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}");
                    }

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Track fill accumulation (sum partial fills) instead of overwriting _boughtQuantity on every filled event.
  2. Guard against duplicate fills by checking orderEvent.OrderId or a processed-fill set.
  3. Confirm only one Buy(_contractToTrade, 1) call executes (the _boughtQuantity == 0 gate at line 95).
  4. If partial fills are expected, accumulate quantity until OrderStatus.Filled terminal and then record once.

Example fix

// before
if (_boughtQuantity != 0 && _liquidatedQuantity != 0) { throw ...; }
_boughtQuantity = orderEvent.Quantity;

// after: accumulate partial buys, record the buy total once
_boughtQuantity += orderEvent.Quantity;
Defensive patterns

Strategy: validation

Validate before calling

// Accumulate fills instead of overwriting; detect the first buy only
if (orderEvent.Direction == OrderDirection.Buy && orderEvent.Status == OrderStatus.Filled)
{
    _boughtQuantity += orderEvent.Quantity;
}

Prevention

When it happens

Trigger: An OrderDirection.Buy with OrderStatus.Filled arrives when _boughtQuantity is already non-zero and _liquidatedQuantity is already non-zero. Concretely, a duplicate buy fill after the position was already opened and closed.

Common situations: A partial fill followed by another fill that the state machine treats as a second full buy; a re-entry order the algorithm didn't intend; engine fill event duplication during delisting liquidation; order updates/cancels producing extra filled events.

Related errors


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/f0a1fa8ca8092ad1. Report an issue: GitHub.