/
HullWhiteIborFutureTradePricer.java
284 lines (259 loc) · 11.9 KB
/
HullWhiteIborFutureTradePricer.java
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/*
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.index;
import java.time.LocalDate;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.pricer.model.HullWhiteOneFactorPiecewiseConstantParametersProvider;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.product.index.IborFuture;
import com.opengamma.strata.product.index.IborFutureTrade;
import com.opengamma.strata.product.index.ResolvedIborFuture;
import com.opengamma.strata.product.index.ResolvedIborFutureTrade;
/**
* Pricer for for Ibor future trades.
* <p>
* This function provides the ability to price a {@link IborFutureTrade} based on
* Hull-White one-factor model with piecewise constant volatility.
* <p>
* Reference: Henrard M., Eurodollar Futures and Options: Convexity Adjustment in HJM One-Factor Model. March 2005.
* Available at <a href="http://ssrn.com/abstract=682343">http://ssrn.com/abstract=682343</a>
*
* <h4>Price</h4>
* The price of an Ibor future is based on the interest rate of the underlying index.
* It is defined as {@code (100 - percentRate)}.
* <p>
* Strata uses <i>decimal prices</i> for Ibor futures in the trade model, pricers and market data.
* The decimal price is based on the decimal rate equivalent to the percentage.
* For example, a price of 99.32 implies an interest rate of 0.68% which is represented in Strata by 0.9932.
*/
public class HullWhiteIborFutureTradePricer {
/**
* Default implementation.
*/
public static final HullWhiteIborFutureTradePricer DEFAULT =
new HullWhiteIborFutureTradePricer(HullWhiteIborFutureProductPricer.DEFAULT);
/**
* Underlying pricer.
*/
private final HullWhiteIborFutureProductPricer productPricer;
/**
* Creates an instance.
*
* @param productPricer the pricer for {@link IborFuture}
*/
public HullWhiteIborFutureTradePricer(HullWhiteIborFutureProductPricer productPricer) {
this.productPricer = ArgChecker.notNull(productPricer, "productPricer");
}
//-------------------------------------------------------------------------
/**
* Calculates the price of the Ibor future trade.
* <p>
* The price of the trade is the price on the valuation date.
* The price is calculated using the Hull-White model.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the price of the trade, in decimal form
*/
public double price(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
return productPricer.price(trade.getProduct(), ratesProvider, hwProvider);
}
//-------------------------------------------------------------------------
/**
* Calculates the price sensitivity of the Ibor future product.
* <p>
* The price sensitivity of the product is the sensitivity of the price to the underlying curves.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the price curve sensitivity of the product
*/
public PointSensitivities priceSensitivityRates(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
return productPricer.priceSensitivityRates(trade.getProduct(), ratesProvider, hwProvider);
}
//-------------------------------------------------------------------------
/**
* Calculates the reference price for the trade.
* <p>
* If the valuation date equals the trade date, then the reference price is the trade price.
* Otherwise, the reference price is the last settlement price used for margining.
*
* @param trade the trade
* @param valuationDate the date for which the reference price should be calculated
* @param lastSettlementPrice the last settlement price used for margining, in decimal form
* @return the reference price, in decimal form
*/
private double referencePrice(ResolvedIborFutureTrade trade, LocalDate valuationDate, double lastSettlementPrice) {
ArgChecker.notNull(valuationDate, "valuationDate");
return trade.getTradedPrice()
.filter(tp -> tp.getTradeDate().equals(valuationDate))
.map(tp -> tp.getPrice())
.orElse(lastSettlementPrice);
}
//-------------------------------------------------------------------------
/**
* Calculates the present value of the Ibor future trade from the current price.
* <p>
* The present value of the product is the value on the valuation date.
* <p>
* The calculation is performed against a reference price. The reference price
* must be the last settlement price used for margining, except on the trade date,
* when it must be the trade price.
*
* @param trade the trade
* @param currentPrice the current price, in decimal form
* @param referencePrice the reference price to margin against, typically the last settlement price, in decimal form
* @return the present value
*/
CurrencyAmount presentValue(ResolvedIborFutureTrade trade, double currentPrice, double referencePrice) {
ResolvedIborFuture future = trade.getProduct();
double priceIndex = productPricer.marginIndex(future, currentPrice);
double referenceIndex = productPricer.marginIndex(future, referencePrice);
double pv = (priceIndex - referenceIndex) * trade.getQuantity();
return CurrencyAmount.of(future.getCurrency(), pv);
}
//-------------------------------------------------------------------------
/**
* Calculates the present value of the Ibor future trade.
* <p>
* The present value of the product is the value on the valuation date.
* The current price is calculated using the Hull-White model.
* <p>
* This method calculates based on the difference between the model price and the
* last settlement price, or the trade price if traded on the valuation date.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @param lastSettlementPrice the last settlement price used for margining, in decimal form
* @return the present value
*/
public CurrencyAmount presentValue(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider,
double lastSettlementPrice) {
double referencePrice = referencePrice(trade, ratesProvider.getValuationDate(), lastSettlementPrice);
double price = price(trade, ratesProvider, hwProvider);
return presentValue(trade, price, referencePrice);
}
//-------------------------------------------------------------------------
/**
* Calculates the present value sensitivity of the Ibor future trade.
* <p>
* The present value sensitivity of the trade is the sensitivity of the present value to
* the underlying curves.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the present value curve sensitivity of the trade
*/
public PointSensitivities presentValueSensitivityRates(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
ResolvedIborFuture product = trade.getProduct();
PointSensitivities priceSensi = productPricer.priceSensitivityRates(product, ratesProvider, hwProvider);
PointSensitivities marginIndexSensi = productPricer.marginIndexSensitivity(product, priceSensi);
return marginIndexSensi.multipliedBy(trade.getQuantity());
}
//-------------------------------------------------------------------------
/**
* Calculates the present value sensitivity to piecewise constant volatility parameters of the Hull-White model.
*
* @param trade the trade to price
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the present value parameter sensitivity of the trade
*/
public DoubleArray presentValueSensitivityModelParamsHullWhite(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
ResolvedIborFuture product = trade.getProduct();
DoubleArray hwSensi = productPricer.priceSensitivityModelParamsHullWhite(product, ratesProvider, hwProvider);
hwSensi = hwSensi.multipliedBy(product.getNotional() * product.getAccrualFactor() * trade.getQuantity());
return hwSensi;
}
//-------------------------------------------------------------------------
/**
* Calculates the par spread of the Ibor future trade.
* <p>
* The par spread is defined in the following way. When the reference price (or market quote)
* is increased by the par spread, the present value of the trade is zero.
* The current price is calculated using the Hull-White model.
* <p>
* This method calculates based on the difference between the model price and the
* last settlement price, or the trade price if traded on the valuation date.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @param lastSettlementPrice the last settlement price used for margining, in decimal form
* @return the par spread.
*/
public double parSpread(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider,
double lastSettlementPrice) {
double referencePrice = referencePrice(trade, ratesProvider.getValuationDate(), lastSettlementPrice);
return price(trade, ratesProvider, hwProvider) - referencePrice;
}
//-------------------------------------------------------------------------
/**
* Calculates the par spread sensitivity of the Ibor future trade.
* <p>
* The par spread sensitivity of the trade is the sensitivity of the par spread to
* the underlying curves.
*
* @param trade the trade
* @param ratesProvider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @return the par spread curve sensitivity of the trade
*/
public PointSensitivities parSpreadSensitivityRates(
ResolvedIborFutureTrade trade,
RatesProvider ratesProvider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider) {
return productPricer.priceSensitivityRates(trade.getProduct(), ratesProvider, hwProvider);
}
//-------------------------------------------------------------------------
/**
* Calculates the currency exposure of the Ibor future trade.
* <p>
* Since the Ibor future is based on a single currency, the trade is exposed to only this currency.
* <p>
* This method calculates based on the difference between the model price and the
* last settlement price, or the trade price if traded on the valuation date.
*
* @param trade the trade
* @param provider the rates provider
* @param hwProvider the Hull-White model parameter provider
* @param lastSettlementPrice the last settlement price used for margining, in decimal form
* @return the currency exposure of the trade
*/
public MultiCurrencyAmount currencyExposure(
ResolvedIborFutureTrade trade,
RatesProvider provider,
HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider,
double lastSettlementPrice) {
return MultiCurrencyAmount.of(presentValue(trade, provider, hwProvider, lastSettlementPrice));
}
}