|
| 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 | +} |
0 commit comments