optionstratlib_simulation/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, #808). `clippy.toml` exempts the unary minus on
12// `Decimal`, which cannot overflow. Casts that truncate, wrap or drop the
13// sign are 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-simulation
34//!
35//! The simulation engine of OptionStratLib: random walks, stochastic
36//! processes, simulators, exit policies and the generic evaluation and
37//! statistics of simulated paths. It depends on `optionstratlib-core` and
38//! `optionstratlib-pricing`, and on no option chain, strategy, backtesting,
39//! plotting, I/O or terminal-presentation code.
40//!
41//! - [`simulation`]: the stochastic processes ([`simulation::WalkType`]:
42//! Brownian, geometric Brownian, log-returns, mean-reverting, jump
43//! diffusion, GARCH, Heston, telegraph, custom and historical) and their
44//! default kernels ([`simulation::WalkTypeAble`]); walk parameters and
45//! steps ([`simulation::WalkParams`], [`simulation::steps::Step`],
46//! [`simulation::steps::Xstep`], [`simulation::steps::Ystep`]); the walk
47//! driver shared by every generator ([`simulation::walk_steps`],
48//! [`simulation::walk_steps_par`], [`simulation::generator_positive`]);
49//! [`simulation::randomwalk::RandomWalk`] and
50//! [`simulation::simulator::Simulator`]; the Ornstein-Uhlenbeck process
51//! ([`simulation::generate_ou_process`]); exit policies
52//! ([`simulation::ExitPolicy`], [`simulation::check_exit_policy`]); and the
53//! generic path evaluation ([`simulation::PathEvaluator`],
54//! [`simulation::PathOutcome`], [`simulation::PathStatistics`],
55//! [`simulation::evaluate_paths`]).
56//! - [`error`]: [`error::SimulationError`] and [`error::SimulationResult`].
57//!
58//! Prices along a path are `Positive`, drifts and statistics `Decimal`;
59//! `f64` stays inside the kernels, and a non-finite value at an
60//! `f64` → `Decimal` boundary is reported as
61//! [`error::SimulationError::NonFinite`].
62//!
63//! The evaluation of a strategy over simulated paths, its statistics report
64//! and the charts of a walk stay with the backtesting and visualization
65//! layers, which the `optionstratlib` facade provides; the chain and series
66//! generators built on these walks are in `optionstratlib-market`, behind
67//! its `synthetic` feature.
68//!
69//! ## Imports
70//!
71//! There is no prelude, as in the other component crates (ADR-0001 D7): the
72//! [`simulation`] module root re-exports the capability, and the
73//! `optionstratlib` facade prelude serves broad imports.
74//!
75//! ## Place in the workspace
76//!
77//! - **Depends on** `optionstratlib-core` and `optionstratlib-pricing`.
78//! - **Must not depend on** `optionstratlib-market`, `-analytics`, `-strategies`,
79//! `-backtest` and `-visualization`; `make check-graph` enforces the layering
80//! (ADR-0001 D9).
81//! - **In the facade:** `optionstratlib::simulation` and `SimulationError` /
82//! `SimulationResult` in `optionstratlib::error`, under the facade feature
83//! `simulation`. The facade paths are the same types as the paths here; the
84//! [ownership
85//! map](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/ownership.md)
86//! lists every one with its feature.
87//!
88//! Moving from 0.21? The [0.22 architecture and adoption
89//! guide](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/migration-0.22.md)
90//! maps each redesign to its replacement workflow; 0.22 keeps no
91//! compatibility with 0.21.
92//!
93//! ## Minimal example
94//!
95//! ```rust
96//! use optionstratlib_core::pos_or_panic;
97//! use optionstratlib_simulation::simulation::generate_ou_process;
98//!
99//! // An Ornstein-Uhlenbeck path of 50 steps mean-reverting to 100.
100//! let path = generate_ou_process(
101//! pos_or_panic!(100.0),
102//! pos_or_panic!(100.0),
103//! pos_or_panic!(0.5),
104//! pos_or_panic!(0.2),
105//! pos_or_panic!(0.01),
106//! 50,
107//! )?;
108//! assert_eq!(path.len(), 50);
109//! # Ok::<(), optionstratlib_simulation::error::SimulationError>(())
110//! ```
111//!
112//! ## Runnable example
113//!
114//! A runnable program that depends on this crate directly, with the smallest
115//! dependency set and no facade, is [`osl-example-direct-simulation`](https://github.com/joaquinbejar/OptionStratLib/tree/main/examples/direct/simulation); `make tree-example-direct-simulation`
116//! asserts its resolved graph.
117//!
118//! ## Features
119//!
120//! - `schema` (off by default): derives `utoipa::ToSchema` on the simulation
121//! types and enables `schema` in core and pricing.
122
123/// Random walks, stochastic processes, simulators, exit policies and the
124/// generic evaluation of simulated paths.
125pub mod simulation;
126
127/// Errors raised by the simulation layer.
128pub mod error;
129
130/// Version of the `optionstratlib-simulation` crate.
131pub const VERSION: &str = env!("CARGO_PKG_VERSION");
132
133/// Compiles the Rust examples of this crate's `README.md` as doctests, so the
134/// README cannot drift from the API (#554). Exists only under `cfg(doctest)`.
135#[cfg(doctest)]
136#[doc = include_str!("../README.md")]
137pub struct ReadmeDoctests;