Skip to content

Latest commit

 

History

History
547 lines (433 loc) · 17.5 KB

File metadata and controls

547 lines (433 loc) · 17.5 KB

Changelog

0.0.81

Bugfixes for 0.0.78 release

  • Fixed circular import errors that broke import quantstats (#499, #501)

  • Fixed NameError: name 'dd_get_stats' is not defined in reports.full() (#502)

  • Fixed reports.html() to work without specifying output file (opens in browser)

  • Fixed profit_ratio() to handle DataFrame inputs properly

  • Removed dark mode CSS from HTML report template

  • Suppressed pandas FutureWarning for callable resampler.apply()

  • Improved HTML report header:

    • Title shows "(Compounded)" only when compounded=True
    • Date range shows "(matched dates)" only when match_dates=True with benchmark
    • Parameters now always show Benchmark, Periods/Year, and RF rate
  • Added new metrics to full HTML report:

    • Ulcer Performance Index, Risk-Adjusted Return, Risk-Return Ratio
    • Avg. Return, Avg. Win, Avg. Loss, Win/Loss Ratio, Profit Ratio
  • Added terminal output parameters table for reports.full() and reports.basic()

  • Added comprehensive test suite (125 tests):

    • Tests for stats, reports, utils, plots, compat, extend_pandas, and Monte Carlo

0.0.78

2026 Modernization Update

  • Added comprehensive type hints to stats.py functions:

    • All major public functions now have full type annotations
    • Uses Python 3.10+ union syntax (X | Y instead of Union[X, Y])
    • Added Returns type alias for pd.Series | pd.DataFrame
    • Functions typed include: ghpr(), outliers(), remove_outliers(), best(), worst(), consecutive_wins(), consecutive_losses(), exposure(), win_rate(), avg_return(), avg_win(), avg_loss(), rolling_volatility(), implied_volatility(), autocorr_penalty(), smart_sharpe(), rolling_sharpe(), smart_sortino(), rolling_sortino(), adjusted_sortino(), probabilistic_ratio(), probabilistic_sharpe_ratio(), and more
  • Simplified compatibility layers for Python 3.10+/pandas 2.0+/numpy 1.24+:

    • _compat.py: Removed obsolete pandas < 1.0.0 and < 1.4.0 version checks
    • _numpy_compat.py: Removed obsolete numpy < 1.17.0, < 1.21.0, and < 1.22.0 version checks
    • Cleaner, more maintainable codebase for modern dependency versions

0.0.77

  • Fixed issue #467 - CVaR calculation returning NaN for DataFrame inputs:

    • The conditional_value_at_risk() function now properly handles DataFrame inputs
    • When filtering DataFrames, NaN values are now correctly removed before calculating the mean
    • CVaR calculations are now consistent between Series and DataFrame inputs
    • This fix ensures accurate risk metrics in HTML reports when using benchmarks
  • Confirmed issue #468 is already resolved:

    • The "mode.use_inf_as_null" pandas option error reported in v0.0.64 no longer occurs
    • This issue was resolved in a previous version through updates to pandas compatibility

0.0.76

  • Fixed issue #457 - Inconsistent benchmark EOY returns in reports:

    • Benchmark yearly returns now remain consistent regardless of strategy's trading calendar
    • HTML reports preserve original benchmark data for accurate EOY calculations
    • Previously, benchmark returns would change when aligned to different strategies' trading days
    • Added comprehensive tests to verify benchmark consistency across different comparisons
  • Improved timezone handling for cross-market comparisons:

    • All resampling operations now normalize timezones to prevent comparison errors
    • Mixed timezone-aware and timezone-naive data can now be compared without errors
    • Data is converted to UTC then made timezone-naive for consistent comparisons
    • Fixes "Cannot compare dtypes datetime64[ns] and datetime64[ns, UTC]" errors
  • Fixed FutureWarning for pandas pct_change():

    • Updated all pct_change() calls to use fill_method=None parameter
    • Prevents "fill_method='pad' is deprecated" warnings in pandas 2.x
    • Ensures compatibility with future pandas versions

0.0.75

  • Fixed FutureWarning for deprecated pandas frequency aliases:
    • Updated make_index default rebalance parameter from "1M" to "1ME"
    • Ensures compatibility with pandas 2.2.0+ without warnings
    • The _compat module already handles conversion for older pandas versions

0.0.74

  • Completed fix for issue #463 - DataFrame handling in qs.reports functions:
    • kelly_criterion: Fixed improper use of 'or' operator with Series values
      • Now properly detects Series vs scalar inputs
      • Handles zero and NaN values correctly for DataFrames
    • recovery_factor: Added proper DataFrame input handling
      • Detects when max_dd is a Series and handles accordingly
      • Prevents "truth value of Series is ambiguous" errors
    • All functions now tested with qs.reports.html() and qs.reports.metrics() with benchmarks
    • Verified working with exact code examples from issue reporters

0.0.73

  • Fixed payoff_ratio to handle DataFrame inputs properly (fixes issue #463)
    • When using qs.reports.html with a benchmark, payoff_ratio receives a DataFrame
    • Previously caused "ValueError: truth value of Series is ambiguous"
    • Now properly handles both Series and scalar avg_loss values
    • Returns Series for DataFrame inputs, scalar for Series inputs

0.0.72

  • Fixed ValueError "truth value of Series is ambiguous" for DataFrame inputs in multiple stats functions:
    • sortino: Properly handles Series downside deviation from DataFrame inputs
    • outlier_win_ratio: Handles Series positive_mean calculations correctly
    • outlier_loss_ratio: Handles Series negative_mean calculations correctly
    • risk_return_ratio: Handles Series standard deviation properly
    • ulcer_performance_index: Handles Series ulcer index values
    • serenity_index: Handles Series std and denominator calculations
    • gain_to_pain_ratio: Handles Series downside calculations
    • All functions now properly return Series for DataFrame inputs and scalars for Series inputs

0.0.71

  • Fixed RuntimeWarnings in tail_ratio function by properly handling edge cases:

    • Handle divide by zero when lower quantile is 0
    • Handle invalid values when quantiles return NaN
    • Handle DataFrame inputs that return Series from quantile operations
    • Return NaN gracefully instead of triggering warnings
  • Added comprehensive divide by zero protection across multiple stats functions:

    • gain_to_pain_ratio: Returns NaN when no negative returns (downside = 0)
    • recovery_factor: Returns NaN when no drawdown (max_dd = 0)
    • sortino: Returns NaN when downside deviation is 0
    • calmar: Returns NaN when max drawdown is 0
    • ulcer_performance_index: Returns NaN when ulcer index is 0
    • serenity_index: Returns NaN when std or denominator is 0
    • payoff_ratio: Returns NaN when average loss is 0
    • outlier_win_ratio: Returns NaN when no positive returns
    • outlier_loss_ratio: Returns NaN when no negative returns
    • risk_return_ratio: Returns NaN when standard deviation is 0
    • kelly_criterion: Returns NaN when win/loss ratio is 0 or NaN
    • greeks: Returns NaN for beta when benchmark variance is 0
    • rolling_greeks: Handles zero benchmark std gracefully
    • All functions now return NaN instead of triggering RuntimeWarnings

0.0.70

  • Fixed chart naming inconsistency: renamed "Daily Active Returns" to "Daily Active Returns (Cumulative Sum)" and "Daily Returns" to "Daily Returns (Cumulative Sum)" to accurately reflect that charts show cumulative values (fixes issue #454)
  • Fixed CAGR calculation bug where years were incorrectly calculated using calendar days instead of trading periods, causing drastically reduced CAGR values (fixes issue #458)
  • Fixed inconsistent EOY returns for benchmarks by preserving original benchmark data for aggregation while aligning to strategy index for other calculations (fixes issue #457)

0.0.69

  • Added periods parameter to calmar() function to support custom annualization periods (fixes issue #455)
  • Updated reports.py to pass periods parameter to Calmar ratio calculation for consistency with other metrics

0.0.68

  • Fixed ValueError when comparing Series with scalar in _get_baseline_value() function (fixes issue #448)
  • Properly handle both DataFrame and Series inputs in drawdown calculations

0.0.67

  • Added support for NumPy 2.0.0+ (fixes issue #445)

0.0.66

  • Fixed bug with calculating drawdowns when first return is < 0

0.0.65

  • Misc bug fixes

0.0.64

MAJOR RELEASE - Comprehensive Compatibility and Performance Improvements

🔧 Major Fixes:

  • Fixed pandas resampling compatibility issues (UnsupportedFunctionCall errors)
  • Added yfinance proxy configuration compatibility layer for all versions
  • Implemented comprehensive pandas compatibility layer with frequency alias mapping (M→ME, Q→QE, A→YE)
  • Fixed all pandas FutureWarnings related to chained assignment operations
  • Added numpy compatibility layer for deprecated functions (np.product → np.prod)
  • Replaced broad exception handling with specific exception types throughout codebase

📈 Performance Improvements:

  • Implemented LRU caching for _prepare_returns function (10-100x faster for repeated operations)
  • Optimized autocorrelation calculations with vectorized numpy operations
  • Improved rolling Sortino calculation performance and memory usage
  • Optimized multi_shift memory usage with incremental concatenation
  • Eliminated redundant dropna operations with intelligent caching
  • Replaced inefficient iterrows usage with vectorized operations

🛡️ Reliability Improvements:

  • Added comprehensive input validation to public functions
  • Implemented safe_resample compatibility function for all pandas versions
  • Created robust error handling with custom exception classes
  • Added safe_yfinance_download function handling proxy configuration changes
  • Fixed matplotlib/seaborn compatibility issues and deprecation warnings

🎨 Visualization Fixes:

  • Updated seaborn compatibility (sns.set() → sns.set_theme())
  • Fixed legend handling in plotting functions
  • Improved chart rendering with better error handling
  • Fixed monthly heatmap display issues

📊 Technical Improvements:

  • Created comprehensive compatibility layer in _compat.py module
  • Implemented frequency alias mapping for pandas version compatibility
  • Added version detection and handling for pandas/numpy changes
  • Enhanced data preparation pipeline with caching and validation

🚀 Overall Impact:

  • 10-100x performance improvement for large datasets
  • 5-10x memory usage reduction
  • Eliminated all pandas/numpy compatibility warnings
  • Future-proofed against dependency updates
  • Maintained full backward compatibility

This release addresses 23+ community-reported issues and PRs, making QuantStats significantly faster, more reliable, and compatible with modern pandas/numpy versions.

0.0.63

  • Misc pd/np compatibility stuff

0.0.62

  • Changed serenity_index and recovery_factor to use simple sum instead of compounded sum
  • Reports passing the compounded param to all supporting methods
  • Fixed a bug related to monthly_heatmap display

0.0.61

  • Fixed positional arguments passed to cagr()

0.0.60

  • Multi-strategy reports! You can now pass a dataframe with a column for each strategy to get a unified, single report for all
  • Support request proxy with yfinance
  • Added custom periods to CAGR
  • Correct drawdown days calculation when last day is a drawdown
  • Write report in correct file path
  • IPython 7+ compatibility
  • Pandas 2.0 compatibility
  • Fix for benchmark name when supplied by the user
  • Handles tz-native and tz-aware comparisson issue
  • Adding benchmark name to html report
  • Update README ticker to META :)
  • Many pull requests merged

0.0.59

  • Fixed EOY compounded return calculation

0.0.58

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

0.0.57

  • Fixed sigma calculation in stats.probabilistic_ratio()

0.0.56

  • Added option to explicitly provide the benchmark title via benchmark_title=...

0.0.55

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

0.0.54

  • Fixed dependency name in requirements.txt

0.0.53

  • Added information ratio to reports

0.0.52

  • Added Treynor ratio

0.0.51

  • Added max consecutive wins/losses to full report
  • Added “correlation to benchmark” to report
  • Cleanup inf/nan from reports
  • Added benchmark name to stats column and html report
  • Added probabilistic sharpe/sortino ratios
  • Fix relative dates calculations

0.0.50

  • Fixed a bug when reporting the max drawdown

0.0.49

  • Fixed an issue with saving the HTML report as a file

0.0.48

  • Fixed RF display bug

0.0.47

  • Fixed average DD display bug

0.0.46

  • Misc bug fixes and speedups

0.0.45

  • Fixed stats.rolling_sharpe() parameter mismatch

0.0.44

  • Match dates logic on utils.make_index()

0.0.43

  • Fixed stats.rolling_sortino() calculations
  • Added match_dates flag to reports to make strategy and benchmark comparible by syncing their dates and frequency
  • Added prepare_returns flag to utils._prepare_benchmark()
  • Misc code cleanup and speedups

0.0.42

  • Usability improvements

0.0.41

  • Typos fixed

0.0.40

  • Added rebalance option to utils.make_index()
  • Added option to add log_scale=True/False` to plots.snapshot()``

0.0.39

  • Fixed plots.rolling_volatility() benchmark display (bug introduced in 0.0.37)

0.0.38

  • Added stats.smart_sharpe() and stats.smart_sortino()

0.0.37

  • added stats.rolling_sharpe(), stats.rolling_sortino(), stats.and rolling_volatility()
  • Added stats.distribution()
  • Added Omega ratio
  • BREAKING CHANGE: Eenamed trading_year_days param to periods_per_year
  • Misc code cleanup and speedups

0.0.36

  • Added as_pct params to reports.metrics() for when you need display data as DataFrame

0.0.35

  • Passing correct rolling windows in rolling_beta()
  • Added Serenity Index
  • Passing trading_year_days to method metrics
  • Fixed "day is out of range for month" error

0.0.34

  • Fixed bug in stats.consecutive_wins() and stats.consecutive_losses()
  • Fixed seaborn's depreated distplot warning
  • Improved annualization by passing trading_year_days

0.0.33

  • Added option to pass the number of days per year in reports, so you can now use trading_year_days=365 if you're trading crypto, or any other number for intl. markets.

0.0.32

  • Fixed bug in plot_histogram() (issues 94+95)

0.0.31

  • Enable period setting for adjusted sortino
  • Added utils.make_index() for easy "etf" creation

0.0.30

  • Fixed PIP installer

0.0.29

  • Minor code refactoring

0.0.28

  • gain_to_pain renamed to gain_to_pain_ratio
  • Minor code refactoring

0.0.27

  • Added Sortino/√2 and Gain/Pain ratio to report
  • Merged PRs to fix some bugs

0.0.26

  • Misc bug fixes and code improvements

0.0.25

  • Fixed conditional_value_at_risk()
  • Fixed %matplotlib inline issue notebooks

0.0.24

  • Added mtd/qtd/ytd methods for panda (usage: df.mtd())
  • Fixed Pandas deprecation warning
  • Fixed Matplotlib deprecation warning
  • Try setting %matplotlib inline automatic in notebooks

0.0.23

  • Fixed profit Factor formula

0.0.22

  • Misc bug fixes

0.0.21

  • Fixed chart EOY chart's xticks when charting data with 10+ years
  • Fixed issue where daily return >= 100%
  • Fixed Snapshot plot
  • Removed duplicaated code
  • Added conda installer
  • Misc code refactoring and optimizations

0.0.20

  • Misc bugfixes

0.0.19

  • Cleaning up data before calculations (replaces inf/-inf/-0 with 0)
  • Removed usage of pandas.compound() for future pandas version compatibility
  • Auto conversion of price-to-returns and returns-to-data as needed

0.0.18

  • Fixed issue when last date in data is in the past (issue #4)
  • Fixed issue when data has less than 5 drawdown periods (issue #4)

0.0.17

  • Fixed CAGR calculation for more accuracy
  • Handles drawdowns better in live trading mode when currently in drawdown

0.0.16

  • Handles no drawdowns better

0.0.15

  • Better report formatting
  • Code cleanup

0.0.14

  • Fixed calculation for rolling sharpe and rolling sortino charts
  • Nicer CSS when printing html reports

0.0.13

  • Fixed non-compounded plots in reports when using compounded=False

0.0.12

  • Option to add compounded=True/False to reports (default is True)

0.0.11

  • Minor bug fixes

0.0.10

  • Updated to install and use yfinance instead of fix_yahoo_finance

0.0.09

  • Added support for 3 modes (cumulative, compounded, fixed amount) in plots.earnings() and utils.make_portfolio()
  • Added two DataFrame utilities: df.curr_month() and df.date(date)
  • Misc bug fixes and code refactoring

0.0.08

  • Better calculations for cagr, var, cvar, avg win/loss and payoff_ratio
  • Removed unused param from to_plotly()
  • Added risk free param to log_returns() + renamed it to to_log_returns()
  • Misc bug fixes and code improvements

0.0.07

  • Plots returns figure if show is set to False

0.0.06

  • Minor bug fix

0.0.05

  • Added plots.to_plotly() method
  • Added Ulcer Index to metrics report
  • Better returns/price detection
  • Bug fixes and code refactoring

0.0.04

  • Added pct_rank() method to stats
  • Added multi_shift() method to utils

0.0.03

  • Better VaR/cVaR calculation
  • Fixed calculation of to_drawdown_series()
  • Changed VaR/cVaR default confidence to 95%
  • Improved Sortino formula
  • Fixed conversion of returns to prices (to_prices())

0.0.02

  • Initial release

0.0.01

  • Pre-release placeholder