microsoft/qlib · error · ValueError

Unsupported policy type: {type(policy)}.

Error message

Unsupported policy type: {type(policy)}.

What it means

ValueError in `PWStrategy`-style RL strategy setup (qlib/rl/order_execution/strategy.py:500). The `policy` argument must be either a dict config (instantiated via `init_instance_by_config` after qlib injects obs_space/action_space/network) or a `BasePolicy` instance. Any other type — string, lambda, nn.Module, numpy array — is rejected.

Source

Thrown at qlib/rl/order_execution/strategy.py:500

                        "obs_space": self._state_interpreter.observation_space,
                    }
                )
                network_inst = init_instance_by_config(network)
            else:
                network_inst = network

            policy["kwargs"].update(
                {
                    "obs_space": self._state_interpreter.observation_space,
                    "action_space": self._action_interpreter.action_space,
                    "network": network_inst,
                }
            )
            self._policy = init_instance_by_config(policy)
        elif isinstance(policy, BasePolicy):
            self._policy = policy
        else:
            raise ValueError(f"Unsupported policy type: {type(policy)}.")

        if self._policy is not None:
            self._policy.eval()

    def reset(self, outer_trade_decision: BaseTradeDecision | None = None, **kwargs: Any) -> None:
        super().reset(outer_trade_decision=outer_trade_decision, **kwargs)

    def _generate_trade_details(self, act: np.ndarray, exec_vols: List[float]) -> pd.DataFrame:
        assert hasattr(self.outer_trade_decision, "order_list")

        trade_details = []
        for a, v, o in zip(act, exec_vols, getattr(self.outer_trade_decision, "order_list")):
            trade_details.append(
                {
                    "instrument": o.stock_id,
                    "datetime": self.trade_calendar.get_step_time()[0],
                    "freq": self.trade_calendar.get_freq(),
                    "rl_exec_vol": v,

View on GitHub (pinned to 79633dd950)

Solutions

  1. If using config-based init, pass a dict like `{"class": "PPOPolicy", "module": "qlib.rl.order_execution.policy"}` (kwargs obs_space/action_space/network are injected automatically).
  2. If constructing manually, build a `BasePolicy` subclass instance first and pass that object.
  3. Check `isinstance(policy, BasePolicy)` before strategy init in your own glue code to fail early with a clearer message.

Example fix

// before
strategy = MyRLStrategy(policy="ppo")  // string not supported
// after
strategy = MyRLStrategy(policy={"class": "PPOPolicy", "module": "qlib.rl.order_execution.policy"})
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.rl.utils.config import init_instance_by_config  # conceptually
from qlib.model.base import Base as _QlibBase  # placeholder; use real BasePolicy import
from tianshou.policy import BasePolicy

def check_policy(policy):
    assert isinstance(policy, (dict, BasePolicy)), f"policy must be dict config or BasePolicy, got {type(policy)}"

Type guard

def is_supported_policy(p) -> bool:
    from tianshou.policy import BasePolicy
    return isinstance(p, (dict, BasePolicy)) and not isinstance(p, (str, list, tuple))

Try / catch

try:
    strategy = MyRLStrategy(policy=policy_cfg)
except ValueError as e:
    if "Unsupported policy type" in str(e):
        raise ValueError("wrap policy as dict config or BasePolicy instance") from e
    raise

Prevention

When it happens

Trigger: Passing `policy="ppo"`, a bare torch module, or a partially constructed policy object to the RL executor strategy config; passing a list/tuple of configs; passing a tianshou policy that is not a qlib/tianshou `BasePolicy` subclass.

Common situations: YAML/JSON workflow configs where policy is given as a plain string class name instead of `{class: ..., module: ...}` dict; users trying to plug in a raw PyTorch net where a policy wrapper is required; version drift where the policy base class moved between tianshou releases.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/7049e57a447e872d. Report an issue: GitHub.