Skip to main content

QuantInvestStrats (qis)

qis - performance analytics, portfolio backtesting, risk analysis, and factsheet reporting in Python.

Quantitative Investment Strategies covers time-series and cross-sectional performance, drift-aware portfolio histories, ex-ante and ex-post risk, and reproducible reports.

PyPI Python License CI Docs Downloads Monthly


Overview

The package is split into 5 main modules with the dependency path increasing sequentially as follows.

  1. qis.utils is module containing low level utilities for operations with pandas, numpy, and datetimes.

  2. qis.perfstats is module for computing performance statistics and performance attribution including returns, volatilities, etc.

  3. qis.plots is module for plotting and visualization apis.

  4. qis.models is module containing statistical models including filtering and regressions.

  5. qis.portfolio is high level module for analysis, simulation, backtesting, and reporting of quant strategies. Function backtest_model_portfolio() in qis.portfolio.backtester.py takes instrument prices and simulated weights from a generic strategy and compute the total return, performance attribution, and risk analysis

Risk and tracking-error analytics are consolidated in qis.portfolio.risk. The public qis.RiskModel is the point-in-time weights-and-covariance layer for ex-ante tracking error, standalone group risk, factor exposures, benchmark beta and loadings, systematic/residual tracking-error decomposition, and Euler marginal tracking-error contributions. Ex-post analytics use portfolio and benchmark NAVs or return differences: compute_ewma_realised_tracking_error produces a conditional annualised series, while compute_te_ir_errors and compute_info_ratio_table produce whole-sample tracking error and information-ratio estimates. The weights_tracking_error_report_by_ac_subac report brings these views together with ex-ante versus realised tracking error, ex-ante versus ex-post beta, annualised ex-post alpha, and optional factor panels. Some established API names retain the abbreviation tre, but all refer to tracking error.

Covariance-implied Euler attribution also lives here for the whole OSS stack: compute_portfolio_risk_contributions returns asset contributions in volatility units, compute_portfolio_risk_contribution_ratios returns their dimensionless shares, and compute_group_portfolio_risk_contribution_ratios aggregates those shares over clusters, sectors, asset classes, or any other complete labelled partition.

qis.market_data is an auxiliary module of market-data containers and FX analytics. FxRatesData holds FX spot and domestic short-rate panels and derives cross rates, covered-interest-parity forward premia, carry decomposition, and reference-currency / FX-hedged return translation of multi-asset panels, together with single- and multi-asset FX-hedging reports. FactorsData is a generic container for tradable-factor prices. Examples build the container from free Yahoo data or from Bloomberg via bbg-fetch; see the module README at src/qis/market_data/README.md for the data contract and conventions.

The repository-root examples/ directory contains runnable scripts showcasing the analytics. It is intentionally separate from the installed qis package:

  • examples/perfstats — performance metrics on price series: quickstart usage, Sharpe vs Sortino across return frequencies, rolling performance, bond-ETF risk/return frontier, multi-figure performance reports, miss-best-worst-days impact, infrequent-returns interpolation, and an end-to-end de-levering / unsmoothing walkthrough on a bundled BDC vs private-credit dataset.

  • examples/models — numba-vs-pandas EWM kernel benchmarks, multivariate EWM linear factor models, multivariate OLS, EWM correlation tables, OHLC realised-volatility estimators, intraday/overnight return decomposition, rolling correlations, and block bootstrap of price paths.

  • examples/regimes — regime-conditional analytics: bull/bear/normal Sharpe attribution, conditional return boxplots by VIX regime, calendar-month seasonality, US election regime study.

  • examples/portfolios — backtests using backtest_model_portfolio: balanced 60/40 with and without a BTC sleeve, constant-notional short, leveraged-ETF combinations, long/short pairs, vol-target / trend-following parameter sweeps, and separate offline ex-ante and ex-post tracking-error workflows.

  • examples/factsheets — full multi-page factsheets for simulated and actual strategies, cross-sectional asset-class comparisons, multi-strategy parameter sweeps, and optional pybloqs-rendered variants.

  • examples/plots — plotting primitives showcase: dual-axis figures, scatter with regression diagnostics.

  • examples/utils — date schedules and rolling calendars: option / futures roll generation via generate_fixed_maturity_rolls.

  • examples/case_studies — cross-cutting domain studies: VIX beta to equities and bonds, VIX term-structure correlation with SPX, conditional returns on the front-month short-VIX strategy, credit-spread regression vs equity / rates.

