/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.equity;
import com.opengamma.analytics.financial.equity.option.EquityIndexFutureOption;
import com.opengamma.analytics.financial.equity.option.EquityIndexOption;
import com.opengamma.analytics.financial.equity.option.EquityOption;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorAdapter;
import com.opengamma.analytics.financial.model.volatility.BlackScholesFormulaRepository;
import com.opengamma.util.ArgumentChecker;
/**
* Calculates the Black-Scholes daily theta
*/
public final class EquityOptionBlackScholesThetaCalculator extends
InstrumentDerivativeVisitorAdapter<StaticReplicationDataBundle, Double> {
/** Static instance */
private static final EquityOptionBlackScholesThetaCalculator s_instance = new EquityOptionBlackScholesThetaCalculator();
/**
* Gets the (singleton) instance of this calculator
* @return The instance of this calculator
*/
public static EquityOptionBlackScholesThetaCalculator getInstance() {
return s_instance;
}
private EquityOptionBlackScholesThetaCalculator() {
}
@Override
public Double visitEquityIndexOption(EquityIndexOption option, StaticReplicationDataBundle data) {
ArgumentChecker.notNull(option, "option");
ArgumentChecker.notNull(data, "data");
double t = option.getTimeToExpiry();
double k = option.getStrike();
boolean isCall = option.isCall();
return computeTheta(k, t, isCall, data);
}
@Override
public Double visitEquityOption(EquityOption option, StaticReplicationDataBundle data) {
ArgumentChecker.notNull(option, "option");
ArgumentChecker.notNull(data, "data");
double t = option.getTimeToExpiry();
double k = option.getStrike();
boolean isCall = option.isCall();
return computeTheta(k, t, isCall, data);
}
/*
* For index options, standard theta is driftless theta, i.e., b=r=0.
* Thus use {@link EquityOptionBlackThetaCalculator} for this instrument.
*/
@Override
public Double visitEquityIndexFutureOption(EquityIndexFutureOption option,
final StaticReplicationDataBundle data) {
ArgumentChecker.notNull(option, "option");
ArgumentChecker.notNull(data, "data");
double t = option.getExpiry();
double k = option.getStrike();
boolean isCall = option.isCall();
return computeTheta(k, t, isCall, data);
}
private double computeTheta(double k, double t, boolean isCall, StaticReplicationDataBundle data) {
double s = data.getForwardCurve().getSpot();
double fwd = data.getForwardCurve().getForward(t);
double r = data.getDiscountCurve().getInterestRate(t);
double b = t > 0 ? Math.log(fwd / s) / t : r;
double volatility = data.getVolatilitySurface().getVolatility(t, k);
double theta = BlackScholesFormulaRepository.theta(s, k, t, volatility, r, b, isCall) / 365.0; // daily theta
return theta;
}
}