Portfolio analytics for quants, written in Python

ranaroussi, updated ๐Ÿ•ฅ 2023-02-21 07:31:35

.. image:: https://img.shields.io/badge/python-3.6+-blue.svg?style=flat :target: https://pypi.python.org/pypi/quantstats :alt: Python version

.. image:: https://img.shields.io/pypi/v/quantstats.svg?maxAge=60 :target: https://pypi.python.org/pypi/quantstats :alt: PyPi version

.. image:: https://img.shields.io/pypi/status/quantstats.svg?maxAge=60 :target: https://pypi.python.org/pypi/quantstats :alt: PyPi status

.. image:: https://img.shields.io/travis/ranaroussi/quantstats/main.svg?maxAge=1 :target: https://travis-ci.com/github/ranaroussi/quantstats :alt: Travis-CI build status

.. image:: https://img.shields.io/pypi/dm/quantstats.svg?maxAge=2592000&label=installs&color=%2327B1FF :target: https://pypi.python.org/pypi/quantstats :alt: PyPi downloads

.. image:: https://www.codefactor.io/repository/github/ranaroussi/quantstats/badge :target: https://www.codefactor.io/repository/github/ranaroussi/quantstats :alt: CodeFactor

.. image:: https://img.shields.io/github/stars/ranaroussi/quantstats.svg?style=social&label=Star&maxAge=60 :target: https://github.com/ranaroussi/quantstats :alt: Star this repo

.. image:: https://img.shields.io/twitter/follow/aroussi.svg?style=social&label=Follow&maxAge=60 :target: https://twitter.com/aroussi :alt: Follow me on twitter


QuantStats: Portfolio analytics for quants

QuantStats Python library that performs portfolio profiling, allowing quants and portfolio managers to understand their performance better by providing them with in-depth analytics and risk metrics.

Changelog ยป <./CHANGELOG.rst>__

QuantStats is comprised of 3 main modules: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  1. quantstats.stats - for calculating various performance metrics, like Sharpe ratio, Win rate, Volatility, etc.
  2. quantstats.plots - for visualizing performance, drawdowns, rolling statistics, monthly returns, etc.
  3. quantstats.reports - for generating metrics reports, batch plotting, and creating tear sheets that can be saved as an HTML file.

Here's an example of a simple tear sheet analyzing a strategy:

Quick Start

.. code:: python

%matplotlib inline
import quantstats as qs

# extend pandas functionality with metrics, etc.

# fetch the daily returns for a stock
stock = qs.utils.download_returns('FB')

# show sharpe ratio

# or using extend_pandas() :)


.. code:: text


Visualize stock performance ~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python

qs.plots.snapshot(stock, title='Facebook Performance')

# can also be called via:
# stock.plot_snapshot(title='Facebook Performance')


.. image:: https://github.com/ranaroussi/quantstats/blob/main/docs/snapshot.jpg?raw=true :alt: Snapshot plot

Creating a report ~~~~~~~~~~~~~~~~~