The examples/README.md index lists every script with a one-line description; examples that need a Bloomberg terminal are flagged inline.

Table of contents

  1. Analytics
  2. Installation
  3. Offline quickstart
  4. Examples
    1. Visualization of price data
    2. Multi assets factsheet
    3. Strategy factsheet
    4. Strategy benchmark factsheet
    5. Multi strategy factsheet
    6. Runnable examples
  5. Contributions
  6. Changelog
  7. ToDos
  8. Disclaimer

Installation

Install using

pip install qis

Upgrade using

pip install --upgrade qis

Close using

git clone https://github.com/ArturSepp/QuantInvestStrats.git

Core dependencies: python = ">=3.10", numba = ">=0.63.0", numpy = ">=2.0", scipy = ">=1.12.0", statsmodels = ">=0.14.0", pandas = ">=2.2.0", matplotlib = ">=3.8.0", seaborn = ">=0.13.0", openpyxl = ">=3.1.0", PyYAML = ">=6.0"

src/qis/tests/test_documentation.py asserts that this list is the dependencies table of pyproject.toml, so it cannot drift from what pip install qis actually pulls.

Python 3.14 is supported (numba 0.63+ ships cp314 wheels).

Optional dependencies: yfinance = ">=0.2.40" and pandas-datareader = ">=0.10.0" (examples and tests that pull free price data — install with pip install qis[data]; never imported by library code), pybloqs ">=1.2.13" (for producing html and pdf factsheets — install with pip install qis[reports]), bbg-fetch ">=2.0.0" (third-party; for examples that pull data from a Bloomberg terminal)

See pyproject.toml for the full list of optional extras (reports, visualization, io, database, jupyter, dev, all).

Offline quickstart

Open In Colab

The authoritative first-success workflow is examples/getting_started/offline_quickstart.py. It generates seeded data in-process, builds a live-universe-aware quarterly weight schedule, backtests with explicit transaction costs, and prints performance plus benchmark-relative risk. It needs only the core qis installation and writes no files.

From a repository checkout:

python examples/getting_started/offline_quickstart.py

With only pip install qis, copy the complete code from the hosted offline quickstart. That page includes the runnable script directly, so the README, documentation, and example cannot develop independent full-code versions.

The Colab entry point installs the latest release from public PyPI, reports its exact version and import path, and runs that same mechanically checked source with no saved notebook outputs.

Examples

1. Visualization of price data

This is an optional network-backed plotting example. For the core-install first-success path, use the offline quickstart above.

The script is located at examples/perfstats/quickstart.py. Run python -m examples.perfstats.quickstart from the repository root to produce the figures below; perf1 to perf3 are excluded from the repository by .gitignore on size, so only the last is embedded here.

import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
import qis
from qis import PerfStat

# define tickers and fetch price data
tickers = ['SPY', 'QQQ', 'EEM', 'TLT', 'IEF', 'SHY', 'LQD', 'HYG', 'GLD']
prices = yf.download(tickers, start="2003-12-31", end=None, ignore_tz=True, auto_adjust=True)['Close'][tickers].dropna()

# plotting price data with minimum usage
with sns.axes_style("darkgrid"):
    fig, ax = plt.subplots(1, 1, figsize=(10, 7))
    qis.plot_prices(prices=prices, x_date_freq='YE', ax=ax)
