Re: BlackCalculator greeks does not match the formula in wiki
Posted by SteveGe on Sep 22, 2014; 5:21am
URL: http://quantlib.414.s1.nabble.com/BlackCalculator-greeks-does-not-match-the-formula-in-wiki-tp15802p15908.html
Thanks for the reply. I agree the implementation match with the wiki.
There is not much going on for RawFXOption class. it just wrap the BlackCalculator. the discountFactor won't make big difference, and all other greek value match perfect, only the theta way off.
I notice Quantlib per day is divide by 365, not sure what value bloomberg divide.
public class RawFxOption {
public final Option.Type type;
public final double strike;
public final double spot;
public final double forward;
public final double maturity;
public final double volatility;
public final double domesticDiscount;
private BlackCalculator blackCalculator;
public RawFxOption(Option.Type type, double strike, double spot, double forward, double maturity, double volatility, double domesticDiscount) {
this.type = type;
this.strike = strike;
this.spot = spot;
this.forward = forward;
this.maturity = maturity;
this.volatility = volatility;
this.domesticDiscount = domesticDiscount;
}
public RawFxOption inverse() {
Option.Type inverseType = type == (Call) ? Put : Call;
return new RawFxOption(inverseType, 1.0 / strike, 1.0 / spot, 1.0 / forward, maturity, volatility, foreignDiscount());
}
public double price() {
createCalculator();
return blackCalculator.value();
}
public double delta() {
createCalculator();
return blackCalculator.delta(spot);
}
public double forwardDelta() {
return delta() / foreignDiscount();
}
public double gamma() {
createCalculator();
return blackCalculator.gamma(spot) * spot / 100.0;
}
public double vega() {
createCalculator();
return blackCalculator.vega(maturity) / 100.0;
}
public double rho() {
createCalculator();
return blackCalculator.rho(maturity);
}
public double phi() {
createCalculator();
return blackCalculator.dividendRho(maturity);
}
public double thetaPerDay() {
createCalculator();
return blackCalculator.thetaPerDay(spot,maturity);
}
public double decay() {
createCalculator();
return blackCalculator.theta(spot, maturity);
}
public double breakEven() {
if (type == Option.Type.Call) {
return strike - price();
}
return strike - price();
}
private double foreignDiscount() {
return forward / spot * domesticDiscount;
}
private void createCalculator() {
if (blackCalculator == null) {
blackCalculator = new BlackCalculator(new PlainVanillaPayoff(type, strike),
forward,
volatility * Math.sqrt(maturity),
domesticDiscount
);
}
}