Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Finalytics

PyPI Python 3.10+ Downloads CI Licence Homepage

Finalytics is a portfolio analytics engine written in Rust, with this typed Python package over it. It compares portfolio optimisation methods on returns they have not seen, and keeps the books of a real portfolio to report its performance, risk and attribution.

pip install "finalytics[pandas]"  # with pandas, as the examples below use
pip install finalytics            # with NumPy only

Without pandas, the datasets come as price tables, which Assets takes as well: fl.Assets(fl.datasets.asset_class_table(), risk_free_asset="T-Bills").

Until 1.0.0 is released, pip install finalytics gives 0.9; install a 1.0 pre-release with pip install --pre finalytics. The migration guide explains what replaces each part of 0.9.

Sample reports, built by the programs below from the bundled datasets: comparison · backtest · optimisation · portfolio · rebalance

Portfolio optimisation

Compare optimisation methods on the same assets. Each method is refitted every quarter on the five years before, and judged on the quarter that follows.

import finalytics as fl

assets = fl.Assets(fl.datasets.asset_class_prices(), risk_free_asset="T-Bills")

result = assets.compare(
    methods=[
        "equal_weight",
        "minimum_variance",
        "maximum_sharpe",
        "maximum_diversification",
        "risk_parity",
        "hierarchical_risk_parity",
    ],
    max_weight=0.40,
    rebalance="quarterly",
    validation=fl.WalkForward(years=5),
    trading_cost_bps=10,
)

result.show()

The comparison report: each method's return, volatility, Sharpe ratio, drawdown and turnover out of sample

Every result has the same shape: result.report is the report, which print(result) prints as text and result.show() opens as a page (inline in a Jupyter notebook), and result.results holds every return and trade behind it.

To test one allocation, give a method or your own weights. Here, the maximum Sharpe ratio fitted to the years before November 2016, held from then on against a 60/40 benchmark:

result = assets.backtest(
    method="maximum_sharpe",
    max_weight=0.40,
    benchmark={"US Equity": 0.60, "Bonds": 0.40},
    rebalance="quarterly",
    validation=fl.Holdout(start="2016-11-01"),
)

result.show()

The backtest report: the allocation, its statistics in and out of sample against the benchmark, and its growth

To see the weights a method chooses today, where their risk comes from and where they sit on the efficient frontier:

result = assets.optimise(
    method="maximum_sharpe", max_weight=0.40, frontier=True
)

result.show()

The optimisation report: the weights, what they are expected to deliver, and each asset's share of the risk

Portfolio analytics

Load a portfolio from its transactions and prices, and report on it: holdings, performance, risk, attribution and scenarios.

import finalytics as fl

portfolio = fl.Portfolio.from_csv(
    transactions="transactions.csv",
    prices="prices.csv",
    fx="fx.csv",
    instruments="instruments.csv",
    accounts="accounts.csv",
)

report = portfolio.report(benchmark="BENCH", group_by=["asset_class", "region"])

report.show()

The portfolio report: value, returns, volatility, drawdown and value at risk, and growth against the benchmark

The files are the portfolio dataset: a household's brokerage and retirement accounts, holding five funds in dollars and euros for three years. fl.datasets.file("portfolio/prices.csv") and the like return each of them, and fl.datasets.portfolio() loads the same portfolio without them. BENCH is a column of prices.csv, the benchmark's levels; asset_class and region are columns of instruments.csv that classify each holding. The sample report adds the attribution and scenarios of fl.datasets.report_options(). A portfolio's report is its own result: every figure in it is the portfolio's, so report() returns the report, with no results beside it.

The start of the dataset's files
id,kind,currency,name,class.asset_class,class.region
VTI,fund,USD,Vanguard Total Stock Market ETF,Equity,North America
EXSA,fund,EUR,iShares STOXX Europe 600 UCITS ETF (DE),Equity,Europe
date,VTI,EXSA,BND,GLD,VNQ,BENCH
2023-11-01,208.86,43.21,68.99,183.51,73.37,100.0000
2023-11-02,213.01,43.92,69.39,184.12,75.78,101.4345
id,name,lot_method,taxable,class.owner,class.wrapper
brokerage,Brokerage account,fifo,true,Alex,Taxable
ira,Retirement account,fifo,false,Alex,Tax-deferred

The data guide describes every file, column by column.

To move the same funds to their least risky mix, 5% to 40% each, optimise the holdings and rebalance the accounts together, with fees and tax rates:

target = portfolio.assets().optimise(
    method="minimum_variance", bounds=(0.05, 0.40)
)

result = portfolio.rebalance(
    target, whole_units=True, fee_bps=5, minimum_fee=1, tax=(0.37, 0.20)
)

result.show()

The rebalance report: the trades, how each holding's weight moves, and what the trades change and cost

Sales in the brokerage account take the lots that cost the least tax; the retirement account is not taxable (taxable is false in accounts.csv), so its sales pay none. portfolio.with_rebalance(result) makes the trades.

What is included

