Skip to content

Commit d480bcd

Browse files
Merge pull request #103 from AlessandroGnoatto/main
EuropeanOption
2 parents efc999c + 6bb2dd9 commit d480bcd

21 files changed

Lines changed: 709 additions & 36 deletions

File tree

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package net.finmath.finitedifference.products;
2+
3+
import net.finmath.finitedifference.models.FiniteDifference1DBoundary;
4+
import net.finmath.finitedifference.models.FiniteDifference1DModel;
5+
import net.finmath.modelling.products.CallOrPut;
6+
7+
8+
/**
9+
* Implements valuation of a European option on a single asset.
10+
*
11+
* Given a model for an asset <i>S</i>, the European option with strike <i>K</i>, maturity <i>T</i>
12+
* pays
13+
* <br>
14+
* <i>max((S(T) - K) * CallOrPut , 0)</i> in <i>T</i>
15+
* <br>
16+
*
17+
* The class implements the characteristic function of the call option
18+
* payoff, i.e., its Fourier transform.
19+
*
20+
* @author Christian Fries
21+
* @author Ralph Rudd
22+
* @author Alessandro Gnoatto
23+
* @version 1.0
24+
*/
25+
public class EuropeanOption implements FiniteDifference1DProduct, FiniteDifference1DBoundary{
26+
27+
private final String underlyingName;
28+
private final double maturity;
29+
private final double strike;
30+
private final CallOrPut callOrPutSign;
31+
32+
/**
33+
* Construct a product representing an European option on an asset S (where S the asset with index <code>underlyingIndex</code> from the model - single asset case).
34+
* @param underlyingName Name of the underlying
35+
* @param maturity The maturity T in the option payoff max(sign * (S(T)-K),0).
36+
* @param strike The strike K in the option payoff max(sign * (S(T)-K),0).
37+
* @param callOrPutSign The sign in the payoff.
38+
*/
39+
public EuropeanOption(final String underlyingName, final double maturity, final double strike, final double callOrPutSign) {
40+
super();
41+
this.underlyingName = underlyingName;
42+
this.maturity = maturity;
43+
this.strike = strike;
44+
if(callOrPutSign == 1.0) {
45+
this.callOrPutSign = CallOrPut.CALL;
46+
}else if(callOrPutSign == - 1.0) {
47+
this.callOrPutSign = CallOrPut.PUT;
48+
}else {
49+
throw new IllegalArgumentException("Unknown option type");
50+
}
51+
}
52+
53+
/**
54+
* Construct a product representing an European option on an asset S (where S the asset with index <code>underlyingIndex</code> from the model - single asset case).
55+
* @param underlyingName Name of the underlying
56+
* @param maturity The maturity T in the option payoff max(sign * (S(T)-K),0).
57+
* @param strike The strike K in the option payoff max(sign * (S(T)-K),0).
58+
* @param callOrPutSign The sign in the payoff.
59+
*/
60+
public EuropeanOption(final String underlyingName, final double maturity, final double strike, final CallOrPut callOrPutSign) {
61+
super();
62+
this.underlyingName = underlyingName;
63+
this.maturity = maturity;
64+
this.strike = strike;
65+
this.callOrPutSign = callOrPutSign;
66+
}
67+
68+
/**
69+
* Construct a product representing an European option on an asset S (where S the asset with index 0 from the model - single asset case).
70+
* @param maturity The maturity T in the option payoff max(S(T)-K,0)
71+
* @param strike The strike K in the option payoff max(S(T)-K,0).
72+
* @param callOrPutSign The sign in the payoff.
73+
* @param underlyingIndex The index of the underlying to be fetched from the model.
74+
*/
75+
public EuropeanOption(final double maturity, final double strike, final double callOrPutSign) {
76+
super();
77+
this.maturity = maturity;
78+
this.strike = strike;
79+
if(callOrPutSign == 1.0) {
80+
this.callOrPutSign = CallOrPut.CALL;
81+
}else if(callOrPutSign == - 1.0) {
82+
this.callOrPutSign = CallOrPut.PUT;
83+
}else {
84+
throw new IllegalArgumentException("Unknown option type");
85+
}
86+
this.underlyingName = null; // Use underlyingIndex
87+
}
88+
89+
/**
90+
* Construct a product representing an European option on an asset S (where S the asset with index 0 from the model - single asset case).
91+
* @param maturity The maturity T in the option payoff max(S(T)-K,0)
92+
* @param strike The strike K in the option payoff max(S(T)-K,0).
93+
* @param callOrPutSign The sign in the payoff.
94+
* @param underlyingIndex The index of the underlying to be fetched from the model.
95+
*/
96+
public EuropeanOption(final double maturity, final double strike, final CallOrPut callOrPutSign) {
97+
super();
98+
this.maturity = maturity;
99+
this.strike = strike;
100+
this.callOrPutSign = callOrPutSign;
101+
this.underlyingName = null; // Use underlyingIndex
102+
}
103+
104+
/**
105+
* Construct a product representing an European option on an asset S (where S the asset with index <code>underlyingIndex</code> from the model - single asset case).
106+
* @param underlyingName Name of the underlying
107+
* @param maturity The maturity T in the option payoff max(S(T)-K,0)
108+
* @param strike The strike K in the option payoff max(S(T)-K,0).
109+
*/
110+
public EuropeanOption(final String underlyingName, final double maturity, final double strike) {
111+
this(underlyingName, maturity, strike, 1.0);
112+
}
113+
114+
115+
/**
116+
* Construct a product representing an European option on an asset S (where S the asset with index 0 from the model - single asset case).
117+
* @param maturity The maturity T in the option payoff max(S(T)-K,0)
118+
* @param strike The strike K in the option payoff max(S(T)-K,0).
119+
*/
120+
public EuropeanOption(final double maturity, final double strike) {
121+
this(maturity, strike, 1.0);
122+
}
123+
124+
@Override
125+
public double[][] getValue(final double evaluationTime, final FiniteDifference1DModel model) {
126+
127+
/*
128+
* The FDM algorithm requires the boundary conditions of the product.
129+
* This product implements the boundary interface
130+
*/
131+
final FiniteDifference1DBoundary boundary = this;
132+
133+
if(callOrPutSign == CallOrPut.CALL) {
134+
return model.getValue(evaluationTime, maturity, assetValue -> Math.max(assetValue - strike, 0), boundary);
135+
}else {
136+
return model.getValue(evaluationTime, maturity, assetValue -> Math.max(strike - assetValue, 0), boundary);
137+
}
138+
}
139+
140+
/*
141+
* Implementation of the interface:
142+
* @see net.finmath.finitedifference.products.FiniteDifference1DBoundary#getValueAtLowerBoundary(net.finmath.finitedifference.models.FDMBlackScholesModel, double, double)
143+
*/
144+
@Override
145+
public double getValueAtLowerBoundary(final FiniteDifference1DModel model, final double currentTime, final double stockPrice) {
146+
if(callOrPutSign == CallOrPut.CALL) {
147+
return 0;
148+
}else {
149+
return strike * Math.exp(-model.getRiskFreeRate()*(maturity - currentTime));
150+
}
151+
}
152+
153+
@Override
154+
public double getValueAtUpperBoundary(final FiniteDifference1DModel model, final double currentTime, final double stockPrice) {
155+
if(callOrPutSign == CallOrPut.CALL) {
156+
return stockPrice - strike * Math.exp(-model.getRiskFreeRate()*(maturity - currentTime));
157+
}else {
158+
return 0.0;
159+
}
160+
161+
}
162+
163+
public String getUnderlyingName() {
164+
return underlyingName;
165+
}
166+
167+
public double getMaturity() {
168+
return maturity;
169+
}
170+
171+
public double getStrike() {
172+
return strike;
173+
}
174+
175+
public CallOrPut getCallOrPutSign() {
176+
return callOrPutSign;
177+
}
178+
179+
}

