From 146585fb496f44d67d09e9c2fcc070e2b1702420 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:35:44 +0000 Subject: [PATCH 1/2] Initial plan From f13b7fca21530564939fa65d8379a110bdcfb734 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:39:37 +0000 Subject: [PATCH 2/2] chore: bump version to 1.0.0 and document stable API Co-authored-by: tschm <2046079+tschm@users.noreply.github.com> Agent-Logs-Url: https://github.com/tschm/jquantstats/sessions/13be9448-4c1a-4776-adb2-407983997f8a --- CHANGELOG.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d075c879..de8424c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,99 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.0.0] - 2026-03-23 + +### Stable API + +This release establishes the **stable public API** for jQuantStats. +The following surfaces are covered by semantic versioning guarantees — breaking changes +will not be introduced without a major version bump. + +#### Entry points (top-level imports) + +| Symbol | Type | Description | +|--------|------|-------------| +| `jquantstats.Portfolio` | class | High-level entry point for price + position workflows | +| `jquantstats.build_data` | function | Lower-level entry point for pre-computed return series | +| `jquantstats.__version__` | str | Package version string | + +#### `Portfolio` class + +| Member | Kind | Description | +|--------|------|-------------| +| `Portfolio.from_cash_position(prices, cash_position, aum)` | class method | Construct from absolute position sizes | +| `Portfolio.from_risk_position(prices, risk_position, aum, vola)` | class method | Construct from risk-scaled positions | +| `.stats` | property | Returns a `Stats` object (see Stats API below) | +| `.plots` | property | Returns a portfolio-specific `Plots` object | +| `.report` | property | Returns a `Report` object | +| `.data` | property | Returns the underlying `Data` object (Entry point 2) | + +#### `build_data` function + +```python +build_data(returns, benchmark=None, rf=0.0, date_col="Date") -> Data +``` + +#### `Stats` API (available via `.stats` on both `Portfolio` and `Data`) + +| Method | Description | +|--------|-------------| +| `sharpe()` | Sharpe ratio | +| `sortino()` | Sortino ratio | +| `calmar()` | Calmar ratio | +| `volatility()` | Annualised volatility | +| `cagr()` | Compound annual growth rate | +| `max_drawdown()` | Maximum drawdown | +| `avg_drawdown()` | Average drawdown | +| `max_drawdown_duration()` | Longest drawdown period | +| `value_at_risk()` | Value at Risk (VaR) | +| `conditional_value_at_risk()` | Conditional VaR (CVaR / Expected Shortfall) | +| `win_rate()` | Fraction of positive-return periods | +| `avg_win()` | Average winning-period return | +| `avg_loss()` | Average losing-period return | +| `payoff_ratio()` | Average win / average loss | +| `profit_factor()` | Gross profit / gross loss | +| `profit_ratio()` | Net profit ratio | +| `kelly_criterion()` | Kelly fraction | +| `skew()` | Return skewness | +| `kurtosis()` | Return kurtosis (excess) | +| `avg_return()` | Mean period return | +| `recovery_factor()` | Net profit / max drawdown | +| `risk_return_ratio()` | CAGR / volatility | +| `gain_to_pain_ratio()` | Sum of returns / sum of losses | +| `information_ratio()` | Active return / tracking error (requires benchmark) | +| `r_squared()` / `r2()` | R² vs benchmark (requires benchmark) | +| `greeks()` | Alpha and beta vs benchmark (requires benchmark) | +| `up_capture()` | Capture ratio in up markets (requires benchmark) | +| `down_capture()` | Capture ratio in down markets (requires benchmark) | +| `adjusted_sortino()` | Adjusted Sortino ratio | +| `rolling_sharpe()` | Rolling Sharpe series | +| `rolling_sortino()` | Rolling Sortino series | +| `rolling_volatility()` | Rolling volatility series | +| `drawdown()` | Full drawdown series | +| `prices()` | Cumulative price series from returns | +| `summary()` | Key-metric summary table | +| `annual_breakdown()` | Year-by-year performance table | +| `monthly_win_rate()` | Win rate broken down by calendar month | +| `worst_n_periods()` | Worst N return periods | + +#### `Plots` API (available via `.plots` on both `Portfolio` and `Data`) + +| Method | Description | +|--------|-------------| +| `plot_snapshot(title, log_scale)` | Full performance dashboard (Plotly figure) | + +#### `Report` API (available via `.report` / `.reports`) + +| Method | Description | +|--------|-------------| +| `metrics(periods)` | DataFrame of key metrics across time periods | + +### Added + +- **Stable-API declaration** — the surfaces listed above are now covered by + semantic versioning guarantees; breaking changes require a major version bump. + ## [0.1.1] - 2026-03-23 ### Added @@ -27,5 +120,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Interactive notebooks** — Marimo notebooks for exploratory analysis. - **Documentation book** — rendered documentation available at . -[Unreleased]: https://github.com/tschm/jquantstats/compare/v0.1.1...HEAD +[Unreleased]: https://github.com/tschm/jquantstats/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/tschm/jquantstats/compare/v0.1.1...v1.0.0 [0.1.1]: https://github.com/tschm/jquantstats/releases/tag/v0.1.1 diff --git a/pyproject.toml b/pyproject.toml index 0afc55b5..f17d3581 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ # Main project metadata [project] name = 'jquantstats' -version = "0.1.1" +version = "1.0.0" description = "Analytics for quants" authors = [{name='tschm', email= 'thomas.schmelzer@gmail.com'}] readme = "README.md" diff --git a/uv.lock b/uv.lock index 125618d2..e0a842f3 100644 --- a/uv.lock +++ b/uv.lock @@ -628,7 +628,7 @@ wheels = [ [[package]] name = "jquantstats" -version = "0.1.1" +version = "1.0.0" source = { editable = "." } dependencies = [ { name = "jinja2" },