{"record":{"id":"41d5ce0179e48e38","repo":"microsoft/qlib","slug":"direction-not-supported-order-sell-for-sell-o","errorCode":null,"errorMessage":"direction not supported, `Order.SELL` for sell, `Order.BUY` for buy","messagePattern":"direction not supported, `Order\\.SELL` for sell, `Order\\.BUY` for buy","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/decision.py","lineNumber":85,"sourceCode":"    # What the value should be about in all kinds of cases\n    # - not tradable: the deal_amount == 0 , factor is None\n    #    - the stock is suspended and the entire order fails. No cost for this order\n    # - dealt or partially dealt: deal_amount >= 0 and factor is not None\n    deal_amount: float = 0.0  # `deal_amount` is a non-negative value\n    factor: Optional[float] = None\n\n    # TODO:\n    # a status field to indicate the dealing result of the order\n\n    # FIXME:\n    # for compatible now.\n    # Please remove them in the future\n    SELL: ClassVar[OrderDir] = OrderDir.SELL\n    BUY: ClassVar[OrderDir] = OrderDir.BUY\n\n    def __post_init__(self) -> None:\n        if self.direction not in {Order.SELL, Order.BUY}:\n            raise NotImplementedError(\"direction not supported, `Order.SELL` for sell, `Order.BUY` for buy\")\n        self.deal_amount = 0.0\n        self.factor = None\n\n    @property\n    def amount_delta(self) -> float:\n        \"\"\"\n        return the delta of amount.\n        - Positive value indicates buying `amount` of share\n        - Negative value indicates selling `amount` of share\n        \"\"\"\n        return self.amount * self.sign\n\n    @property\n    def deal_amount_delta(self) -> float:\n        \"\"\"\n        return the delta of deal_amount.\n        - Positive value indicates buying `deal_amount` of share\n        - Negative value indicates selling `deal_amount` of share","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/decision.py#L67-L103","documentation":"DatasetURICache/IndexManager.sync_to_disk (qlib/data/cache.py:815) persists the in-memory cache index to an HDF5 .index file; it refuses when self._data is None, i.e. no index was ever loaded (sync_from_disk was not called / no data was set). This prevents writing an empty/garbage index file that would masquerade as a valid cache index.","triggerScenarios":"Constructing IndexManager(cache_path) and calling sync_to_disk() before get_index()/sync_from_disk()/update() has populated _data; typically in custom code driving the dataset-URI index, or a code path where sync_from_disk found no '/df' key (empty DataFrame case still sets _data, so the None case means load was skipped entirely).","commonSituations":"Custom maintenance scripts touching qlib's cache index; edge flows where a fresh cache directory has no .index file yet and the caller tries to write before any read/update.","solutions":["Call index_manager.get_index(...) or sync_from_disk() first so _data is populated, then sync_to_disk()","Or use IndexManager.update(data, sync=True) which sets _data then syncs in one step","If the .index file does not exist yet, generate the cache (DatasetCache.update / gen_dataset_cache) through public APIs instead of hand-driving IndexManager"],"exampleFix":"# before\nim = IndexManager(cache_path)\nim.sync_to_disk()  # ValueError: No data to sync to disk.\n\n# after\nim = IndexManager(cache_path)\nidx = im.get_index()      # triggers sync_from_disk, populates _data\nim.sync_to_disk()","handlingStrategy":"validation","validationCode":"im = IndexManager(cache_path)\nif im._data is None:\n    im.sync_from_disk()  # or im.get_index() — populates _data first\nim.sync_to_disk()","typeGuard":"def index_ready(im) -> bool:\n    return im._data is not None","tryCatchPattern":"try:\n    im.sync_to_disk()\nexcept ValueError as e:\n    if \"No data to sync\" in str(e):\n        im.sync_from_disk()\n        im.sync_to_disk()\n    else:\n        raise","preventionTips":["Drive cache index updates through public DatasetCache APIs, not IndexManager directly","Always read (get_index/sync_from_disk) or update() before sync_to_disk","Guard custom maintenance scripts with an _data is not None check"],"tags":["qlib","disk-cache","hdf5","index","internal-api"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}