public void TestCrankNicolson() { double spot = 385.5; double epsilon = 0.0001; double strike = 400; double[] rt = { 0.0425, 0.0452, 0.0457, 0.0462 }; int[] tt = { 1, 32, 63, 93 }; int[] divdays = { 0, 48 }; double[] divs = { 20, 10 }; double vol = 0.2046; int steps = 80; double tStepSize = 0.01; DateTime today = new DateTime(2010, 05, 07); DateTime expiry = new DateTime(2010, 06, 24); //string style = "European"; double t = expiry.Subtract(today).Days / 365.0 + epsilon; // For CN backwards propagation div time needs to be strictly less than expiry time double fwd = EquityAnalytics.GetForwardCCLin365(spot, t, divdays, divs, tt, rt); double df = EquityAnalytics.GetDFCCLin365(0, t, tt, rt); BlackScholes bs = new BlackScholes(spot, strike, false, t, vol, tt, rt, divdays, divs); CrankNicolson lhs = new CrankNicolson(false, false, spot, strike, t, vol, steps, tStepSize, 8.0, divdays, divs, tt, rt); double[,] res0 = OptionAnalytics.BlackScholesWithGreeks(false, fwd, strike, vol, t); double[] res_cn = lhs.GetPriceAndGreeks(); double pr_bs = bs.GetPrice(); double delta_bs = bs.GetDelta(); double gamma_bs = bs.GetGamma(); double theta_bs = bs.GetTheta(); double pr_cn = res_cn[0]; double delta_cn = res_cn[1]; double gamma_cn = res_cn[2]; double theta_cn = res_cn[3]; Assert.AreEqual(pr_cn, pr_bs, 0.50); Assert.AreEqual(delta_cn, delta_bs, 0.03); Assert.AreEqual(gamma_cn, 0.012931145370580023, 0.005); Assert.AreEqual(bs.GetTheta(), theta_cn, 0.01); }
public void FurtherCNTests() { int[] dt = { 448, 813, 1179, 1544, 1909, 2274, 2640, 3005, 3370, 3735 }; double[] divs = { 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2 }; int[] rtdt = { 74, 439 }; double[] rtam = { 0.03, 0.03 }; DateTime today = new DateTime(2009, 4, 13); DateTime expiry = new DateTime(2010, 04, 13); double tau = expiry.Subtract(today).Days / 365.0; double spot = 26.4; double strike = 30; double vol = 0.20; CrankNicolson cn_ep = new CrankNicolson(false, false, spot, strike, tau, vol, 800, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ec = new CrankNicolson(true, false, spot, strike, tau, vol, 100, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ac = new CrankNicolson(true, true, spot, strike, tau, vol, 100, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ap = new CrankNicolson(false, true, spot, strike, tau, vol, 100, 0.05, 8, dt, divs, rtdt, rtam); //CrankNicolson cn_ep = new CrankNicolson(ep, rc, dl, 8, 800, 0.05); //extra fine grid //CrankNicolson cn_ec = new CrankNicolson(ec, rc, dl, 8, 100, 0.05); //CrankNicolson cn_ac = new CrankNicolson(ac, rc, dl, 8, 100, 0.05); //CrankNicolson cn_ap = new CrankNicolson(ap, rc, dl, 8, 100, 0.05); double[] ep_pr = cn_ep.GetPriceAndGreeks(); double[] ec_pr = cn_ec.GetPriceAndGreeks(); double[] ac_pr = cn_ac.GetPriceAndGreeks(); double[] ap_pr = cn_ap.GetPriceAndGreeks(); Assert.AreEqual(ep_pr[0], 3.825991125, 0.001); Assert.AreEqual(ec_pr[0], 1.121514221, 0.001); Assert.AreEqual(ac_pr[0], 1.121514221, 0.001); Assert.AreEqual(ap_pr[0], 4.065906254, 0.001); }
public void FurtherCNTestsLongDated() { int[] dt = { 83, 2274, 2640, 3005, 3370, 3735 }; double[] divs = { 5, 0, 0, 0, 0, 0 }; int[] rtdt = { 74, 439 }; double[] rtam = { 0.05, 0.05 }; DateTime today = new DateTime(2009, 4, 13); DateTime expiry = new DateTime(2014, 04, 13); double spot = 26.4; double strike = 30; double vol = 0.30; double tau = expiry.Subtract(today).Days / 365.0; CrankNicolson cn_ep = new CrankNicolson(false, false, spot, strike, tau, vol, 200, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ec = new CrankNicolson(true, false, spot, strike, tau, vol, 200, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ac = new CrankNicolson(true, true, spot, strike, tau, vol, 200, 0.05, 8, dt, divs, rtdt, rtam); CrankNicolson cn_ap = new CrankNicolson(false, true, spot, strike, tau, vol, 200, 0.05, 8, dt, divs, rtdt, rtam); double[] ep = cn_ep.GetPriceAndGreeks(); double[] ec = cn_ec.GetPriceAndGreeks(); double[] ac = cn_ac.GetPriceAndGreeks(); double[] ap = cn_ap.GetPriceAndGreeks(); double volback = cn_ep.ImpVol(ep[0]); Assert.AreEqual(vol, volback, 0.001); double ep_delta = ep[1]; double ec_delta = ec[1]; double ac_delta = ac[1]; double ap_delta = ap[1]; double ep_gamma = ep[2]; double ec_gamma = ec[2]; double ac_gamma = ac[2]; double ap_gamma = ap[2]; double ep_theta = ep[3]; double ec_theta = ec[3]; double ac_theta = ac[3]; double ap_theta = ap[3]; Assert.AreEqual(ep[0], 6.9534149, 0.001); Assert.AreEqual(ec[0], 5.0652783, 0.001); Assert.AreEqual(ac[0], 5.0652783, 0.001); Assert.AreEqual(ap[0], 9.3556003, 0.001); Assert.AreEqual(ep_delta, -0.41851728556981282, 0.001); Assert.AreEqual(ec_delta, 0.58178041660965252, 0.001); Assert.AreEqual(ac_delta, 0.58178041660965252, 0.001); Assert.AreEqual(ap_delta, -0.6687734186983475, 0.001); Assert.AreEqual(ep_gamma, 0.026900894453080339, 0.001); Assert.AreEqual(ec_gamma, 0.026899818384012897, 0.001); Assert.AreEqual(ac_gamma, 0.026899818384012897, 0.001); Assert.AreEqual(ap_gamma, 0.052277076176625865, 0.001); //Assert.AreEqual(ep_theta, 0 , 0.001); //Assert.AreEqual(ec_theta, 0.026899818384012897, 0.001); //Assert.AreEqual(ac_theta, 0.026899818384012897, 0.001); //Assert.AreEqual(ap_theta, 0.052277076176625865, 0.001); }