microsoft/qlib · error · NotImplementedError

This type of input is not supported

Error message

This type of input is not supported

What it means

In Position._sell_stock, after computing new_cash = trade_val - cost the code routes the proceeds by self._settle_type: ST_CASH goes to position['cash_delay'], ST_NO goes directly to 'cash'. Any other value hits NotImplementedError('This type of input is not supported'). _settle_type is set by settle_start(settle_type), so this fires when settle_start was called with an unrecognized settle type.

Source

Thrown at qlib/backtest/position.py:382

                # decrease the amount of stock
                self.position[stock_id]["amount"] -= trade_amount
                # check if to delete
                if self.position[stock_id]["amount"] < -1e-5:
                    raise ValueError(
                        "only have {} {}, require {}".format(
                            self.position[stock_id]["amount"] + trade_amount,
                            stock_id,
                            trade_amount,
                        ),
                    )

        new_cash = trade_val - cost
        if self._settle_type == self.ST_CASH:
            self.position["cash_delay"] += new_cash
        elif self._settle_type == self.ST_NO:
            self.position["cash"] += new_cash
        else:
            raise NotImplementedError(f"This type of input is not supported")

    def _del_stock(self, stock_id: str) -> None:
        del self.position[stock_id]

    def check_stock(self, stock_id: str) -> bool:
        return stock_id in self.position

    def update_order(self, order: Order, trade_val: float, cost: float, trade_price: float) -> None:
        # handle order, order is a order class, defined in exchange.py
        if order.direction == Order.BUY:
            # BUY
            self._buy_stock(order.stock_id, trade_val, cost, trade_price)
        elif order.direction == Order.SELL:
            # SELL
            self._sell_stock(order.stock_id, trade_val, cost, trade_price)
        else:
            raise NotImplementedError("do not support order direction {}".format(order.direction))

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use only the class constants: position.settle_start(Position.ST_CASH) or Position.ST_NO
  2. If passing the string, use exactly 'cash' or 'None' — note ST_NO is the string 'None', not Python None
  3. Patch settle_start to validate settle_type up front instead of failing later mid-trade

Example fix

# before
position.settle_start(None)        # Python None -> falls through both branches

# after
position.settle_start(Position.ST_NO)  # the string "None"
Defensive patterns

Strategy: validation

Validate before calling

VALID = {Position.ST_CASH, Position.ST_NO}
assert settle_type in VALID, f"settle_type must be one of {VALID}, got {settle_type!r}"

Type guard

def is_valid_settle_type(t: str) -> bool:
    return t in (Position.ST_CASH, Position.ST_NO)

Try / catch

try:
    position.update_order(order, trade_val, cost, trade_price)
except NotImplementedError as e:
    raise ValueError(f"bad settle_type {position._settle_type!r}") from e

Prevention

When it happens

Trigger: Calling position.settle_start(some_type) with some_type not in {'cash', 'None'} and then executing a sell order. The ST_CASH/ST_NO string constants are defined in BasePosition; passing e.g. None (the object) or 'delayed' triggers it.

Common situations: Custom nested executor passing a novel settle_type; passing Python None instead of the string 'None' (ST_NO = 'None' is deliberately a string); typos like 'Cash' or 'CASH'.

Related errors


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