microsoft/qlib · error · NotImplementedError
order direction {} error
Error message
order direction {} error What it means
In Exchange._calc_trade_info_by_order, the amount-adjustment branch handles Order.BUY (cash limit, trade-unit rounding) and Order.SELL; reaching the else with any other direction value means the order is malformed, and NotImplementedError is raised. The direction must be the Order.BUY/Order.SELL constants expected by this Exchange version.
Source
Thrown at qlib/backtest/exchange.py:945
order.deal_amount = 0
self.logger.debug(f"Order clipped due to cost higher than cash: {order}")
elif cash < trade_val + max(trade_val * cost_ratio, self.min_cost):
# The money is not enough
max_buy_amount = self._get_buy_amount_by_cash_limit(trade_price, cash, cost_ratio)
order.deal_amount = self.round_amount_by_trade_unit(
min(max_buy_amount, order.deal_amount),
order.factor,
)
self.logger.debug(f"Order clipped due to cash limitation: {order}")
else:
# The money is enough
order.deal_amount = self.round_amount_by_trade_unit(order.deal_amount, order.factor)
else:
# Unknown amount of money. Just round the amount
order.deal_amount = self.round_amount_by_trade_unit(order.deal_amount, order.factor)
else:
raise NotImplementedError("order direction {} error".format(order.direction))
trade_val = order.deal_amount * trade_price
trade_cost = max(trade_val * cost_ratio, self.min_cost)
if trade_val <= 1e-5:
# if dealing is not successful, the trade_cost should be zero.
trade_cost = 0
return trade_price, trade_val, trade_cost
def get_order_helper(self) -> OrderHelper:
if not hasattr(self, "_order_helper"):
# cache to avoid recreate the same instance
self._order_helper = OrderHelper(self)
return self._order_helper
View on GitHub (pinned to 79633dd950)
Solutions
- Construct orders with Order.BUY / Order.SELL from the same qlib package as Exchange
- Use order_helper = exch.get_order_helper() and helper.create(...) so directions are always canonical
- Check for mixed qlib versions: python -c 'import qlib; print(qlib.__version__, qlib.__file__)' and dedupe the environment
Example fix
# before order = Order(sid, 100, 1.0, t0, t1, direction=1) # fragile literal # after from qlib.backtest.order import Order order = Order(sid, 100, 1.0, t0, t1, direction=Order.BUY)
Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.backtest.order import Order
assert order.direction in (Order.BUY, Order.SELL), f'bad direction: {order.direction!r}'
exch.deal_order(order, trade_account=account) Type guard
from qlib.backtest.order import Order
def order_direction_valid(order) -> bool:
return order.direction in (Order.BUY, Order.SELL) Try / catch
try:
exch.deal_order(order, trade_account=account)
except NotImplementedError:
logger.error('malformed order direction: %r', order.direction)
raise Prevention
- Create orders via OrderHelper (exch.get_order_helper()) so directions are canonical
- Ensure a single qlib version is importable; mixed installs shift Order constants
When it happens
Trigger: deal_order on an Order constructed with direction=0, direction='buy', or an Order class/constants imported from a mismatched qlib install (e.g. mixing qlib versions in one environment).
Common situations: Orders deserialized from logs/portfolios and rebuilt with int directions; multiple qlib versions on sys.path so Order.BUY from module A has a different value than executor.py's Order expects; custom Order subclasses overriding direction semantics.
Related errors
- This type of input is not supported
- This type of `limit_threshold` is not supported
- nfs-common is not found, please install it by execute: sudo
- Mount failed: requires sudo or permission denied
- mount {provider_uri} on {mount_path} error! Command error
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/33b0def3bec06407.
Report an issue: GitHub.