microsoft/qlib · error · ValueError

weight_position is {}, weight_position is not in the range o

Error message

weight_position is {}, weight_position is not in the range of (0, 1).

What it means

In Exchange's target-weight order flow, each per-stock weight in weight_position must lie in [0, 1]; a negative weight or a weight above 1 is rejected with ValueError (only tradable stocks are validated). The method then converts weights into share amounts proportional to tradable_weight, so out-of-range weights would produce nonsensical amounts.

Source

Thrown at qlib/backtest/exchange.py:561

        Generates the target position according to the weight and the cash.
        NOTE: All the cash will be assigned to the tradable stock.
        Parameter:
        weight_position : dict {stock_id : weight}; allocate cash by weight_position
            among then, weight must be in this range: 0 < weight < 1
        cash : cash
        start_time : the start time point of the step
        end_time : the end time point of the step
        direction : the direction of the deal price for estimating the amount
                    # NOTE: this function is used for calculating target position. So the default direction is buy
        """

        # calculate the total weight of tradable value
        tradable_weight = 0.0
        for stock_id, wp in weight_position.items():
            if self.is_stock_tradable(stock_id=stock_id, start_time=start_time, end_time=end_time):
                # weight_position must be greater than 0 and less than 1
                if wp < 0 or wp > 1:
                    raise ValueError(
                        "weight_position is {}, " "weight_position is not in the range of (0, 1).".format(wp),
                    )
                tradable_weight += wp

        if tradable_weight - 1.0 >= 1e-5:
            raise ValueError("tradable_weight is {}, can not greater than 1.".format(tradable_weight))

        amount_dict = {}
        for stock_id in weight_position:
            if weight_position[stock_id] > 0.0 and self.is_stock_tradable(
                stock_id=stock_id,
                start_time=start_time,
                end_time=end_time,
            ):
                amount_dict[stock_id] = (
                    cash
                    * weight_position[stock_id]
                    / tradable_weight

View on GitHub (pinned to 79633dd950)

Solutions

  1. Clip weights before calling: {k: min(max(v, 0.0), 1.0) for k, v in weight_position.items()}
  2. If weights are percentages, divide by 100 first
  3. If you intend short positions, note this API does not support them; use positive weights plus cash remainder

Example fix

# before
amounts = exch.get_amount_from_weight({'SH600000': 35.0}, ...)  # percent -> ValueError
# after
weights = {'SH600000': 35.0 / 100}
amounts = exch.get_amount_from_weight(weights, ...)
Defensive patterns

Strategy: validation

Validate before calling

bad = {k: v for k, v in weight_position.items() if not (0.0 <= v <= 1.0)}
assert not bad, f'weights out of [0,1]: {bad}'
weights = {k: min(max(v, 0.0), 1.0) for k, v in weight_position.items()}

Type guard

def weights_in_range(w: dict) -> bool:
    return all(0.0 <= v <= 1.0 for v in w.values())

Prevention

When it happens

Trigger: Passing a weight dict to the amount-from-weights path (get_amount_from_weight / target-weight order creation) containing values like -0.1 or 1.5, or weights expressed in percent (e.g. 30 for 30%).

Common situations: Alpha model outputs unnormalized or signed scores fed directly as weights; percentages not divided by 100; NaN-free but unbounded factor z-scores used as weights.

Related errors


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