|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to **OptionStratLib** are documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), |
| 6 | +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | + |
| 8 | +## [Unreleased] |
| 9 | + |
| 10 | +## [0.16.0] - 2026-04-19 |
| 11 | + |
| 12 | +Breaking release. Focus: panic-free core, arithmetic discipline, |
| 13 | +typed errors everywhere, and a crate-wide discipline pass over |
| 14 | +attributes, docs, and test hygiene. |
| 15 | + |
| 16 | +### Added |
| 17 | + |
| 18 | +- Checked `Decimal` helpers `d_add` / `d_sub` / `d_mul` / `d_div` |
| 19 | + plus `d_sum` and the iterator-based `d_sum_iter` in |
| 20 | + `src/model/decimal.rs`. Every monetary-path kernel now routes |
| 21 | + through them instead of raw `+ - * /`, surfacing `DecimalError::Overflow` |
| 22 | + with an operation tag. (#335, #336, #337, #338, #372) |
| 23 | +- Domain-specific `NonFinite { context, value }` variants on |
| 24 | + `PricingError`, `GreeksError`, `VolatilityError`, and |
| 25 | + `SimulationError` plus the crate-private `finite_decimal(f64)` |
| 26 | + guard used at every `f64 → Decimal` boundary. (#336, #337, #338) |
| 27 | +- Public `tracing::instrument` on hot paths: `pricing::black_scholes`, |
| 28 | + `pricing::monte_carlo_option_pricing`, `pricing::price_binomial`, |
| 29 | + `volatility::utils::implied_volatility`, and |
| 30 | + `strategies::base::Optimizable::{get_best_ratio, get_best_area}`. (#342) |
| 31 | +- `utils::deterministic_rng(seed)` plus |
| 32 | + `DETERMINISTIC_RNG_DEFAULT_SEED` — canonical entry point for |
| 33 | + reproducible Monte-Carlo / simulation tests. (#344) |
| 34 | +- Deterministic regression tests under |
| 35 | + `tests/unit/pricing/identities_test.rs` covering put-call parity, |
| 36 | + CRR binomial convergence to Black-Scholes, and Greek |
| 37 | + sanity identities (`Γ_c == Γ_p`, `V_c == V_p`, |
| 38 | + `Δ_c − Δ_p ≈ e^{-qT}`). (#345) |
| 39 | +- `CHANGELOG.md` following Keep a Changelog 1.1.0. (#346) |
| 40 | + |
| 41 | +### Changed |
| 42 | + |
| 43 | +- Breaking: step / simulation counts on `price_binomial`, |
| 44 | + `monte_carlo_option_pricing`, and related kernels are now |
| 45 | + `NonZeroUsize` so zero is structurally invalid at the type |
| 46 | + level. (#337) |
| 47 | +- Breaking: many public surfaces now return |
| 48 | + `Result<T, concrete_error>` instead of panicking; `unsafe` |
| 49 | + blocks have been removed from the core in favour of typed |
| 50 | + guards. (#333, #334, #335, #338) |
| 51 | +- Canonical `#[derive]` ordering |
| 52 | + (`Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, |
| 53 | + Default, …, Serialize, Deserialize, ToSchema`), `#[repr(u8)]` |
| 54 | + on small stable enums, `#[serde(deny_unknown_fields)]` on |
| 55 | + input DTOs, and `#[serde(rename_all = "snake_case")]` on |
| 56 | + public-facing enums unless an existing wire contract |
| 57 | + forbids it (e.g. `BasicAxisTypes` keeps Pascal case). (#340) |
| 58 | +- `#[inline]` applied on hot-path helpers and public entry |
| 59 | + points, `#[inline(never)]` on multi-arg builders, and |
| 60 | + `#[cold] #[inline(never)]` on every error constructor across |
| 61 | + `src/error/*`. (#339) |
| 62 | +- `CustomStrategy::calculate_profit_at` no longer allocates a |
| 63 | + `Vec<Decimal>` per invocation; aggregates via `try_fold` + `d_add`. (#372) |
| 64 | + |
| 65 | +### Fixed |
| 66 | + |
| 67 | +- Doc-coverage floor: crate-level |
| 68 | + `#![deny(missing_docs, rustdoc::broken_intra_doc_links)]` |
| 69 | + with every previously-bare `pub` item now documented, and |
| 70 | + broken intra-doc links (e.g. `DecimalError::Overflow` → |
| 71 | + `crate::error::DecimalError::Overflow`) repaired. (#343) |
| 72 | +- Unchecked `[]` indexing in production code migrated to |
| 73 | + `.get(..).ok_or_else(..)` on the highest-risk paths |
| 74 | + (`OptionChain` file-name / CSV readers, binomial-root lookup |
| 75 | + in `Option::binomial_price`) and |
| 76 | + `#![deny(clippy::indexing_slicing)]` enforced crate-wide |
| 77 | + with scoped, documented escapes on the remaining modules |
| 78 | + as follow-up work. (#341) |
| 79 | + |
| 80 | +### Internal |
| 81 | + |
| 82 | +- `#[must_use]` applied across the pure / builder public |
| 83 | + surface to catch discarded results at compile time. |
| 84 | + |
| 85 | +[Unreleased]: https://github.com/joaquinbejar/OptionStratLib/compare/v0.16.0...HEAD |
| 86 | +[0.16.0]: https://github.com/joaquinbejar/OptionStratLib/releases/tag/v0.16.0 |
0 commit comments