{"record":{"id":"de1ab8e5e986f1ea","repo":"microsoft/qlib","slug":"this-type-of-input-is-not-supported-de1ab8","errorCode":null,"errorMessage":"This type of input is not supported","messagePattern":"This type of input is not supported","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/exchange.py","lineNumber":164,"sourceCode":"\n        # TODO: the quote, trade_dates, codes are not necessary.\n        # It is just for performance consideration.\n        self.limit_type = self._get_limit_type(limit_threshold)\n        if limit_threshold is None:\n            if C.region in [REG_CN, REG_TW]:\n                self.logger.warning(f\"limit_threshold not set. The stocks hit the limit may be bought/sold\")\n        elif self.limit_type == self.LT_FLT and abs(cast(float, limit_threshold)) > 0.1:\n            if C.region in [REG_CN, REG_TW]:\n                self.logger.warning(f\"limit_threshold may not be set to a reasonable value\")\n\n        if isinstance(deal_price, str):\n            if deal_price[0] != \"$\":\n                deal_price = \"$\" + deal_price\n            self.buy_price = self.sell_price = deal_price\n        elif isinstance(deal_price, (tuple, list)):\n            self.buy_price, self.sell_price = cast(Tuple[str, str], deal_price)\n        else:\n            raise NotImplementedError(f\"This type of input is not supported\")\n\n        if isinstance(codes, str):\n            codes = D.instruments(codes)\n        self.codes = codes\n        # Necessary fields\n        # $close is for calculating the total value at end of each day.\n        # - if $close is None, the stock on that day is regarded as suspended.\n        # $factor is for rounding to the trading unit\n        # $change is for calculating the limit of the stock\n\n        # 　get volume limit from kwargs\n        self.buy_vol_limit, self.sell_vol_limit, vol_lt_fields = self._get_vol_limit(volume_threshold)\n\n        necessary_fields = {self.buy_price, self.sell_price, \"$close\", \"$change\", \"$factor\", \"$volume\"}\n        if self.limit_type == self.LT_TP_EXP:\n            assert isinstance(limit_threshold, tuple)\n            for exp in limit_threshold:\n                necessary_fields.add(exp)","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/exchange.py#L146-L182","documentation":"Exchange normalizes deal_price into $-prefixed column names: a str becomes both buy and sell price (e.g. 'close' -> '$close'), and a tuple/list of two strings becomes (buy_price, sell_price). Any other Python type (int, float, dict, None mishandled, pd.Series) cannot name a quote column, so __init__ raises NotImplementedError.","triggerScenarios":"Exchange(deal_price=0.98), Exchange(deal_price=('close',)), or passing a DataFrame/Series of prices instead of a column name; also deal_price loaded from YAML as a non-string scalar.","commonSituations":"Confusing deal_price (a quote field name like 'close' or 'vwap') with an actual numeric price; configs where deal_price ends up as None after a lookup fails; tuples with the wrong arity.","solutions":["Pass a single column name string: Exchange(deal_price='close') -> uses $close for both sides","Or pass a 2-tuple of strings: Exchange(deal_price=('buy_vwap', 'sell_vwap'))","Validate config-loaded values before constructing: assert isinstance(deal_price, (str, tuple, list))"],"exampleFix":"# before\nexch = Exchange(deal_price=('close', 'vwap', 'open'))  # wrong arity/type combos\n# after\nexch = Exchange(deal_price=('close', 'vwap'))","handlingStrategy":"type-guard","validationCode":"assert isinstance(deal_price, (str, tuple, list)), 'deal_price must be str or (buy, sell) strings'\nif isinstance(deal_price, (tuple, list)):\n    assert len(deal_price) == 2 and all(isinstance(p, str) for p in deal_price)\nexch = Exchange(deal_price=deal_price)","typeGuard":"def is_valid_deal_price(p) -> bool:\n    if isinstance(p, str):\n        return True\n    return isinstance(p, (tuple, list)) and len(p) == 2 and all(isinstance(x, str) for x in p)","tryCatchPattern":null,"preventionTips":["Remember deal_price names a quote column ('close', 'vwap'), not a number","Assert the type when deal_price comes from config files"],"tags":["qlib","exchange","deal-price","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}