Reproducible quantitative-finance research studies, written as compact empirical research notes. Each study is a self-contained folder with an executed Jupyter notebook (readable directly on GitHub, no installation needed), a short README, the figures it produced and machine-readable results.
The studies are built on QuantLab, a research and backtesting platform (data pipeline, execution costs, look-ahead-safe accounting, risk metrics, validation and inference tools). The notebooks reuse QuantLab wherever it already provides a component and keep only the experiment-specific logic local.
Research and educational material only. Nothing here is investment advice, and historical results do not predict future performance.
| Study | Question | Method | Main finding | Links |
|---|---|---|---|---|
| Pairs trading & stationarity | Does ADF filtering actually improve pairs-trading performance out-of-sample? | 92 within-group ETF pairs, 34 walk-forward folds with non-overlapping trading windows (2008–2026), one ADF filter (p < 0.05) vs. no filter applied to one fixed trading rule through QuantLab's next_bar_open accounting, a rule-free, fold-clustered test of OOS stationarity persistence, fold-clustered Fama–MacBeth and paired-Sharpe inference cross-checked with a Newey–West test, a block bootstrap and a two-way clustered regression (quantlab.validation.panel_inference), portfolio-level comparison and seven robustness checks (including the Engle–Granger cointegration test as the filter instead of the residual ADF one) |
No detectable OOS benefit from ADF filtering; mean return difference −0.25 pp per window (p = 0.23), with robustness checks reaching the same qualitative conclusion. | study.ipynb · README |
quant-research-notebooks/
├── README.md
├── LICENSE # MIT
├── requirements.txt # loose dependency spec (QuantLab pinned to a commit)
├── requirements.lock.txt # exact versions used for the committed results (Python 3.13.7)
├── pytest.ini # test discovery and warning filters
├── .github/workflows/ci.yml # unit tests + notebook/artefact consistency checks
├── scripts/check_artefacts.py # the artefact consistency check run by CI
├── .gitignore
└── pairs_trading_stationarity/
├── study.ipynb # the research note (executed, outputs included)
├── README.md # standalone summary of the study
├── study_lib.py # experiment-specific helpers (imports QuantLab)
├── test_study_lib.py # unit tests for the helpers
├── data/cache/ # QuantLab Parquet snapshot of the price data used
├── figures/ # figures produced by the notebook
└── results/ # CSV/Parquet/JSON results and experiment metadata
git clone https://github.com/sefaav/quant-research-notebooks.git
cd quant-research-notebooks
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
pip install -r requirements.lock.txt # exact versions used for the committed results
python -m pytest -q pairs_trading_stationarity
jupyter nbconvert --to notebook --execute --inplace pairs_trading_stationarity/study.ipynbrequirements.lock.txt pins every package to the version used for the committed results (Python
3.13.7; platform-specific packages carry environment markers; no hashes) and pins QuantLab to a commit;
requirements.txt is the loose specification. The price data snapshot is committed, so a rerun is
offline and deterministic; results/metadata.json records the data hash, parameters, seed, the
installed QuantLab commit (read from the package's PEP 610 metadata), Python and dependency versions.
MIT.