Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
385 commits
Select commit Hold shift + click to select a range
9e9d16e
Fixed rolling_sortino #129
ranaroussi Oct 10, 2021
fe74b32
Added prepare_returns flag to utils._prepare_benchmark()
ranaroussi Oct 10, 2021
b9c54aa
Added match_dates flag to reports to make
ranaroussi Oct 10, 2021
7322c36
removed unused param
ranaroussi Oct 10, 2021
dc41a1b
v# + clog
ranaroussi Oct 10, 2021
820b183
fix an typo where a cumprod series, not compound value is returned in…
taohu88 Oct 12, 2021
9d693c5
For yearly_return, fix a typo where a cumprod series, not a single co…
taohu88 Oct 12, 2021
bf5ca75
Merge branch 'main' of github.com:blackcherry88/quantstats
taohu88 Oct 12, 2021
4b3a453
Match dates logic on make_index function
galarosa Oct 23, 2021
b4e919b
Merge pull request #140 from galarosa/main
ranaroussi Oct 25, 2021
19ec292
v# + clog
ranaroussi Oct 25, 2021
e67b4c1
Update stats.py
kartiksubbarao Oct 31, 2021
214b68a
Merge pull request #143 from kartiksubbarao/main
ranaroussi Oct 31, 2021
0228606
v# + clog
ranaroussi Oct 31, 2021
c185479
remove duplicate type check
lau-jay Nov 16, 2021
d35f474
Merge pull request #148 from lau-jay/main
ranaroussi Nov 16, 2021
8b2389c
Merge pull request #134 from blackcherry88/main
ranaroussi Nov 16, 2021
0a095a4
fixed as_pct bug in dd
ranaroussi Nov 16, 2021
f79c140
v# + clog
ranaroussi Nov 16, 2021
52e0959
Fixed average DD display bug
ranaroussi Dec 1, 2021
bb67e58
v# + clog
ranaroussi Dec 1, 2021
88306cc
temporary fix for: Rf rate when not 0 metrics are incorrectly calcula…
BartStolarek Jan 14, 2022
d2ee0b2
added a x100 on metrics[
BartStolarek Jan 19, 2022
e3e7f3f
Merge pull request #159 from BartStolarek/temp-fix-for-Rf-rate-report
ranaroussi Jan 22, 2022
d1a71ed
merged pr #159
ranaroussi Jan 22, 2022
4ebdb12
removed support for python
ranaroussi Jan 22, 2022
3f6d42f
removed support for python 3.5
ranaroussi Jan 22, 2022
5132f94
Added PiP uploader
ranaroussi Jan 22, 2022
412f00d
opening correct file stream for html save
yarimiz Feb 14, 2022
99efe5d
Merge pull request #164 from yarimiz/main
ranaroussi Feb 14, 2022
a0d9651
Update requirements.txt
ranaroussi Feb 14, 2022
0c7c87e
Update version.py
ranaroussi Feb 14, 2022
6d2f078
Update CHANGELOG.rst
ranaroussi Feb 14, 2022
0cac4f9
fixed a bug when reporting the max drawdown
Feb 14, 2022
30be30c
Merge pull request #165 from msh855/msh855Branch
ranaroussi Feb 14, 2022
fa9fe3d
Update version.py
ranaroussi Feb 14, 2022
1445fe5
Update CHANGELOG.rst
ranaroussi Feb 14, 2022
317a058
adding benchmark name to html report
yarimiz Feb 15, 2022
cb23e8e
fix errror for date calculations
Amirnajafi Mar 3, 2022
161a646
fix months calculations
Amirnajafi Mar 17, 2022
a575ff6
added probabilistic sharpe/sortino ratios
ranaroussi Apr 23, 2022
28370d7
Merge pull request #170 from Amirnajafi/main
ranaroussi Apr 23, 2022
8e3910b
Merge pull request #166 from yarimiz/include-benchmark-name-in-html
ranaroussi Apr 23, 2022
a31de28
added dateutil
ranaroussi Apr 23, 2022
eb1bf64
Merge branch 'main' of github.com:ranaroussi/quantstats
ranaroussi Apr 23, 2022
08233d7
format report header
ranaroussi Apr 23, 2022
b9f4ecd
added benchmark name to column
ranaroussi Apr 23, 2022
e105d35
removed spaces
ranaroussi Apr 23, 2022
e790746
cleanup inf/nan from reports
ranaroussi Apr 23, 2022
8de9c68
added “correlation to benchmark” to report
ranaroussi Apr 23, 2022
63d4115
added max consecutive wins/losses to full report
ranaroussi Apr 23, 2022
b0a5dfa
clog + v#
ranaroussi Apr 23, 2022
507ed96
Added Treynor ratio
ranaroussi Apr 23, 2022
4d2b537
Added information ratio to reports
ranaroussi Apr 28, 2022
de366a0
correct package name
binary-signal Apr 28, 2022
5fdeed1
Merge pull request #1 from binary-signal/binary-signal-patch-package-…
binary-signal Apr 28, 2022
374fa52
Merge pull request #184 from binary-signal/main
ranaroussi Apr 28, 2022
7cf64f8
Update CHANGELOG.rst
ranaroussi Apr 28, 2022
9ee9d70
Update version.py
ranaroussi Apr 28, 2022
b4e3a8c
Fix for benchmark name displayed not correctly
binary-signal May 1, 2022
2a51315
Merge pull request #2 from binary-signal/binary-signal-patch-1
binary-signal May 1, 2022
c326f8d
Merge pull request #186 from binary-signal/main
ranaroussi May 1, 2022
034e908
Update version.py
ranaroussi May 1, 2022
d6d3915
Update CHANGELOG.rst
ranaroussi May 1, 2022
8da8638
Removed extra space
ranaroussi May 2, 2022
b1b0210
Simplified benchmark_title
ranaroussi May 2, 2022
2d084cd
Added option to explicitly provide the benchmark title
ranaroussi May 2, 2022
d3fb3c3
Fixed `sigma_sr` in `probabilistic_ratio`
ranaroussi Jun 12, 2022
0050c23
Update version.py
ranaroussi Jun 12, 2022
acd534b
Update CHANGELOG.rst
ranaroussi Jun 12, 2022
fb4dbb3
fillna() beta #193
ranaroussi Jun 14, 2022
53dcc65
Update CHANGELOG.rst
ranaroussi Jun 14, 2022
f43965f
Update version.py
ranaroussi Jun 14, 2022
017b7ef
add strategy title and reflect changes in tables
s0ap Jun 18, 2022
5306b04
change plot legends to reflect to actual portfolio names
s0ap Jun 19, 2022
35a8c3f
change histogram to plot benchmark as well if present
s0ap Jun 19, 2022
643e9df
added parameter for active returns in the heatmap (defaults to False)
s0ap Jun 19, 2022
c2d2e5a
added parameter for active returns in daily returns plot
s0ap Jun 19, 2022
357f15f
Resolve: Missing argument in function call PYL-E1120
s0ap Jun 19, 2022
2f7a970
cleaner box plot without color fill
s0ap Jun 19, 2022
8a5df7d
modify the codebase to handle multiple strategies in a single report
s0ap Jul 1, 2022
8901a5f
resolve PYL-R1721 and PYL-W0404 found by deepsource
s0ap Jul 1, 2022
1297244
resolve issue found by codefactor
s0ap Jul 1, 2022
b1fedca
Fix EOY compound return bug
TradingDominion Jul 4, 2022
f56f0aa
Merge pull request #200 from TradingDominion/bug-monthly_returns
ranaroussi Jul 5, 2022
cdb2319
Update CHANGELOG.rst
ranaroussi Jul 5, 2022
960657a
Update version.py
ranaroussi Jul 5, 2022
444e182
Merge branch 'main' into table_plot_titles
s0ap Jul 6, 2022
89b6766
Update utils.py
rmfish Oct 26, 2022
5d5c9d4
Closes #33
git-shogg Nov 8, 2022
928f41f
added custom periods to CAGR
Dec 3, 2022
5367bfa
_drawdown_details() correct starts/ends index selection
drusakov778 Dec 14, 2022
256d898
_drawdown_details() 'end' denotes last day of the drawdown
drusakov778 Dec 14, 2022
7b9c199
write report in input output variable instead of default download_fil…
jatorna Feb 1, 2023
e0cde9f
Automatically update GitHub Actions
jgopel Feb 10, 2023
b42c608
Update reports.py
grizzlybearg Feb 21, 2023
b1c5494
fix: type error in pandas 2.0
manhinhang Apr 25, 2023
d6cc9f9
remove timezone from dataframe
ranaroussi Jun 22, 2023
a8451f4
addresses FutureWarning in pivot
ranaroussi Jun 22, 2023
aaebf3c
Merge pull request #263 from manhinhang/fix/pivot-error
ranaroussi Jun 22, 2023
fedfff7
Merge pull request #254 from grizzlybearg/patch-1
ranaroussi Jun 22, 2023
bc51495
fallback import for IPython < 7
ranaroussi Jun 22, 2023
7b6fc7f
Merge pull request #227 from git-shogg/main
ranaroussi Jun 22, 2023
3ee0def
Update README ticker to META
ranaroussi Jun 22, 2023
ac5d9cf
Merge pull request #231 from lbsm2017/cagr_custom_periods
ranaroussi Jun 22, 2023
4103145
Merge pull request #234 from drusakov778/dd_days_fix
ranaroussi Jun 22, 2023
1a89998
Merge pull request #224 from rmfish/main
ranaroussi Jun 22, 2023
6c67014
remove whitespce
ranaroussi Jun 22, 2023
dda41f8
Merge branch 'main' of github.com:ranaroussi/quantstats
ranaroussi Jun 22, 2023
cf300e2
formatting
ranaroussi Jun 22, 2023
ec728fd
cleanup
ranaroussi Jun 22, 2023
208fd7a
Merge pull request #252 from jgopel/dependabot-github-actions
ranaroussi Jun 22, 2023
f6f9049
Bump actions/setup-python from 2 to 4
dependabot[bot] Jun 22, 2023
88034cd
Bump github/codeql-action from 1 to 2
dependabot[bot] Jun 22, 2023
562a2b0
Merge pull request #199 from s0ap/table_plot_titles
ranaroussi Jun 22, 2023
d2cb13a
Merge pull request #270 from ranaroussi/dependabot/github_actions/git…
ranaroussi Jun 22, 2023
2dd4516
Merge pull request #268 from ranaroussi/dependabot/github_actions/act…
ranaroussi Jun 22, 2023
f4f5a21
Merge pull request #248 from jatorna/main
ranaroussi Jun 22, 2023
e151310
use output param
ranaroussi Jun 22, 2023
88177ea
download multiple tickers
ranaroussi Jun 22, 2023
678281b
new ver
ranaroussi Jun 22, 2023
bb46155
Merge branch 'main' of github.com:ranaroussi/quantstats
ranaroussi Jun 22, 2023
bc731c0
Multi-strategy reports
ranaroussi Jun 22, 2023
697358f
fixed single strategy basic report
ranaroussi Jun 22, 2023
2326941
Update README.rst
ranaroussi Jun 22, 2023
964a4b3
cleanup
ranaroussi Jun 23, 2023
b3a522a
updated copyright settings
ranaroussi Jun 23, 2023
82bc267
document formatting using black
ranaroussi Jun 23, 2023
9bb7361
Fixed positional arguments passed to cagr()
ranaroussi Jun 25, 2023
c0a2ad3
explicitly set params for monthly_heatmap
ranaroussi Jul 6, 2023
f6d0d92
passing compounded var to supporting methods
ranaroussi Jul 6, 2023
8d5b6c1
changed formulas from compounded to sum
ranaroussi Jul 6, 2023
fb7b3c5
v# + cl
ranaroussi Jul 6, 2023
857798c
Update reports.py
kartiksubbarao Jul 11, 2023
7422434
Bump actions/checkout from 2 to 4
dependabot[bot] Sep 4, 2023
c288bc3
Updated to allow matplotlib to display plots.
git-shogg Dec 8, 2023
70218b2
Metrics report updated to include key dates of maximum drawdown +blac…
git-shogg Dec 8, 2023
d7dc329
Respect boolean parameter ylabel (disable when False)
A-Weinsziehr Jan 17, 2024
3426e4d
remove cumulative input argument and use only compound option
Jan 21, 2024
4f90876
[add] compound option as long as each function has its option
Jan 21, 2024
53a0514
[fix] compounded False
Feb 3, 2024
169d3f0
Refactor resample parameter to use "ME" instead of "M"
ranaroussi Oct 25, 2024
864dc54
Update copyright year to 2024
ranaroussi Oct 25, 2024
8b76d63
Bump version to 0.0.63
ranaroussi Oct 25, 2024
434e8d7
Misc pd/np compatibility stuff
ranaroussi Oct 25, 2024
8d70575
Misc pd/np compatibility stuff
ranaroussi Oct 25, 2024
0c9bfed
Misc pd/np compatibility stuff
ranaroussi Oct 25, 2024
32fec25
Bump version to 0.0.64
ranaroussi Oct 25, 2024
79926aa
Update version.py
ranaroussi Oct 25, 2024
3449e84
Update reports.py
AlanWoo77 Dec 25, 2024
d574f83
Update reports.py
AlanWoo77 Dec 25, 2024
6858f4d
Fix https://github.com/ranaroussi/quantstats/issues/416
nextdorf Mar 26, 2025
aade3ed
## 🎉 **Implementation Complete!**
ranaroussi Jul 13, 2025
47897ba
## Summary
ranaroussi Jul 13, 2025
bb729fd
## ✅ All Remaining Visualization Issues Fixed!
ranaroussi Jul 13, 2025
62840e9
Great! The code imports successfully. Let me create a summary of all …
ranaroussi Jul 13, 2025
cd1ec19
Perfect! The unnecessary try/except block has been removed since yfin…
ranaroussi Jul 13, 2025
800faec
Great! The test works successfully. The main functionality is working…
ranaroussi Jul 13, 2025
c7ff2ed
# ✅ **ALL ISSUES ADDRESSED - MAJOR TO MINOR!**
ranaroussi Jul 13, 2025
6b66390
## Fixed!
ranaroussi Jul 13, 2025
1626ac2
Fix typos in docstrings for `sharpe`, `sortino`, `cagr`, and `rar` fu…
ranaroussi Jul 13, 2025
ddaa0d7
Bump version to 0.0.64 and update changelog
ranaroussi Jul 13, 2025
1d2278f
Apply suggestion from @Copilot
ranaroussi Jul 13, 2025
b9b6c64
Merge branch 'main' into main
ranaroussi Jul 13, 2025
9b22423
Merge pull request #329 from katsu1110/main
ranaroussi Jul 13, 2025
a68d52d
Merge pull request #327 from alexcalligraphy/FIX-conditional-ylabel-h…
ranaroussi Jul 13, 2025
51ecc36
Merge pull request #395 from AlanWoo77/main
ranaroussi Jul 13, 2025
b14bcc9
Merge pull request #417 from nextdorf/main
ranaroussi Jul 13, 2025
f5c04df
Merge pull request #300 from ranaroussi/dependabot/github_actions/act…
ranaroussi Jul 13, 2025
6a7fcc7
Update ylabel parameter in html and plots functions to default to an …
ranaroussi Jul 13, 2025
d338302
Merge PR 322: Update quantstats.reports.metrics to include key dates …
ranaroussi Jul 13, 2025
37a8377
Merge: Merge PR 322 (vibe-kanban)
ranaroussi Jul 13, 2025
c5148b2
Add .flake8 configuration for style checks and update copyright year …
ranaroussi Jul 13, 2025
e668cc6
## Summary
ranaroussi Jul 13, 2025
dfa6eb1
Refactor drawdown-related keys in reports and improve whitespace cons…
ranaroussi Jul 13, 2025
9bcedc8
Refactor and enhance type safety in quantstats
ranaroussi Jul 14, 2025
116056a
Replace JPEG images with WEBP format and update tearsheet HTML header
ranaroussi Jul 14, 2025
ebbae0c
Enhance compatibility and documentation in quantstats modules
ranaroussi Jul 14, 2025
509ae10
Update README with new output values and image format changes
ranaroussi Jul 14, 2025
de6b600
updated gitignore
ranaroussi Jul 14, 2025
2c3384f
Refactor drawdown metrics in reports for clarity and consistency
ranaroussi Jul 14, 2025
c7d9fa8
Add raw_data parameter to plot_timeseries and drawdown functions
ranaroussi Jul 14, 2025
3a8f432
converted to md
ranaroussi Jul 14, 2025
b0fb0b7
cleanup
ranaroussi Jul 14, 2025
f150d80
cleanup
ranaroussi Jul 14, 2025
0c1a1d4
update report in docs
ranaroussi Jul 14, 2025
112ec1d
Updated link to changelog
ranaroussi Jul 14, 2025
6a4bd5c
Delete meta.yaml
ranaroussi Jul 14, 2025
c5a6645
Merge branch 'main' into patch-1
ranaroussi Jul 18, 2025
18b53fe
Merge pull request #279 from kartiksubbarao/patch-1
ranaroussi Jul 18, 2025
43860a8
Update version.py
ranaroussi Jul 18, 2025
de845fe
Update reports.py
kartiksubbarao Jul 18, 2025
4258d6c
Merge pull request #444 from kartiksubbarao/patch-1
ranaroussi Jul 18, 2025
50ddacd
merge PR #444 (vibe-kanban 346f7684)
ranaroussi Jul 18, 2025
fbc8c3f
Close stale issues (vibe-kanban fac289b1)
ranaroussi Jul 18, 2025
9610194
Max DD (vibe-kanban 5503a9f9)
ranaroussi Jul 18, 2025
6e29c60
Update version to 0.0.66 and fix formatting in stats.py
ranaroussi Jul 18, 2025
0401896
Update CHANGELOG for version 0.0.66: fix drawdown calculation bug
ranaroussi Jul 18, 2025
79220a4
Issue 445 has been successfully fixed! Here's a summary of what was c…
ranaroussi Jul 20, 2025
b2e2260
Delete logs/pre_tool_use.json
ranaroussi Jul 20, 2025
cb6df8a
Delete logs/post_tool_use.json
ranaroussi Jul 20, 2025
608fbd4
Merge pull request #447 from ranaroussi/vk-2b7f-please-fix
ranaroussi Jul 20, 2025
a1cfac8
Fix ValueError when comparing Series with scalar (Issue #448)
ranaroussi Jul 22, 2025
1ec0f03
Using .iat[0, 0] for better performance and clarity
ranaroussi Jul 22, 2025
877478d
Handling empty DataFrames or DataFrames with no columns
ranaroussi Jul 22, 2025
d541395
Merge pull request #450 from ranaroussi/fix-issue-448
ranaroussi Jul 22, 2025
4149714
Delete DRAWDOWN_FIX_SUMMARY.md
ranaroussi Jul 22, 2025
0a8ef3a
Delete .github/workflows/codeql-analysis.yml
ranaroussi Jul 22, 2025
4948298
Add periods parameter to calmar() function (fixes #455)
ranaroussi Jul 30, 2025
8029063
Merge pull request #456 from ranaroussi/fix-issue-455
ranaroussi Jul 30, 2025
34a2a12
Fix inconsistent EOY returns for benchmarks (fixes #457)
ranaroussi Aug 7, 2025
c7d1708
Fix CAGR calculation bug (fixes #458)
ranaroussi Aug 7, 2025
b95e77e
Merge pull request #459 from ranaroussi/fix-issue-457
ranaroussi Aug 7, 2025
4958654
Merge pull request #460 from ranaroussi/analyze-issue-458-vs-457
ranaroussi Aug 7, 2025
8ef9794
Fix chart naming to indicate cumulative returns (fixes #454)
ranaroussi Aug 7, 2025
aeab745
Merge pull request #461 from ranaroussi/fix-issue-454-chart-naming
ranaroussi Aug 7, 2025
e663ccf
Fix RuntimeWarnings in tail_ratio function
ranaroussi Aug 14, 2025
eec5cfc
Bump version to 0.0.71 and update changelog
ranaroussi Aug 14, 2025
7179ba4
Fix tail_ratio to handle DataFrame inputs properly
ranaroussi Aug 14, 2025
f669282
Fix additional divide by zero warnings in stats functions
ranaroussi Aug 14, 2025
821d69c
Add comprehensive divide by zero protection across stats functions
ranaroussi Aug 14, 2025
0a86645
Update CHANGELOG.md with comprehensive list of division by zero fixes…
ranaroussi Aug 14, 2025
0ca0d25
Fix sortino to handle DataFrame inputs properly
ranaroussi Aug 14, 2025
d6a11f9
Fix multiple stats functions to handle DataFrame inputs properly
ranaroussi Aug 14, 2025
2126658
Bump version to 0.0.72 and update changelog
ranaroussi Aug 14, 2025
3b98ca0
Fix payoff_ratio to handle DataFrame inputs (fixes #463)
ranaroussi Aug 15, 2025
cfdfb59
Bump version to 0.0.73 and update changelog
ranaroussi Aug 15, 2025
0b2d281
Fix remaining DataFrame handling issues in kelly_criterion and recove…
ranaroussi Aug 17, 2025
5d75896
Bump version to 0.0.74 and update changelog
ranaroussi Aug 17, 2025
75066a1
Fix FutureWarning for pandas frequency aliases
ranaroussi Aug 18, 2025
683447d
Fix issue #457: Benchmark EOY returns now consistent across comparisons
ranaroussi Aug 20, 2025
a2d1033
Add comprehensive timezone normalization for cross-market comparisons
ranaroussi Aug 20, 2025
f83547c
Fix FutureWarning for deprecated fill_method in pandas pct_change()
ranaroussi Aug 20, 2025
e8b3dff
fix(stats): fix CVaR calculation for DataFrame inputs
ranaroussi Sep 5, 2025
dfc64d0
chore: bump version to 0.0.77 and update changelog
ranaroussi Sep 5, 2025
defca9b
Merge pull request #471 from ranaroussi/terragon/check-open-issues
ranaroussi Sep 5, 2025
ab9d3f9
feat: 2026 Modernization - Python 3.10+, Monte Carlo, Bug Fixes
ranaroussi Jan 13, 2026
eb5d18b
Merge pull request #494 from ranaroussi/ranaroussi/2026-updates
ranaroussi Jan 13, 2026
61e9e1d
docs: clarify period-based vs trade-based metrics in README
ranaroussi Jan 13, 2026
4856e3c
Merge pull request #495 from ranaroussi/docs/period-based-metrics
ranaroussi Jan 13, 2026
ad708fe
Bump actions/checkout from 4 to 6 (#483)
dependabot[bot] Jan 13, 2026
f6a16f7
chore: remove old test files from root directory (#496)
ranaroussi Jan 13, 2026
3f9bf65
docs: add developer instructions to PROJECT.md (#497)
ranaroussi Jan 13, 2026
fcd6654
docs: add DeepWiki badge to README (#498)
ranaroussi Jan 13, 2026
8d956ce
fix: resolve circular import error on import (#499) (#500)
ranaroussi Jan 13, 2026
f91052f
chore: bump version to 0.0.79
ranaroussi Jan 13, 2026
5d06402
fix: resolve all circular import errors (#499, #501)
ranaroussi Jan 13, 2026
8c09951
fix: dd_stats variable name typo in reports.py (#502)
ranaroussi Jan 13, 2026
9d255e6
fix: misc bugfixes for 0.0.78 release (#499, #501, #502)
ranaroussi Jan 13, 2026
f76ef15
feat: add compounded flag to calmar() for non-compounded return streams
wavebyrd Mar 13, 2026
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
228 changes: 228 additions & 0 deletions .claude/2026-modernization-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
# QuantStats 2026 Modernization Plan

## Overview

Modernize QuantStats for Python 3.10+ with modern tooling, better typing, and bug fixes.

---

## 1. Python Version & Packaging

### Drop Python 3.8/3.9 Support
- **Minimum**: Python 3.10 (or 3.11 for even cleaner code)
- **Benefits**:
- Native `X | Y` union types (no `Union[X, Y]`)
- `match` statements for cleaner branching
- Better error messages
- Structural pattern matching
- Parenthesized context managers

### Migrate setup.py → pyproject.toml
```toml
[project]
name = "quantstats"
requires-python = ">=3.10"
dependencies = [
"pandas>=2.0.0",
"numpy>=1.24.0",
...
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

**Tasks:**
- [x] Create `pyproject.toml` with all metadata
- [x] Remove `setup.py`
- [x] Update classifiers for Python 3.10-3.13 only
- [x] Update `README.md` requirements section

---

## 2. Dependency Updates

| Current | Proposed | Why |
|---------|----------|-----|
| `pandas>=1.5.0` | `pandas>=2.0.0` | Better performance, CoW |
| `numpy>=1.21.0` | `numpy>=1.24.0` | NumPy 2.0 compat |
| `seaborn>=0.11.0` | `seaborn>=0.13.0` | Better defaults |
| `matplotlib>=3.3.0` | `matplotlib>=3.7.0` | Style improvements |
| `scipy>=1.7.0` | `scipy>=1.11.0` | Performance |

**Optional modern deps:**
- `polars` (optional) for faster data processing
- `plotly>=5.0` for interactive plots

---

## 3. Type Hints & Code Quality

### Add Comprehensive Type Hints
Currently minimal typing. Add throughout:

```python
# Before
def sharpe(returns, rf=0.0, periods=252, annualize=True, smart=False):

# After
def sharpe(
returns: pd.Series | pd.DataFrame,
rf: float = 0.0,
periods: int = 252,
annualize: bool = True,
smart: bool = False,
) -> float | pd.Series:
```

**Tasks:**
- [x] Add type hints to key public functions in `stats.py` (sharpe, volatility, etc.)
- [ ] Add type hints to remaining functions in `stats.py`
- [ ] Add type hints to all public functions in `utils.py`
- [x] Add type hints to plotting functions
- [x] Add `py.typed` marker for PEP 561
- [x] Configure `pyright` in CI (with continue-on-error)

### Remove Legacy Patterns
- [ ] Remove `_pd`, `_np` import aliases (use `pd`, `np`) - optional, low priority
- [x] Remove `# -*- coding: UTF-8 -*-` (Python 3 default)
- [x] Fix deprecated IPython import

---

## 4. Open Issues to Address

### High Priority Bugs

| # | Issue | Priority | Status |
|---|-------|----------|--------|
| 493 | Trade-analysis metrics computed from returns | HIGH | Documented (valid for returns) |
| 491 | Error generating HTML report with benchmark Series | HIGH | FIXED |
| 486 | reports.metrics vs reports.full inconsistency | HIGH | FIXED |
| 485 | Benchmark Omega always same as Strategy | HIGH | FIXED |
| 484 | make_index is incorrect | HIGH | FIXED |

### Medium Priority

| # | Issue | Priority | Status |
|---|-------|----------|--------|
| 481 | NaN in EOY Returns vs Benchmark | MEDIUM | FIXED |
| 480 | Inconsistent metrics benchmark vs return-only | MEDIUM | FIXED |
| 479 | EOY Returns vs Benchmark section issues | MEDIUM | FIXED |
| 475 | Double "%" in HTML report | MEDIUM | FIXED |
| 477 | Noisy variance warning messages | MEDIUM | FIXED |

### Low Priority / Features

| # | Issue | Priority | Status |
|---|-------|----------|--------|
| 492 | Chrome dark mode styling | LOW | FIXED |
| 489 | Underwater plot average drawdown | LOW | FIXED |
| 472 | Add parameters table to HTML report | FEATURE | FIXED |
| 473 | Mass closure communication | META | Open |

---

## 5. Code Structure Improvements

### Simplify Module Structure
```
quantstats/
├── __init__.py
├── stats.py # Core statistics
├── plots.py # Plotting wrappers
├── reports.py # Report generation
├── utils.py # Utilities
├── _montecarlo.py # Monte Carlo (new)
├── _plotting/
│ ├── __init__.py
│ ├── core.py # Plot implementations
│ └── wrappers.py # Public API
└── py.typed # PEP 561 marker
```

### Remove Compat Layers (if dropping old Python)
- [ ] Review `_compat.py` - may be removable
- [ ] Review `_numpy_compat.py` - may be removable

---

## 6. Testing & CI

### Current: 179 tests passing

### Improvements:
- [x] Add GitHub Actions workflow
- [x] Add type checking to CI (`pyright --warnings`)
- [x] Add coverage reporting (Codecov integration)
- [x] Add benchmarking tests for performance regression

### Test Categories:
```yaml
# .github/workflows/test.yml
jobs:
test:
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
```

---

## 7. Documentation

- [ ] Keep README.md (done - converted from RST)
- [ ] Monte Carlo docs (done)
- [ ] Generate API docs with `mkdocs` or `pdoc`
- [ ] Add examples notebook

---

## 8. Implementation Order

### Phase 1: Foundation (Week 1)
1. Create `pyproject.toml`
2. Update Python version requirement
3. Update dependency versions
4. Remove `setup.py`

### Phase 2: Bug Fixes (Week 2-3)
1. Fix #493 (trade metrics)
2. Fix #491 (HTML report benchmark)
3. Fix #486 (metrics inconsistency)
4. Fix #485 (Omega benchmark)
5. Fix #484 (make_index)

### Phase 3: Modernization (Week 4)
1. Add type hints to stats.py
2. Add type hints to utils.py
3. Remove legacy patterns
4. Add `py.typed`

### Phase 4: Polish (Week 5)
1. Fix remaining issues
2. Add GitHub Actions CI
3. Update all docs
4. Release v1.0.0

---

## 9. Breaking Changes

Document these for CHANGELOG:

1. **Python 3.10+ required** (drop 3.8, 3.9)
2. **pandas 2.0+ required** (drop 1.x)
3. Any function signature changes from bug fixes

---

## 10. New Features (Post-Modernization)

Ideas for future:
- [ ] Polars backend support
- [ ] Async data fetching
- [ ] Interactive Plotly reports
- [ ] PDF export
- [ ] Multi-strategy comparison reports
102 changes: 102 additions & 0 deletions .claude/PROJECT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
updated: 2026-01-13T14:49:14Z
---

# QuantStats

## Purpose
Portfolio analytics library for quants - calculates 50+ performance metrics (Sharpe, Sortino, max drawdown, VaR, etc.) and generates HTML tearsheet reports comparing strategies to benchmarks.

## Domain Knowledge
- Returns can be simple (arithmetic) or log returns; most metrics use simple
- "Compounded" means geometric growth (1+r1)*(1+r2)... vs arithmetic sum
- Drawdown = peak-to-trough decline; max drawdown is worst historical decline
- Risk-free rate (rf) typically US Treasury; affects Sharpe/Sortino calculations
- Trading days: 252/year (US equities), 365 for crypto
- Monte Carlo: shuffling returns preserves distribution but varies paths
- **Period-based metrics**: win_rate, consecutive_wins, payoff_ratio analyze return periods (not discrete trades)

## Conventions
- `_prepare_returns()` normalizes all input data before calculations
- `_compat.py` handles pandas 1.5+/2.0+ specifics (freq aliases, timezone normalization)
- `_numpy_compat.py` handles numpy 1.24+ specifics (product deprecation)
- Stats functions return scalar for Series input, Series for DataFrame input
- `extend_pandas()` adds methods directly to DataFrame/Series objects
- Monte Carlo functions return `MonteCarloResult` dataclass with properties

## Current Focus
v0.0.78 released - 2026 modernization complete.
Remaining open: #493 (trade-based metrics - documented as period-based, not removing)

## Recently Completed (v0.0.78)
- GitHub release v0.0.78 published
- 12 issues closed (#472, #475, #477, #479, #480, #481, #484, #485, #486, #489, #491, #492)
- 5 PRs closed (superseded by #494)
- PR #495 merged: README updated with period-based metrics clarification
- PR #483 merged: Dependabot - actions/checkout v4 → v6
- Feature #472: Parameters table in HTML/text reports
- Type hints: Python 3.10+ union syntax throughout
- pyproject.toml migration (setup.py removed)
- Monte Carlo integration (stats, plots, pandas extension)
- pandas >=1.5.0 (supports both 1.x and 2.x)
- 104 tests passing

## Project Structure

```
quantstats/
├── __init__.py # Main exports (stats, plots, reports, utils)
├── stats.py # Statistical metrics (Sharpe, Sortino, drawdown, etc.)
├── plots.py # Visualization functions
├── reports.py # Report generation (HTML, metrics tables)
├── utils.py # Utility functions (data prep, download)
├── _compat.py # Pandas version compatibility layer
├── _numpy_compat.py # NumPy version compatibility layer
├── _montecarlo.py # Monte Carlo simulation module
├── version.py # Version string
└── report.html # HTML template for reports
```

## Development

### Testing
```bash
pytest tests/ -v # Run all tests
pytest tests/test_stats.py -v # Run specific test file
pytest tests/ --cov=quantstats # Run with coverage
```

### Code Quality
```bash
ruff check quantstats/ # Lint
pyright quantstats/ # Type check
```

## Common Tasks

### Adding a New Metric
1. Add function to `stats.py` with full type hints
2. Add tests to `tests/test_stats.py`
3. If shown in reports, update `reports.py` metrics dict

### Updating Dependencies
1. Edit `pyproject.toml` dependencies section
2. Update README Requirements section to match
3. If pandas/numpy behavior changed, update `_compat.py` or `_numpy_compat.py`

### Version Bump
1. Update `quantstats/version.py`
2. Update `CHANGELOG.md`
3. Create GitHub release with tag

## Gotchas

1. **yfinance MultiIndex**: When downloading data, use `.squeeze()` to flatten single-ticker results
2. **Frequency aliases**: Use `_compat.get_frequency_alias()` for pandas 2.2.0+ compatibility
3. **DataFrame vs Series**: Many stats functions handle both - check `isinstance()` and handle appropriately
4. **NaN handling**: Use `dropna()` before calculations, especially for CVaR/VaR

## Notes
- Author: Ran Aroussi (same as yfinance)
- Target: Python 3.10+, pandas >=1.5.0, numpy >=1.24.0
- PR #470 still open (Dependabot setup-python) - requires workflow scope to merge
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 120
exclude = .git,__pycache__,build,dist
15 changes: 15 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

# custom: ['https://paypal.me/ranaroussi']
patreon: ranaroussi
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
31 changes: 31 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
release:
types: [created]

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
Loading