Optimisation

  • Equal weight, minimum variance, mean–variance and robust mean–variance, maximum Sharpe, target return or volatility, maximum diversification, minimum CVaR, risk parity, hierarchical risk parity
  • Limits on each asset and on groups, turnover, tracking error and factor exposure
  • Black–Litterman and resampled estimates; Ledoit–Wolf, OAS and EWMA covariance
  • Validation in sample, on a holdout, or walk-forward; calendar or drift rebalancing; trading costs

Analytics

  • Books from transactions: lots, corporate actions, several accounts and currencies
  • Time- and money-weighted returns, contribution, Brinson–Fachler and currency attribution
  • Volatility, drawdowns, value at risk, risk decomposition, factor models and scenarios
  • Rebalancing trades with fees and tax-aware lot selection, across accounts

Every report prints as text, 80 columns wide, and shows as one self-contained HTML page, in light and dark. Every model is tested against an independent implementation; the methods pages define each one.

Beneath the front doors, fl.risk, fl.opt and fl.performance give each method on its own, and results are frozen dataclasses with documented fields (see finalytics.types). Wheels are published for Linux, macOS and Windows.

Documentation

Data guide · Methods · Performance · Migrating from 0.9 · Source and issues

Contributing and licence

Contributions are welcome: see CONTRIBUTING.md. Finalytics is licensed under MIT or Apache-2.0, at your option. It provides analysis tools only and is not investment advice.

Metadata

Release files for finalytics 1.0.0rc2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for finalytics 1.0.0rc2
File Size Uploaded Provenance Actions
finalytics-1.0.0rc2.tar.gz 2.0 MB Without provenance Details for finalytics-1.0.0rc2.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for finalytics 1.0.0rc2
File Actions
finalytics-1.0.0rc2-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for finalytics-1.0.0rc2-cp310-abi3-win_amd64.whl
finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details for finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_x86_64.whl
finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details for finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_aarch64.whl
finalytics-1.0.0rc2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for finalytics-1.0.0rc2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
finalytics-1.0.0rc2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for finalytics-1.0.0rc2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
finalytics-1.0.0rc2-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for finalytics-1.0.0rc2-cp310-abi3-macosx_11_0_arm64.whl
finalytics-1.0.0rc2-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for finalytics-1.0.0rc2-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 38.8 MB

Release files / finalytics-1.0.0rc2.tar.gz

Download URL finalytics-1.0.0rc2.tar.gz
Size 2.0 MB
Tags Source
SHA-256 checksum
How to use checksums
6a29ef26c1d73c707ad628c599250469189347754fc97a4a25486315920d767f
BLAKE2b-256 checksum
How to use checksums
80c3d1ba8ad7ab5e43c511228889d0293783f440fc8960b669cde38b04ee39ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-win_amd64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-win_amd64.whl
Size 5.4 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
36cfdf12e4f4bc829626a3db1e2c51c14591fbdb501daa9f1e9dd564527f0bdb
BLAKE2b-256 checksum
How to use checksums
8ebacec54675641914fec9bb401d0963057f3d3974cf3c270079bfec724cdd77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_x86_64.whl
Size 5.6 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
840579f463823d76e4bddd513b76f5b7c25244d0905eafa4af90f75fb864cb4c
BLAKE2b-256 checksum
How to use checksums
8456b5e6cffe79a4ef6d0077d53a4d1b568c0ef98acf07acf8ff2b23ade56844
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-musllinux_1_2_aarch64.whl
Size 5.2 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
0cb539c4df4369b4b48a22461d914fb28e414320541d23a236fe667bd6b8f22b
BLAKE2b-256 checksum
How to use checksums
65f4bc6c45c9875126382979a09e34cf555396f1c17d5e377367c337ed447a1b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 5.4 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
4ca72859b90317491e0eac369b270d84150a1c03c23b116f745639eb753f1f66
BLAKE2b-256 checksum
How to use checksums
3fa32f93145f0a3a8fc52541cc940267f6bfc57d88969b4b170a955047b53c27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 5.0 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
1a96f2b25c2704de19fb66a5af9291a634f2c0222cb6a43fd872cdd70bc08d9a
BLAKE2b-256 checksum
How to use checksums
f1ddac6c4e57113d8c777f9bdb4e8268abd0e88c7b1e2012bbbfdd60ffebbe7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-macosx_11_0_arm64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-macosx_11_0_arm64.whl
Size 4.9 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d44882f1ebc69b47f82cefe2f18b61f9729decf701e677e0600760c1903c52e4
BLAKE2b-256 checksum
How to use checksums
e82b550425d1e6f0b01f7b914a0ba637d0d1783f38a16f21654e22c9d4e6ac72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / finalytics-1.0.0rc2-cp310-abi3-macosx_10_12_x86_64.whl

Download URL finalytics-1.0.0rc2-cp310-abi3-macosx_10_12_x86_64.whl
Size 5.2 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
f83e498fdfb4f9f22507776b19c76958c070d7a9bc452d15ed1b72ccd9bfaf65
BLAKE2b-256 checksum
How to use checksums
6da85789bb3a3e615e2f812d325b32c3e6b19953ecec55f94b686c16af202739
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for finalytics 1.0.0rc2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page