* security: constrain config-driven code execution * fix: address security test and lint failures * ci: restore dependency and title lint compatibility * ci: handle current MLflow and Windows OSQP changes * ci: use lxml release with cross-platform wheels * fix: defer optional CVXPY solver imports * style: document intentional lazy import * ci: skip broken released OSQP on Windows Python 3.8 * test: make MLflow client timing check robust * ci: retry nondeterministic benchmark smoke test * fix: cap filelock before fork safety regression * fix: use filelock release compatible with multiprocessing * fix(security): restrict operator lookup and validate trusted roots * fix(security): preserve numeric expressions and legacy model imports * fix: preserve TRA initialization and document config migration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: preserve safe expression syntax and cache semantics Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use explicit scoped trust for file modules Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: satisfy CI lint without weakening trust checks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: handle escaped file paths in module refusal errors Match the repr-formatted module path in refusal messages and cover Windows, UNC, quoted, and newline-containing paths on every platform. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: preserve expression parser error logging Log ExpressionSyntaxError with its field and traceback before re-raising, while preserving custom operator NameError and SyntaxError handling. Add five regression cases covering logging, exception identity, and failed cache entries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: isolate expression logger capture Capture parser logs directly on qlib.data without propagating to parent and root capture handlers. Restore logger state with monkeypatch and retain exact single-record, traceback, and exception-identity assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): preserve malformed feature boundaries and reject unsupported literals * test(security): cover malformed dollar-prefixed expressions --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Yang Liu <DG-git-dev@users.noreply.github.com>
Learning Multiple Stock Trading Patterns with Temporal Routing Adaptor and Optimal Transport
Temporal Routing Adaptor (TRA) is designed to capture multiple trading patterns in the stock market data. Please refer to our paper for more details.
If you find our work useful in your research, please cite:
@inproceedings{HengxuKDD2021,
author = {Hengxu Lin and Dong Zhou and Weiqing Liu and Jiang Bian},
title = {Learning Multiple Stock Trading Patterns with Temporal Routing Adaptor and Optimal Transport},
booktitle = {Proceedings of the 27th ACM SIGKDD Conference on Knowledge Discovery \& Data Mining},
series = {KDD '21},
year = {2021},
publisher = {ACM},
}
@article{yang2020qlib,
title={Qlib: An AI-oriented Quantitative Investment Platform},
author={Yang, Xiao and Liu, Weiqing and Zhou, Dong and Bian, Jiang and Liu, Tie-Yan},
journal={arXiv preprint arXiv:2009.11189},
year={2020}
}
Usage (Recommended)
When upgrading, consult the configuration migration guide.
It covers the unreleased source changes, including explicit MODEL_TYPES
registration for custom built-in TRA backbones. Register extensions before model
construction in each worker; source/main/tagged installations may differ.
Update: TRA has been moved to qlib.contrib.model.pytorch_tra to support other Qlib components like qlib.workflow and Alpha158/Alpha360 dataset.
Please follow the official doc to use TRA with workflow. Here we also provide several example config files:
workflow_config_tra_Alpha360.yaml: runningTRAwithAlpha360datasetworkflow_config_tra_Alpha158.yaml: runningTRAwithAlpha158dataset (with feature subsampling)workflow_config_tra_Alpha158_full.yaml: runningTRAwithAlpha158dataset (without feature subsampling)
The performances of TRA are reported in Benchmarks.
Usage (Not Maintained)
This section is used to reproduce the results in the paper.
Running
We attach our running scripts for the paper in run.sh.
Run the commands below from examples/benchmarks/TRA. The legacy configurations
load src/model.py and src/dataset.py, so both task.model and
task.dataset declare top-level trusted: true, alongside class,
module_path, and kwargs. Relative file paths use the current working
directory, not the YAML file. Only use these settings with code and
configurations you trust; consent is not inherited from another component.
If you copied an older configuration, add these per-component booleans and
remove any qlib_init.trusted_module_roots setting from earlier PR revisions.
If you copied example.py, retain full initialization forwarding with
qlib.init(**config["qlib_init"]); it forwards settings, not file-import
permission. See the migration guide
for strict boolean semantics, workers, and independent artifact permissions.
The legacy model_type: LSTM belongs to src/model.py; do not rename it just
because the separate built-in TRA implementation supports RNN and Transformer.
And here are two ways to run the model:
-
Running from scripts with default parameters
You can directly run from Qlib command
qrun:qrun configs/config_alstm.yaml -
Running from code with self-defined parameters
Setting different parameters is also allowed. See codes in
example.py:python example.py --config_file configs/config_alstm.yaml
Here we trained TRA on a pretrained backbone model. Therefore we run *_init.yaml before TRA's scripts.
Results
After running the scripts, you can find result files in path ./output:
info.json- config settings and result metrics.log.csv- running logs.model.bin- the model parameter dictionary.pred.pkl- the prediction scores and output for inference.
Evaluation metrics reported in the paper: This result is generated by qlib==0.7.1.
| Methods | MSE | MAE | IC | ICIR | AR | AV | SR | MDD |
|---|---|---|---|---|---|---|---|---|
| Linear | 0.163 | 0.327 | 0.020 | 0.132 | -3.2% | 16.8% | -0.191 | 32.1% |
| LightGBM | 0.160(0.000) | 0.323(0.000) | 0.041 | 0.292 | 7.8% | 15.5% | 0.503 | 25.7% |
| MLP | 0.160(0.002) | 0.323(0.003) | 0.037 | 0.273 | 3.7% | 15.3% | 0.264 | 26.2% |
| SFM | 0.159(0.001) | 0.321(0.001) | 0.047 | 0.381 | 7.1% | 14.3% | 0.497 | 22.9% |
| ALSTM | 0.158(0.001) | 0.320(0.001) | 0.053 | 0.419 | 12.3% | 13.7% | 0.897 | 20.2% |
| Trans. | 0.158(0.001) | 0.322(0.001) | 0.051 | 0.400 | 14.5% | 14.2% | 1.028 | 22.5% |
| ALSTM+TS | 0.160(0.002) | 0.321(0.002) | 0.039 | 0.291 | 6.7% | 14.6% | 0.480 | 22.3% |
| Trans.+TS | 0.160(0.004) | 0.324(0.005) | 0.037 | 0.278 | 10.4% | 14.7% | 0.722 | 23.7% |
| ALSTM+TRA(Ours) | 0.157(0.000) | 0.318(0.000) | 0.059 | 0.460 | 12.4% | 14.0% | 0.885 | 20.4% |
| Trans.+TRA(Ours) | 0.157(0.000) | 0.320(0.000) | 0.056 | 0.442 | 16.1% | 14.2% | 1.133 | 23.1% |
A more detailed demo for our experiment results in the paper can be found in Report.ipynb.
Common Issues
For help or issues using TRA, please submit a GitHub issue.
Sometimes we might encounter situation where the loss is NaN, please check the epsilon parameter in the sinkhorn algorithm, adjusting the epsilon according to input's scale is important.