All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.finmath.montecarlo.assetderivativevaluation.models.MultiAssetBlackScholesModel Maven / Gradle / Ivy

Go to download

finmath lib is a Mathematical Finance Library in Java. It provides algorithms and methodologies related to mathematical finance.

The newest version!
/*
 * (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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy