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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RustQuant: A Rust library for quantitative finance tools.
// Copyright (C) 2023 https://github.com/avhz
// Dual licensed under Apache 2.0 and MIT.
// See:
// - LICENSE-APACHE.md
// - LICENSE-MIT.md
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use crate::Payoff;
use super::{BarrierType, OptionContract, TypeFlag};
/// Barrier option.
#[derive(Debug, Clone)]
pub struct BarrierOption {
/// The option contract.
pub contract: OptionContract,
/// Barrier type (up-and-out, down-and-out, up-and-in, down-and-in).
pub barrier_type: BarrierType,
/// Barrier level.
pub barrier: f64,
/// Strike price of the option.
pub strike: f64,
/// Rebate amount.
pub rebate: Option<f64>,
}
impl Payoff for BarrierOption {
type Underlying = Vec<f64>;
fn payoff(&self, underlying: Self::Underlying) -> f64 {
let s = underlying;
let b = self.barrier;
let k = self.strike;
let terminal = s.last().unwrap();
let above = s.iter().any(|&x| x >= b);
let below = s.iter().any(|&x| x <= b);
match self.contract.type_flag {
TypeFlag::Call => {
let payoff = (terminal - k).max(0.0);
match self.barrier_type {
BarrierType::UpAndOut => match above {
true => 0.0,
false => payoff,
},
BarrierType::DownAndOut => match below {
true => 0.0,
false => payoff,
},
BarrierType::UpAndIn => match above {
true => payoff,
false => 0.0,
},
BarrierType::DownAndIn => match below {
true => payoff,
false => 0.0,
},
}
}
TypeFlag::Put => {
let payoff = (k - terminal).max(0.0);
match self.barrier_type {
BarrierType::UpAndOut => match above {
true => 0.0,
false => payoff,
},
BarrierType::DownAndOut => match below {
true => 0.0,
false => payoff,
},
BarrierType::UpAndIn => match above {
true => payoff,
false => 0.0,
},
BarrierType::DownAndIn => match below {
true => payoff,
false => 0.0,
},
}
}
}
}
}