public void DeltaGammaFacts() { var t = 1.0; var k = 100; var f = 100; var vol = 0.32; var rf = 0.05; var cp = OptionType.P; //delta closely matches numerical estimate var PV1 = BlackFunctions.BlackPV(f + 0.000005, k, rf, t, vol, cp); var PV2 = BlackFunctions.BlackPV(f - 0.000005, k, rf, t, vol, cp); var deltaEst = (PV1 - PV2) / 0.00001; var delta = BlackFunctions.BlackDelta(f, k, rf, t, vol, cp); Assert.Equal(deltaEst, delta, 6); //all else the same, more time for OTM option == more delta k = 150; var deltaNear = BlackFunctions.BlackDelta(f, k, rf, t, vol, cp); var deltaFar = BlackFunctions.BlackDelta(f, k, rf, t * 2, vol, cp); Assert.True(deltaFar > deltaNear); //put-call parity var deltaCall = BlackFunctions.BlackDelta(f, k, rf, t, vol, OptionType.C); var deltaPut = BlackFunctions.BlackDelta(f, k, rf, t, vol, OptionType.P); var syntheticFwdDelta = deltaCall - deltaPut; Assert.Equal(System.Math.Exp(-rf * t), syntheticFwdDelta, 10); //gamma closely matches numerical estimate var delta1 = BlackFunctions.BlackDelta(f + 0.000005, k, rf, t, vol, cp); var delta2 = BlackFunctions.BlackDelta(f - 0.000005, k, rf, t, vol, cp); var gammaEst = (delta1 - delta2) / 0.00001; var gamma = BlackFunctions.BlackGamma(f, k, rf, t, vol); Assert.Equal(gammaEst, gamma, 6); //cases for zero delta / gamma delta = BlackFunctions.BlackDelta(f, 0, rf, t, vol, OptionType.P); Assert.Equal(0, delta, 8); delta = BlackFunctions.BlackDelta(f, 1e6, rf, t, vol, OptionType.C); Assert.Equal(0, delta, 8); gamma = BlackFunctions.BlackGamma(f, 0, rf, t, vol); Assert.Equal(0, gamma, 8); gamma = BlackFunctions.BlackGamma(f, 1e6, rf, t, vol); Assert.Equal(0, gamma, 8); }
public double Dvdk(double strike, DateTime expiry, double fwd) { if (StrikeType == StrikeType.ForwardDelta) { var t = TimeBasis.CalculateYearFraction(OriginDate, expiry); var pillarIx = Array.BinarySearch(Expiries, expiry); var interpForMaturity = pillarIx > 0 ? _interpolators[pillarIx] : InterpolatorFactory.GetInterpolator(Strikes, Strikes.Select(k => GetVolForDeltaStrike(k, expiry, fwd)).ToArray(), StrikeInterpolatorType); var deltaK = GetDeltaStrikeForAbs(fwd, strike, t); var vol = GetVolForAbsoluteStrike(strike, expiry, fwd); var gamma = BlackFunctions.BlackGamma(fwd, strike, 0.0, t, vol); return(interpForMaturity.FirstDerivative(deltaK) * gamma); } else { var interpForMaturity = InterpolatorFactory.GetInterpolator(Strikes, Strikes.Select(k => GetVolForAbsoluteStrike(k, expiry, fwd)).ToArray(), StrikeInterpolatorType); return(interpForMaturity.FirstDerivative(strike)); } }
public void BlackGammaVega_Facts() { Assert.Equal(0.0, BlackFunctions.BlackGamma(0.1, 1.0, 0.5, 0.0, 0.001)); Assert.Equal(0.0, BlackFunctions.BlackVega(0.1, 1.0, 0.5, 0.0, 0.001)); }