/* * (c) Copyright Christian P. Fries, Germany. All rights reserved. Contact: email@christianfries.com. * * Created on 28.06.2016 */ package net.finmath.montecarlo.assetderivativevaluation; import java.text.DecimalFormat; import org.junit.Test; import net.finmath.exception.CalculationException; import net.finmath.functions.AnalyticFormulas; import net.finmath.montecarlo.BrownianMotion; import net.finmath.montecarlo.BrownianMotionInterface; import net.finmath.montecarlo.BrownianMotionView; import net.finmath.montecarlo.assetderivativevaluation.HestonModel.Scheme; import net.finmath.montecarlo.assetderivativevaluation.products.EuropeanOption; import net.finmath.montecarlo.model.AbstractModel; import net.finmath.montecarlo.process.AbstractProcess; import net.finmath.montecarlo.process.ProcessEulerScheme; import net.finmath.time.TimeDiscretization; import net.finmath.time.TimeDiscretizationInterface; /** * @author Christian Fries * */ public class MertonModelTest { // Model properties private final double initialValue = 1.0; private final double riskFreeRate = 0.05; private final double volatility = 0.30; private final double theta = volatility*volatility; private final double kappa = 1.0; private final double xi = 0.3; private final double rho = 0.0; private final Scheme scheme = Scheme.FULL_TRUNCATION; // Process discretization properties private final int numberOfPaths = 100000; private final int numberOfTimeSteps = 100; private final double deltaT = 0.02; private final int seed = 3141; // Product properties private final int assetIndex = 0; private final double optionMaturity = 2.0; private final double optionStrike = 1.10; @Test public void test() throws CalculationException { long start = System.currentTimeMillis(); // Create a time discretization TimeDiscretizationInterface timeDiscretization = new TimeDiscretization(0.0 /* initial */, numberOfTimeSteps, deltaT); BrownianMotionInterface brownianMotion = new BrownianMotion(timeDiscretization, 2 /* numberOfFactors */, numberOfPaths, seed); AssetModelMonteCarloSimulationInterface monteCarloBlackScholesModel; { // Create a model AbstractModel model = new BlackScholesModel(initialValue, riskFreeRate, volatility); // Create a corresponding MC process AbstractProcess process = new ProcessEulerScheme(new BrownianMotionView(brownianMotion, new Integer[] { new Integer(0) })); // Using the process (Euler scheme), create an MC simulation of a Black-Scholes model monteCarloBlackScholesModel = new MonteCarloAssetModel(model, process); } AssetModelMonteCarloSimulationInterface monteCarloHestonModel; { // Create a model AbstractModel model = new HestonModel(initialValue, riskFreeRate, volatility, theta, kappa, xi, rho, scheme); // Create a corresponding MC process AbstractProcess process = new ProcessEulerScheme(brownianMotion); // Using the process (Euler scheme), create an MC simulation of a Black-Scholes model monteCarloHestonModel = new MonteCarloAssetModel(model, process); } AssetModelMonteCarloSimulationInterface monteCarloMertonModel; { double m = 1.0; double nu = 0.15; double lambda = 0.4; double jumpSizeStdDev = nu; double jumpSizeMean = Math.log(m); monteCarloMertonModel = new MonteCarloMertonModel( timeDiscretization, numberOfPaths, seed, initialValue, riskFreeRate, volatility, lambda, jumpSizeMean, jumpSizeStdDev); } /* * Value a call option (using the product implementation) */ for(double moneyness = 0.0; moneyness <= 2.0; moneyness += 0.1) { EuropeanOption europeanOption = new EuropeanOption(optionMaturity, optionStrike * moneyness); double value = europeanOption.getValue(monteCarloBlackScholesModel); double value2 = europeanOption.getValue(monteCarloHestonModel); double value3 = europeanOption.getValue(monteCarloMertonModel); double valueAnalytic = AnalyticFormulas.blackScholesOptionValue(initialValue, riskFreeRate, volatility, optionMaturity, optionStrike); double impliedVol1 = AnalyticFormulas.blackScholesOptionImpliedVolatility(initialValue*Math.exp(riskFreeRate*optionMaturity), optionMaturity, optionStrike*moneyness, Math.exp(-riskFreeRate*optionMaturity), value); double impliedVol2 = AnalyticFormulas.blackScholesOptionImpliedVolatility(initialValue*Math.exp(riskFreeRate*optionMaturity), optionMaturity, optionStrike*moneyness, Math.exp(-riskFreeRate*optionMaturity), value2); double impliedVol3 = AnalyticFormulas.blackScholesOptionImpliedVolatility(initialValue*Math.exp(riskFreeRate*optionMaturity), optionMaturity, optionStrike*moneyness, Math.exp(-riskFreeRate*optionMaturity), value3); DecimalFormat formatter2 = new DecimalFormat("0.00"); DecimalFormat formatter4 = new DecimalFormat("0.00%"); System.out.print(formatter2.format(optionStrike * moneyness) + "\t" + formatter4.format(impliedVol1)); // System.out.println("\t " + value2 + "\t " + impliedVol2); System.out.println("\t " + formatter4.format(value3) + "\t " + formatter4.format(impliedVol3)); } long end = System.currentTimeMillis(); System.out.print("Test took " + (end-start) / 1000.0 + " sec."); } }