-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathCashflows.jl
212 lines (156 loc) · 5.07 KB
/
Cashflows.jl
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
"""
abstract type CashFlow end
A CashFlow represents a general payment in an unspecified currency.
In a simulation, we calculate discounted expected cash flows in a
consistent numeraire currency.
The `CashFlow` object is inspired by QuantLib's CashFlow interface.
We apply the convention that cash flows are formulated for unit notionals.
Actual notionals are applied at the level of legs. This design aims at
simplifying MTM cross currency swap legs with notional exchange.
"""
abstract type CashFlow end
"""
pay_time(cf::CashFlow)
Return the payment time for a CashFlow.
This represents a default implementation
This method is used to calculate discounted expected values.
"""
pay_time(cf::CashFlow) = cf.pay_time
"""
amount(cf::CashFlow)
Return the payoff representing the simulated cash flow amount of the payment.
This method is intended to be used for general payoffs in conjunction with AMC.
"""
function amount(cf::CashFlow)
error("CashFlow needs to implement amount method.")
end
"""
expected_amount(cf::CashFlow, obs_time::ModelTime)
Return the payoff representing the simulated expected amount of the payment.
Expectation is calculated in ``T``-forward measure of cash flow currency with
``T`` being the payment time and conditioning on observation time.
This method is intended to be used for analytical pricers.
"""
function expected_amount(cf::CashFlow, obs_time::ModelTime)
error("CashFlow needs to implement expected_amount method.")
end
"""
abstract type Coupon <: CashFlow end
A Coupon is a payment that is composed of an (effective) coupon rate and
a year fraction.
"""
abstract type Coupon <: CashFlow end
"""
year_fraction(cf::Coupon)
Derive the year fraction for a Coupon.
"""
function year_fraction(cf::Coupon)
error("Coupon needs to implement year_fraction method.")
end
"""
coupon_rate(cf::Coupon)
Return a payoff for the realised simulated effective coupon rate.
"""
function coupon_rate(cf::Coupon)
error("Coupon needs to implement coupon_rate method.")
end
"""
forward_rate(cf::Coupon, obs_time::ModelTime)
Return a payoff for the effective forward rate of the coupon.
Expectation is calculated in T-forward measure of cash flow currency with
T being the payment time and conditioning on observation time.
This method is intended to be used for analytical pricers.
"""
function forward_rate(cf::Coupon, obs_time::ModelTime)
error("Coupon needs to implement forward_rate method.")
end
"""
amount(cf::Coupon)
Calculate payment amount for a Coupon.
"""
amount(cf::Coupon) = coupon_rate(cf) * year_fraction(cf)
"""
expected_amount(cf::Coupon, obs_time::ModelTime)
Calculate expected payment amount for a Coupon.
"""
expected_amount(cf::Coupon, obs_time::ModelTime) = forward_rate(cf, obs_time) * year_fraction(cf)
"""
first_time(cf::Coupon)
Derive the first event time of the `Coupon`.
This time is used in conjunction with call rights to determine whether
a coupon period is already broken.
"""
function first_time(cf::Coupon)
error("Coupon needs to implement first_time method.")
end
"""
struct FixedCashFlow <: CashFlow
pay_time::ModelTime
amount::ModelValue
end
A simple deterministic cash flow (normalised to one unit notional)
"""
struct FixedCashFlow <: CashFlow
pay_time::ModelTime
amount::ModelValue
end
"""
amount(cf::FixedCashFlow)
Return FixedCashFlow amount.
"""
amount(cf::FixedCashFlow) = Fixed(cf.amount)
"""
expected_amount(cf::FixedCashFlow, obs_time::ModelTime)
Return FixedCashFlow expected amount.
"""
expected_amount(cf::FixedCashFlow, obs_time::ModelTime) = Fixed(cf.amount)
"""
struct CombinedCashFlow <: CashFlow
first::CashFlow
second::CashFlow
op::Function
end
A composition of two cash flows in a single cash flow.
This `CashFlow` type is intended e.g. for spreads and caplets/floorlets.
"""
struct CombinedCashFlow <: CashFlow
first::CashFlow
second::CashFlow
op::Function
end
"""
combined_cashflow(
first::CashFlow,
second::CashFlow,
op::Function,
)
Create a CombinedCashFlow object.
"""
function combined_cashflow(
first::CashFlow,
second::CashFlow,
op::Function,
)
#
@assert pay_time(first) == pay_time(second)
return CombinedCashFlow(first, second, op)
end
import Base.+
import Base.-
(+)(first::CashFlow, second::CashFlow) = combined_cashflow(first, second, +)
(-)(first::CashFlow, second::CashFlow) = combined_cashflow(first, second, -)
"""
pay_time(cf::CombinedCashFlow)
Return the payment time for a CombinedCashFlow.
"""
pay_time(cf::CombinedCashFlow) = pay_time(cf.first)
"""
amount(cf::CombinedCashFlow)
Return the payoff representing the simulated cash flow amount of the payment.
"""
amount(cf::CombinedCashFlow) = cf.op(amount(cf.first), amount(cf.second))
"""
expected_amount(cf::CombinedCashFlow, obs_time::ModelTime)
Return the payoff representing the simulated expected amount of the payment.
"""
expected_amount(cf::CombinedCashFlow, obs_time::ModelTime) = cf.op(expected_amount(cf.first, obs_time), expected_amount(cf.second, obs_time))