{"record":{"id":"33b0def3bec06407","repo":"microsoft/qlib","slug":"order-direction-error","errorCode":null,"errorMessage":"order direction {} error","messagePattern":"order direction (.+?) error","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/exchange.py","lineNumber":945,"sourceCode":"                    order.deal_amount = 0\n                    self.logger.debug(f\"Order clipped due to cost higher than cash: {order}\")\n                elif cash < trade_val + max(trade_val * cost_ratio, self.min_cost):\n                    # The money is not enough\n                    max_buy_amount = self._get_buy_amount_by_cash_limit(trade_price, cash, cost_ratio)\n                    order.deal_amount = self.round_amount_by_trade_unit(\n                        min(max_buy_amount, order.deal_amount),\n                        order.factor,\n                    )\n                    self.logger.debug(f\"Order clipped due to cash limitation: {order}\")\n                else:\n                    # The money is enough\n                    order.deal_amount = self.round_amount_by_trade_unit(order.deal_amount, order.factor)\n            else:\n                # Unknown amount of money. Just round the amount\n                order.deal_amount = self.round_amount_by_trade_unit(order.deal_amount, order.factor)\n\n        else:\n            raise NotImplementedError(\"order direction {} error\".format(order.direction))\n\n        trade_val = order.deal_amount * trade_price\n        trade_cost = max(trade_val * cost_ratio, self.min_cost)\n        if trade_val <= 1e-5:\n            # if dealing is not successful, the trade_cost should be zero.\n            trade_cost = 0\n        return trade_price, trade_val, trade_cost\n\n    def get_order_helper(self) -> OrderHelper:\n        if not hasattr(self, \"_order_helper\"):\n            # cache to avoid recreate the same instance\n            self._order_helper = OrderHelper(self)\n        return self._order_helper\n","sourceCodeStart":927,"sourceCodeEnd":959,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/exchange.py#L927-L959","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"# before\norder = Order(sid, 100, 1.0, t0, t1, direction=1)  # fragile literal\n# after\nfrom qlib.backtest.order import Order\norder = Order(sid, 100, 1.0, t0, t1, direction=Order.BUY)","handlingStrategy":"type-guard","validationCode":"from qlib.backtest.order import Order\nassert order.direction in (Order.BUY, Order.SELL), f'bad direction: {order.direction!r}'\nexch.deal_order(order, trade_account=account)","typeGuard":"from qlib.backtest.order import Order\ndef order_direction_valid(order) -> bool:\n    return order.direction in (Order.BUY, Order.SELL)","tryCatchPattern":"try:\n    exch.deal_order(order, trade_account=account)\nexcept NotImplementedError:\n    logger.error('malformed order direction: %r', order.direction)\n    raise","preventionTips":["Create orders via OrderHelper (exch.get_order_helper()) so directions are canonical","Ensure a single qlib version is importable; mixed installs shift Order constants"],"tags":["qlib","exchange","order-direction","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}