1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Per rules/global_rules.md §Error Handling, unchecked `[]` / slicing is
// banned in production code.
// Unit tests routinely index into `Vec`s they just pushed into, so the lint
// is silenced in `#[cfg(test)]` only.
// Per rules/global_rules.md §Arithmetic, an operator that overflows, divides
// by zero or breaks the `Positive` invariant aborts the caller, so every
// operation on `Decimal`, `Positive` and the integers goes through its
// checked form (#788). `clippy.toml` exempts the unary minus on `Decimal`,
// which cannot overflow. Casts that truncate, wrap or drop the sign are
// denied for the same reason. Unit tests are exempt, as above.
// An error or a default built eagerly in `ok_or` / `unwrap_or` is paid on
// the success path too (#857), so it is built in a closure.
//! # optionstratlib-core
//!
//! The core domain model of OptionStratLib: the types every other
//! OptionStratLib crate builds on. It holds no pricing model, market data,
//! strategy, backtesting or presentation code, and depends on no other
//! OptionStratLib crate.
//!
//! - [`model`]: [`model::Options`], [`model::Position`], [`model::leg::Leg`]
//! and its spot, future and perpetual legs, [`model::Trade`], payoff
//! contracts at expiry and checked `Decimal` helpers.
//! - [`error`]: the errors those types raise.
//! - [`utils`]: time frames and date helpers, the deterministic RNG,
//! numeric helpers and [`utils::Len`].
//! - [`constants`]: library-wide numeric constants, market conventions and time units.
//!
//! Monetary values are [`rust_decimal::Decimal`] or [`positive::Positive`],
//! and arithmetic on them is checked.
//!
//! ## Foundational types
//!
//! Four standalone crates define the newtypes and enums every OptionStratLib
//! crate shares. Core depends on them and re-exports their types unchanged,
//! never wrapping or copying one, so a value reached through any path below
//! is the same type as the original and needs no conversion. Each crate
//! resolves to a single version across the workspace (`make check-graph`).
//!
//! | Type | Defining crate | Re-exported at |
//! | --- | --- | --- |
//! | `Positive`, `PositiveError`, `is_positive` | `positive` | `optionstratlib_core::model`, `optionstratlib::model`; `Positive` also in `optionstratlib::prelude` |
//! | `pos_or_panic!`, `spos!`, `assert_pos_relative_eq!` | `positive` | `optionstratlib_core`, `optionstratlib::prelude` |
//! | `ExpirationDate`, `ExpirationDateError` | `expiration_date` | `optionstratlib_core::model`, `optionstratlib::model`; `ExpirationDate` also at the `optionstratlib` root and in its prelude |
//! | `Side`, `OptionStyle`, `Action`, `UnderlyingAssetType` | `financial_types` | `optionstratlib_core::model::types`; `Side` and `OptionStyle` also in `optionstratlib_core::model` and at the `optionstratlib` root; `Side`, `OptionStyle` and `Action` in its prelude |
//! | `OptionType`, `OptionBasicType`, `AsianAveragingType`, `BarrierType`, `BinaryType`, `LookbackType`, `RainbowType` | `option_type` | `optionstratlib_core::model::types`; `OptionType` and `RainbowType` also in `optionstratlib_core::model` and at the `optionstratlib` root; `OptionType` in its prelude |
//! | `DAYS_IN_A_YEAR` | `positive` | `optionstratlib_core::constants`, `optionstratlib::constants` |
//! | `StrictlyPositive`, `PositiveResult`, the other `positive::constants`; `ParseEnumError`; the day-count conventions (`DayCount`, `Actual360`, `Actual365Fixed`, `Thirty360US`) | `positive`; `financial_types`; `expiration_date` | not re-exported: name them through the defining crate |
//!
//! The facade's `optionstratlib::model` *is* `optionstratlib_core::model`, so
//! every core path above is also reachable with the `optionstratlib::model`
//! prefix. Enabling `schema` adds `ToSchema` impls to these types; it does not
//! change which type a path names.
//!
//! ## Imports: no prelude
//!
//! This crate has no `prelude` module, by decision (#518). The module roots
//! already are the curated entry points: `model` re-exports the domain types
//! and the foundational ones (`Options`, `Position`, `Trade`, `TradeStatus`,
//! `ExpirationDate`, `Side`, `OptionStyle`, `OptionType`, `Positive`),
//! `model::leg` the leg types, and `utils` `TimeFrame` and `Len`.
//!
//! Measured when the crate was extracted, counting explicit
//! `optionstratlib::{model,utils,constants}::…` imports: 168 of the 178
//! example files import through the facade's `prelude::*`, and the examples
//! name 8 distinct core items explicitly (in 25 files). Tests and benches (139
//! files) name 31 distinct core items in 40 files, 18 of them through deep
//! paths such as `model::decimal::DecimalStats` or `utils::time::…`. Nothing
//! outside the workspace imports `optionstratlib_core` directly. The use is
//! spread thinly across many items, so no small glob would cover it, and the
//! few types every consumer needs are already one path away at the module
//! roots. A crate glob would only duplicate those roots and make every future
//! addition a prelude commitment. The facade prelude is M7-03's to redesign.
//!
//! ```rust
//! use optionstratlib_core::model::leg::{Leg, LegAble, SpotPosition};
//! use optionstratlib_core::model::{
//! ExpirationDate, OptionStyle, OptionType, Options, Position, Positive, Side, Trade,
//! };
//! use optionstratlib_core::utils::{Len, TimeFrame};
//! use optionstratlib_core::pos_or_panic;
//! ```
//!
//! ## Place in the workspace
//!
//! - **Depends on** no other OptionStratLib crate; the foundational `positive`,
//! `expiration_date`, `financial_types` and `option_type`, which it re-exports.
//! - **Must not depend on** every other OptionStratLib crate (it is the bottom
//! layer); `make check-graph` enforces the layering (ADR-0001 D9).
//! - **In the facade:** always present: `optionstratlib::{model, utils,
//! constants}`, the core errors in `optionstratlib::error`, the root types
//! `Options`, `ExpirationDate`, `OptionStyle`, `OptionType`, `RainbowType`,
//! `Side` and the root macros. The facade paths are the same types as the paths
//! here; the [ownership
//! map](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/ownership.md)
//! lists every one with its feature.
//!
//! Moving from 0.21? The [0.22 architecture and adoption
//! guide](https://github.com/joaquinbejar/OptionStratLib/blob/main/docs/migration-0.22.md)
//! maps each redesign to its replacement workflow; 0.22 keeps no
//! compatibility with 0.21.
//!
//! ## Minimal example
//!
//! ```rust
//! use optionstratlib_core::model::{ExpirationDate, OptionStyle, OptionType, Options, Positive, Side};
//! use optionstratlib_core::pos_or_panic;
//! use rust_decimal_macros::dec;
//!
//! // A call struck at 100 with the underlying at 105; the payoff at
//! // expiry needs no pricing model.
//! let option = Options::new(
//! OptionType::European,
//! Side::Long,
//! "XYZ".to_string(),
//! pos_or_panic!(100.0),
//! ExpirationDate::Days(pos_or_panic!(30.0)),
//! pos_or_panic!(0.2),
//! Positive::ONE,
//! pos_or_panic!(105.0),
//! dec!(0.05),
//! OptionStyle::Call,
//! Positive::ZERO,
//! None,
//! );
//! assert_eq!(option.payoff()?, dec!(5));
//! # Ok::<(), optionstratlib_core::error::OptionsError>(())
//! ```
//!
//! ## Runnable example
//!
//! A runnable program that depends on this crate directly, with the smallest
//! dependency set and no facade, is [`osl-example-direct-pricing`](https://github.com/joaquinbejar/OptionStratLib/tree/main/examples/direct/pricing); `make tree-example-direct-pricing`
//! asserts its resolved graph. Core is in every example's graph; this is the smallest program that uses it.
//!
//! ## Features
//!
//! - `schema` (off by default): derives `utoipa::ToSchema` on the core types
//! and enables the same derive on `positive`, `expiration_date`,
//! `financial_types` and `option_type`.
/// Domain types: options, positions, legs, trades, payoffs and checked
/// `Decimal` helpers.
/// Errors raised by the core domain types.
/// Time frames, date helpers, the deterministic RNG and numeric helpers.
/// Library-wide numeric constants, market conventions and time units.
pub use ;
/// Version of the `optionstratlib-core` crate.
pub const VERSION: &str = env!;
/// Compiles the Rust examples of this crate's `README.md` as doctests, so the
/// README cannot drift from the API (#554). Exists only under `cfg(doctest)`.
;