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
184
185
186
187
/******************************************************************************
use positive::pos_or_panic;
Author: Joaquín Béjar García
Email: jb@taunais.com
Date: 1/8/24
******************************************************************************/
//! # SPAN (Standard Portfolio Analysis of Risk) Module
//!
//! This module implements the SPAN® (Standard Portfolio Analysis of Risk) methodology,
//! a system developed by the Chicago Mercantile Exchange (CME) for calculating margin
//! requirements for derivatives portfolios.
//!
//! ## Overview
//!
//! SPAN calculates margin requirements by analyzing the potential losses a portfolio might
//! experience under various market scenarios. It considers:
//! - Price changes in the underlying asset
//! - Changes in volatility
//! - Extreme market moves
//! - Time decay effects
//! - Short option exposure
//!
//! ## Core Components
//!
//! ### SPANMargin Structure
//!
//! ```rust
//! pub struct SPANMargin {
//! scanning_range: f64, // Overall market move range
//! short_option_minimum: f64, // Minimum charge for short options
//! price_scan_range: f64, // Range for price scenarios
//! volatility_scan_range: f64, // Range for volatility scenarios
//! }
//! ```
//!
//! ### Risk Scenarios
//!
//! The module evaluates positions under multiple scenarios combining:
//! - Price movements (up/down/unchanged)
//! - Volatility changes (up/down/unchanged)
//! - Time decay effects
//!
//! ## Usage Examples
//!
//! ### Basic Margin Calculation
//!
//! ```rust
//! use optionstratlib::{ExpirationDate, Options};
//! use optionstratlib::model::types::{ OptionStyle, OptionType, Side};
//! use positive::Positive;
//! use optionstratlib::model::position::Position;
//! use positive::pos_or_panic;
//! use chrono::Utc;
//! use rust_decimal_macros::dec;
//! use optionstratlib::risk::SPANMargin;
//!
//! // Create an option position
//! let option = Options::new(
//! OptionType::European,
//! Side::Short,
//! "STOCK".to_string(),
//! pos_or_panic!(150.0), // Strike price
//! ExpirationDate::Days(pos_or_panic!(30.0)),
//! pos_or_panic!(0.2), // Volatility
//! Positive::ONE, // Quantity
//! pos_or_panic!(155.0), // Current price
//! dec!(0.05), // Risk-free rate
//! OptionStyle::Call,
//! Positive::ZERO, // Dividend yield
//! None, // Exotic parameters
//! );
//!
//! let position = Position {
//! option,
//! premium: pos_or_panic!(5.0),
//! date: Utc::now(),
//! open_fee: pos_or_panic!(0.5),
//! close_fee: pos_or_panic!(0.5),
//! epic: None,
//! extra_fields: None,
//! };
//!
//! // Create SPAN calculator
//! let span = SPANMargin::new(
//! dec!(0.10), // 10% short option minimum
//! dec!(0.05), // 5% price scan range
//! dec!(0.10), // 10% volatility scan range
//! );
//!
//! // Calculate margin requirement
//! let margin = span.calculate_margin(&position);
//! ```
//!
//! ### Portfolio Analysis
//!
//! ```rust
//! use chrono::Utc;
//! use rust_decimal::Decimal;
//! use rust_decimal_macros::dec;
//! use optionstratlib::{ExpirationDate, Options};
//! use optionstratlib::model::types::{ OptionStyle, OptionType, Side};
//! use optionstratlib::model::position::Position;
//! use positive::Positive;
//! use positive::pos_or_panic;
//! use optionstratlib::risk::SPANMargin;
//!
//! let option = Options {
//! option_type: OptionType::European,
//! side: Side::Long,
//! underlying_symbol: "AAPL".to_string(),
//! strike_price: Positive::HUNDRED,
//! expiration_date: ExpirationDate::Days(pos_or_panic!(30.0)),
//! implied_volatility: pos_or_panic!(0.2),
//! quantity: Positive::ONE,
//! underlying_price: pos_or_panic!(105.0),
//! risk_free_rate: dec!(0.05),
//! option_style: OptionStyle::Call,
//! dividend_yield: pos_or_panic!(0.01),
//! exotic_params: None,
//! };
//! // Create multiple positions
//! let positions = vec![
//! Position {
//! option: option.clone(),
//! premium: pos_or_panic!(5.0),
//! date: Utc::now(),
//! open_fee: pos_or_panic!(0.5),
//! close_fee: pos_or_panic!(0.5),
//! epic: None,
//! extra_fields: None,
//! },
//! Position {
//! option,
//! premium: pos_or_panic!(3.0),
//! date: Utc::now(),
//! open_fee: pos_or_panic!(0.5),
//! close_fee: pos_or_panic!(0.5),
//! epic: None,
//! extra_fields: None,
//! },
//! ];
//!
//! let span = SPANMargin::new(dec!(0.10), dec!(0.05), dec!(0.10));
//!
//! // Calculate margin for each position
//! let margins: Vec<Decimal> = positions.iter()
//! .map(|pos| span.calculate_margin(pos))
//! .collect();
//! ```
//!
//! ## Implementation Details
//!
//! ### Risk Array Calculation
//!
//! The risk array is calculated by:
//! 1. Generating price scenarios
//! 2. Generating volatility scenarios
//! 3. Calculating potential loss in each scenario
//! 4. Taking the maximum loss as the base margin requirement
//!
//! ### Short Option Minimum
//!
//! Additional protection against short option positions:
//! - Applied when the position is short
//! - Based on the underlying price and quantity
//! - Acts as a floor for the margin requirement
//!
//!
//! ## Performance Considerations
//!
//! - Time complexity: O(n * m) where n is the number of price scenarios and m is the number of volatility scenarios
//! - Memory complexity: O(n * m) for storing the risk array
//! - Calculation intensive due to multiple option pricing calculations per position
//!
//! ## Notes
//!
//! - All parameters should be provided as decimals (e.g., 0.15 for 15%)
//! - The module uses Black-Scholes pricing for scenario calculations
//! - Short option minimum is always enforced for short positions
//! - Results are conservative estimates of potential losses
pub use ;
pub use SPANMargin;