V0 Changelog#

0.58.6 (2026-05-19)#

Fixed#

  • generate_comprehensive_excel_report now restores the date index column on the portfolio_bench_total_value sheet. pd.concat([register_df, benchmark[...]], axis=1) was silently dropping index.name because the two source DataFrames carried different names (register_df.index.name == "date" vs benchmark.index.name == "date_column" from StandardField.DATE.value). Without a name, include_index = dataframe.index.name is not None evaluated False and the writer skipped both the header and every date cell, leaving the sheet with only the value columns. The concat result is now explicitly renamed to "date", mirroring the other data sheets.

0.58.5 (2026-05-13)#

Changed#

  • BatchConfigParser.parse_dict() / parse_file() now reject execution_price in global_defaults with a BatchConfigError pointing to user_column_trade_execution_price. The key was silently ignored since v0.57.0 (when execution_price was removed from the Excel configuration and order execution was wired to StandardField.TRADE_EXECUTION_PRICE exclusively), which let users believe they were configuring the execution price via the batch dict/YAML when in fact only user_column_trade_execution_price was being read. Surfacing the error closes that hidden mismatch and makes the batch path consistent with the Excel path.

0.58.4 (2026-05-13)#

Changed#

  • MultiPortfolioRunner.run() now logs the empty-batch failure via logger.error(...) before raising NoPortfoliosDiscoveredError. The error message appears as a single [ERROR] line in the configured logger format (matching the surrounding [INFO] Discovered 0 portfolio files ... line) instead of only surfacing as a raw Python traceback when callers invoke the runner directly without a top-level try/except BacktestError wrapper like the one in backtest_engine.main().

0.58.3 (2026-05-13)#

Added#

  • NoPortfoliosDiscoveredError exception (subclass of BatchConfigErrorConfigurationError) exported from kaxanuk.backtest_engine.exceptions.

Fixed#

  • MultiPortfolioRunner.run() no longer crashes with an opaque IndexError: list index out of range inside _build_reference_configuration when portfolio_directory is configured but resolves to zero portfolios (empty directory, missing directory, or no files matching the expected format). It now raises NoPortfoliosDiscoveredError with a message that includes the scanned directory and the expected format.

0.58.2 (2026-05-12)#

Fixed#

  • MultiPortfolioBacktester.generate_individual_reports now sets the benchmark DatetimeIndex from the canonical StandardField.DATE column (currently "date_column") instead of the literal string "date" that does not exist in the schema. The old lookup silently fell through and called pd.to_datetime on the integer RangeIndex (0, 1, 2, …), producing timestamps near 1970-01-01 that propagated to every annual-returns row, the Max Drawdown Date of the benchmark, and the embedded chart. Annual returns and Max Drawdown Date for the benchmark now align with the portfolio’s date range. Same fix applied to the register_df lookup for symmetry.

0.58.1 (2026-05-12)#

Fixed#

  • portfolio_drawdown_viz now picks the date_column from the benchmark DataFrame when present, instead of relying on its index. The previous 0.58.0 fix coerced the index to datetime, but when the benchmark comes from a pa.Table.to_pandas() the index is a plain RangeIndex (0, 1, 2, …) and pd.to_datetime interpreted those integers as nanoseconds-since-epoch, leaving every point near 1970-01-01 — the visible vertical line in the embedded Excel charts.

0.58.0 (2026-05-12)#

Breaking Changes#

  • Renamed environment variable KNPC_API_KEY_KAXANUKKNBE_API_KEY_KAXANUK. Update your Config/.env file accordingly.

Added#

  • arrow_to_pandas_for_analysis() helper in kaxanuk.backtest_engine.modules.type_converters. Converts a pyarrow.Table to a pandas.DataFrame with analysis-friendly dtypes: decimal128/decimal256 columns are coerced to float64 and date32/timestamp columns to datetime64[ns]. Use it when feeding a backtest’s PyArrow result into matplotlib, numpy or scikit-learn.

Fixed#

  • portfolio_drawdown_viz no longer renders a spurious vertical line at 1970-01-01 when the caller passes a benchmark DataFrame that originated from a pa.Table.to_pandas() (object dtype with datetime.date index and decimal.Decimal values). The function now coerces the index and the plotted columns defensively before drawing.

Documentation#

  • Full Sphinx documentation overhaul: real runtime dependencies in docs/requirements.txt (no more MagicMock in signatures), new Backtest Components section covering cost_models, enums, execution, interfaces and orchestrators subpackages, enriched docstrings across the backtest package and the data/portfolio/market pipelines, CLI page rebuilt with intro + summary table + common workflows, and See Also cross-references from load methods to the user guide. Build now finishes with 0 warnings.

  • Fixed two malformed .. deprecated:: directives in portfolio_configuration_service.py so the rendered notice reads “Deprecated since version 0.40.0: Use load_from_file() instead.” instead of the previous garbled output.

  • load_portfolio_from_name and load_portfolio_from_weights are excluded from the Sphinx API reference (still callable from Python for backwards compatibility).

