QuantConnect/Lean · error · RegressionTestException

Index is not tradable.

Error message

Index is not tradable.

What it means

Thrown in OnEndOfAlgorithm when Portfolio[Nifty].TotalSaleVolume > 0, meaning the NIFTY50 index received order fills. India market index symbols (NIFTY50) are non-tradable by design — the algorithm trades the JUNIORBEES ETF instead. Any fill on the index itself signals an engine-level tradability defect.

Source

Thrown at Algorithm.CSharp/BasicTemplateIndiaIndexAlgorithm.cs:95

            if (_emaFast > _emaSlow)
            {
                if (!Portfolio.Invested)
                {
                    var marketTicket = MarketOrder(NiftyETF, 1);
                }
            }
            else
            {
                Liquidate();
            }
        }

        public override void OnEndOfAlgorithm()
        {
            if (Portfolio[Nifty].TotalSaleVolume > 0)
            {
                throw new RegressionTestException("Index is not tradable.");
            }
        }

        /// <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 virtual bool CanRunLocally { get; } = true;

        /// <summary>
        /// This is used by the regression test system to indicate which languages this algorithm is written in.
        /// </summary>
        public virtual List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };

        /// <summary>
        /// Data Points count of all timeslices of algorithm
        /// </summary>
        public long DataPoints => 2882;

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Confirm all MarketOrder/Liquidate calls use NiftyETF, never Nifty.
  2. Log Securities[Nifty].IsTradable after Initialize to confirm it is false.
  3. Check the IndiaOrderProperties and brokerage model for Market.India to ensure index fills are blocked.
  4. Review OnData for any code path that passes Nifty to an order method.

Example fix

// before
MarketOrder(Nifty, 1);

// after
MarketOrder(NiftyETF, 1);
Defensive patterns

Strategy: validation

Validate before calling

// Verify NIFTY50 index is non-tradable
if (Securities[Nifty].IsTradable)
{
    Log($"WARNING: {Nifty} is marked tradable");
}
// Confirm ETF is the only traded security
if (Portfolio[NiftyETF].TotalSaleVolume == 0)
{
    Log($"No trades on ETF {NiftyETF} — check OnData logic");
}

Type guard

bool IsIndexNonTradable(Symbol sym) =>
    Securities[sym].Type == SecurityType.Index && !Securities[sym].IsTradable;

Prevention

When it happens

Trigger: Code calls MarketOrder(Nifty, qty) instead of MarketOrder(NiftyETF, qty), the engine sets IsTradable=true for Market.India index securities, or a Liquidate() call targets the Nifty symbol.

Common situations: Using the index symbol instead of the ETF symbol in order calls, India market-hours or security-type handling changes in the engine, or brokerage model updates affecting Market.India tradability.

Related errors


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