Quantitative factor scoring for equities and ETFs
Project description
factor-score
Quantitative factor scoring for equities and ETFs.
from factor_score import FactorEngine
engine = FactorEngine()
scores = engine.score(["DIS", "NVDA", "MSFT", "META"])
for s in scores:
print(f"{s.ticker:6} composite={s.composite_score:.2f} rank=#{s.composite_rank}")
Install
pip install factor-score # core (bring your own data)
pip install 'factor-score[yfinance]' # with built-in yfinance provider
Design
- Input-agnostic: implement the two-method
DataProviderprotocol to plug in any data source (yfinance, Polygon, IBKR, CSV). - Code-driven config: use
FactorConfigto override weights and lookback periods — no YAML required. - Normalized scores: composite scores are 0–1 within the scored universe; raw factor values are always returned alongside.
Factors
| Factor | Weight | Description |
|---|---|---|
| Vol-adjusted momentum | 35% | 90d return / annualized vol — rewards smooth trends |
| Momentum (90d) | 25% | Trailing 90-day return |
| Momentum (180d) | 25% | Trailing 180-day return |
| Relative value | 15% | Proximity to 52-week low (mean-reversion tilt) |
Custom config
from factor_score import FactorEngine, FactorConfig
config = FactorConfig(
weight_vol_adj_momentum=0.50,
weight_momentum_short=0.25,
weight_momentum_long=0.15,
weight_relative_value=0.10,
momentum_short_days=60,
)
engine = FactorEngine(config=config)
Custom data provider
import pandas as pd
from factor_score import FactorEngine
class MyProvider:
def get_history(self, ticker: str, period: str = "1y") -> pd.DataFrame:
# return a DataFrame with a "Close" column
...
engine = FactorEngine(provider=MyProvider())
Contributing
Local development setup
Prerequisites: Python 3.11 or 3.12, and pip.
- Clone the repo and create a virtual environment:
git clone https://github.com/brainscanstudios/factor-score.git
cd factor-score
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
- Install the package in editable mode with dev dependencies:
pip install -e '.[dev]'
This installs pytest, pytest-cov, and the yfinance provider so the full test suite can run.
Running tests
pytest
To see coverage:
pytest --cov=factor_score
Project layout
factor_score/ # library source
engine.py # FactorEngine — main entry point
models.py # FactorConfig, FactorScore dataclasses
factors/ # individual factor implementations
providers/ # DataProvider implementations (yfinance, …)
tests/ # pytest suite
Adding a factor
- Implement the scoring logic in
factor_score/factors/. - Add a weight field to
FactorConfiginmodels.py(default to0.0so existing configs stay valid). - Wire it into
FactorEngine.score()inengine.py. - Add tests in
tests/.
Adding a data provider
Implement the two-method DataProvider protocol (see factor_score/providers/) and pass an instance to FactorEngine(provider=...). No base class required — duck typing is sufficient.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file factor_score-0.2.0.tar.gz.
File metadata
- Download URL: factor_score-0.2.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5209aec6748ba077e730bbe4639de3fa28e2d38befbabc5e4b843cb39e96f6e
|
|
| MD5 |
513b5cf85ba2bb7cec54b520108a1206
|
|
| BLAKE2b-256 |
4ee767369dcf092270e238728446cf1126038ae9f3086eef985d2991b4174a1a
|
Provenance
The following attestation bundles were made for factor_score-0.2.0.tar.gz:
Publisher:
publish.yml on brainscanstudios/factor-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
factor_score-0.2.0.tar.gz -
Subject digest:
c5209aec6748ba077e730bbe4639de3fa28e2d38befbabc5e4b843cb39e96f6e - Sigstore transparency entry: 1634389798
- Sigstore integration time:
-
Permalink:
brainscanstudios/factor-score@ef378c12c70e7d4d6958e38cd369abd85e0847a1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/brainscanstudios
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ef378c12c70e7d4d6958e38cd369abd85e0847a1 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file factor_score-0.2.0-py3-none-any.whl.
File metadata
- Download URL: factor_score-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af8492352942e3c6d3f9de6cc2febe1022857565b288c5098026cc9dc69a8cd6
|
|
| MD5 |
aec6fd50781ceba7d5ea6b9fce4f119a
|
|
| BLAKE2b-256 |
2c3b39f70d25652dafd70eb45e20466ef1c3e75cc960a8020cb7e3c052ce304d
|
Provenance
The following attestation bundles were made for factor_score-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on brainscanstudios/factor-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
factor_score-0.2.0-py3-none-any.whl -
Subject digest:
af8492352942e3c6d3f9de6cc2febe1022857565b288c5098026cc9dc69a8cd6 - Sigstore transparency entry: 1634389825
- Sigstore integration time:
-
Permalink:
brainscanstudios/factor-score@ef378c12c70e7d4d6958e38cd369abd85e0847a1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/brainscanstudios
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ef378c12c70e7d4d6958e38cd369abd85e0847a1 -
Trigger Event:
workflow_dispatch
-
Statement type: