|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Guidance for AI coding agents working in the **factorlasso** repository. |
| 4 | + |
| 5 | +## Project overview |
| 6 | + |
| 7 | +`factorlasso` estimates sparse multi-asset factor models with cell-level sign |
| 8 | +constraints, prior-centred shrinkage, and hierarchical clustering group LASSO (HCGL), |
| 9 | +and assembles the implied factor covariance matrix (Sigma_y = B Sigma_x B' + D). The |
| 10 | +API is scikit-learn compatible (`fit` / `predict` / `score`). |
| 11 | + |
| 12 | +It is the estimation engine behind `optimalportfolios` and the companion code to a |
| 13 | +paper under review at the *Journal of Statistical Software*. Distribution and import |
| 14 | +name `factorlasso`. Licensed **GPL-3.0** (`LICENSE`) — unlike most of the stack, which |
| 15 | +is MIT. |
| 16 | + |
| 17 | +## Ecosystem position |
| 18 | + |
| 19 | +This package is one of eight open-source Python libraries maintained at |
| 20 | +[github.com/ArturSepp](https://github.com/ArturSepp). Before implementing anything |
| 21 | +non-trivial, check whether it already exists in one of these: |
| 22 | + |
| 23 | +| Package | Repository | Purpose | |
| 24 | +|---|---|---| |
| 25 | +| `qis` | QuantInvestStrats | Performance analytics, factsheets, visualisation | |
| 26 | +| `optimalportfolios` | OptimalPortfolios | Portfolio construction and backtesting | |
| 27 | +| `factorlasso` | factorlasso | Sparse factor models and factor covariance estimation | |
| 28 | +| `bbg-fetch` | BloombergFetch | Bloomberg data fetching | |
| 29 | +| `trendfollowing` | TrendFollowingSystems | Trend-following systems: closed-form theory and replication | |
| 30 | +| `goal-based-allocation` | GoalBasedAllocation | Dynamic MV allocation under regime-switching jump-diffusions | |
| 31 | +| `stochvolmodels` | StochVolModels | Stochastic volatility pricing analytics | |
| 32 | +| `vanilla-option-pricers` | VanillaOptionPricers | Vanilla option pricers and implied volatility fitters | |
| 33 | + |
| 34 | +Actual package dependencies within the stack: `optimalportfolios` depends on `qis` |
| 35 | +and `factorlasso`; `trendfollowing` depends on `qis`; `stochvolmodels` has an |
| 36 | +optional `research` extra that pulls in `qis`. The others are independent. |
| 37 | + |
| 38 | +Do not vendor or copy code between these packages. If functionality belongs in a |
| 39 | +sibling package, say so rather than reimplementing it here. |
| 40 | + |
| 41 | +## Repository layout |
| 42 | + |
| 43 | +``` |
| 44 | +factorlasso/ |
| 45 | + lasso_estimator.py main estimator (sklearn-compatible) |
| 46 | + factor_covar.py factor covariance assembly |
| 47 | + sign_constraints.py sign-constraint handling |
| 48 | + cluster_utils.py hierarchical clustering for grouped penalties |
| 49 | + cv.py cross-validation and lambda paths |
| 50 | + ewm_utils.py exponentially weighted moment utilities |
| 51 | +tests/ 23 test modules (top-level, test_*.py) |
| 52 | +benchmarks/ performance benchmarks |
| 53 | +examples/ runnable examples |
| 54 | +papers/jss_2026/ JSS paper source, replication scripts, simulations |
| 55 | +COMPARISON.md empirical comparison against competing packages |
| 56 | +COMPATIBILITY.md scikit-learn compatibility notes |
| 57 | +``` |
| 58 | + |
| 59 | +## Commands |
| 60 | + |
| 61 | +```bash |
| 62 | +pip install -e ".[dev]" # editable install with dev tools |
| 63 | +pytest # full suite (testpaths = tests) |
| 64 | +pytest tests/test_integration.py -v # one module |
| 65 | +pytest --cov=factorlasso --cov-report=term-missing -q # as CI runs it |
| 66 | +ruff check factorlasso/ # lint, as CI runs it |
| 67 | +``` |
| 68 | + |
| 69 | +Optional extras: `dev`, `docs`, `simulations` (for `papers/jss_2026/simulations/`). |
| 70 | +Supported Python is >= 3.10; CI runs 3.11 – 3.14. |
| 71 | + |
| 72 | +## Conventions |
| 73 | + |
| 74 | +- Test files are named `test_*.py` and live in the top-level `tests/` directory. |
| 75 | +- Line length 100 (`ruff`, rules `E`, `F`, `W`, `I`). |
| 76 | +- The estimator follows scikit-learn conventions: constructor parameters are stored |
| 77 | + unmodified, fitted attributes end with a trailing underscore, and `fit` returns |
| 78 | + `self`. `COMPATIBILITY.md` documents what this guarantees — keep it true. |
| 79 | +- Convex problems are expressed with `cvxpy`. |
| 80 | +- Dataclasses carry estimator configuration and result containers. |
| 81 | +- Runtime dependencies are numpy, pandas, scipy, cvxpy and openpyxl. scikit-learn is a |
| 82 | + **dev/test** dependency only: the package is compatible with sklearn but must not |
| 83 | + import it at runtime. |
| 84 | + |
| 85 | +## Constraints — do not do these |
| 86 | + |
| 87 | +- Do not import scikit-learn in package code. Compatibility is achieved by following |
| 88 | + its conventions, not by depending on it. |
| 89 | +- Do not change estimator defaults, penalty scaling, or the sign-constraint logic |
| 90 | + without re-running the replication and comparison material (see below). |
| 91 | +- Do not break the sklearn API contract (`get_params`/`set_params`, trailing-underscore |
| 92 | + fitted attributes) — `COMPATIBILITY.md` and downstream `optimalportfolios` rely on it. |
| 93 | +- Do not relicense or copy code from MIT-licensed sibling packages into this repository |
| 94 | + without checking direction of licence compatibility. |
| 95 | + |
| 96 | +## Replication contract |
| 97 | + |
| 98 | +`papers/jss_2026/` contains the paper source, replication scripts, and the simulation |
| 99 | +harness. Numbers in the paper, in `COMPARISON.md`, and in the JSS submission must |
| 100 | +reproduce exactly. Any change to estimator internals, cross-validation, or covariance |
| 101 | +assembly requires re-running the replication scripts and diffing the output against the |
| 102 | +published tables. Report differences rather than updating the tables to match new |
| 103 | +output. |
| 104 | + |
| 105 | +## Release checklist |
| 106 | + |
| 107 | +A release touches three version locations. All three must agree: |
| 108 | + |
| 109 | +1. `version` in `pyproject.toml` |
| 110 | +2. `version` and `date-released` in `CITATION.cff` |
| 111 | +3. the software BibTeX entry in `README.md` (if it pins a version) |
| 112 | + |
| 113 | +Then: commit, tag `v<version>`, build and publish to PyPI, and cut a GitHub Release |
| 114 | +with the same tag. Do not bump versions as part of an unrelated change, and do not |
| 115 | +publish without the maintainer explicitly asking for a release. |
0 commit comments