ffn: a financial toolbox whose own example zeroes two of its five tickers
ffn - a financial function library for Python
At a glance
- What is it?
- ffn is a small Python library of quantitative finance functions sitting on Pandas, NumPy and Scipy. Its packaging metadata and Makefile say more about how it is built than its README does: a market data downloader in the runtime dependencies, a Beta classifier on version 1.3.0, and a type checker no target calls.
- Who is it for?
- ffn is a bag of analysis functions with a thin layer of its own around them, and its packaging metadata is more informative than its promotional copy: an unpinned numpy, a market data downloader in the runtime dependencies, a Beta classifier on a 1.3.0 version, and a type checker that no make target calls. Reach for it when the work is performance measurement, portfolio weighting or data reshaping and you would rather keep working in Pandas than adopt an ORM.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
yfinance is a runtime dependency, not an optional extra
The runtime dependency list runs to eight entries: decorator, matplotlib, numpy, pandas, scikit-learn, scipy, tabulate and yfinance. The last of those is a market data downloader, so installing the analysis library reaches for a network client whether or not the caller ever asks for a price. The README's account of the stack, that ffn stands on the shoulders of giants such as Pandas, Numpy and Scipy, does not mention scikit-learn or matplotlib, although both are declared. The lower bounds are uneven as well. `decorator>=5.0.7`, `pandas>=0.19`, `scikit-learn>=0.15`, `scipy>=0.15` and `tabulate>=0.7.5` all carry a floor, while numpy is written as bare `numpy` and yfinance as `yfinance>=0.2`, the loosest bound in the set.
requires-python opens at 3.9 while the classifiers stop at 3.13
The metadata sets the interpreter floor at `>=3.9` and then enumerates individual versions as classifiers, 3.9, 3.10, 3.11, 3.12 and 3.13, with nothing listed for 3.14. The same block labels the project `Development Status :: 4 - Beta`, which is a packaging classification rather than a statement about the release history: the version in the file is 1.3.0 and three tags are published. Keywords sit at that level too, running from python and finance through quant, quant finance, algotrading and algorithmic trading, so the intended audience is spelled out in the distribution rather than in prose. Authorship is a single entry, one named maintainer with an email address in the author table.
v1.2.0 and v1.2.1 were published fifteen seconds apart
The three recent releases are v1.2.0 published on 2026-09-07 at 18:17:35, v1.2.1 published the same day at 18:17:50, and v1.3.0 published on 2026-10-03. Two tags fifteen seconds apart read like a packaging correction applied on the spot rather than two planned releases. The version number itself is held in two places in pyproject.toml: the project table's `version` field and the bumpversion table's `current_version`, both reading 1.3.0, with the bumpversion section ending partway through its next key. The tool that keeps them aligned is `bump-my-version` in the develop extra, paired with a `show-version` target in the Makefile. The default branch is `master` rather than `main`.
ty is installed as a checker, and no make target invokes it
The develop extra installs `ty` among two dozen build tools, and the Makefile gives it a target of its own:
ty check ffnThat target's own comment calls the check advisory, and nothing calls the target. `lint` is defined as `lint-py lint-docs`, `checks` is `check-dist` alone, and `test` is `python -m pytest tests`, so type checking sits outside every aggregate target while ruff and codespell run on each `make lint`. The docs linter covers `README.md docs/development.md docs/source/*.md` and nothing else, which leaves any other markdown in the tree unchecked and unspell checked. The benchmark suite has the same shape, a separate target running pytest with `--benchmark-only` against a `benchmarks/` directory.
The headline example returns zero weight for two of five tickers
The entire demonstration is three lines of work:
import ffn
returns = ffn.get('aapl,msft,c,gs,ge', start='2010-01-01').to_returns().dropna()
print(returns.calc_mean_var_weights().as_format('.2%'))The block underneath it is static text headed as example output, and two of the five positions come back at `-0.00%`: `c` and `gs`. The remaining three carry aapl at 62.54%, ge at 36.19% and msft at 1.26%. The symbols are Yahoo style tickers, which is the reason the downloader appears among the runtime dependencies rather than behind an extra. The printed frame ends with `dtype: object`, so what the reader sees is a formatted frame of strings rather than numbers, and the weights were produced by a single call, `calc_mean_var_weights`, that the README does not describe further.
uv drives the Makefile while the install notes point at Anaconda
End users are told to run one command and nothing else:
pip install ffnThey are then told that because ffn has many dependencies, the Anaconda Scientific Python Distribution is strongly recommended, on the grounds that it ships many of the required packages and pip itself. Contributors go another way entirely. The Makefile drives `uv pip install -e '.[develop]'` to set up development, `uv pip install -r pyproject.toml --extra develop` for prerequisites, `uv pip install .` to install, and `python -m build -n` to build. Nothing in the repository root records resolved versions: no lock file, no requirements file, and no uv configuration file sit beside pyproject.toml.
bt takes the backtesting half, and the tree is template generated
The README draws its own boundary in the first paragraph: readers who want a full backtesting framework are pointed at bt, which is built atop ffn. That is the division of labour in a sentence, measurement, weighting and data transformation here, strategy testing in the other package. The repository root is short, thirteen entries including `benchmarks/`, `docs/`, `ffn/`, `tests/` and a `.copier-answers.yaml`. That last file, together with `copier`, `yardang` and `klink` in the develop extra and a contribution note about Copier template updates in the development guide, means part of the tree is generated rather than written by hand, so an edit to a generated file is an edit that can be overwritten.
Editorial conclusion
ffn is a bag of analysis functions with a thin layer of its own around them, and its packaging metadata is more informative than its promotional copy: an unpinned numpy, a market data downloader in the runtime dependencies, a Beta classifier on a 1.3.0 version, and a type checker that no make target calls. Reach for it when the work is performance measurement, portfolio weighting or data reshaping and you would rather keep working in Pandas than adopt an ORM. Look elsewhere when you need a strategy backtester, since the project hands that job to bt in its first paragraph. Before installing, read the dependency list and decide whether yfinance belongs in your environment, and check whether the files you plan to edit were generated from the Copier template.
Frequently asked questions
What does ffn provide for quantitative finance in Python?
A collection of utilities that the README describes as spanning performance measurement and evaluation, graphing and common data transformations, built on Pandas, Numpy and Scipy. The worked example fetches tickers, converts them to returns and computes mean variance weights.
How is ffn installed from PyPI?
With pip install ffn. Because ffn has many dependencies, the README recommends the Anaconda Scientific Python Distribution, which ships many of the required packages including pip. Contributors instead use uv through the Makefile targets develop, install and build.
Does ffn include a backtesting framework?
No. The README says that readers looking for a full backtesting framework should check out bt, and that bt is built atop ffn and makes it easy and fast to backtest quantitative strategies.
Which Python versions does ffn declare support for?
The metadata sets requires-python to >=3.9 and lists classifiers for 3.9 through 3.13, with no entry for 3.14. The project is classified as Development Status :: 4 - Beta at version 1.3.0.
What are the runtime dependencies of ffn?
Eight of them: decorator>=5.0.7, matplotlib>=1, numpy, pandas>=0.19, scikit-learn>=0.15, scipy>=0.15, tabulate>=0.7.5 and yfinance>=0.2. Only numpy carries no lower bound at all, and yfinance is a market data downloader rather than a numeric library.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pmorissette-ffn)