{"record":{"id":"66b15371ba5b27d2","repo":"microsoft/qlib","slug":"order-direction-cannot-be-none-when-deal-price-typ","errorCode":null,"errorMessage":"Order direction cannot be none when deal_price_type is not close.","messagePattern":"Order direction cannot be none when deal_price_type is not close\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/rl/data/pickle_styled.py","lineNumber":133,"sourceCode":"        # backtest = backtest.droplevel([0, 2])\n\n        self.data: pd.DataFrame = backtest\n        self.deal_price_type: DealPriceType = deal_price\n        self.order_dir = order_dir\n\n    def __repr__(self) -> str:\n        with pd.option_context(\"memory_usage\", False, \"display.max_info_columns\", 1, \"display.large_repr\", \"info\"):\n            return f\"{self.__class__.__name__}({self.data})\"\n\n    def __len__(self) -> int:\n        return len(self.data)\n\n    def get_deal_price(self) -> pd.Series:\n        \"\"\"Return a pandas series that can be indexed with time.\n        See :attribute:`DealPriceType` for details.\"\"\"\n        if self.deal_price_type in (\"bid_or_ask\", \"bid_or_ask_fill\"):\n            if self.order_dir is None:\n                raise ValueError(\"Order direction cannot be none when deal_price_type is not close.\")\n            if self.order_dir == OrderDir.SELL:\n                col = \"$bid0\"\n            else:  # BUY\n                col = \"$ask0\"\n        elif self.deal_price_type == \"close\":\n            col = \"$close0\"\n        else:\n            raise ValueError(f\"Unsupported deal_price_type: {self.deal_price_type}\")\n        price = self.data[col]\n\n        if self.deal_price_type == \"bid_or_ask_fill\":\n            if self.order_dir == OrderDir.SELL:\n                fill_col = \"$ask0\"\n            else:\n                fill_col = \"$bid0\"\n            price = price.replace(0, np.nan).fillna(self.data[fill_col])\n\n        return price","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/rl/data/pickle_styled.py#L115-L151","documentation":"get_deal_price (qlib/rl/data/pickle_styled.py:133) maps deal_price_type to a price column. For 'bid_or_ask' and 'bid_or_ask_fill' the fill price depends on order direction (SELL hits $bid0, BUY hits $ask0), so self.order_dir must be set. If order_dir is None while deal_price_type is one of those two, it raises ValueError('Order direction cannot be none when deal_price_type is not close.'), since no price column can be chosen.","triggerScenarios":"Building an order/data object with deal_price_type='bid_or_ask' (or 'bid_or_ask_fill') but leaving order_dir=None; simulating orders without specifying buy/sell direction against order-book data.","commonSituations":"Adapting the RL order execution workflow where close-price configs are switched to bid/ask without threading the OrderDir through; constructing test orders programmatically and forgetting the direction field.","solutions":["Set order_dir to OrderDir.BUY or OrderDir.SELL when deal_price_type is 'bid_or_ask'/'bid_or_ask_fill'","If direction is genuinely unknown, use deal_price_type='close' which reads $close0 without direction","Fix the order-generation code so every emitted order carries a direction"],"exampleFix":"# before\norder = MyOrder(deal_price_type='bid_or_ask', order_dir=None)\nprice = data.get_deal_price()  # ValueError\n\n# after\nfrom qlib.rl.data import OrderDir\norder = MyOrder(deal_price_type='bid_or_ask', order_dir=OrderDir.BUY)\nprice = data.get_deal_price()","handlingStrategy":"validation","validationCode":"if data.deal_price_type in ('bid_or_ask', 'bid_or_ask_fill'):\n    assert data.order_dir is not None, 'order_dir (OrderDir.BUY/SELL) is required for bid/ask deal prices'","typeGuard":"def has_direction(order) -> bool:\n    return getattr(order, 'order_dir', None) is not None","tryCatchPattern":"try:\n    price = data.get_deal_price()\nexcept ValueError as e:\n    if 'Order direction cannot be none' in str(e):\n        raise ValueError('set order_dir=OrderDir.BUY/SELL or use deal_price_type=\"close\"') from e\n    raise","preventionTips":["Thread order direction through order generation code whenever using book data","Default to deal_price_type='close' when direction is unknown"],"tags":["qlib","rl","order-execution","deal-price","value-error"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}