Skip to main content

optionstratlib_backtest/
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-backtest
34//!
35//! Strategy backtests over simulated paths: a strategy is evaluated on every
36//! path of a simulator ([`backtesting::Simulate`]), each path ends by an exit
37//! policy, and the run is summarised as [`backtesting::SimulationStatsResult`]
38//! with its report types and metrics. It depends on `optionstratlib-core`,
39//! `optionstratlib-pricing`, `optionstratlib-simulation`,
40//! `optionstratlib-analytics` and `optionstratlib-strategies`, and on no
41//! option-chain I/O, plotting or async code.
42//!
43//! - [`backtesting`]: [`backtesting::Simulate`] and its single-leg
44//!   implementations, the adapters from the simulation engine's generic
45//!   `PathOutcome` / `PathStatistics` to the backtest results, run
46//!   statistics, report types and performance metrics.
47//! - [`error`]: the [`error::BacktestError`] type.
48//!
49//! The generic engine (random walks, exit policies, path evaluation and
50//! statistics) is `optionstratlib-simulation`'s; this crate adapts it to
51//! strategies and owns the reports. Charts stay with the visualization layer,
52//! `optionstratlib-visualization`, which the `optionstratlib` facade
53//! re-exports.
54//!
55//! ## Imports
56//!
57//! There is no prelude, as in the other component crates (ADR-0001 D7): the
58//! module roots re-export each capability, and the `optionstratlib` facade
59//! prelude serves broad imports.
60//!
61//! ## Place in the workspace
62//!
63//! - **Depends on** `optionstratlib-core`, `optionstratlib-pricing`,
64//!   `optionstratlib-simulation`, `optionstratlib-analytics` and
65//!   `optionstratlib-strategies`.
66//! - **Must not depend on** `optionstratlib-visualization`; `make check-graph`
67//!   enforces the layering (ADR-0001 D9).
68//! - **In the facade:** `optionstratlib::backtesting` and `BacktestError` in
69//!   `optionstratlib::error`, under the facade feature `backtest`. The facade
70//!   paths are the same types as the paths here; the [ownership
71//!   map](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/ownership.md)
72//!   lists every one with its feature.
73//!
74//! Moving from 0.21? The [0.22 architecture and adoption
75//! guide](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/migration-0.22.md)
76//! maps each redesign to its replacement workflow; 0.22 keeps no
77//! compatibility with 0.21.
78//!
79//! ## Minimal example
80//!
81//! ```rust
82//! use optionstratlib_backtest::backtesting::SimulationStatsResult;
83//!
84//! // A run's statistics start empty; `Simulate::simulate` fills them from a
85//! // `Simulator`'s paths (see the runnable example below).
86//! let stats = SimulationStatsResult::default();
87//! assert_eq!(stats.total_simulations, 0);
88//! ```
89//!
90//! ## Runnable example
91//!
92//! A runnable program that depends on this crate directly, with the smallest
93//! dependency set and no facade, is [`osl-example-direct-backtest`](https://github.com/joaquinbejar/OptionStratLib/tree/main/examples/direct/backtest); `make tree-example-direct-backtest`
94//! asserts its resolved graph.
95//!
96//! ## Features
97//!
98//! - `schema` (off by default): derives `utoipa::ToSchema` on the backtest
99//!   types and enables `schema` in core, pricing, simulation, analytics and
100//!   strategies.
101
102/// Strategy backtests over simulated paths: evaluation, statistics, reports
103/// and metrics.
104pub mod backtesting;
105
106/// Errors raised by the backtest layer.
107pub mod error;
108
109/// Version of the `optionstratlib-backtest` crate.
110pub const VERSION: &str = env!("CARGO_PKG_VERSION");
111
112/// Compiles the Rust examples of this crate's `README.md` as doctests, so the
113/// README cannot drift from the API (#554). Exists only under `cfg(doctest)`.
114#[cfg(doctest)]
115#[doc = include_str!("../README.md")]
116pub struct ReadmeDoctests;