microsoft/qlib · error · ValueError
not found executor
Error message
not found executor
What it means
Raised in OnlineOperator.check when type is not 'SIM' (the only branch that constructs an executor). Practically this means type='YC': it passes the earlier type-in-['SIM','YC'] gate but has no executor implementation on this code path, so the else branch raises. It is effectively dead-end functionality rather than a user input typo — the supported value is 'SIM' only.
Source
Thrown at qlib/contrib/online/operator.py:193
Parameters
----------
date : str (YYYY-MM-DD)
Trade date, that the generated order list will be traded.
path : str
Path to save user account.
type : str
which executor was been used to execute the order list
'SIM': SimulatorExecutor()
"""
if type not in ["SIM", "YC"]:
raise ValueError("type is invalid, {}".format(type))
um, pred_date, trade_date = self.init(self.client, path, date)
for user_id, user in um.users.items():
dates, trade_exchange = prepare(um, trade_date, user_id)
if type == "SIM":
executor = SimulatorExecutor(trade_exchange=trade_exchange)
else:
raise ValueError("not found executor")
# dates[0] is the last_trading_date
if str(dates[0].date()) > str(pred_date.date()):
raise ValueError(
"The account data is not newest! last trading date {}, today {}".format(
dates[0].date(), trade_date.date()
)
)
# load trade info and update account
trade_info = executor.load_trade_info_from_executed_file(
user_path=(pathlib.Path(path) / user_id), trade_date=trade_date
)
score_series = load_score_series((pathlib.Path(path) / user_id), trade_date)
update_account(user.account, trade_info, trade_exchange, trade_date)
portfolio_metrics = user.account.portfolio_metrics.generate_portfolio_metrics_dataframe()
self.logger.info(portfolio_metrics)
um.save_user_data(user_id)
self.logger.info("Update account state {} for {}".format(trade_date, user_id))
View on GitHub (pinned to 79633dd950)
Solutions
- Use type='SIM'.
- If you need a different executor, implement/patch the branch in operator.py to construct it, or call the executor API directly instead of through check().
- Track upstream qlib for a YC executor implementation before relying on that value.
Example fix
# before op.check(date=d, path=p, type="YC") # ValueError: not found executor # after op.check(date=d, path=p, type="SIM")
Defensive patterns
Strategy: type-guard
Validate before calling
if type != "SIM":
raise ValueError("only the 'SIM' executor is implemented in OnlineOperator.check")
op.check(date=d, path=p, type=type) Type guard
def is_implemented_executor(t) -> bool:
return t == "SIM" Prevention
- Treat 'YC' as unsupported until an implementation lands upstream.
- Pin the executor choice in one config constant.
When it happens
Trigger: Calling op.check(..., type='YC') — the second allowed value — which reaches the else branch and raises 'not found executor'.
Common situations: Users following the docstring ('SIM': SimulatorExecutor()) and trying the other whitelisted value; leftover half-implemented executor support in this contrib module.
Related errors
- type is invalid, {}
- atomic executor doesn't support specify `range_limit`
- This type of input is not supported
- trade date is not tradable date
- add date is not tradable date
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/b9525db03c28d554.
Report an issue: GitHub.