# 2-axis plot with drawdowns using sns styles
with sns.axes_style("darkgrid"):
    fig, axs = plt.subplots(2, 1, figsize=(10, 7), tight_layout=True)
    qis.plot_prices_with_dd(prices=prices, x_date_freq='YE', axs=axs)
# plot risk-adjusted performance table with excess Sharpe ratio
ust_3m_rate = yf.download('^IRX', start="2003-12-31", end=None, ignore_tz=True, auto_adjust=True)['Close'].dropna() / 100.0
# set parameters for computing performance stats including returns vols and regressions
perf_params = qis.PerfParams(freq='ME', freq_reg='QE', rates_data=ust_3m_rate)
# perf_columns is list to display different perfomance metrics from enumeration PerfStat
fig = qis.plot_ra_perf_table(prices=prices,
                             perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
                                           PerfStat.VOL, PerfStat.SHARPE_RF0,
                                           PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
                                           PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
                                           PerfStat.SKEWNESS, PerfStat.KURTOSIS],
                             title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')}",
                             perf_params=perf_params)
# add benchmark regression using excess returns for linear beta
# regression frequency is specified using perf_params.freq_reg
# regression alpha is multiplied using alpha_an_factor
fig, _ = qis.plot_ra_perf_table_benchmark(prices=prices,
                                          benchmark='SPY',
                                          perf_columns=[PerfStat.TOTAL_RETURN, PerfStat.PA_RETURN, PerfStat.PA_EXCESS_RETURN,
                                                        PerfStat.VOL, PerfStat.SHARPE_RF0,
                                                        PerfStat.SHARPE_EXCESS, PerfStat.SORTINO_RATIO, PerfStat.CALMAR_RATIO,
                                                        PerfStat.MAX_DD, PerfStat.MAX_DD_VOL,
                                                        PerfStat.SKEWNESS, PerfStat.KURTOSIS,
                                                        PerfStat.ALPHA_AN, PerfStat.BETA, PerfStat.R2],
                                          title=f"Risk-adjusted performance: {qis.get_time_period_label(prices, date_separator='-')} benchmarked with SPY",
                                          perf_params=perf_params)

image info

2. Multi assets factsheet

This report is adopted for reporting the risk-adjusted performance of several assets with the goal of cross-sectional comparision

Run examples/factsheets/multi_assets.py.

image info

3. Strategy factsheet

This report is adopted for report performance, risk, and trading statistics for either backtested or actual strategy with strategy data passed as PortfolioData object

Run examples/factsheets/strategy.py.

image info image info image info

4. Strategy benchmark factsheet

This report is adopted for report performance and marginal comparison of strategy vs a benchmark strategy (data for both are passed using individual PortfolioData object)

Run examples/factsheets/strategy_benchmark.py.

image info

