net.finmath.functions.BachelierModel 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.
/*
* Created on 23.01.2004.
*
* (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
*/
package net.finmath.functions;
import net.finmath.optimizer.GoldenSectionSearch;
import net.finmath.stochastic.RandomVariable;
/**
* This class implements some functions as static class methods related to the Bachelier model.
*
* There are different variants of the Bachelier model, depending on if the volatility of the stock
* or the volatility of the forward are assumed to be constant.
*
*
* - Bachelier model
* - the model for a forward F(t) following dF = sigma dW, valuing the option max(F(T)-K,0) * N(T)
*
* - Homogeneous Bachelier model
* - the model for a stock S(t) following dS = rS dt + sigma exp(rt) dW, valuing the option max(S(T)-K,0)
*
* - Inhomogeneous Bachelier model
* - the model for a stock S(t) following dS = rS dt + sigma dW, valuing the option max(S(T)-K,0)
*
*
* The class {@link net.finmath.montecarlo.assetderivativevaluation.models.BachelierModel} is the Monte-Carlo
* implementation of a Homogeneous Bachelier model.
*
* The class {@link net.finmath.montecarlo.assetderivativevaluation.models.InhomogenousBachelierModel} is the Monte-Carlo
* implementation of a Inhomogeneous Bachelier model.
*
* @see net.finmath.montecarlo.assetderivativevaluation.models.BachelierModel
* @see net.finmath.montecarlo.assetderivativevaluation.models.InhomogenousBachelierModel
*
* @author Christian Fries
* @version 1.11
* @date 27.04.2012
*/
public class BachelierModel {
// Suppress default constructor for non-instantiability
private BachelierModel() {
// This constructor will never be invoked
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = \exp(-r T) \))
* @return Returns the value of a European call option under the Bachelier model.
*/
public static double bachelierOptionValue(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
if(optionMaturity < 0) {
return 0;
}
else if(forward == optionStrike) {
return volatility * Math.sqrt(optionMaturity / Math.PI / 2.0) * payoffUnit;
}
else
{
// Calculate analytic value
final double dPlus = (forward - optionStrike) / (volatility * Math.sqrt(optionMaturity));
final double valueAnalytic = ((forward - optionStrike) * NormalDistribution.cumulativeDistribution(dPlus)
+ volatility * Math.sqrt(optionMaturity) * NormalDistribution.density(dPlus)) * payoffUnit;
return valueAnalytic;
}
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierOptionValue(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
if(optionMaturity < 0) {
return forward.mult(0.0);
}
else
{
final RandomVariable integratedVolatility = volatility.mult(Math.sqrt(optionMaturity));
final RandomVariable dPlus = forward.sub(optionStrike).div(integratedVolatility);
final RandomVariable valueAnalytic = dPlus.apply(NormalDistribution::cumulativeDistribution).mult(forward.sub(optionStrike))
.add(dPlus.apply(NormalDistribution::density).mult(integratedVolatility)).mult(payoffUnit);
return valueAnalytic;
}
}
/**
* Calculates the Bachelier option implied volatility of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike. If the option strike is ≤ 0.0 the method returns the value of the forward contract paying S(T)-K in T.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @param optionValue The option value.
* @return Returns the implied volatility of a European call option under the Bachelier model.
*/
public static double bachelierOptionImpliedVolatility(
final double forward,
final double optionMaturity,
final double optionStrike,
final double payoffUnit,
final double optionValue)
{
// Limit the maximum number of iterations, to ensure this calculation returns fast, e.g. in cases when there is no such thing as an implied vol
// TODO An exception should be thrown, when there is no implied volatility for the given value.
final int maxIterations = 100;
final double maxAccuracy = 0.0;
// Calculate an lower and upper bound for the volatility
final double volatilityLowerBound = 0.0;
final double volatilityUpperBound = Math.sqrt(2 * Math.PI * Math.E) * (optionValue / payoffUnit + Math.abs(forward-optionStrike)) / Math.sqrt(optionMaturity);
// Solve for implied volatility
final GoldenSectionSearch solver = new GoldenSectionSearch(volatilityLowerBound, volatilityUpperBound);
while(solver.getAccuracy() > maxAccuracy && !solver.isDone() && solver.getNumberOfIterations() < maxIterations) {
final double volatility = solver.getNextPoint();
final double valueAnalytic = bachelierOptionValue(forward, volatility, optionMaturity, optionStrike, payoffUnit);
final double error = valueAnalytic - optionValue;
solver.setValue(error*error);
}
return solver.getBestPoint();
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static double bachelierOptionDelta(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
if(optionMaturity < 0) {
return 0;
}
else if(forward == optionStrike) {
return 1.0 / 2.0;
}
else
{
// Calculate analytic value
final double dPlus = (forward - optionStrike) / (volatility * Math.sqrt(optionMaturity));
final double deltaAnalytic = NormalDistribution.cumulativeDistribution(dPlus);
return deltaAnalytic;
}
}
/**
* Calculates the option delta dV(0)/dS(0) of a digital call option, i.e., the payoff V(T)=indicator(S(T)-K > 0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* The delta reported is \[ \frac{1}{\sigma \sqrt{T}} \phi( \frac{F-K}{\sigma \sqrt{T}} ) \], where \( \phi \) is the density of the standard normal distribution.
*
* Note: The delta does not depend on the argument payoffUnit, due to \( \frac{\mathrm{d}F(0)}{\mathrm{d}S(0)} = \frac{1}{N(0)} \) being equal to 1 / payoffUnit.
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static double bachelierDigitalOptionDelta(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
if(optionMaturity < 0) {
return 0;
}
else if(forward == optionStrike) {
return 1.0 / Math.sqrt(2.0 * Math.PI) / (volatility * Math.sqrt(optionMaturity));
}
else
{
// Calculate analytic value
final double dPlus = (forward - optionStrike) / (volatility * Math.sqrt(optionMaturity));
final double deltaAnalytic = NormalDistribution.density(dPlus) / (volatility * Math.sqrt(optionMaturity));
return deltaAnalytic;
}
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierOptionDelta(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
if(optionMaturity < 0) {
return forward.mult(0.0);
}
else
{
final RandomVariable integratedVolatility = volatility.mult(Math.sqrt(optionMaturity));
final RandomVariable dPlus = forward.sub(optionStrike).div(integratedVolatility);
final RandomVariable deltaAnalytic = dPlus.apply(NormalDistribution::cumulativeDistribution);
return deltaAnalytic;
}
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static double bachelierOptionVega(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
if(optionMaturity < 0) {
return 0;
}
else if(forward == optionStrike) {
return Math.sqrt(optionMaturity / (Math.PI * 2.0)) * payoffUnit;
}
else
{
// Calculate analytic value
final double dPlus = (forward - optionStrike) / (volatility * Math.sqrt(optionMaturity));
final double vegaAnalytic = Math.sqrt(optionMaturity) * NormalDistribution.density(dPlus) * payoffUnit;
return vegaAnalytic;
}
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(-r (T-t)) \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierOptionVega(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
if(optionMaturity < 0) {
return forward.mult(0.0);
}
else
{
final RandomVariable integratedVolatility = volatility.mult(Math.sqrt(optionMaturity));
final RandomVariable dPlus = forward.sub(optionStrike).div(integratedVolatility);
final RandomVariable vegaAnalytic = dPlus.apply(NormalDistribution::density).mult(payoffUnit).mult(Math.sqrt(optionMaturity));
return vegaAnalytic;
}
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of a European call option under the Bachelier model.
*/
public static double bachelierHomogeneousOptionValue(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
return bachelierOptionValue(forward, volatility/payoffUnit, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierHomogeneousOptionValue(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
return bachelierOptionValue(forward, volatility.div(payoffUnit), optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the Bachelier option implied volatility of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike. If the option strike is ≤ 0.0 the method returns the value of the forward contract paying S(T)-K in T.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @param optionValue The option value.
* @return Returns the implied volatility of a European call option under the Bachelier model.
*/
public static double bachelierHomogeneousOptionImpliedVolatility(
final double forward,
final double optionMaturity,
final double optionStrike,
final double payoffUnit,
final double optionValue)
{
return bachelierOptionImpliedVolatility(forward, optionMaturity, optionStrike, payoffUnit, optionValue)*payoffUnit;
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static double bachelierHomogeneousOptionDelta(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
return bachelierOptionDelta(forward, volatility/payoffUnit, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierHomogeneousOptionDelta(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
return bachelierOptionDelta(forward, volatility.div(payoffUnit), optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static double bachelierHomogeneousOptionVega(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
return bachelierOptionVega(forward, volatility/payoffUnit, optionMaturity, optionStrike, payoffUnit)/payoffUnit;
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with numeraire scaled volatility, i.e., a homogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma exp(rt) \mathrm{d}W(t)
* \]
*
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma / N(T) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F(0) = S(0)/N(0) = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \) of the forward process.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor \( N(0)/N(T) = exp(-r T) \))
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierHomogeneousOptionVega(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
return bachelierOptionVega(forward, volatility.div(payoffUnit), optionMaturity, optionStrike, payoffUnit).div(payoffUnit);
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with constant volatility, i.e., a inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(r (T-t)) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the value of a European call option under the Bachelier model.
*/
public static double bachelierInhomogeneousOptionValue(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
final double scaling = payoffUnit != 1 ? Math.sqrt((payoffUnit*payoffUnit-1)/(2.0*Math.log(payoffUnit))) : 1.0;
final double volatilityEffective = volatility * scaling;
return bachelierHomogeneousOptionValue(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the option value of a call, i.e., the payoff max(S(T)-K,0), where S follows a
* normal process with constant volatility, i.e., a inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(r (T-t)) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the value of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierInhomogeneousOptionValue(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
// TODO The formula fails if payoffUnit == 1
final RandomVariable volatilityEffective = volatility.mult(payoffUnit.squared().sub(1.0).div(payoffUnit.log().mult(2)).sqrt());
return bachelierHomogeneousOptionValue(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the Bachelier option implied volatility of a call, i.e., the payoff
* max(S(T)-K,0)
, where S follows a
* normal process with constant volatility, i.e., a inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(r (T-t)) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying.
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike. If the option strike is ≤ 0.0 the method returns the value of the forward contract paying S(T)-K in T.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @param optionValue The option value.
* @return Returns the implied volatility of a European call option under the Bachelier model.
*/
public static double bachelierInhomogeneousOptionImpliedVolatility(
final double forward,
final double optionMaturity,
final double optionStrike,
final double payoffUnit,
final double optionValue)
{
final double volatilityEffective = bachelierHomogeneousOptionImpliedVolatility(forward, optionMaturity, optionStrike, payoffUnit, optionValue);
final double scaling = payoffUnit != 1 ? Math.sqrt((payoffUnit*payoffUnit-1)/(2.0*Math.log(payoffUnit))) : 1.0;
final double volatility = volatilityEffective / scaling;
return volatility;
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with constant volatility, i.e., a inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(r (T-t)) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static double bachelierInhomogeneousOptionDelta(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
final double scaling = payoffUnit != 1 ? Math.sqrt((payoffUnit*payoffUnit-1)/(2.0*Math.log(payoffUnit))) : 1.0;
final double volatilityEffective = volatility * scaling;
return bachelierHomogeneousOptionDelta(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the option delta dV(0)/dS(0) of a call option, i.e., the payoff V(T)=max(S(T)-K,0), where S follows a
* normal process with constant volatility, i.e., a inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp(-r (T-t)) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(r (T-t)) \mathrm{d}W(t) \text{.}
* \]
*
* This implies an effective "Bachelier" integrated variance, being (with \( s = 0 \)
* \[
* 1/T \int_{0}^{T} \sigma^2 exp(2 r (T-t)) \mathrm{d}t \ = \ sigma^2 \frac{exp(2 r (T-0))-exp(2 r (T-T)}{2 r T}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike K.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the value of the option delta (dV/dS(0)) of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierInhomogeneousOptionDelta(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
// TODO The formula fails if payoffUnit == 1
final RandomVariable volatilityEffective = volatility.mult(payoffUnit.squared().sub(1.0).div(payoffUnit.log().mult(2)).sqrt());
return bachelierHomogeneousOptionDelta(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with constant volatility, i.e., a Inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp( r t ) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(-r t) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static double bachelierInhomogeneousOptionVega(
final double forward,
final double volatility,
final double optionMaturity,
final double optionStrike,
final double payoffUnit)
{
final double scaling = payoffUnit != 1 ? Math.sqrt((payoffUnit*payoffUnit-1)/(2.0*Math.log(payoffUnit))) : 1.0;
final double volatilityEffective = volatility * scaling;
final double vegaHomogenouse = bachelierHomogeneousOptionVega(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
return vegaHomogenouse * scaling;
}
/**
* Calculates the vega of a call, i.e., the payoff max(S(T)-K,0) P, where S follows a
* normal process with constant volatility, i.e., a Inhomogeneous Bachelier model
* \[
* \mathrm{d} S(t) = r S(t) \mathrm{d} t + \sigma \mathrm{d}W(t)
* \]
* Considering the numeraire \( N(t) = exp( r t ) \), this implies that \( F(t) = S(t)/N(t) \) follows
* \[
* \mathrm{d} F(t) = \sigma exp(-r t) \mathrm{d}W(t) \text{.}
* \]
*
* @param forward The forward of the underlying \( F = S(0) \exp(r T) \).
* @param volatility The Bachelier volatility \( \sigma \).
* @param optionMaturity The option maturity T.
* @param optionStrike The option strike.
* @param payoffUnit The payoff unit (e.g., the discount factor)
* @return Returns the vega of a European call option under the Bachelier model.
*/
public static RandomVariable bachelierInhomogeneousOptionVega(
final RandomVariable forward,
final RandomVariable volatility,
final double optionMaturity,
final double optionStrike,
final RandomVariable payoffUnit)
{
// TODO The formula fails if payoffUnit == 1
final RandomVariable volatilityEffective = volatility.mult(payoffUnit.squared().sub(1.0).div(payoffUnit.log().mult(2)).sqrt());
final RandomVariable vegaHomogenouse = bachelierHomogeneousOptionVega(forward, volatilityEffective, optionMaturity, optionStrike, payoffUnit);
return vegaHomogenouse.mult(volatilityEffective).div(volatility);
}
}