src/main/java/net/finmath/finitedifference/products/FDMEuropeanCallOption.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77

88
/**
99
* Implementation of a European option to be valued by a the finite difference method.
10+
*
11+
* WARNING!! This class is scheduled for deletion in a future release. Use EuropeanOption.
1012
*
1113
* @author Christian Fries
1214
* @author Ralph Rudd
1315
* @version 1.0
1416
*/
17+
@Deprecated
1518
public class FDMEuropeanCallOption implements FiniteDifference1DProduct, FiniteDifference1DBoundary {
1619
private final double maturity;
1720
private final double strike;

src/main/java/net/finmath/finitedifference/products/FDMEuropeanPutOption.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
/**
77
* Implementation of a European option to be valued by a the finite difference method.
88
*
9+
* WARNING!! This class is scheduled for deletion in a future release. Use EuropeanOption.
10+
*
911
* @author Christian Fries
1012
* @author Ralph Rudd
1113
*/
14+
@Deprecated
1215
public class FDMEuropeanPutOption implements FiniteDifference1DProduct, FiniteDifference1DBoundary {
1316
private final double maturity;
1417
private final double strike;

src/main/java/net/finmath/fouriermethod/models/BatesModel.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,30 @@ public double getInitialValue() {
394394
return initialValue;
395395
}
396396

397+
/**
398+
* @return the discountCurveForForwardRate
399+
*/
400+
@Override
401+
public DiscountCurve getDiscountCurveForForwardRate() {
402+
return discountCurveForForwardRate;
403+
}
404+
397405
/**
398406
* @return the riskFreeRate
399407
*/
408+
@Override
400409
public double getRiskFreeRate() {
401410
return riskFreeRate;
402411
}
403412

413+
/**
414+
* @return the discountCurveForDiscountRate
415+
*/
416+
@Override
417+
public DiscountCurve getDiscountCurveForDiscountRate() {
418+
return discountCurveForDiscountRate;
419+
}
420+
404421
/**
405422
* @return the volatility
406423
*/

src/main/java/net/finmath/fouriermethod/models/BlackScholesModel.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,15 @@ private double getLogDiscountFactorForDiscounting(final double time) {
129129
/**
130130
* @return the referenceDate
131131
*/
132+
@Override
132133
public LocalDate getReferenceDate() {
133134
return referenceDate;
134135
}
135136

136137
/**
137138
* @return the initialValue
138139
*/
140+
@Override
139141
public double getInitialValue() {
140142
return initialValue;
141143
}

src/main/java/net/finmath/fouriermethod/models/CharacteristicFunctionModel.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
package net.finmath.fouriermethod.models;
88

9+
import java.time.LocalDate;
10+
911
import net.finmath.fouriermethod.CharacteristicFunction;
12+
import net.finmath.marketdata.model.curves.DiscountCurve;
1013
import net.finmath.modelling.Model;
1114

1215
/**
@@ -16,7 +19,6 @@
1619
* @author Christian Fries
1720
* @version 1.0
1821
*/
19-
@FunctionalInterface
2022
public interface CharacteristicFunctionModel extends Model {
2123

2224
/**
@@ -26,4 +28,37 @@ public interface CharacteristicFunctionModel extends Model {
2628
* @return The characteristic function of X(t).
2729
*/
2830
CharacteristicFunction apply(double time);
31+
32+
/**
33+
*
34+
* @return the reference date
35+
*/
36+
public LocalDate getReferenceDate();
37+
38+
/**
39+
*
40+
* @return the initial value of the stock
41+
*/
42+
public double getInitialValue();
43+
44+
/**
45+
* @return the discountCurveForForwardRate
46+
*/
47+
public DiscountCurve getDiscountCurveForForwardRate();
48+
49+
/**
50+
* @return the riskFreeRate
51+
*/
52+
public double getRiskFreeRate();
53+
54+
/**
55+
* @return the discountCurveForDiscountRate
56+
*/
57+
public DiscountCurve getDiscountCurveForDiscountRate();
58+
59+
/**
60+
* @return the discountRate
61+
*/
62+
public double getDiscountRate();
63+
2964
}

src/main/java/net/finmath/fouriermethod/models/HestonModel.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,41 +209,47 @@ private double getLogDiscountFactorForDiscounting(final double time) {
209209
/**
210210
* @return the referenceDate
211211
*/
212+
@Override
212213
public LocalDate getReferenceDate() {
213214
return referenceDate;
214215
}
215216

216217
/**
217218
* @return the initialValue
218219
*/
220+
@Override
219221
public double getInitialValue() {
220222
return initialValue;
221223
}
222224

223225
/**
224226
* @return the discountCurveForForwardRate
225227
*/
228+
@Override
226229
public DiscountCurve getDiscountCurveForForwardRate() {
227230
return discountCurveForForwardRate;
228231
}
229232

230233
/**
231234
* @return the riskFreeRate
232235
*/
236+
@Override
233237
public double getRiskFreeRate() {
234238
return riskFreeRate;
235239
}
236240

237241
/**
238242
* @return the discountCurveForDiscountRate
239243
*/
244+
@Override
240245
public DiscountCurve getDiscountCurveForDiscountRate() {
241246
return discountCurveForDiscountRate;
242247
}
243248

244249
/**
245250
* @return the discountRate
246251
*/
252+
@Override
247253
public double getDiscountRate() {
248254
return discountRate;
249255
}

0 commit comments

Comments
 (0)