Implementation:Shiyu coder Kronos QlibBacktest Usage
| Field | Value |
|---|---|
| implementation_name | QlibBacktest_Usage |
| type | Wrapper Doc (wraps Microsoft Qlib's backtesting framework) |
| repository | https://github.com/shiyu-coder/Kronos |
| source_file | finetune/qlib_test.py:L96-201 |
| implements | Principle:Shiyu_coder_Kronos_Qlib_Backtesting |
| last_updated | 2026-02-09 14:00 GMT |
Summary
The QlibBacktest class wraps Microsoft Qlib's backtesting infrastructure to evaluate model prediction signals through simulated portfolio trading with configurable strategies and cost models.
Class
QlibBacktest
API Signature
QlibBacktest(config: Config) -> QlibBacktest
.run_single_backtest(signal_series: pd.Series) -> pd.DataFrame
.run_and_plot_results(signals: dict[str, pd.DataFrame]) -> None
Import
from qlib_test import QlibBacktest
Dependencies
qlib(Microsoft Qlib framework)qlib.backtest.backtest,qlib.backtest.executor.SimulatorExecutorqlib.contrib.evaluate.risk_analysisqlib.contrib.strategy.TopkDropoutStrategyqlib.utils.time.Freqmatplotlibpandas
External Reference
Wraps: https://github.com/microsoft/qlib
Constructor
def __init__(self, config: Config):
self.config = config
self.initialize_qlib()
The constructor stores the configuration and immediately initializes the Qlib environment via qlib.init(provider_uri=config.qlib_data_path, region=REG_CN).
Methods
run_single_backtest(signal_series)
def run_single_backtest(self, signal_series: pd.Series) -> pd.DataFrame
Runs a single backtest for a given prediction signal.
Input:
signal_series: Apd.Serieswith a MultiIndex(instrument, datetime)containing prediction scores
Strategy configuration:
strategy = TopkDropoutStrategy(
topk=self.config.backtest_n_symbol_hold, # 50
n_drop=self.config.backtest_n_symbol_drop, # 5
hold_thresh=self.config.backtest_hold_thresh, # 5
signal=signal_series,
)
Executor configuration:
executor_config = {
"time_per_step": "day",
"generate_portfolio_metrics": True,
"delay_execution": True,
}
Backtest configuration:
| Parameter | Value | Description |
|---|---|---|
start_time |
config.backtest_time_range[0] |
Backtest start date |
end_time |
config.backtest_time_range[1] |
Backtest end date |
account |
100,000,000 |
Initial capital |
benchmark |
config.backtest_benchmark |
Benchmark index (e.g., SH000300) |
freq |
"day" |
Trading frequency |
limit_threshold |
0.095 |
Price limit (9.5%) |
deal_price |
"open" |
Execution price |
open_cost |
0.001 |
Buy transaction cost (0.1%) |
close_cost |
0.0015 |
Sell transaction cost (0.15%) |
min_cost |
5 |
Minimum transaction cost |
Output: A pd.DataFrame with columns:
cum_bench: Cumulative benchmark returncum_return_w_cost: Cumulative portfolio return with costscum_ex_return_w_cost: Cumulative excess return with costs
Also prints risk analysis to stdout: benchmark return, excess return without cost, excess return with cost.
run_and_plot_results(signals)
def run_and_plot_results(self, signals: dict[str, pd.DataFrame]) -> None
Runs backtests for multiple signals and plots cumulative return curves.
Input:
signals: A dictionary where keys are signal names (e.g.,'mean','last') and values are prediction DataFrames with datetime index and symbol columns
Processing:
- For each signal, converts the DataFrame to a stacked Series with
(instrument, datetime)MultiIndex - Calls
run_single_backtest()for each signal - Aggregates results across signals
Output:
- Generates a two-panel plot saved to
../figures/backtest_result_example.pngat 200 DPI:- Top panel: Cumulative return with cost for each signal, plus benchmark (dashed black line)
- Bottom panel: Cumulative excess return with cost for each signal
Example Usage
from config import Config
from qlib_test import QlibBacktest
config = Config()
backtester = QlibBacktest(config)
# signals is a dict[str, pd.DataFrame] from generate_predictions()
backtester.run_and_plot_results(signals)
Source Reference
File: finetune/qlib_test.py, lines 96-201.