Brinson-Fachler performance attribution (https://en.wikipedia.org/wiki/Performance_attribution) image info

5. Multi strategy factsheet

This report is adopted to examine the sensitivity of backtested strategy to a parameter or set of parameters:

Run examples/factsheets/multi_strategy.py.

image info

6. Runnable examples

The examples are plain scripts under examples/, each runnable top to bottom. src/qis/tests/test_examples.py checks them for symbols and keyword arguments that exist, and runs the examples that need no data vendor.

The four factsheet archetypes shown above are multi_assets.py, strategy.py, strategy_benchmark.py and multi_strategy.py.

The consolidated tracking-error analytics are demonstrated offline in ex_anti_tracking_error_and_risk.py for the covariance-based ex-ante view and ex_post_tracking_error_and_risk.py for realised EWMA tracking error, whole-sample TE/IR, and EWMA beta/alpha.

Ecosystem

This package is part of an open-source Python stack for quantitative finance — full catalogue at github.com/ArturSepp:

Package Purpose
qis (this package) Performance and risk analytics, factsheets, and visualisation
optimalportfolios Portfolio construction and backtesting
factorlasso Sparse factor models and factor covariance estimation
bbg-fetch Bloomberg data fetching
trendfollowing Trend-following systems: closed-form theory and replication
privateassets Private-asset return unsmoothing and capital market assumptions
goal-based-allocation Dynamic MV allocation under regime-switching jump-diffusions
stochvolmodels Stochastic volatility pricing analytics
vanilla-option-pricers Vectorised vanilla option pricers and implied volatility fitters

Dependency links within the stack: optimalportfolios builds on qis and factorlasso; trendfollowing and privateassets build on qis.

Contributions

If you are interested in extending and improving QIS analytics, please consider contributing to the library.

I have found it is a good practice to isolate general purpose and low level analytics and visualizations, which can be outsourced and shared, while keeping the focus on developing high level commercial applications.

There are a number of requirements:

  • The code is Pep 8 compliant

  • Reliance on common Python data types including numpy arrays, pandas, and dataclasses.

  • Transparent naming of functions and data types with enough comments. Type annotations of functions and arguments is a must.

  • Each submodule has a unit test for core functions and a localised entry point to core functions.

  • Avoid "super" pythonic constructions. Readability is the priority.

Changelog

Release history is maintained in CHANGELOG.md.

ToDos

  1. Enhanced documentation and readme examples.

  2. Docstrings for key functions.

  3. Reporting analytics and factsheets generation enhancing to matplotlib.

License

MIT — see LICENSE.txt.

Disclaimer

QIS package is distributed FREE & WITHOUT ANY WARRANTY under the MIT License.

See the LICENSE.txt in the release for details.

Please report any bugs or suggestions by opening an issue.

Citation

If you use QIS in your research, please cite it as:

@software{sepp2026qis,
  title={qis: Implementation of visualisation and reporting analytics for Quantitative Investment Strategies},
  author={Sepp, Artur},
  year={2026},
  version={5.11.1},
  url={https://github.com/ArturSepp/QuantInvestStrats}
}

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qis-5.11.1.tar.gz (614.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qis-5.11.1-py3-none-any.whl (716.2 kB view details)

Uploaded Python 3

File details

Details for the file qis-5.11.1.tar.gz.

File metadata

  • Download URL: qis-5.11.1.tar.gz
  • Upload date:
  • Size: 614.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for qis-5.11.1.tar.gz
Algorithm Hash digest
SHA256 34e43f551dab7db83e52d6c3555c86104eb19000b370128619ae7fe29511ed18
MD5 1621a7990bb9db0f4128c9c1560ff2e3
BLAKE2b-256 aa8893a4aa18ebd42a9ae01e5db98d066d645d66d8a35c9da75171611f86e22d

See more details on using hashes here.

File details

Details for the file qis-5.11.1-py3-none-any.whl.

File metadata

  • Download URL: qis-5.11.1-py3-none-any.whl
  • Upload date:
  • Size: 716.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for qis-5.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d97ff502b297ddbe2cdfb663eb8058753d16632d70bb86ca42f45673277e1274
MD5 56014baed48a41a9ccdf6dc6f6275529
BLAKE2b-256 41a4bd0d26938932f56696aef4d559a7cb88d945885554454991053c6bd5983d

See more details on using hashes here.

Release history Release notifications | RSS feed

5.12.0

2 files

5.11.3

2 files

5.11.2

2 files

This release

5.11.1 This release

2 files

5.11.0

2 files

5.10.0

2 files

5.9.4

2 files

5.9.3

2 files

5.9.2

2 files

5.9.1

2 files

5.8.0

2 files

5.7.0

2 files

5.6.2

2 files

5.6.1

2 files

5.6.0

2 files

5.5.0

2 files

5.4.0

2 files

5.3.0

2 files

5.2.1

2 files

5.2.0

2 files

5.1.0

2 files

5.0.10

1 file

5.0.9

1 file

5.0.8

1 file

5.0.7

1 file

5.0.6

1 file

5.0.5

1 file

5.0.4

1 file

5.0.3

1 file

5.0.2

1 file

5.0.1

1 file

5.0.0

1 file

4.3.4

1 file

4.3.3

1 file

4.3.2

1 file

4.3.1

1 file

4.3.0

1 file

4.2.7

2 files

4.2.6

2 files

4.2.5

2 files

4.2.4

2 files

4.2.3

1 file

4.2.2

2 files

4.2.1

2 files

4.2.0

2 files

4.1.5

2 files

4.1.4

2 files

4.1.3

1 file

4.1.2

1 file

4.1.1

1 file

4.0.4

2 files

4.0.3

2 files

4.0.2

2 files

4.0.1

2 files

4.0.0

1 file

3.5.6

1 file

3.5.5

1 file

3.5.4

1 file

3.5.3

1 file

3.5.2

1 file

3.5.1

1 file

3.4.7

1 file

3.4.6

1 file

3.4.5

1 file

3.4.4

1 file

3.4.3

1 file

3.4.2

1 file

3.4.1

1 file

3.3.21

1 file

3.3.20

1 file

3.3.19

1 file

3.3.18

1 file

3.3.17

1 file

3.3.16

1 file

3.3.15

1 file

3.3.14

1 file

3.3.13

1 file

3.3.12

1 file

3.3.11

1 file

3.3.10

1 file

3.3.9

1 file

3.3.8

1 file

3.3.7

1 file

3.3.6

1 file

3.3.5

1 file

3.3.4

1 file

3.3.3

1 file

3.3.2

1 file

3.3.1

1 file

3.2.30

1 file

3.2.29

1 file

3.2.28

1 file

3.2.27

1 file

3.2.26

1 file

3.2.25

1 file

3.2.24

1 file

3.2.23

1 file

3.2.22

1 file

3.2.21

1 file

3.2.20

1 file

3.2.19

1 file

3.2.18

1 file

3.2.17

1 file

3.2.15

1 file

3.2.14

1 file

3.2.12

1 file

3.2.11

1 file

3.2.10

1 file

3.2.9

1 file

3.2.8

1 file

3.2.7

1 file

3.2.5

1 file

3.2.4

1 file

3.2.3

1 file

3.2.2

1 file

3.2.1

1 file

3.1.6

1 file

3.1.5

1 file

3.1.4

1 file

3.1.3

1 file

3.1.2

1 file

3.1.1

1 file

3.0.10

1 file

3.0.9

1 file

3.0.8

1 file

3.0.7

1 file

3.0.6

1 file

3.0.5

1 file

3.0.4

1 file

3.0.3

1 file

3.0.2

1 file

3.0.1

1 file

2.1.40

1 file

2.1.38

1 file

2.1.37

1 file

2.1.36

1 file

2.1.35

1 file

2.1.34

1 file

2.1.33

1 file

2.1.32

1 file

2.1.31

1 file

2.1.30

1 file

2.1.29

1 file

2.1.28

1 file

2.1.27

1 file

2.1.26

1 file

2.1.25

1 file

2.1.24

1 file

2.1.23

1 file

2.1.22

1 file

2.1.21

1 file

2.1.20

1 file

2.1.19

1 file

2.1.18

1 file

2.1.17

1 file

2.1.16

1 file

2.1.15

1 file

2.1.14

1 file

2.1.13

1 file

2.1.11

1 file

2.1.10

1 file

2.1.9

1 file

2.1.8

1 file

2.1.7

1 file

2.1.6

1 file

2.1.5

1 file

2.1.4

1 file

2.1.3

1 file

2.1.2

1 file

2.1.1

1 file

2.0.94

1 file

2.0.93

1 file

2.0.92

1 file

2.0.91

1 file

2.0.90

1 file

2.0.89

1 file

2.0.88

1 file

2.0.87

1 file

2.0.86

1 file

2.0.85

1 file

2.0.84

1 file

2.0.83

1 file

2.0.82

1 file

2.0.81

1 file

2.0.80

1 file

2.0.79

1 file

2.0.78

1 file

2.0.77

1 file

2.0.75

1 file

2.0.74

1 file

2.0.73

1 file

1.0.8

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page