You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
What's New in v2.3.0
Added
Sortino ratio (calculate_sortino_ratio()) — penalises only downside volatility, complementing Sharpe for leveraged-ETF portfolios.
CVaR / Expected Shortfall (calculate_cvar()) at 95% and 99% confidence — answers "how bad is it when VaR is breached?"
Portfolio RSI — rsi_portfolio field now populated in analyze_risk() using the portfolio cumulative-return series.
Portfolio data export — new clawdfolio export CLI command with CSV and JSON output for portfolio, risk metrics, and alerts (output/export.py).
Dynamic trading calendar — algorithmic US holiday generation for any year (Easter via anonymous Gregorian algorithm, nth-weekday rules for MLK, Presidents, Memorial, Labor, Thanksgiving). Hardcoded 2024-2026 sets retained as fast-path cache.
Tests for previously untested modules: test_price_monitor.py, test_earnings_monitor.py, test_dca.py, test_json_output.py, test_export.py.
Python 3.13 added to CI matrix and pyproject.toml classifiers.
pip-audit security scanning step in CI.
Coverage enforcement: --cov-fail-under=48 in CI pytest step.
Changed
analyze_risk() fetches SPY and QQQ benchmarks in a single get_history_multi() call instead of two sequential get_history() calls.
Portfolio.get_position() now uses O(1) dict lookup via _ticker_index instead of O(n) linear scan.
calculate_ema() replaced Python for-loop with pd.Series.ewm() for better performance.
Fixed
calculate_dca_performance() no longer passes invalid period strings (e.g. "12mo") to yfinance; uses _months_to_period() mapping.
Position._weight attribute properly declared as a dataclass field, eliminating getattr fallback.
Cache TOCTOU race in _cached() — per-key locking prevents redundant expensive calls from concurrent threads.