microsoft/qlib · error · ValueError
Order direction cannot be none when deal_price_type is not c
Error message
Order direction cannot be none when deal_price_type is not close.
What it means
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.
Source
Thrown at qlib/rl/data/pickle_styled.py:133
# backtest = backtest.droplevel([0, 2])
self.data: pd.DataFrame = backtest
self.deal_price_type: DealPriceType = deal_price
self.order_dir = order_dir
def __repr__(self) -> str:
with pd.option_context("memory_usage", False, "display.max_info_columns", 1, "display.large_repr", "info"):
return f"{self.__class__.__name__}({self.data})"
def __len__(self) -> int:
return len(self.data)
def get_deal_price(self) -> pd.Series:
"""Return a pandas series that can be indexed with time.
See :attribute:`DealPriceType` for details."""
if self.deal_price_type in ("bid_or_ask", "bid_or_ask_fill"):
if self.order_dir is None:
raise ValueError("Order direction cannot be none when deal_price_type is not close.")
if self.order_dir == OrderDir.SELL:
col = "$bid0"
else: # BUY
col = "$ask0"
elif self.deal_price_type == "close":
col = "$close0"
else:
raise ValueError(f"Unsupported deal_price_type: {self.deal_price_type}")
price = self.data[col]
if self.deal_price_type == "bid_or_ask_fill":
if self.order_dir == OrderDir.SELL:
fill_col = "$ask0"
else:
fill_col = "$bid0"
price = price.replace(0, np.nan).fillna(self.data[fill_col])
return priceView on GitHub (pinned to 79633dd950)
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
Example fix
# before order = MyOrder(deal_price_type='bid_or_ask', order_dir=None) price = data.get_deal_price() # ValueError # after from qlib.rl.data import OrderDir order = MyOrder(deal_price_type='bid_or_ask', order_dir=OrderDir.BUY) price = data.get_deal_price()
Defensive patterns
Strategy: validation
Validate before calling
if data.deal_price_type in ('bid_or_ask', 'bid_or_ask_fill'):
assert data.order_dir is not None, 'order_dir (OrderDir.BUY/SELL) is required for bid/ask deal prices' Type guard
def has_direction(order) -> bool:
return getattr(order, 'order_dir', None) is not None Try / catch
try:
price = data.get_deal_price()
except ValueError as e:
if 'Order direction cannot be none' in str(e):
raise ValueError('set order_dir=OrderDir.BUY/SELL or use deal_price_type="close"') from e
raise Prevention
- Thread order direction through order generation code whenever using book data
- Default to deal_price_type='close' when direction is unknown
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unsupported deal_price_type: {self.deal_price_type}
- Unrecognized data shape: {shape}
- Multiple paths are found with prefix '{filename_without_suff
- This type of input {rtype} is not supported
- Get Unexpected arguments {kwargs}
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/66b15371ba5b27d2.
Report an issue: GitHub.