Skip to content

Commit 5679eec

Browse files
committed
docs: align README positioning and feedback
1 parent b8342b0 commit 5679eec

3 files changed

Lines changed: 80 additions & 79 deletions

File tree

CITATION.cff

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ references:
5050
family-names: Hansen
5151
- given-names: Mika
5252
family-names: Kastenholz
53-
title: "Capital Market Assumptions Using Multi-Asset Tradable Factors: The MATF-CMA Framework"
53+
title: "Capital Market Assumptions and Strategic Asset Allocation Using Multi-Asset Tradable Factors"
5454
journal: "Journal of Portfolio Management"
5555
year: 2026
5656
notes: "Methodology paper documenting the framework in which factorlasso is deployed; forthcoming."
@@ -70,17 +70,6 @@ references:
7070
end: 120
7171
year: 2026
7272
url: "https://eprints.pm-research.com/17511/143431/index.html"
73-
- type: article
74-
authors:
75-
- given-names: Artur
76-
family-names: Sepp
77-
- given-names: Emilie
78-
family-names: Hansen
79-
- given-names: Mika
80-
family-names: Kastenholz
81-
title: "Capital Market Assumptions and Strategic Asset Allocation Using Multi-Asset Tradable Factors"
82-
journal: "Journal of Portfolio Management, forthcoming"
83-
year: 2026
8473
- type: article
8574
authors:
8675
- given-names: Sourav

README.md

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
# factorlasso
22