0.57.0 (2026-04-15)#

Breaking Changes#

  • Removed ``execution_price`` Excel configuration field. Order execution now always uses the column named in trade_execution_price_column (internally mapped to StandardField.TRADE_EXECUTION_PRICE). To migrate, run kaxanuk.backtest_engine update excel and delete the execution_price row from your existing Config/backtest_engine_parameters.xlsx if you updated manually.

  • Renamed environment variable KAXANUK_LICENSE_KEYKNPC_API_KEY_KAXANUK. Update your Config/.env file accordingly.

  • ``MarketDataBundlePyarrow.get_execution_table()`` signature changed. The method no longer accepts an execution_price parameter; it returns the TRADE_EXECUTION_PRICE table directly.

  • Excel template format version bumped from 0.54.0 to 0.56.0. The engine enforces this check at startup — outdated Excels must be regenerated via kaxanuk.backtest_engine update excel.

  • Minimum rebalance dates relaxed from 2 → 1. Users relying on the previous validation for error detection should revisit their portfolio files.

Added#

  • __parameters_format_version__ constant exported from kaxanuk.backtest_engine for tracking Excel schema version independently of the package version.

  • Explicit version-compatibility check at Excel load time: raises ConfigurationHandlerError with a “run update excel” hint when the Excel format is outdated, and logs a warning when the Excel is newer than the engine supports.

  • Support for buy-and-hold portfolios: a single rebalance date is now valid.

  • Validation preventing any price column (commission_price_column, trade_execution_price_column, mark_to_market_price_column) from being set to the same value as user_column_date.

  • packaging added as an explicit dependency for semantic version comparison.

Changed#

  • __version__ bumped to 0.57.0, __parameters_format_version__ bumped to 0.56.0.

  • CLI module (services/cli.py) aligned stylistically with sibling packages: added -> None return annotations, periods to docstrings, removed dead commented code.

  • dependencies in pyproject.toml sorted alphabetically (case-insensitive).

Fixed#

  • Duplicate log output when ExcelConfigurator was instantiated in a session that already had a root logger configured (logger.propagate = False and handler-deduplication guard added).

0.55.0 (2026-04-01)#

Added#

  • ``load_config_env()`` helper that loads Config/.env into the process environment, eliminating the need to manually set KNPC_API_KEY_KAXANUK=… in the terminal before every run

  • Config/.env template generated automatically by init excel with a placeholder for the license key

  • python-dotenv dependency for .env file loading

  • load_config_env exported at the top-level package namespace (from kaxanuk.backtest_engine import load_config_env)

Changed#

  • Template __main__.py now calls load_config_env() before any license-validated code

  • License error message updated to recommend Config/.env as the primary configuration method

  • README examples updated to include load_config_env() call

0.54.0 (2026-03-31)#

Added#

  • Runtime license validation (phone-home) to protect against unauthorized use

  • license_validator service with device fingerprinting, local cache (24h TTL), and 7-day offline grace period

  • License validation at all entry points: __main__.py, main(), and PyArrowBacktester.run()

  • Custom exception hierarchy: LicenseError, LicenseNotFoundError, LicenseValidationError, LicenseServerError

  • HMAC-signed local cache file (~/.kaxanuk_cache) to prevent tampering

  • In-process validation flag to avoid redundant server calls within the same session

  • httpx dependency for license server communication

Changed#

  • .gitignore updated to exclude .kaxanuk_license and .kaxanuk_cache files

0.52.0 (2026-03-04)#

Added#

  • Batch backtesting capability for running multiple portfolios in a single execution

  • BatchRunner orchestrator with SharedDataPool for efficient market data reuse across portfolios

  • BatchConfigParser for dict/YAML-based batch configuration

  • Directory scanning mode to auto-discover portfolio files

  • Comparative Excel report ranking portfolios by configurable metric

  • Individual Excel reports per portfolio with:

  • Full performance metrics

  • Drawdown analysis

  • Annual returns breakdown

  • Benchmark statistics computation in batch processing

  • Alpha calculation in batch path

Changed#

  • PyArrow Decimal-to-float coercion at numpy math operation boundaries for compatibility

0.51.0 (2026-02-18)#

