Skip to content
All library documents

Qlib LightGBM Pipeline for CSI 300 Stock Ranking

Code Qlib

Summary

This Qlib configuration defines a daily stock-ranking experiment for the CSI 300 universe, using the CSI 300 index as its benchmark. Its features combine price and volume transformations, including residual and fit measures, intraday range, and rolling correlations between returns and volume changes. The label is a forward close-to-close return, and cross-sectional z-score normalization is applied to labels after missing labels are dropped.

A LightGBM gradient-boosted model is trained on an earlier historical segment, validated on a subsequent period, and evaluated on a later test segment. The portfolio layer uses a top-k dropout strategy: it holds a selected group of predictions and replaces only some names at a time. The backtest specifies closing-price execution, transaction costs, a minimum fee, and a price limit threshold, with signal and portfolio analysis records enabled. This is an experiment specification, not a report of results; it does not show returns, robustness checks, or whether the feature and execution assumptions avoid leakage or match live trading.

Key ideas

  • The experiment ranks CSI 300 stocks using daily price and volume features.
  • Its target is a forward close-to-close return and labels receive cross-sectional normalization.
  • LightGBM is trained, validated, and tested on sequential historical date segments.
  • The portfolio strategy holds top-ranked names and periodically replaces a subset.
  • Backtest settings include a benchmark, closing-price fills, transaction costs, and price limits.
  • The configuration provides no evidence of realized performance or live-trading robustness.

Tags

Full text
# workflow_config_lightgbm_configurable_dataset.yaml


```yaml
qlib_init:
    provider_uri: "~/.qlib/qlib_data/cn_data"
    region: cn
market: &market csi300
benchmark: &benchmark SH000300
data_handler_config: &data_handler_config
    start_time: 2008-01-01
    end_time: 2020-08-01
    instruments: *market
    data_loader:
        class: QlibDataLoader
        kwargs:
            config:
                feature:
                    - ["Resi($close, 15)/$close", "Std(Abs($close/Ref($close, 1)-1)*$volume, 5)/(Mean(Abs($close/Ref($close, 1)-1)*$volume, 5)+1e-12)", "Rsquare($close, 5)", "($high-$low)/$open", "Rsquare($close, 10)", "Corr($close, Log($volume+1), 5)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 5)", "Corr($close, Log($volume+1), 10)", "Rsquare($close, 20)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 60)", "Corr($close/Ref($close,1), Log($volume/Ref($volume, 1)+1), 10)", "Corr($close, Log($volume+1), 20)", "(Less($open, $close)-$low)/$open"]
                    - ["RESI5", "WVMA5", "RSQR5", "KLEN", "RSQR10", "CORR5", "CORD5", "CORR10", "RSQR20", "CORD60", "CORD10", "CORR20", "KLOW"]
                label:
                    - ["Ref($close, -2)/Ref($close, -1) - 1"]
                    - ["LABEL0"]
            freq: day

    learn_processors:
        - class: DropnaLabel
        - class: CSZScoreNorm
          kwargs:
            fields_group: label
port_analysis_config: &port_analysis_config
    strategy:
        class: TopkDropoutStrategy
        module_path: qlib.contrib.strategy
        kwargs:
            signal: <PRED>
            topk: 50
            n_drop: 5
    backtest:
        start_time: 2017-01-01
        end_time: 2020-08-01
        account: 100000000
        benchmark: *benchmark
        exchange_kwargs:
            limit_threshold: 0.095
            deal_price: close
            open_cost: 0.0005
            close_cost: 0.0015
            min_cost: 5
task:
    model:
        class: LGBModel
        module_path: qlib.contrib.model.gbdt
        kwargs:
            loss: mse
            colsample_bytree: 0.8879
            learning_rate: 0.2
            subsample: 0.8789
            lambda_l1: 205.6999
            lambda_l2: 580.9768
            max_depth: 8
            num_leaves: 210
            num_threads: 20
    dataset:
        class: DatasetH
        module_path: qlib.data.dataset
        kwargs:
            handler:
                class: DataHandlerLP
                module_path: qlib.data.dataset.handler
                kwargs: *data_handler_config
            segments:
                train: [2008-01-01, 2014-12-31]
                valid: [2015-01-01, 2016-12-31]
                test: [2017-01-01, 2020-08-01]
    record: 
        - class: SignalRecord
          module_path: qlib.workflow.record_temp
          kwargs: 
            model: <MODEL>
            dataset: <DATASET>
        - class: SigAnaRecord
          module_path: qlib.workflow.record_temp
          kwargs: 
            ana_long_short: False
            ann_scaler: 252
        - class: PortAnaRecord
          module_path: qlib.workflow.record_temp
          kwargs: 
            config: *port_analysis_config

```

Shown in full with attribution under the source's licence. Licence: MIT

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.