optionstratlib_math/lib.rs
1#![deny(missing_docs, rustdoc::broken_intra_doc_links)]
2// Per rules/global_rules.md §Error Handling, unchecked `[]` / slicing is
3// banned in production code.
4#![deny(clippy::indexing_slicing)]
5// Unit tests routinely index into `Vec`s they just pushed into, so the lint
6// is silenced in `#[cfg(test)]` only.
7#![cfg_attr(test, allow(clippy::indexing_slicing))]
8// Per rules/global_rules.md §Arithmetic, an operator that overflows, divides
9// by zero or breaks the `Positive` invariant aborts the caller, so every
10// operation on `Decimal`, `Positive` and the integers goes through its
11// checked form (#788). `clippy.toml` exempts the unary minus on `Decimal`,
12// which cannot overflow. Casts that truncate, wrap or drop the sign are
13// denied for the same reason. Unit tests are exempt, as above.
14#![deny(
15 clippy::arithmetic_side_effects,
16 clippy::cast_possible_truncation,
17 clippy::cast_possible_wrap,
18 clippy::cast_sign_loss
19)]
20#![cfg_attr(
21 test,
22 allow(
23 clippy::arithmetic_side_effects,
24 clippy::cast_possible_truncation,
25 clippy::cast_possible_wrap,
26 clippy::cast_sign_loss
27 )
28)]
29// An error or a default built eagerly in `ok_or` / `unwrap_or` is paid on
30// the success path too (#857), so it is built in a closure.
31#![deny(clippy::or_fun_call)]
32
33//! # optionstratlib-math
34//!
35//! Generic numerical containers and algorithms of OptionStratLib: 2D curves,
36//! 3D surfaces, the geometry, construction and interpolation machinery they
37//! share, and the statistics extracted from them. Nothing here knows about
38//! option chains, Greeks, pricing or plotting; it depends only on
39//! `optionstratlib-core` and general numeric crates.
40//!
41//! - [`curves`]: [`curves::Curve`], [`curves::Point2D`] and the curve traits.
42//! - [`surfaces`]: [`surfaces::Surface`], [`surfaces::Point3D`] and the
43//! surface traits.
44//! - [`geometrics`]: construction, interpolation (linear, bilinear, cubic,
45//! spline), arithmetic and metric extraction shared by curves and surfaces.
46//! - [`error`]: [`error::CurveError`], [`error::SurfaceError`],
47//! [`error::InterpolationError`] and [`error::MetricsError`].
48//!
49//! Coordinates are `rust_decimal::Decimal`; arithmetic on them is checked.
50//! Option-specific projections of curves and surfaces (`BasicCurves`,
51//! `BasicSurfaces`) belong to the analytics layer, and plotting to
52//! `optionstratlib-visualization`; the `optionstratlib` facade provides both.
53//!
54//! ## Imports: no prelude
55//!
56//! This crate has no `prelude` module, by decision (#518). Each module root
57//! re-exports what a caller needs: `curves` (`Curve`, `Point2D`, `Curvable`,
58//! `StatisticalCurve`, `CurveSpline`), `surfaces` (`Surface`, `Point3D`,
59//! `Surfacable`), `geometrics` (construction, interpolation and the shared
60//! traits) and `error`.
61//!
62//! Measured when the crate was extracted, counting explicit
63//! `optionstratlib::{curves,surfaces,geometrics}::…` imports: the examples
64//! name no math item explicitly (they use the facade's `prelude::*`), and
65//! tests and benches name 20 distinct math items in 4 files, most of them in
66//! one property test that imports 15 `geometrics` items. That use is narrow
67//! and specialised; a crate glob would serve none of it better than the
68//! module roots already do.
69//!
70//! ```rust
71//! use optionstratlib_math::curves::{Curvable, Curve, Point2D, StatisticalCurve};
72//! use optionstratlib_math::error::{CurveError, SurfaceError};
73//! use optionstratlib_math::geometrics::{
74//! ConstructionMethod, ConstructionParams, GeometricObject, Interpolate, InterpolationType,
75//! };
76//! use optionstratlib_math::surfaces::{Point3D, Surfacable, Surface};
77//! ```
78//!
79//! ## Behaviour that lives outside this crate
80//!
81//! Some capabilities take a math type as input but belong to a higher layer,
82//! so they are implemented there, not here (#517):
83//!
84//! | Capability | Where | Owner |
85//! | --- | --- | --- |
86//! | `BasicCurves`, `BasicSurfaces`: projecting an option set onto a `Curve` or `Surface` (prices options, reads Greeks) | `optionstratlib::analytics` | analytics; final adapter in M4-01 (#529) |
87//! | `Graph` and `Plottable` for `Curve`, `Vec<Curve>` and `Surface` | `optionstratlib_visualization::visualization`, also `optionstratlib::visualization` | visualization (#542) |
88//!
89//! Rendering failures are `GraphError`s of the visualization layer; the math
90//! errors carry no rendering variant.
91//!
92//! ## Place in the workspace
93//!
94//! - **Depends on** `optionstratlib-core`.
95//! - **Must not depend on** `optionstratlib-pricing`, `-simulation`, `-market`,
96//! `-analytics`, `-strategies`, `-backtest` and `-visualization`; `make
97//! check-graph` enforces the layering (ADR-0001 D9).
98//! - **In the facade:** `optionstratlib::{curves, surfaces, geometrics}` and the
99//! math errors in `optionstratlib::error`, under the facade feature `math`. The
100//! facade paths are the same types as the paths here; the [ownership
101//! map](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/ownership.md)
102//! lists every one with its feature.
103//!
104//! Moving from 0.21? The [0.22 architecture and adoption
105//! guide](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/migration-0.22.md)
106//! maps each redesign to its replacement workflow; 0.22 keeps no
107//! compatibility with 0.21.
108//!
109//! ## Minimal example
110//!
111//! ```rust
112//! use optionstratlib_math::curves::{Curve, Point2D};
113//! use std::collections::BTreeSet;
114//!
115//! let points: BTreeSet<Point2D> = [(0, 0), (1, 2), (2, 4)]
116//! .into_iter()
117//! .map(|(x, y)| Point2D::new(x, y))
118//! .collect();
119//! let curve = Curve::new(points);
120//! assert_eq!(curve.points.len(), 3);
121//! ```
122//!
123//! ## Runnable example
124//!
125//! A runnable program that depends on this crate directly, with the smallest
126//! dependency set and no facade, is [`osl-example-direct-math`](https://github.com/joaquinbejar/OptionStratLib/tree/main/examples/direct/math); `make tree-example-direct-math`
127//! asserts its resolved graph.
128//!
129//! ## Features
130//!
131//! - `schema` (off by default): derives `utoipa::ToSchema` on the math types
132//! and enables `optionstratlib-core/schema`.
133
134/// Geometry shared by curves and surfaces: construction, interpolation,
135/// arithmetic and metric extraction.
136pub mod geometrics;
137
138/// Two-dimensional curves: `Curve`, `Point2D` and their traits.
139pub mod curves;
140
141/// Three-dimensional surfaces: `Surface`, `Point3D` and their traits.
142pub mod surfaces;
143
144/// Errors raised by the math types.
145pub mod error;
146
147/// Version of the `optionstratlib-math` crate.
148pub const VERSION: &str = env!("CARGO_PKG_VERSION");
149
150/// Compiles the Rust examples of this crate's `README.md` as doctests, so the
151/// README cannot drift from the API (#554). Exists only under `cfg(doctest)`.
152#[cfg(doctest)]
153#[doc = include_str!("../README.md")]
154pub struct ReadmeDoctests;