Added#

  • BacktestSuite class with add_variation() method to define configuration overrides per variation

  • “auto” date derivation from portfolio rebalancing dates

  • Comparative Excel reports with:

  • Summary metrics across all variations

  • Cumulative returns comparison

  • Drawdown comparison charts

Fixed#

  • Alpha metric calculation bug

  • CAGR (Compound Annual Growth Rate) metric calculation bug

0.50.0 (2026-01-16)#

Added#

  • New PyArrow-based backtesting engine (backtest_2) with component-oriented design:

  • Explicit PortfolioStateManager, ExecutionBroker, and ReportingEngine components

  • Pluggable commission and slippage models via interfaces

  • Immutable BacktestReport dataclass as structured result container

  • Clear separation between configuration (inputs) and runtime state

  • Ability to run multiple backtest cases (different parameters) with only one data pipeline

Fixed#

  • Summary card alpha now uses the same calculation as annual returns table, ensuring consistent alpha display across dashboards

0.49.0 (2025-11-25)#

Added#

  • StandardField enum for type-safe field names (VWAP, ADJUSTED_VWAP, ADJUSTED_CLOSE, DATE)

  • Long-short portfolio support with allow_short parameter in PortfolioEntity

  • PortfolioEntity.from_dict() class method for creating portfolios from dictionaries

Changed#

  • Portfolio validation now supports both long-only and long-short strategies

  • README documentation updated

Removed#

  • Unnecessary configuration entity fields

0.48.0 (2025-10-30)#

Added#

  • Annual returns table to Excel report

  • Annual returns analysis to dashboard

  • Alpha metric to annual returns table (both dashboard and Excel report)

Fixed#

  • Performance metrics formatting

  • Dashboard alpha metric format display

0.47.0 (2025-10-15)#

Added#

  • Helper functions module (input_handlers_helpers) for common data processing operations

  • Interactive dropdown menu in portfolio weights evolution chart to filter tickers

  • Comprehensive docstrings to almost all codes

Changed#

  • ExcelPortfolioInputHandler now returns pa.Table instead of pd.DataFrame

  • Dashboard pie chart now displays Top 10 assets alphabetically with “Others” category for remaining positions

  • Benchmark builder now uses ADJ_CLOSE_COLUMN_NAME constant instead of hardcoded strings

  • Excel portfolio validates first column must be ‘Ticker’

0.46.0 (2025-10-06)#

Added#

  • MissingBenchmark exception and benchmark validation before processing

  • Benchmark availability validation (_validate_benchmark_availability())

Changed#

  • Backtest engine optimized (converted class parameters to Python float for better performance)

  • Portfolio transformer now includes all ticker weights (not just >0)

  • Increased decimal precision for financial calculations

Fixed#

  • Portfolio calculation bugs

  • _convert_df_to_python() now properly handles None/NaN values (converts to 0.0)

0.45.0 (2025-10-02)#

Added#

  • Execution price selection option (customizable execution price for backtesting)

  • safe_decimal() function for PyArrow Decimal conversions

  • _convert_df_to_python() method for converting PyArrow scalars to Python values

Changed#

  • Migrated data handling from Pandas to PyArrow

  • Build system changed from pdm-backend to hatchling

Fixed#

  • Input handler and Entities bugs

Removed#

  • Unnecessary project directories and files

0.44.0 (2025-08-27)#

Added#

  • Project templates for easier setup (__main__.py template for CLI init)

  • .gitkeep files for empty directories

Changed#

  • Rebalancing logic improvements

  • CLI interface updates and improvements

  • pdm.lock now excluded from version control

Fixed#

  • CLI bugs

0.43.0 (2025-08-12)#

Added#

  • Benchmark name displayed in plot legends

  • Sortino ratio calculation with robust downside deviation methodology

Changed#

  • Dashboard color scheme updated to company brand colors

  • Interactive pie chart now updates based on selected date

Fixed#

  • Functions for CVaR and VaR calculations with robust historical and parametric Gaussian methods (including Cornish-Fisher modification) were fixed

0.42.0 (2025-07-29)#

Added#

  • Broker interfaces implementation

  • Config factory as alternative to Excel configuration

  • PyArrow-based portfolio entity

  • Custom exceptions for better error handling

  • Mixed date format support

  • New ‘portfolio’ Excel report sheet added

0.41.0 (2025-06-17)#

Added#

  • Portfolio weights evolution plot

  • Custom market data column names support

Changed#

  • Market data builder updated to support custom column names

Fixed#

  • Annualized return calculation

  • CAGR calculation

  • Alpha metric calculation

0.40.1 (2025-06-04)#

Fixed#

  • OS Error on cli init script because of entry script template missing from wheel data

0.40.0 (2025-06-04)#

Changed#

  • First public release, now on PyPI