Alpha158 Improvement Case
This case compares the adapted Qlib Alpha158 baseline, two added risk factors, and a rank-retention strategy. For controls and independent confirmation, see experiment design.
This page retains one experiment group run on machine 45 on 2026-10-10 from commit 8fc1174: Alpha158, risk factors, and 3-day rank retention. Both models rerun ETL, training, prediction and backtesting from the same data snapshot; the strategy reuses the new factor-model predictions. Buy/sell fees are 0.05% / 0.15%; all other parameters retain the existing settings. Plugin READMEs describe algorithms and interfaces.
Shared settings
| Setting | Value |
|---|---|
| Data / universe | Tushare; Shanghai/Shenzhen excluding Beijing; 11,446,950 rows, 5,477 stocks; 158 / 171 ETL features; min_history_coverage=0.8. |
| Training / labels | [20150101,20230101); label_return_rank; trim_tail=0.025; label_winsorize_tail=0.025; validation_ratio=0.10; cutoff-crossing labels excluded. |
| Samples / validation | refit=5,838,557; tuning=5,010,901; validation=823,601; validation_start=20220316 |
| Model | parameter_preset=axonx; learning_rate=0.03; num_leaves=31; max_depth=-1; min_data_in_leaf=20; bagging_fraction=0.9; bagging_freq=1; lambda_l1=lambda_l2=0; random_seed=42; num_threads=8. |
| Training rounds | num_boost_round=1000; early_stopping_rounds=50; select by validation L2, then refit all training rows. |
| Prediction / evaluation | pred_start=20230101; pred_end=20261008; as_of_date=20261008; 909 market dates; top_ns=[20,30]; index_codes=[]; minimum_index_weight_coverage=0.98. |
| Fees / annualization | buy_cost_rate=0.0005; sell_cost_rate=0.0015; no minimum monetary fee; annualization_days=252; annual_risk_free_rate=0.012. |
| Execution | Same-close quote proxy; sells before buys; no substitution for unfilled targets; no final forced liquidation; shared base ETL market/calendar/labels. |
Scheme settings
| Scheme | Features | context_groups | feature_fraction | Best rounds | Validation RankIC | Exit |
|---|---|---|---|---|---|---|
| Alpha158 | 158 | — | 0.9 | 422 | 0.10789 | holding_days=1 |
| Risk factors | 160 | risk | 1.0 | 426 | 0.11321 | holding_days=1 |
| 3-day strategy | 160 | risk | 1.0 | 426 | 0.11321 | minimum_holding_days=3 |
The strategy uses replacement_fraction=0.2 and rank_buffer=1: at most 4/6 filled orders per side daily for Top20/Top30, with initial construction exempt. The factor model selects only the two risk features; context_windows=[10] does not change their fixed horizons.
Metric definitions
IC/RankIC average daily Pearson/Spearman correlations of eligible signal-date predictions and valid next-day labels. RankICIR is mean daily RankIC / sample standard deviation × sqrt(252). Net returns compound and annualize over 252 trading days; net Sharpe subtracts the daily risk-free return. Drawdown includes initial equity 1 in the running peak. Turnover and costs normalize by prior equity.
Universe mean equally weights valid forward-label returns; HS300 is a constituent-weighted proxy requiring 98% weight coverage. Net active return subtracts the daily benchmark from portfolio net return; net IR is its mean / sample standard deviation × sqrt(252). Active annualization and drawdown use compounded active returns on shared benchmark-valid dates.
Overall signals and Top20
| Metric | Alpha158 | Risk factors | 3-day strategy |
|---|---|---|---|
| Overall IC | 0.0530 | 0.0545 | 0.0545 |
| Overall RankIC | 0.0923 | 0.0966 | 0.0966 |
| Overall RankICIR (annualized) | 12.8817 | 14.2859 | 14.2859 |
| Net annualized | 7.67% | 9.03% | 32.37% |
| Net cumulative return | 30.56% | 36.60% | 174.99% |
| Net Sharpe | 0.3619 | 0.4052 | 1.1575 |
| Net annualized volatility | 28.20% | 28.53% | 26.19% |
| Max drawdown | -38.65% | -40.69% | -24.91% |
| Daily return win rate | 53.47% | 53.47% | 55.89% |
| Mean daily two-sided turnover | 198.83% | 199.35% | 40.01% |
| Mean daily cost / prior equity | 0.1989% | 0.1994% | 0.0400% |
| Closed trades | 18,032 | 18,079 | 3,624 |
| Net active annualized vs universe mean | -3.50% | -1.88% | 18.64% |
| Net IR vs universe mean | -0.1422 | -0.0665 | 1.4543 |
| Net active max drawdown vs universe mean | -28.51% | -21.71% | -18.63% |
| Net active annualized vs HS300 proxy | 2.74% | 4.07% | 26.04% |
| Net IR vs HS300 proxy | 0.2340 | 0.2936 | 1.2697 |
| Net active max drawdown vs HS300 proxy | -31.94% | -29.37% | -23.96% |
Top30
| Scheme | Net annualized | Net Sharpe | Max drawdown | Turnover | Net IR: universe | Net IR: HS300 |
|---|---|---|---|---|---|---|
| Alpha158 | 0.97% | 0.1308 | -40.60% | 199.02% | -0.5956 | -0.0792 |
| Risk factors | 4.25% | 0.2472 | -41.41% | 199.37% | -0.4265 | 0.0822 |
| 3-day strategy | 29.30% | 1.0884 | -25.53% | 40.03% | 1.4081 | 1.1909 |
Top20 yearly annualized returns
| Year | Days | Alpha158 | Risk factors | 3-day strategy |
|---|---|---|---|---|
| 2023 | 242 | -9.13% | -10.06% | 9.71% |
| 2024 | 242 | 5.06% | 10.52% | 17.73% |
| 2025 | 243 | 48.57% | 56.63% | 72.52% |
| 2026 | 182 | -9.31% | -14.73% | 39.42% |
Limits
This run evaluates the three fixed configurations, without candidate reselection or an independent confirmation window. Base/factor feature_fraction is 0.9/1.0, so differences do not isolate the added factors. 2026 is a partial year and fills use same-close quotes. All three backtests report incomplete_market_data; missing quotes can delay exits and retain stale marks.
These results compare AxonX plugin configurations, not the original Qlib benchmark. Data, labels, training, and execution differ; see differences from original Qlib.
Reproduce
Fix one data snapshot; retain Task/Run IDs and wait for success before downstream submission. Use the same --target for remote commands. Run fixed-holding backtests once for base and once for factor predictions; use qlib_a158_backtest for the base model.
# Base model: 158 features
axonx submit --task qlib_a158_etl --input-dir '<same_data_snapshot>' --start-date 20150101 --end-date 20261008
axonx submit --task qlib_a158_train --source-tasks '<base_etl_task_id>' \
--train-start 20150101 --train-end 20230101 --label-column label_return_rank \
--parameter-preset axonx --feature-fraction 0.9 --random-seed 42 --num-threads 8
axonx submit --task qlib_a158_predict --source-tasks '<base_train_task_id>' \
--pred-start 20230101 --pred-end 20261008
# Final factor model: 158 base + 2 risk features
axonx submit --task qlib_factor_etl --input-dir '<same_data_snapshot>' --start-date 20150101 --end-date 20261008
axonx submit --task qlib_factor_train --source-tasks '<factor_etl_task_id>' \
--train-start 20150101 --train-end 20230101 --label-column label_return_rank \
--parameter-preset axonx --context-groups risk --context-windows '[10]' \
--feature-fraction 1.0 --random-seed 42 --num-threads 8
axonx submit --task qlib_factor_predict --source-tasks '<factor_train_task_id>' \
--pred-start 20230101 --pred-end 20261008
# Fixed holding: run once for base and once for factor predictions
axonx submit --task qlib_factor_backtest --source-tasks '<factor_predict_task_id>' \
--top-ns '[20,30]' --holding-days 1 --buy-cost-rate 0.0005 --sell-cost-rate 0.0015 \
--as-of-date 20261008 --annualization-days 252 --annual-risk-free-rate 0.012 \
--market-file '<base_etl_market_path>' --calendar-file '<base_etl_calendar_path>' \
--labels-file '<base_etl_labels_path>'
# Strategy version: reuse factor predictions with the selected 3-day policy
axonx submit --task qlib_strategy_backtest --source-tasks '<factor_predict_task_id>' \
--top-ns '[20,30]' --minimum-holding-days 3 \
--replacement-fraction 0.2 --rank-buffer 1 --buy-cost-rate 0.0005 --sell-cost-rate 0.0015 \
--as-of-date 20261008 --annualization-days 252 --annual-risk-free-rate 0.012 \
--market-file '<base_etl_market_path>' --calendar-file '<base_etl_calendar_path>' \
--labels-file '<base_etl_labels_path>'Task provenance
Execution workspace: /nas/jinli.yl/data/axon on machine 45. Raw artifacts remain there; only this run group is listed.
| Stage | Task ID | Run ID |
|---|---|---|
| base_etl | etl#qlib_a158_etl#fees-1010-base-etl | 41fb603467ac4e78acc68294ae7d2699 |
| base_train | train#qlib_a158_train#fees-1010-base-train | eff2152ad9a244cb95a91f834e41a33a |
| base_predict | predict#qlib_a158_predict#fees-1010-base-predict | c9eaa50835004b9284897e5f2ad001e6 |
| base_backtest | backtest#qlib_a158_backtest#fees-1010-base-backtest | b7ca108ed67a4ef4b38968f0770430bc |
| factor_etl | etl#qlib_factor_etl#fees-1010-factor-etl | 1d17d053b24b4e58b2175184372ea718 |
| factor_train | train#qlib_factor_train#fees-1010-factor-train | c3ec05d4cbac4905b5603d9d6d2b07b1 |
| factor_predict | predict#qlib_factor_predict#fees-1010-factor-predict | f541bb3b20eb406fb9dfb5c9c4f705a4 |
| factor_backtest | backtest#qlib_factor_backtest#fees-1010-factor-backtest | 3d0a9f5a718a4bb4a6f14873cad8e8ad |
| strategy_backtest | backtest#qlib_strategy_backtest#fees-1010-strategy-backtest | 51c8cf5fca3d47cf95c6f4965e0c0302 |
| Shared input | SHA-256 |
|---|---|
| market | 5416cdf28fdd8bfb0280afa5d080fd7db0c6e50b82373cd024e910229c8dbc17 |
| calendar | b8048084ff1abafa81b97af01a58b7c8addf96fb061b7898127035e61408e731 |
| labels | 52e832db44e3a961942c7d6e485b355378dea081c8b53ca34cf01aa2b1d0bda6 |
All backtests share these input digests; factor and strategy share predictions. Core/plugin versions: 0.1.1/0.2.0; Python 3.12.14, Polars 1.44.2, LightGBM 4.7.0.