3+
**`factorlasso` estimates sparse multi-output factor models with sign constraints, prior-centred
4+
shrinkage, data-driven grouped penalties, and consistent factor covariance assembly.**
5+
6+
It provides LASSO, Hierarchical Clustering Group LASSO (HCGL), Factor-Clustering Group LASSO
7+
(FCGL), sparse-group, UniLasso, and cooperative penalties through auditable CVXPY formulations.
8+
9+
**Install:** `pip install factorlasso` · **Import:** `factorlasso` · **Status:** Beta
10+
311
[![PyPI](https://img.shields.io/pypi/v/factorlasso?style=flat-square)](https://pypi.org/project/factorlasso/)
412
[![Python](https://img.shields.io/pypi/pyversions/factorlasso?style=flat-square)](https://pypi.org/project/factorlasso/)
5-
[![License](https://img.shields.io/github/license/ArturSepp/factorlasso.svg?style=flat-square)](LICENSE)
613
[![CI](https://github.com/ArturSepp/factorlasso/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ArturSepp/factorlasso/actions/workflows/ci.yml)
714
[![Docs](https://readthedocs.org/projects/factorlasso/badge/?version=latest)](https://factorlasso.readthedocs.io/en/latest/)
15+
[![License: GPL-3.0-or-later](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg?style=flat-square)](LICENSE)
816
[![Downloads](https://static.pepy.tech/badge/factorlasso)](https://pepy.tech/project/factorlasso)
917
[![Monthly](https://static.pepy.tech/badge/factorlasso/month)](https://pepy.tech/project/factorlasso)
1018

11-
**`factorlasso` is a Python library for sparse multi-output factor-model estimation with sign
12-
constraints, prior-centred shrinkage, data-driven grouped penalties, and consistent factor
13-
covariance assembly.**
14-
15-
It provides LASSO, Hierarchical Clustering Group LASSO (HCGL), Factor-Clustering Group LASSO
16-
(FCGL), sparse-group, UniLasso, and cooperative penalties through auditable CVXPY formulations.
17-
1819
**Paper:** Sepp, A. and Kastenholz, M. (2026), *factorlasso: Hierarchical
1920
Clustering Group LASSO (HCGL) with Cluster-Pooled Sign Derivation for
2021
Multi-Asset Factor Models in Python*, submitted to the *Journal of Statistical
@@ -68,6 +69,49 @@ It is written in pure numpy/pandas/scipy/cvxpy. No numba, no custom
6869
coordinate descent. The solver is CVXPY (default `CLARABEL`), so problem
6970
formulation is explicit and auditable.
7071

72+
## Installation
73+
74+
```bash
75+
pip install factorlasso
76+
```
77+
78+
Requires Python ≥ 3.10, CVXPY ≥ 1.3, and numpy / pandas / scipy / openpyxl.
79+
80+
## Five-minute quickstart
81+
82+
```python
83+
import numpy as np
84+
import pandas as pd
85+
from factorlasso import LassoModel, LassoModelType
86+
87+
rng = np.random.default_rng(0)
88+
T, M, N = 200, 4, 10
89+
X = pd.DataFrame(rng.standard_normal((T, M)), columns=[f"f{i}" for i in range(M)])
90+
Y = pd.DataFrame(rng.standard_normal((T, N)), columns=[f"y{i}" for i in range(N)])
91+
92+
model = LassoModel(model_type=LassoModelType.LASSO, reg_lambda=1e-5).fit(x=X, y=Y)
93+
94+
print(model.coef_.shape) # (N, M) estimated β
95+
print(model.intercept_.shape) # (N,) estimated α
96+
print(model.predict(X).shape) # fitted response panel
97+
```
98+
99+
```text
100+
(10, 4)
101+
(10,)
102+
(200, 10)
103+
```
104+
105+
The API mirrors scikit-learn: `fit(x, y)`, `predict(x)`, `score(x, y)`,
106+
`get_params()`, `set_params()`. Fitted attributes carry a trailing underscore.
107+
`fit`/`predict`/`score` accept NumPy arrays as well as pandas objects, and the
108+
estimator declares `__sklearn_tags__`, so it composes directly with
109+
`sklearn.pipeline.Pipeline`, `GridSearchCV`, and `cross_val_score`. A fitted
110+
model also exposes `summary()`. The `plot_signs()` heatmap requires Matplotlib,
111+
which is not a runtime dependency and must be installed separately.
112+
113+
---
114+
71115
## Offline cluster lineage
72116

73117
`analyze_cluster_lineage` turns independently estimated per-date risk clusters in a
@@ -119,47 +163,7 @@ preserves the pre-0.16 flat-window calculation exactly.
119163

120164
---
121165

122-
## Installation
123-
124-
```bash
125-
pip install factorlasso
126-
```
127-
128-
Requires Python ≥ 3.10, CVXPY ≥ 1.3, and numpy / pandas / scipy / openpyxl.
129-
130-
---
131-
132-
## Quickstart
133-
134-
```python
135-
import numpy as np
136-
import pandas as pd
137-
from factorlasso import LassoModel, LassoModelType
138-
139-
rng = np.random.default_rng(0)
140-
T, M, N = 200, 4, 10
141-
X = pd.DataFrame(rng.standard_normal((T, M)), columns=[f"f{i}" for i in range(M)])
142-
Y = pd.DataFrame(rng.standard_normal((T, N)), columns=[f"y{i}" for i in range(N)])
143-
144-
model = LassoModel(model_type=LassoModelType.LASSO, reg_lambda=1e-5).fit(x=X, y=Y)
145-
146-
model.coef_ # (N, M) estimated β
147-
model.intercept_ # (N,) estimated α
148-
model.predict(X) # Ŷ
149-
model.score(X, Y) # mean R²
150-
```
151-
152-
The API mirrors scikit-learn: `fit(x, y)`, `predict(x)`, `score(x, y)`,
153-
`get_params()`, `set_params()`. Fitted attributes carry a trailing underscore.
154-
`fit`/`predict`/`score` accept NumPy arrays as well as pandas objects, and the
155-
estimator declares `__sklearn_tags__`, so it composes directly with
156-
`sklearn.pipeline.Pipeline`, `GridSearchCV`, and `cross_val_score`. A fitted
157-
model also exposes `summary()` (a text fit report) and `plot_signs()` (a
158-
heatmap of the derived sign matrix).
159-
160-
---
161-
162-
## Motivation
166+
## Why factorlasso
163167

164168
Factor models are central to quantitative finance, underpinning the
165169
commercial risk systems in industry use (among others, MSCI Barra, Axioma,
@@ -192,7 +196,7 @@ under [Citation](#citation).
192196

193197
---
194198

195-
## What makes it different
199+
## Key differentiators
196200

197201
### 1. Per-element sign constraints
198202

@@ -373,7 +377,7 @@ References:
373377
* Zou, H. (2006). The adaptive Lasso and its oracle properties.
374378
*J. Amer. Stat. Assoc.* 101(476), 1418–1429.
375379

376-
### 3. Prior-centered regularisation
380+
### 3. Prior-centred regularisation
377381

378382
Pass a `(N × M)` DataFrame `factors_beta_prior` to penalise `‖β − β₀‖` instead
379383
of `‖β‖`. The prior is a soft target, not a hard constraint — the penalty
@@ -882,35 +886,41 @@ Four runnable examples in [`examples/`](examples/):
882886
## Testing
883887

884888
```bash
885-
pip install -e ".[dev]"
886-
pytest
889+
uv sync --locked --group test
890+
uv run --no-sync pytest
891+
uv run --locked --only-group lint ruff check src/factorlasso tests
887892
```
888893

889-
The suite currently collects 500 tests and reports 92.67% line coverage, including numerical parity
890-
tests against `qis` for the EWMA primitives and against `scikit-learn` for the
891-
LASSO path.
894+
The suite covers estimator contracts, independent EWMA references, covariance assembly, cluster
895+
diagnostics, and numerical parity with scikit-learn and skglm on their shared LASSO surface.
892896

893897
---
894898

895899
## Ecosystem
896900

897-
This package is part of an open-source Python stack for quantitative finance — full catalogue at [github.com/ArturSepp](https://github.com/ArturSepp):
901+
This package is part of an open-source Python stack for quantitative finance. The
902+
[ArturSepp profile](https://github.com/ArturSepp) is the canonical full catalogue:
898903

899904
| Package | Purpose |
900905
|---|---|
901906
| [`qis`](https://github.com/ArturSepp/QuantInvestStrats) | Performance analytics, factsheets, and visualisation |
902907
| [`optimalportfolios`](https://github.com/ArturSepp/OptimalPortfolios) | Portfolio construction and backtesting |
903908
| [`factorlasso`](https://github.com/ArturSepp/factorlasso) *(this package)* | Sparse factor models and factor covariance estimation |
904909
| [`bbg-fetch`](https://github.com/ArturSepp/BloombergFetch) | Bloomberg data fetching |
910+
| [`option-chain-analytics`](https://github.com/ArturSepp/OptionChainAnalytics) | Point-in-time option-chain normalisation, reconstruction, querying, and visualisation |
911+
| [`vanilla-option-pricers`](https://github.com/ArturSepp/VanillaOptionPricers) | Vectorised vanilla option pricers and implied volatility fitters |
912+
| [`stochvolmodels`](https://github.com/ArturSepp/StochVolModels) | Stochastic volatility pricing analytics |
905913
| [`trendfollowing`](https://github.com/ArturSepp/TrendFollowingSystems) | Trend-following systems: closed-form theory and replication |
914+
| [`privateassets`](https://github.com/ArturSepp/privateassets) | Money-weighted multi-factor alpha from private-asset cash flows |
906915
| [`goal-based-allocation`](https://github.com/ArturSepp/GoalBasedAllocation) | Dynamic MV allocation under regime-switching jump-diffusions |
907-
| [`stochvolmodels`](https://github.com/ArturSepp/StochVolModels) | Stochastic volatility pricing analytics |
908-
| [`vanilla-option-pricers`](https://github.com/ArturSepp/VanillaOptionPricers) | Vectorised vanilla option pricers and implied volatility fitters |
909916

910-
Dependency links within the stack: `optimalportfolios` builds on `qis` and `factorlasso`; `trendfollowing` builds on `qis`.
917+
`factorlasso` has no runtime dependency on another package in the stack. It is consumed by
918+
`optimalportfolios` and, through its optional `factors` extra, by `privateassets`.
911919

912920
## Citation
913921

922+
A machine-readable citation is available in [`CITATION.cff`](CITATION.cff).
923+
914924
If you use `factorlasso` in academic work, please cite the software
915925
paper describing the package (submitted to the *Journal of Statistical
916926
Software*), the methodology paper for the cluster-pooled sign derivation
@@ -940,8 +950,8 @@ software itself:
940950
941951
@article{SeppHansenKastenholz2026MATF,
942952
author = {Sepp, Artur and Hansen, Emilie and Kastenholz, Mika},
943-
title = {Capital Market Assumptions Using Multi-Asset Tradable Factors:
944-
The {MATF-CMA} Framework},
953+
title = {Capital Market Assumptions and Strategic Asset Allocation Using
954+
Multi-Asset Tradable Factors},
945955
journal = {Journal of Portfolio Management},
946956
year = {2026},
947957
note = {Forthcoming.}
@@ -970,10 +980,12 @@ software itself:
970980

971981
---
972982

973-
## Contributing & feedback
983+
## Feedback & contributing
974984

975-
Issues and pull requests welcome at
976-
<https://github.com/ArturSepp/factorlasso>.
985+
- **Bug:** use the [bug-report form](https://github.com/ArturSepp/factorlasso/issues/new?template=bug_report.yml) with the version, Python/platform, a minimal reproducer, and expected versus actual output.
986+
- **Feature:** use the [feature-request form](https://github.com/ArturSepp/factorlasso/issues/new?template=feature_request.yml) and describe the estimation goal, current workaround, and smallest useful API. In particular: which grouping, constraint, or covariance diagnostic is missing?
987+
- **Question or methodology:** search or open an [issue](https://github.com/ArturSepp/factorlasso/issues) and identify the estimator, paper section, or convention involved.
988+
- **Contribution:** follow [CONTRIBUTING.md](CONTRIBUTING.md) and look for [`good first issue`](https://github.com/ArturSepp/factorlasso/labels/good%20first%20issue) or [`help wanted`](https://github.com/ArturSepp/factorlasso/labels/help%20wanted) work.
977989

978990
See [`CHANGELOG.md`](CHANGELOG.md) for release history and
979991
[`COMPATIBILITY.md`](COMPATIBILITY.md) for the API stability policy

papers/jss_2026/paper/refs.bib

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ @InProceedings{Bertrand+etal:2022
244244
245245
@Unpublished{Sepp+Hansen+Kastenholz:2026MATF,
246246
author = {Artur Sepp and Emilie Hansen and Mika Kastenholz},
247-
title = {Capital Market Assumptions Using Multi-Asset Tradable Factors:
248-
The {MATF-CMA} Framework},
247+
title = {Capital Market Assumptions and Strategic Asset Allocation Using
248+
Multi-Asset Tradable Factors},
249249
year = {2026},
250250
note = {Working paper, under review at the \emph{Journal of Portfolio Management}},
251251
}

0 commit comments

Comments
 (0)