Installation#
quantlab needs Python 3.13 or newer and a C++ compiler on the PATH (g++ or clang++):
KunQuant factors compile to native code the first time they run. Linux and macOS are
supported; a GPU is optional.
Install from PyPI#
pip install quantlab-py # or: uv add quantlab-py
pip install 'quantlab-py[all]' # with every optional extra except mosek
The distribution is quantlab-py (quantlab on PyPI is an unrelated project); the package
is imported as quantlab. Importing a component whose extra is missing raises an
ImportError that names the extra:
Extra |
Installs |
Needed by |
|---|---|---|
|
cvxpy |
|
|
pytabkit |
|
|
lightgbm, catboost |
|
|
wandb |
|
|
mlflow-skinny |
|
|
boto3 |
Massive flat-file downloads |
|
cvxpy, mosek |
|
|
every extra above except |
Install from source#
git clone https://github.com/ZhaorongDai/quantlab.git
cd quantlab
uv sync --all-extras
uv creates .venv/, downloads a Python 3.13 interpreter if
none is found, installs the versions pinned in uv.lock with every extra and the dev
group, and installs quantlab in editable mode. The first sync downloads a few gigabytes
(PyTorch, XGBoost, KunQuant, vectorbt). Without --all-extras, uv sync uninstalls the
extras. Run every command through uv run:
uv run python -c "import quantlab, sys; print(sys.version)"
3.13.12 (main, Feb 4 2026, 09:25:39) [GCC 13.3.0]
Check the installation#
uv run python examples/quickstart.py # offline, CPU, under a minute
uv run pytest -n auto # the full suite, offline, several minutes
uv run pytest tests/test_backtest_run.py # one file
uv run pytest -k xgb # one keyword
The quickstart ends with Rebuilt from its run directory, same equity curve: True; the
quickstart page walks through it. The test suite needs no network and no
credentials: every vendor client is faked and every dataset is synthetic.
tests/test_crsp_rebuild_measurements.py runs only when named, with QUANTLAB_DATA_ROOT
pointing at a checkout that holds a real CRSP store.
GPU#
Torch heads (TorchModel subclasses such as
GATsRegressor and MASTERRegressor), RealMLPRegressor, XGBoostRegressor and
XGBTDRegressor train on a CUDA GPU when one is visible and on the CPU otherwise; none uses
Apple MPS unless device="mps" is passed. On Linux the PyPI torch wheel bundles the CUDA
runtime, so an NVIDIA driver is enough. A model trained on a GPU loads and predicts without
one, and the backtester runs on the CPU. The models guide covers
the device and the panel_device / panel_dtype hyperparameters.
uv run python -c "import torch; print(torch.__version__, torch.cuda.is_available())"
macOS: PyTorch and XGBoost in one process#
XGBoost’s macOS wheel links Homebrew’s libomp and PyTorch bundles its own; a process that
loads both crashes or hangs. Force a single OpenMP thread before PyTorch loads, either with
export OMP_NUM_THREADS=1 or at the top of the script, before any other import:
import os
import sys
if sys.platform == "darwin":
os.environ.setdefault("OMP_NUM_THREADS", "1")
tests/conftest.py and examples/quickstart.py do the same. Linux is unaffected.
Credentials and data location#
Every credential comes from an environment variable; none is passed on a command line or written to a config, a run directory or a log. Set only the ones for the vendors you use:
Variable |
Vendor |
|---|---|
|
Sharadar (Nasdaq Data Link) |
|
Massive |
|
Tiingo |
|
Alpaca |
|
WRDS (legacy) |
|
Weights & Biases tracking |
|
MLflow tracking, on a server that asks |
FRED needs no key. Keep the exports in a file outside the repository that you source.
credential_status() reports whether each variable is
set, never its value. With none set:
from quantlab.acquisition.base import DataSourceRegistry
from quantlab.acquisition.registry import credential_status
for source in DataSourceRegistry.all():
print(source.vendor, credential_status(source))
alpaca {'APCA_API_KEY_ID': False, 'APCA_API_SECRET_KEY': False}
fred {}
massive {'MASSIVE_API_KEY': False, 'MASSIVE_S3_ACCESS_KEY_ID': False}
sharadar {'SHARADAR_API_KEY': False}
tiingo {'TIINGO_API_KEY': False}
wrds {'WRDS_USERNAME': False}
QUANTLAB_DATA_DIR sets the data root that raw-download and Zarr paths are derived from.
Without it, a source checkout uses data/ at the repository root and an installed package
uses ~/.quantlab/data.
Experiment tracking#
Nothing is tracked unless a model or backtest config names a tracker.
quantlab.tracking.wandb.WandbTracker (extra wandb; log in with uv run wandb login or
set WANDB_API_KEY) accepts mode="offline" to keep runs under ./wandb and
mode="disabled" to record nothing. quantlab.tracking.mlflow.MlflowTracker (extra
mlflow) takes a tracking_uri: a server or a local file: directory; a sqlite: URI needs
the full mlflow package.