Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 50 additions & 140 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,25 @@

**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.md)

### 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.

---

### **NEW! Monte Carlo Simulations**

<img src="https://raw.githubusercontent.com/ranaroussi/pandas-montecarlo/master/demo.png" alt="Monte Carlo Simulation" width="640">

Run probabilistic risk analysis with built-in Monte Carlo simulations:
## Navigation
- [Quick Start](#quick-start)
- [Understanding Returns](#understanding-returns-important)
- [Documentation](docs/docs_and_api_ref.md)
- [NEW! Monte Carlo Simulations](docs/montecarlo.md)
- [Installation](#installation)
- [Questions and Contributions](#questions-and-contributions)
- [Changelog »](./CHANGELOG.md)

```python
mc = qs.stats.montecarlo(returns, sims=1000, bust=-0.20, goal=0.50)
print(f"Bust probability: {mc.bust_probability:.1%}")
print(f"Goal probability: {mc.goal_probability:.1%}")
mc.plot()
```

[Full Monte Carlo documentation »](./docs/montecarlo.md)
## Quick Start

---
### QuantStats is comprised of 3 main modules:

## Quick Start
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.

```python
%matplotlib inline
Expand All @@ -47,13 +38,13 @@ import quantstats as qs
qs.extend_pandas()

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

# show sharpe ratio
qs.stats.sharpe(stock)
qs.stats.sharpe(returns)

# or using extend_pandas() :)
stock.sharpe()
returns.sharpe()
```

Output:
Expand All @@ -71,9 +62,15 @@ qs.plots.snapshot(stock, title='Facebook Performance', show=True)
# stock.plot_snapshot(title='Facebook Performance', show=True)
```

Output:
Output (full-size version [here](https://github.com/ranaroussi/quantstats/blob/main/docs/snapshot.webp?raw=true)):

![Snapshot plot](https://github.com/ranaroussi/quantstats/blob/main/docs/snapshot.webp?raw=true)
<p align="center">
<img
src="https://github.com/ranaroussi/quantstats/blob/main/docs/snapshot.webp?raw=true"
alt="Snapshot plot"
width="450"
/>
</p>

### Creating a report

Expand All @@ -92,113 +89,39 @@ Let's create an html tearsheet:
qs.reports.html(stock, "SPY")
```

Output will generate something like this:

![HTML tearsheet](https://github.com/ranaroussi/quantstats/blob/main/docs/report.webp?raw=true)

[View original html file](https://rawcdn.githack.com/ranaroussi/quantstats/main/docs/tearsheet.html)

### Available methods
Output (full-size version [here](https://rawcdn.githack.com/ranaroussi/quantstats/main/docs/tearsheet.html)):

To view a complete list of available methods, run:
<p align="center">
<img
src="https://github.com/ranaroussi/quantstats/blob/main/docs/report.webp?raw=true"
alt="HTML tearsheet"
width="450"
/>
</p>

### The Returns object
As seen in previous examples, QuantStat's primary input is a time-series:
```python
[f for f in dir(qs.stats) if f[0] != '_']
returns = qs.utils.download_returns('META')
qs.stats.sharpe(returns)
```

Or a dataframe (several series with a shared index):
```python
['avg_loss',
'avg_return',
'avg_win',
'best',
'cagr',
'calmar',
'common_sense_ratio',
'comp',
'compare',
'compsum',
'conditional_value_at_risk',
'consecutive_losses',
'consecutive_wins',
'cpc_index',
'cvar',
'drawdown_details',
'expected_return',
'expected_shortfall',
'exposure',
'gain_to_pain_ratio',
'geometric_mean',
'ghpr',
'greeks',
'implied_volatility',
'information_ratio',
'kelly_criterion',
'kurtosis',
'max_drawdown',
'monthly_returns',
'montecarlo',
'montecarlo_cagr',
'montecarlo_drawdown',
'montecarlo_sharpe',
'outlier_loss_ratio',
'outlier_win_ratio',
'outliers',
'payoff_ratio',
'profit_factor',
'profit_ratio',
'r2',
'r_squared',
'rar',
'recovery_factor',
'remove_outliers',
'risk_of_ruin',
'risk_return_ratio',
'rolling_greeks',
'ror',
'sharpe',
'skew',
'sortino',
'adjusted_sortino',
'tail_ratio',
'to_drawdown_series',
'ulcer_index',
'ulcer_performance_index',
'upi',
'value_at_risk',
'var',
'volatility',
'win_loss_ratio',
'win_rate',
'worst']
returns = DataFrame()
returns["META"] = qs.utils.download_returns('META')
returns["TSLA"] = qs.utils.download_returns('TSLA')
qs.stats.sharpe(returns)
```

```python
[f for f in dir(qs.plots) if f[0] != '_']
```
Quantstats makes several notable assumptions about this object by default:
1. This is a daily (`datetime64[s]` index) time-series of returns (`float64`). These returns are the percent gain from the previous period (e.g. 10% growth -> 0.1, NOT 1.1).
2. There are 252 periods (rows) in a year (not 365!) corresponding to the number of trading days in the U.S. stock market. Many methods assume this amount of periods by default; if you have substantially more or less data in your time-series, the annualization math may be skewed.
3. For an example of correctly shaped returns, see time-series returned by `qs.utils.download_returns()`

```python
['daily_returns',
'distribution',
'drawdown',
'drawdowns_periods',
'earnings',
'histogram',
'log_returns',
'monthly_heatmap',
'montecarlo',
'montecarlo_distribution',
'returns',
'rolling_beta',
'rolling_sharpe',
'rolling_sortino',
'rolling_volatility',
'snapshot',
'yearly_returns']
```

**\*\*\* Full documentation coming soon \*\*\***
## Additional Notes

### Important: Period-Based vs Trade-Based Metrics
### Period-Based vs Trade-Based Metrics

QuantStats analyzes **return series** (daily, weekly, monthly returns), not discrete trade data. This means:

Expand All @@ -216,17 +139,9 @@ For **discretionary traders** with multi-day trades, these period-based metrics

This is consistent with how all return-based analytics work (Sharpe ratio, Sortino ratio, drawdown analysis, etc.) - they operate on return periods, not discrete trade entries/exits.

---

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

```python
help(qs.stats.conditional_value_at_risk)
```

### Help on function conditional_value_at_risk in module quantstats.stats:
```
Help on function conditional_value_at_risk in module quantstats.stats:

conditional_value_at_risk(returns, sigma=1, confidence=0.99)
calculates the conditional daily value-at-risk (aka expected shortfall)
quantifies the amount of tail risk an investment
Expand All @@ -246,7 +161,7 @@ Install using `conda`:
$ conda install -c ranaroussi quantstats
```

## Requirements
### Requirements

* [Python](https://www.python.org) >= 3.10
* [pandas](https://github.com/pydata/pandas) >= 1.5.0
Expand All @@ -258,19 +173,14 @@ $ conda install -c ranaroussi quantstats
* [yfinance](https://github.com/ranaroussi/yfinance) >= 0.2.40
* [plotly](https://plot.ly/) >= 5.0.0 (optional, for using `plots.to_plotly()`)

## Questions?
## Questions and Contributions

This is a new library... If you find a bug, please
[open an issue](https://github.com/ranaroussi/quantstats/issues).

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.
Expand Down
Loading