microsoft/qlib · error · ValueError
direction {direction} is not supported!
Error message
direction {direction} is not supported! What it means
Exchange.check_stock_limit(stop_time...) queries the limit_buy/limit_sell quote fields based on the requested direction: None checks either side, Order.BUY checks limit_buy, Order.SELL checks limit_sell. Any other value for direction cannot select a field, so ValueError is raised. Order.BUY/Order.SELL are integers (1/-1), so arbitrary ints or strings fail.
Source
Thrown at qlib/backtest/exchange.py:376
-------
True: the trading of the stock is limited (maybe hit the highest/lowest price), hence the stock is not tradable
False: the trading of the stock is not limited, hence the stock may be tradable
"""
# NOTE:
# **all** is used when checking limitation.
# For example, the stock trading is limited in a day if every minute is limited in a day if every minute is limited.
if direction is None:
# The trading limitation is related to the trading direction
# if the direction is not provided, then any limitation from buy or sell will result in trading limitation
buy_limit = self.quote.get_data(stock_id, start_time, end_time, field="limit_buy", method="all")
sell_limit = self.quote.get_data(stock_id, start_time, end_time, field="limit_sell", method="all")
return bool(buy_limit or sell_limit)
elif direction == Order.BUY:
return cast(bool, self.quote.get_data(stock_id, start_time, end_time, field="limit_buy", method="all"))
elif direction == Order.SELL:
return cast(bool, self.quote.get_data(stock_id, start_time, end_time, field="limit_sell", method="all"))
else:
raise ValueError(f"direction {direction} is not supported!")
def check_stock_suspended(
self,
stock_id: str,
start_time: pd.Timestamp,
end_time: pd.Timestamp,
) -> bool:
"""if stock is suspended(hence not tradable), True will be returned"""
# is suspended
if stock_id in self.quote.get_all_stock():
# suspended stocks are represented by None $close stock
# The $close may contain NaN,
close = self.quote.get_data(stock_id, start_time, end_time, "$close")
if close is None:
# if no close record exists
return True
elif isinstance(close, IndexData):
# **any** non-NaN $close represents trading opportunity may existView on GitHub (pinned to 79633dd950)
Solutions
- Pass direction=None (either-side check), Order.BUY (=1), or Order.SELL (=-1)
- Import Order/OrderDir from the same qlib version as the Exchange: from qlib.backtest.exchange import Exchange, OrderDir
- If direction comes from an order object, pass order.direction directly rather than re-encoding it
Example fix
# before tradable = exch.is_stock_tradable(sid, t0, t1, direction='buy') # after from qlib.backtest.exchange import Order tradable = exch.is_stock_tradable(sid, t0, t1, direction=Order.BUY)
Defensive patterns
Strategy: validation
Validate before calling
from qlib.backtest.order import Order assert direction is None or direction in (Order.BUY, Order.SELL) exch.is_stock_tradable(sid, t0, t1, direction=direction)
Type guard
def is_valid_direction(d) -> bool:
from qlib.backtest.order import Order
return d is None or d in (Order.BUY, Order.SELL) Prevention
- Never pass strings like 'buy'; use Order.BUY/Order.SELL constants
- Forward order.direction instead of re-encoding direction values
When it happens
Trigger: is_stock_tradable(stock_id, start, end, direction=0), direction='buy', or passing an OrderDir-like enum from a different/older qlib version with different values.
Common situations: Custom strategies passing direction as a string; mixing qlib versions where Order.BUY/SELL constants or OrderDir enum members were imported from mismatched modules.
Related errors
- Get Unexpected arguments {kwargs}
- This type of input {rtype} is not supported
- This type of input is not supported
- $close is necessray in extra_quote
- This type of `limit_threshold` is not supported
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/c748c0f9ac896cba.
Report an issue: GitHub.