QuantConnect/Lean · error · RegressionTestException

Total Profit: Expected {_sumOfDividends}. Actual {Portfolio.

Error message

Total Profit: Expected {_sumOfDividends}. Actual {Portfolio.TotalProfit}

What it means

OnEndOfAlgorithm asserts Portfolio.TotalProfit equals _sumOfDividends (the accumulated Distribution * holdings.Quantity across all OnDividends calls). Because the algorithm uses DataNormalizationMode.Raw and only holds SPY, all profit should come from dividend cash payments — no price P&L is expected from trading. A mismatch means dividend accounting diverged from realized profit.

Source

Thrown at Algorithm.CSharp/DividendRegressionAlgorithm.cs:79

        /// </summary>
        /// <param name="dividends">Data.</param>
        public override void OnDividends(Dividends dividends) // update this to Dividends dictionary
        {
            var dividend = dividends[_symbol];
            var holdings = Portfolio[_symbol];
            Debug($"{dividend.Time.ToStringInvariant("o")} >> DIVIDEND >> {dividend.Symbol} - " +
                $"{dividend.Distribution.ToStringInvariant("C")} - {Portfolio.Cash} - " +
                $"{holdings.Price.ToStringInvariant("C")}"
            );
            _sumOfDividends += dividend.Distribution * holdings.Quantity;
        }
        
        public override void OnEndOfAlgorithm()
        {
            // The expected value refers to sum of dividend payments
            if (Portfolio.TotalProfit != _sumOfDividends)
            {
                throw new RegressionTestException($"Total Profit: Expected {_sumOfDividends}. Actual {Portfolio.TotalProfit}");
            }

            var expectNetProfit = _sumOfDividends - Portfolio.TotalFees;
            if (Portfolio.TotalNetProfit != expectNetProfit)
            {
                throw new RegressionTestException($"Total Net Profit: Expected {expectNetProfit}. Actual {Portfolio.TotalNetProfit}");
            }

            if (Portfolio[_symbol].TotalDividends != _sumOfDividends)
            {
                throw new RegressionTestException($"{_symbol} Total Dividends: Expected {_sumOfDividends}. Actual {Portfolio[_symbol].TotalDividends}");
            }
        }

        /// <summary>
        /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
        /// </summary>
        public bool CanRunLocally { get; } = true;

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Confirm AddEquity uses DataNormalizationMode.Raw — other modes factor dividends into price adjustments instead of cash.
  2. Verify SetHoldings is called once and the position is held continuously (no extra trades generating P&L).
  3. Log each dividend Distribution and holdings.Quantity to recompute _sumOfDividends and compare to Portfolio.TotalProfit.
  4. Check for a Lean regression in dividend cash application to Portfolio.TotalProfit.
Defensive patterns

Strategy: validation

Validate before calling

public override void OnEndOfAlgorithm()
{
    if (Portfolio.TotalProfit != _sumOfDividends)
    {
        Debug($"TotalProfit={Portfolio.TotalProfit} sumOfDividends={_sumOfDividends}");
        // check for unexpected trades generating P&L
        foreach (var t in Transactions.Orders)
            Debug($"Order: {t.Key} {t.Value}");
    }
}

Prevention

When it happens

Trigger: TotalProfit includes unexpected trading P&L (e.g., the position was bought/sold at different prices), a dividend distribution was applied but not reflected in cash, or a Lean change in how Raw-mode dividends hit Portfolio.TotalProfit.

Common situations: Switching away from DataNormalizationMode.Raw (which changes dividend handling), a Lean version change in dividend cash application, or partial fills / re-entry creating unexpected cost-basis P&L.

Related errors


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