net.finmath.montecarlo.assetderivativevaluation.models.MultiAssetBlackScholesModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of finmath-lib Show documentation
Show all versions of finmath-lib Show documentation
finmath lib is a Mathematical Finance Library in Java.
It provides algorithms and methodologies related to mathematical finance.
/*
* (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
*
* Created on 09.06.2014
*/
package net.finmath.montecarlo.assetderivativevaluation.models;
import java.util.Arrays;
import java.util.Map;
import net.finmath.functions.LinearAlgebra;
import net.finmath.montecarlo.RandomVariableFactory;
import net.finmath.montecarlo.RandomVariableFromArrayFactory;
import net.finmath.montecarlo.model.AbstractProcessModel;
import net.finmath.montecarlo.process.MonteCarloProcess;
import net.finmath.stochastic.RandomVariable;
/**
* This class implements a multi-asset Black Scholes model providing an AbstractProcessModel
.
* The class can be used with an EulerSchemeFromProcessModel to create a Monte-Carlo simulation.
*
* The model can be specified by general factor loadings, that is, in the form
* \[
* dS_{i} = r S_{i} dt + S_{i} \sum_{j=0}^{m-1} f{i,j} dW_{j}, \quad S_{i}(0) = S_{i,0},
* \]
* \[
* dN = r N dt, \quad N(0) = N_{0}.
* \]
*
* Alternatively, the model can be specifies by providing volatilities and correlations
* from which the factor loadings \( f_{i,j} \) are derived such that
* \[
* \sum_{k=0}^{m-1} f{i,k} f{j,k} = \sigma_{i} \sigma_{j} \rho_{i,j}
* \]
* such that the effective model is
* \[
* dS_{i} = r S_{i} dt + \sigma_{i} S_{i} dW_{i}, \quad S_{i}(0) = S_{i,0},
* \]
* \[
* dN = r N dt, \quad N(0) = N_{0},
* \]
* \[
* dW_{i} dW_{j} = \rho_{i,j} dt,
* \]
* Note that in case the model is used with an EulerSchemeFromProcessModel, the BrownianMotion used can
* have a correlation, which alters the simulation (which is admissible).
* The specification above hold, provided that the BrownianMotion used has independent components.
*
* The class provides the model of \( S_{i} \) to an {@link net.finmath.montecarlo.process.MonteCarloProcess}
via the specification of
* \( f = exp \), \( \mu_{i} = r - \frac{1}{2} \sigma_{i}^2 \), \( \lambda_{i,j} = \sigma_{i} g_{i,j} \), i.e.,
* of the SDE
* \[
* dX_{i} = \mu_{i} dt + \sum_{j=0}^{m-1} \lambda_{i,j} dW_{j}, \quad X_{i}(0) = \log(S_{i,0}),
* \]
* with \( S = f(X) \). See {@link net.finmath.montecarlo.process.MonteCarloProcess} for the notation.
*
* @author Christian Fries
* @see net.finmath.montecarlo.process.MonteCarloProcess The interface for numerical schemes.
* @see net.finmath.montecarlo.model.ProcessModel The interface for models provinding parameters to numerical schemes.
* @version 1.1
*/
public class MultiAssetBlackScholesModel extends AbstractProcessModel {
private final RandomVariableFactory randomVariableFactory;
private final double[] initialValues;
private final double riskFreeRate; // Actually the same as the drift (which is not stochastic)
private final double[][] factorLoadings;
private final RandomVariable[] initialStates;
private final RandomVariable[] drift;
private final RandomVariable[][] factorLoadingOnPaths;
/**
* Create a multi-asset Black-Scholes model.
*
* @param randomVariableFactory The RandomVariableFactory used to construct model parameters as random variables.
* @param initialValues Spot values.
* @param riskFreeRate The risk free rate.
* @param factorLoadings The matrix of factor loadings, where factorLoadings[underlyingIndex][factorIndex] is the coefficient of the Brownian driver factorIndex used for the underlying underlyingIndex.
*/
public MultiAssetBlackScholesModel(
final RandomVariableFactory randomVariableFactory,
final double[] initialValues,
final double riskFreeRate,
final double[][] factorLoadings
) {
this.randomVariableFactory = randomVariableFactory;
this.initialValues = initialValues;
this.riskFreeRate = riskFreeRate;
this.factorLoadings = factorLoadings;
/*
* The interface definition requires that we provide the initial value, the drift and the volatility in terms of random variables.
* We construct the corresponding random variables here and will return (immutable) references to them.
*
* Since the underlying process is configured to simulate log(S),
* the initial value and the drift are transformed accordingly.
*
*/
initialStates = new RandomVariable[getNumberOfComponents()];
drift = new RandomVariable[getNumberOfComponents()];
factorLoadingOnPaths = new RandomVariable[getNumberOfComponents()][];
for(int underlyingIndex = 0; underlyingIndex dataModified) {
final RandomVariableFactory newRandomVariableFactory = (RandomVariableFactory) dataModified.getOrDefault("randomVariableFactory", randomVariableFactory);
final double[] newInitialValues = (double[]) dataModified.getOrDefault("initialValues", initialValues);
final double newRiskFreeRate = ((Double) dataModified.getOrDefault("riskFreeRate", riskFreeRate)).doubleValue();
double[][] newFactorLoadings = (double[][]) dataModified.getOrDefault("factorLoadings", factorLoadings);
if(dataModified.containsKey("volatilities") || dataModified.containsKey("correlations")) {
if(dataModified.containsKey("factorLoadings")) {
throw new IllegalArgumentException("Inconsistend parameters. Cannot specify volatility or corellation and factorLoadings at the same time.");
}
final double[] newVolatilities = (double[]) dataModified.getOrDefault("volatilities", getVolatilityVector());
final double[][] newCorrelations = (double[][]) dataModified.getOrDefault("correlations", getCorrelationMatrix());
newFactorLoadings = getFactorLoadingsFromVolatilityAnCorrelation(newVolatilities, newCorrelations);
}
return new MultiAssetBlackScholesModel(
newRandomVariableFactory,
newInitialValues,
newRiskFreeRate,
newFactorLoadings
);
}
@Override
public String toString() {
return "MonteCarloMultiAssetBlackScholesModel [initialValues="
+ Arrays.toString(initialValues) + ", riskFreeRate="
+ riskFreeRate + ", factorLoadings="
+ Arrays.toString(factorLoadings) + "]";
}
/**
* Returns the risk free rate parameter of this model.
*
* @return Returns the riskFreeRate.
*/
public double getRiskFreeRate() {
return riskFreeRate;
}
/**
* Returns the factorLoadings parameters of this model.
*
* @return Returns the factorLoadings.
*/
public double[][] getFactorLoadingMatrix() {
return factorLoadings;
}
/**
* Returns the volatility parameters of this model.
*
* @return Returns the volatilities.
*/
public double[] getVolatilityVector() {
final double[] volatilities = new double[factorLoadings.length];
for(int underlyingIndex = 0; underlyingIndex