/* * (c) Copyright Christian P. Fries, Germany. All rights reserved. Contact: email@christianfries.com. * * Created on 15.06.2016 */ package net.finmath.montecarlo.assetderivativevaluation; import org.junit.Assert; import org.junit.Test; import net.finmath.exception.CalculationException; import net.finmath.functions.AnalyticFormulas; import net.finmath.montecarlo.BrownianMotion; 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.stochastic.RandomVariableInterface; import net.finmath.time.TimeDiscretization; import net.finmath.time.TimeDiscretizationInterface; /** * @author Christian Fries * */ public class MonteCarloBlackScholesModelTest { // Model properties private final double initialValue = 1.0; private final double riskFreeRate = 0.05; private final double volatility = 0.30; // Process discretization properties private final int numberOfPaths = 20000; private final int numberOfTimeSteps = 10; private final double deltaT = 0.5; private final int seed = 31415; // Product properties private final int assetIndex = 0; private final double optionMaturity = 2.0; private final double optionStrike = 1.05; @Test public void testDirectValuation() throws CalculationException { // Create a model AbstractModel model = new BlackScholesModel(initialValue, riskFreeRate, volatility); // Create a time discretizeion TimeDiscretizationInterface timeDiscretization = new TimeDiscretization(0.0 /* initial */, numberOfTimeSteps, deltaT); // Create a corresponding MC process AbstractProcess process = new ProcessEulerScheme(new BrownianMotion(timeDiscretization, 1 /* numberOfFactors */, numberOfPaths, seed)); // Link model and process for delegation process.setModel(model); model.setProcess(process); /* * Value a call option - directly */ RandomVariableInterface asset = process.getProcessValue(timeDiscretization.getTimeIndex(optionMaturity), assetIndex); RandomVariableInterface numeraireAtPayment = model.getNumeraire(optionMaturity); RandomVariableInterface numeraireAtEval = model.getNumeraire(0.0); RandomVariableInterface payoff = asset.sub(optionStrike).floor(0.0); double value = payoff.div(numeraireAtPayment).mult(numeraireAtEval).getAverage(); double valueAnalytic = AnalyticFormulas.blackScholesOptionValue(initialValue, riskFreeRate, volatility, optionMaturity, optionStrike); System.out.println("value using Monte-Carlo.......: " + value); System.out.println("value using analytic formula..: " + valueAnalytic); Assert.assertEquals(valueAnalytic, value, 0.005); } @Test public void testProductImplementation() throws CalculationException { // Create a model AbstractModel model = new BlackScholesModel(initialValue, riskFreeRate, volatility); // Create a time discretization TimeDiscretizationInterface timeDiscretization = new TimeDiscretization(0.0 /* initial */, numberOfTimeSteps, deltaT); // Create a corresponding MC process AbstractProcess process = new ProcessEulerScheme(new BrownianMotion(timeDiscretization, 1 /* numberOfFactors */, numberOfPaths, seed)); // Using the process (Euler scheme), create an MC simulation of a Black-Scholes model AssetModelMonteCarloSimulationInterface monteCarloBlackScholesModel = new MonteCarloAssetModel(model, process); /* * Value a call option (using the product implementation) */ EuropeanOption europeanOption = new EuropeanOption(optionMaturity, optionStrike); double value = europeanOption.getValue(monteCarloBlackScholesModel); double valueAnalytic = AnalyticFormulas.blackScholesOptionValue(initialValue, riskFreeRate, volatility, optionMaturity, optionStrike); System.out.println("value using Monte-Carlo.......: " + value); System.out.println("value using analytic formula..: " + valueAnalytic); Assert.assertEquals(valueAnalytic, value, 0.005); } }