microsoft/qlib · error · ValueError

{limit[0]} is not supported

Error message

{limit[0]} is not supported

What it means

Volume-limit rules (volume_threshold on Exchange) are tuples whose first element selects the rule: 'current' limits by a quote field summed over the current bar range, 'cum' limits by cumulative volume minus already-dealt amount. Any other first element raises ValueError. Each rule's remaining elements name the quote field (and the dealt-amount bookkeeping uses dealt_order_amount).

Source

Thrown at qlib/backtest/exchange.py:825

                limit_value = self.quote.get_data(
                    order.stock_id,
                    order.start_time,
                    order.end_time,
                    field=limit[1],
                    method="sum",
                )
                vol_limit_num.append(cast(float, limit_value))
            elif limit[0] == "cum":
                limit_value = self.quote.get_data(
                    order.stock_id,
                    order.start_time,
                    order.end_time,
                    field=limit[1],
                    method="ts_data_last",
                )
                vol_limit_num.append(limit_value - dealt_order_amount[order.stock_id])
            else:
                raise ValueError(f"{limit[0]} is not supported")
        vol_limit_min = min(vol_limit_num)
        orig_deal_amount = order.deal_amount
        order.deal_amount = max(min(vol_limit_min, orig_deal_amount), 0)
        if vol_limit_min < orig_deal_amount:
            self.logger.debug(f"Order clipped due to volume limitation: {order}, {list(zip(vol_limit_num, vol_limit))}")

        return None

    def _get_buy_amount_by_cash_limit(self, trade_price: float, cash: float, cost_ratio: float) -> float:
        """return the real order amount after cash limit for buying.
        Parameters
        ----------
        trade_price : float
        cash : float
        cost_ratio : float

        Return
        ----------

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use rule prefix 'current': (('current', '$volume', 0.2),) style tuples where limit[1] is a $-field summed over the order window
  2. Use 'cum' for cumulative-style caps based on a running field minus dealt amount
  3. Double-check spelling and that volume_threshold is a tuple of tuples

Example fix

# before
exch = Exchange(volume_threshold=(('total', '$volume', 0.2),))
# after
exch = Exchange(volume_threshold=(('current', '$volume', 0.2),))
Defensive patterns

Strategy: validation

Validate before calling

for limit in volume_threshold or ():
    assert isinstance(limit, tuple) and limit[0] in ('current', 'cum'), \
        f"bad volume limit rule: {limit}"
exch = Exchange(volume_threshold=volume_threshold)

Type guard

def vol_rules_valid(rules) -> bool:
    return all(isinstance(r, tuple) and r[0] in ('current', 'cum') for r in (rules or ()))

Prevention

When it happens

Trigger: volume_threshold=(('total', '$volume', 0.2),) or (('avg', ...),); also misspelling 'current'/'cum' or passing bare strings/floats (an assert on tuple also guards shape).

Common situations: Writing custom volume-limit expressions without following the nested-tuple schema; older examples using a different rule vocabulary.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/7195d8ec8f7b6129. Report an issue: GitHub.