@@ -28,7 +28,7 @@ use rand_distr::{Distribution, Normal};
2828/// A struct representing an instrument with dividend properties.
2929#[ derive( Debug , Default , Clone ) ]
3030pub struct Instrument {
31- /// Current price of the underlying asset.
31+ /// Current price of the underlying asset or future price at time 0 .
3232 pub spot : f64 ,
3333 /// Maximum spot price of the underlying asset.
3434 pub max_spot : f64 ,
@@ -47,7 +47,11 @@ pub struct Instrument {
4747}
4848
4949impl Instrument {
50- /// Create a new `Instrument`.
50+ /// Create a new simple `Instrument` with default values.
51+ ///
52+ /// # Returns
53+ ///
54+ /// A new `Instrument`.
5155 pub fn new ( ) -> Self {
5256 Self {
5357 spot : 0.0 ,
@@ -62,24 +66,56 @@ impl Instrument {
6266 }
6367
6468 /// Set the spot price of the instrument.
69+ ///
70+ /// # Arguments
71+ ///
72+ /// * `spot` - The spot price of the instrument (i.e., the current price of the underlying asset or future price at time 0).
73+ ///
74+ /// # Returns
75+ ///
76+ /// The instrument with the spot price set.
6577 pub fn with_spot ( mut self , spot : f64 ) -> Self {
6678 self . spot = spot;
6779 self
6880 }
6981
7082 /// Set the maximum spot price of the instrument.
83+ ///
84+ /// # Arguments
85+ ///
86+ /// * `max_spot` - The maximum spot price of the instrument.
87+ ///
88+ /// # Returns
89+ ///
90+ /// The instrument with the maximum spot price set.
7191 pub fn with_max_spot ( mut self , max_spot : f64 ) -> Self {
7292 self . max_spot = max_spot;
7393 self
7494 }
7595
7696 /// Set the minimum spot price of the instrument.
97+ ///
98+ /// # Arguments
99+ ///
100+ /// * `min_spot` - The minimum spot price of the instrument.
101+ ///
102+ /// # Returns
103+ ///
104+ /// The instrument with the minimum spot price set.
77105 pub fn with_min_spot ( mut self , min_spot : f64 ) -> Self {
78106 self . min_spot = min_spot;
79107 self
80108 }
81109
82110 /// Set the continuous dividend yield of the instrument.
111+ ///
112+ /// # Arguments
113+ ///
114+ /// * `yield_` - The continuous dividend yield of the instrument.
115+ ///
116+ /// # Returns
117+ ///
118+ /// The instrument with the continuous dividend yield set.
83119 pub fn with_continuous_dividend_yield ( mut self , yield_ : f64 ) -> Self {
84120 self . continuous_dividend_yield = yield_;
85121 self . assets . iter_mut ( ) . for_each ( |( a, _) | {
@@ -94,18 +130,42 @@ impl Instrument {
94130 }
95131
96132 /// Set the discrete dividend yield of the instrument.
133+ ///
134+ /// # Arguments
135+ ///
136+ /// * `yield_` - The discrete dividend yield of the instrument.
137+ ///
138+ /// # Returns
139+ ///
140+ /// The instrument with the discrete dividend yield set.
97141 pub fn with_discrete_dividend_yield ( mut self , yield_ : f64 ) -> Self {
98142 self . discrete_dividend_yield = yield_;
99143 self
100144 }
101145
102146 /// Set the dividend times of the instrument.
147+ ///
148+ /// # Arguments
149+ ///
150+ /// * `times` - The dividend times of the instrument.
151+ ///
152+ /// # Returns
153+ ///
154+ /// The instrument with the dividend times set.
103155 pub fn with_dividend_times ( mut self , times : Vec < f64 > ) -> Self {
104156 self . dividend_times = times;
105157 self
106158 }
107159
108160 /// Set the assets of the instrument.
161+ ///
162+ /// # Arguments
163+ ///
164+ /// * `assets` - The assets of the instrument.
165+ ///
166+ /// # Returns
167+ ///
168+ /// The instrument with the assets set.
109169 pub fn with_assets ( mut self , assets : Vec < Instrument > ) -> Self {
110170 if assets. is_empty ( ) {
111171 return self ;
@@ -119,6 +179,14 @@ impl Instrument {
119179 }
120180
121181 /// Set the assets and their weights of the instrument.
182+ ///
183+ /// # Arguments
184+ ///
185+ /// * `assets` - The assets and their weights of the instrument.
186+ ///
187+ /// # Returns
188+ ///
189+ /// The instrument with the assets and their weights set.
122190 pub fn with_weighted_assets ( mut self , assets : Vec < ( Instrument , f64 ) > ) -> Self {
123191 if assets. is_empty ( ) {
124192 return self ;
@@ -138,6 +206,10 @@ impl Instrument {
138206 }
139207
140208 /// Get best performing asset.
209+ ///
210+ /// # Returns
211+ ///
212+ /// The best performing asset.
141213 pub fn best_performer ( & self ) -> & Instrument {
142214 if self . assets . is_empty ( ) {
143215 return self ;
@@ -149,6 +221,10 @@ impl Instrument {
149221 }
150222
151223 /// Get worst performing asset.
224+ ///
225+ /// # Returns
226+ ///
227+ /// The worst performing asset.
152228 pub fn worst_performer ( & self ) -> & Instrument {
153229 if self . assets . is_empty ( ) {
154230 return self ;
@@ -160,7 +236,32 @@ impl Instrument {
160236 & self . assets . last ( ) . unwrap ( ) . 0
161237 }
162238
239+ /// Calculate the adjusted spot price.
240+ ///
241+ /// # Arguments
242+ ///
243+ /// * `instrument` - The instrument to calculate the adjusted spot price for.
244+ /// * `ttm` - Time to maturity of the option.
245+ ///
246+ /// # Returns
247+ ///
248+ /// The adjusted spot price.
249+ pub fn calculate_adjusted_spot ( & self , ttm : f64 ) -> f64 {
250+ let n_dividends = self . dividend_times . iter ( ) . filter ( |& & t| t <= ttm) . count ( ) as f64 ;
251+ self . spot * ( 1.0 - self . discrete_dividend_yield ) . powf ( n_dividends)
252+ }
253+
163254 /// Simulate random asset prices (Euler method)
255+ ///
256+ /// # Arguments
257+ ///
258+ /// * `rng` - Random number generator.
259+ /// * `risk_free_rate` - Risk-free rate.
260+ /// * `volatility` - Volatility.
261+ ///
262+ /// # Returns
263+ ///
264+ /// A vector of simulated asset prices.
164265 pub fn euler_simulation (
165266 & self ,
166267 rng : & mut ThreadRng ,
@@ -181,6 +282,18 @@ impl Instrument {
181282 }
182283
183284 /// Simulate random asset prices' logarithms
285+ ///
286+ /// # Arguments
287+ ///
288+ /// * `rng` - Random number generator.
289+ /// * `volatility` - Volatility.
290+ /// * `time_to_maturity` - Time to maturity.
291+ /// * `risk_free_rate` - Risk-free rate.
292+ /// * `steps` - Number of steps.
293+ ///
294+ /// # Returns
295+ ///
296+ /// A vector of simulated asset prices' logarithms.
184297 pub fn log_simulation (
185298 & self ,
186299 rng : & mut ThreadRng ,
@@ -202,6 +315,19 @@ impl Instrument {
202315 }
203316
204317 /// Average asset prices
318+ ///
319+ /// # Arguments
320+ ///
321+ /// * `rng` - Random number generator.
322+ /// * `method` - Simulation method.
323+ /// * `volatility` - Volatility.
324+ /// * `time_to_maturity` - Time to maturity.
325+ /// * `risk_free_rate` - Risk-free rate.
326+ /// * `steps` - Number of steps.
327+ ///
328+ /// # Returns
329+ ///
330+ /// The average asset price.
205331 pub fn simulate_arithmetic_average (
206332 & self ,
207333 rng : & mut ThreadRng ,
@@ -227,6 +353,19 @@ impl Instrument {
227353 }
228354
229355 /// Geometric average asset prices
356+ ///
357+ /// # Arguments
358+ ///
359+ /// * `rng` - Random number generator.
360+ /// * `method` - Simulation method.
361+ /// * `volatility` - Volatility.
362+ /// * `time_to_maturity` - Time to maturity.
363+ /// * `risk_free_rate` - Risk-free rate.
364+ /// * `steps` - Number of steps.
365+ ///
366+ /// # Returns
367+ ///
368+ /// The geometric average asset price.
230369 pub fn simulate_geometric_average (
231370 & self ,
232371 rng : & mut ThreadRng ,
@@ -250,7 +389,19 @@ impl Instrument {
250389 }
251390 }
252391
253- // Directly simulate the asset price using the geometric Brownian motion formula
392+ /// Directly simulate the asset price using the geometric Brownian motion formula
393+ ///
394+ /// # Arguments
395+ ///
396+ /// * `rng` - Random number generator.
397+ /// * `volatility` - Volatility.
398+ /// * `time_to_maturity` - Time to maturity.
399+ /// * `risk_free_rate` - Risk-free rate.
400+ /// * `steps` - Number of steps.
401+ ///
402+ /// # Returns
403+ ///
404+ /// The simulated asset price.
254405 pub fn simulate_geometric_brownian_motion (
255406 & self ,
256407 rng : & mut ThreadRng ,
0 commit comments