You can create 7 different report tearsheets:

  1. qs.reports.metrics(mode='basic|full", ...) - shows basic/full metrics
  2. qs.reports.plots(mode='basic|full", ...) - shows basic/full plots
  3. qs.reports.basic(...) - shows basic metrics and plots
  4. qs.reports.full(...) - shows full metrics and plots
  5. qs.reports.html(...) - generates a complete report as html

Let' create an html tearsheet

.. code:: python

(benchmark can be a pandas Series or ticker)
qs.reports.html(stock, "SPY")

Output will generate something like this:

.. image:: https://github.com/ranaroussi/quantstats/blob/main/docs/report.jpg?raw=true :alt: HTML tearsheet

(view original html file <https://rawcdn.githack.com/ranaroussi/quantstats/main/docs/tearsheet.html>_)

To view a complete list of available methods, run ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python

[f for f in dir(qs.stats) if f[0] != '_']

.. code:: text


.. code:: python

[f for f in dir(qs.plots) if f[0] != '_']

.. code:: text


*** Full documenttion coming soon ***

In the meantime, you can get insights as to optional parameters for each method, by using Python's help method:

.. code:: python


.. code:: text

Help on function conditional_value_at_risk in module quantstats.stats:

conditional_value_at_risk(returns, sigma=1, confidence=0.99)
    calculats the conditional daily value-at-risk (aka expected shortfall)
    quantifies the amount of tail risk an investment


Install using pip:

.. code:: bash

$ pip install quantstats --upgrade --no-cache-dir

Install using conda:

.. code:: bash

$ conda install -c ranaroussi quantstats


  • Python <https://www.python.org>_ >= 3.5+
  • pandas <https://github.com/pydata/pandas>_ (tested to work with >=0.24.0)
  • numpy <http://www.numpy.org>_ >= 1.15.0
  • scipy <https://www.scipy.org>_ >= 1.2.0
  • matplotlib <https://matplotlib.org>_ >= 3.0.0
  • seaborn <https://seaborn.pydata.org>_ >= 0.9.0
  • tabulate <https://bitbucket.org/astanin/python-tabulate>_ >= 0.8.0
  • yfinance <https://github.com/ranaroussi/yfinance>_ >= 0.1.38
  • plotly <https://plot.ly/>_ >= 3.4.1 (optional, for using plots.to_plotly())


This is a new library... If you find a bug, please open an issue <https://github.com/ranaroussi/quantstats/issues>_ in this repository.

If you'd like to contribute, a great place to look is the issues marked with help-wanted <https://github.com/ranaroussi/quantstats/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22>_.

Known Issues

For some reason, I couldn't find a way to tell seaborn not to return the monthly returns heatmap when instructed to save - so even if you save the plot (by passing savefig={...}) it will still show the plot.

Legal Stuff

QuantStats is distributed under the Apache Software License. See the LICENSE.txt <./LICENSE.txt>_ file in the release for details.


Please drop me a note with any feedback you have.

Ran Aroussi


"Daily Returns" chart better use scatter plot

opened on 2023-02-23 04:19:42 by RuralHunter

Currently we use line chart for it and it seems a bit odd.

Chart "Monthly Returns (%)" shows all zero

opened on 2023-02-22 06:23:00 by RuralHunter

Hi, I'm running quantstats on Ubuntu 20.04 and found the "Monthly Returns (%)" chart shows all "0.0" for every months. Other charts are all fine. I run the same code on another Windows system and the "Monthly Returns (%)" is fine. Not sure what's the problem on the Ubuntu system.

Update reports.py

opened on 2023-02-21 07:31:35 by grizzlybearg

Fixed import due to depracation warning below: Importing display from IPython.core.display is deprecated since IPython 7.14, please import from IPython display

Benchmark data not showing via qs.reports.html

opened on 2023-02-16 13:03:21 by Temjinck


I'm trying to generate the full report for the returns and benchmark series. For example,

qs.reports.html(returns, benckmark=benchmark, rf=0.0, output='', download_filename='quantstats-returns.html', match_dates=True)

The issue is that it would only plot the returns data. The benchmark data does not show up in the plot nor there is a second column in the performance table.

Funny enough, if i use this code, qs.reports.full(returns, benchmark), the IDE would display both tables and all the plots with both set of data (returns and benchmark).

So it seems the qs.reports.html is not working.

Any ideas?

Automatically update GitHub Actions

opened on 2023-02-10 00:51:48 by jgopel

Problem: - GitHub Actions are versioned. There is currently no way of automatically updating to the latest actions.

Solution: - Have dependabot update GitHub Actions.

Question: Which period to choose for Sharpe Ratio calculation based on my use-case?

opened on 2023-02-08 14:11:03 by WoodWorker49

Hi @ranaroussi

First of all, I must thank you for your two amazing projects.

Let me now dive into my question: - Context: I want to compute the Sharpe Ratio of my portfolio consisting of daily results. For now, I only have 1 week of daily results, meaning ~ 5-6 results. - Problem: Leaving the Sharpe Ratio method as-is, the Sharpe Ratio is way too high: around 15!

What I know - I've read in another github issue https://github.com/ranaroussi/quantstats/issues/116 that I needed to change the period in the sharpe ratio method, for instance by overwriting it with a smaller period, which I did with period=52 and period=12. - Another user was mentioning setting trading_year_days=52 for weekly, so I am a bit lost - However, I still believe that the Sharpe Ratio is too high when using these periods. - The Sharpe Ratio seems better when using period=6 or period=4 or period=3, but I have no idea which period I should really use.

Question - I would like to know and understand the relationship between the number of daily results I've got, and the period value I should set in the Sharpe Ratio method, to be as close as possible to a realistic Sharpe Ratio Value - Keep in mind that for now, I only have access to 1 week of daily results, but not the entire month. - Are you able to advise the rule of thumb in that case ? - How about the trading_year_days, does it really need to be modified?

Thanks in advance


0.0.59 2022-07-05 09:18:24

Fixed EOY compounded return calculation

0.0.58 2022-06-14 17:28:42

  • Run fillna(0) on plot's beta (issue #193)

0.0.57 2022-06-12 16:32:48

Fixed sigma calculation in stats.probabilistic_ratio()

0.0.56 2022-05-02 09:49:09

Added option to explicitly provide the benchmark title in html reports via benchmark_title=...

0.0.55 2022-05-01 22:04:06

Fix for benchmark name in html report when supplied by the user

0.0.54 2022-04-28 20:09:46

Fixed dependency name in requirements.txt

Ran Aroussi

Founder @Tradologics. Creating tools to help people work smarter, not harder. Programming is how I meditate.

GitHub Repository

quant algotrading algorithmic-trading quantitative-trading quantitative-analysis algo-trading python visualization plotting quantitative-finance finance