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(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); //derivs k = 100; delta = BlackFunctions.BlackDelta(f, k, rf, t, vol, cp); var derivs = BlackFunctions.BlackDerivs(f, k, rf, t, vol, cp); Assert.Equal(delta, derivs[0]); cp = OptionType.C; delta = BlackFunctions.BlackDelta(f, k, rf, t, vol, cp); derivs = BlackFunctions.BlackDerivs(f, k, rf, t, vol, cp); Assert.Equal(delta, derivs[0]); }