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

net.finmath.fouriermethod.models.HestonModel Maven / Gradle / Ivy

Go to download

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

There is a newer version: 6.0.19
Show newest version
/*
 * (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
 *
 * Created on 23.03.2014
 */

package net.finmath.fouriermethod.models;

import java.time.LocalDate;

import org.apache.commons.math3.complex.Complex;

import net.finmath.fouriermethod.CharacteristicFunction;
import net.finmath.marketdata.model.curves.DiscountCurve;

/**
 * Implements the characteristic function of a Heston model.
 *
 * The model is
 * \[
 * 	dS(t) = r^{\text{c}}(t) S(t) dt + \sqrt{V(t)} S(t) dW_{1}(t), \quad S(0) = S_{0},
 * \]
 * \[
 * 	dV(t) = \kappa ( \theta - V(t) ) dt + \xi \sqrt{V(t)} dW_{2}(t), \quad V(0) = \sigma^2,
 * \]
 * \[
 * 	dW_{1} dW_{2} = \rho dt
 * \]
 * \[
 * 	dN(t) = r^{\text{d}}(t) N(t) dt, \quad N(0) = N_{0},
 * \]
 * where \( W \) is a Brownian motion.
 *
 * The model allows to specify two independent rate for forwarding (\( r^{\text{c}} \)) and discounting (\( r^{\text{d}} \)).
 * It thus allow for a simple modelling of a funding / collateral curve (via (\( r^{\text{d}} \)) and/or the specification of
 * a dividend yield.
 *
 * The free parameters of this model are:
 * 
*
\( S_{0} \)
spot - initial value of S
*
\( r^{\text{c}} \)
the risk free rate (may be provided as a curve or a constant)
*
\( \sigma \)
the initial volatility level
*
\( r^{\text{d}} \)
the discount rate (may be provided as a curve or a constant)
*
\( \xi \)
the volatility of volatility
*
\( \theta \)
the mean reversion level of the stochastic volatility
*
\( \kappa \)
the mean reversion speed of the stochastic volatility
*
\( \rho \)
the correlation of the Brownian drivers
*
* * @author Christian Fries * @author Andy Graf * @author Lorenzo Toricelli * @version 1.0 */ public class HestonModel implements CharacteristicFunctionModel { private final LocalDate referenceDate; private final double initialValue; private final DiscountCurve discountCurveForForwardRate; private final double riskFreeRate; // Constant rate, used if discountCurveForForwardRate is null private final DiscountCurve discountCurveForDiscountRate; private final double discountRate; // Constant rate, used if discountCurveForForwardRate is null private final double volatility; private final double theta; private final double kappa; private final double xi; private final double rho; /** * Create a Heston model (characteristic function) * * @param referenceDate The date representing the time t = 0. All other double times are following {@link net.finmath.time.FloatingpointDate}. * @param initialValue \( S_{0} \) - spot - initial value of S * @param discountCurveForForwardRate The curve specifying \( t \mapsto exp(- r^{\text{c}}(t) \cdot t) \) - with \( r^{\text{c}}(t) \) the risk free rate * @param discountCurveForDiscountRate The curve specifying \( t \mapsto exp(- r^{\text{d}}(t) \cdot t) \) - with \( r^{\text{d}}(t) \) the discount rate * @param volatility \( \sigma \) the initial volatility level * @param theta \( \theta \) - the mean reversion level of the stochastic volatility * @param kappa \( \kappa \) - the mean reversion speed of the stochastic volatility * @param xi \( \xi \) - the volatility of volatility * @param rho \( \rho \) - the correlation of the Brownian drivers */ public HestonModel(final LocalDate referenceDate, final double initialValue, final DiscountCurve discountCurveForForwardRate, final DiscountCurve discountCurveForDiscountRate, final double volatility, final double theta, final double kappa, final double xi, final double rho) { super(); this.referenceDate = referenceDate; this.initialValue = initialValue; this.discountCurveForForwardRate = discountCurveForForwardRate; riskFreeRate = Double.NaN; // For safety this.discountCurveForDiscountRate = discountCurveForDiscountRate; discountRate = Double.NaN; // For safety this.volatility = volatility; this.theta = theta; this.kappa = kappa; this.xi = xi; this.rho = rho; } /** * Create a Heston model (characteristic function) * * @param initialValue \( S_{0} \) - spot - initial value of S * @param discountCurveForForwardRate The curve specifying \( t \mapsto exp(- r^{\text{c}}(t) \cdot t) \) - with \( r^{\text{c}}(t) \) the risk free rate * @param discountCurveForDiscountRate The curve specifying \( t \mapsto exp(- r^{\text{d}}(t) \cdot t) \) - with \( r^{\text{d}}(t) \) the discount rate * @param volatility \( \sigma \) the initial volatility level * @param theta \( \theta \) - the mean reversion level of the stochastic volatility * @param kappa \( \kappa \) - the mean reversion speed of the stochastic volatility * @param xi \( \xi \) - the volatility of volatility * @param rho \( \rho \) - the correlation of the Brownian drivers */ public HestonModel(final double initialValue, final DiscountCurve discountCurveForForwardRate, final DiscountCurve discountCurveForDiscountRate, final double volatility, final double theta, final double kappa, final double xi, final double rho) { this(null, initialValue, discountCurveForForwardRate, discountCurveForDiscountRate, volatility, theta, kappa, xi, rho); } /** * Create a Heston model (characteristic function) * * @param initialValue \( S_{0} \) - spot - initial value of S * @param riskFreeRate \( r^{\text{c}} \) - the risk free rate * @param volatility \( \sigma \) the initial volatility level * @param discountRate \( r^{\text{d}} \) - the discount rate * @param theta \( \theta \) - the mean reversion level of the stochastic volatility * @param kappa \( \kappa \) - the mean reversion speed of the stochastic volatility * @param xi \( \xi \) - the volatility of volatility * @param rho \( \rho \) - the correlation of the Brownian drivers */ public HestonModel(final double initialValue, final double riskFreeRate, final double volatility, final double discountRate, final double theta, final double kappa, final double xi, final double rho) { super(); referenceDate = null; this.initialValue = initialValue; discountCurveForForwardRate = null; this.riskFreeRate = riskFreeRate; discountCurveForDiscountRate = null; this.discountRate = discountRate; this.volatility = volatility; this.theta = theta; this.kappa = kappa; this.xi = xi; this.rho = rho; } public HestonModel(final double initialValue, final double riskFreeRate, final double volatility, final double theta, final double kappa, final double xi, final double rho) { this(initialValue, riskFreeRate, volatility, riskFreeRate, theta, kappa, xi, rho); } @Override public CharacteristicFunction apply(final double time) { final double logDiscountFactorForForward = this.getLogDiscountFactorForForward(time); final double logDiscountFactorForDiscounting = this.getLogDiscountFactorForDiscounting(time); return new CharacteristicFunction() { @Override public Complex apply(final Complex argument) { final Complex iargument = argument.multiply(Complex.I); final Complex gamma = iargument.multiply(rho * xi).subtract(kappa).pow(2) .subtract( iargument.multiply(iargument) .add(iargument.multiply(-1)).multiply(0.5) .multiply(2 * xi * xi)) .sqrt(); final Complex a = iargument .multiply(rho * xi) .subtract(kappa) .subtract(gamma).multiply((-theta*kappa * time) / (xi * xi)) .subtract(iargument.multiply(rho * xi).subtract(kappa).subtract(gamma) .multiply(new Complex(1).divide(gamma.multiply(time).exp()).subtract(1).divide(gamma)) .multiply(0.5).add(new Complex(1).divide(gamma.multiply(time).exp())).log() .add(gamma.multiply(time)).multiply((2 * theta*kappa) / (xi * xi))); final Complex b = iargument.multiply(iargument).add(iargument.multiply(-1)).multiply(-1) .divide(iargument.multiply(rho * xi).subtract(kappa) .add(gamma.multiply(new Complex(1).divide(gamma.multiply(time).exp()).add(1) .divide(new Complex(1).divide(gamma.multiply(time).exp()).subtract(1))))); return a.add(b.multiply(volatility*volatility)).add(iargument.multiply(Math.log(initialValue) - logDiscountFactorForForward)).add(logDiscountFactorForDiscounting).exp(); } }; } /** * Small helper to calculate rate off the curve or use constant. * * @param time Maturity. * @return The log of the discount factor, i.e., - rate * time. */ private double getLogDiscountFactorForForward(final double time) { return discountCurveForForwardRate == null ? -riskFreeRate * time : Math.log(discountCurveForForwardRate.getDiscountFactor(null, time)); } /** * Small helper to calculate rate off the curve or use constant. * * @param time Maturity. * @return The log of the discount factor, i.e., - rate * time. */ private double getLogDiscountFactorForDiscounting(final double time) { return discountCurveForDiscountRate == null ? -discountRate * time : Math.log(discountCurveForDiscountRate.getDiscountFactor(null, time)); } /** * @return the referenceDate */ public LocalDate getReferenceDate() { return referenceDate; } /** * @return the initialValue */ public double getInitialValue() { return initialValue; } /** * @return the discountCurveForForwardRate */ public DiscountCurve getDiscountCurveForForwardRate() { return discountCurveForForwardRate; } /** * @return the riskFreeRate */ public double getRiskFreeRate() { return riskFreeRate; } /** * @return the discountCurveForDiscountRate */ public DiscountCurve getDiscountCurveForDiscountRate() { return discountCurveForDiscountRate; } /** * @return the discountRate */ public double getDiscountRate() { return discountRate; } /** * @return the volatility */ public double getVolatility() { return volatility; } /** * @return the theta */ public double getTheta() { return theta; } /** * @return the kappa */ public double getKappa() { return kappa; } /** * @return the xi */ public double getXi() { return xi; } /** * @return the rho */ public double getRho() { return rho; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "HestonModel [referenceDate=" + referenceDate + ", initialValue=" + initialValue + ", discountCurveForForwardRate=" + discountCurveForForwardRate + ", riskFreeRate=" + riskFreeRate + ", discountCurveForDiscountRate=" + discountCurveForDiscountRate + ", discountRate=" + discountRate + ", volatility=" + volatility + ", theta=" + theta + ", kappa=" + kappa + ", xi=" + xi + ", rho=" + rho + "]"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy