public void testEuropeanHaugValues() { // Testing double barrier european options against Haug's values Exercise.Type european = Exercise.Type.European; NewBarrierOptionData[] values = { /* The data below are from * "The complete guide to option pricing formulas 2nd Ed",E.G. Haug, McGraw-Hill, p.156 and following. * * Note: * The book uses b instead of q (q=r-b) */ // BarrierType, barr.lo, barr.hi, type, exercise,strk, s, q, r, t, v, result, tol new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3515, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 6.1644, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 7.0373, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.9853, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 7.9336, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.5088, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3505, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.8500, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7726, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.8082, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 6.3383, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 4.3841, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 4.3139, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 4.8293, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 3.7765, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 5.9697, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.0004, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 2.2563, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.7516, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6387, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.4903, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.5805, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.5098, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.5635, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.2055, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3098, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0477, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.5537, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0441, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0011, 1.0e-4), // BarrierType, barr.lo, barr.hi, type, exercise,strk, s, q, r, t, v, result, tol new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7855, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.7191, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.7033, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 50.0, 150.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.1683, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7845, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 5.6060, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1374, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 4.6236, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 60.0, 140.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 6.1062, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8825, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.7014, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.6472, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 2.1325, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.8944, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 70.0, 130.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 3.5868, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 1.8600, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 2.6866, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.0719, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.8883, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.7851, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 80.0, 120.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.8244, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.9473, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.3449, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 0.0578, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.4555, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 0.0491, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockOut, 90.0, 110.0, Option.Type.Put, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 0.0013, 1.0e-4), // BarrierType, barr.lo, barr.hi, type, strk, s, q, r, t, v, result, tol new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0000, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.0900, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 1.1537, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.0292, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 1.6487, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 50.0, 150.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 5.7321, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0010, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 0.4045, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 2.4184, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 0.2062, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 3.2439, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 60.0, 140.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 7.8569, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.0376, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 1.4252, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 4.4145, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 1.0447, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 5.5818, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 70.0, 130.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 9.9846, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 0.5999, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 3.6158, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 6.7007, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 3.4340, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 8.0724, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 80.0, 120.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 11.6774, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.15, 3.1460, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.25, 5.9447, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.25, 0.35, 8.1432, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.15, 6.4608, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.25, 9.5382, 1.0e-4), new NewBarrierOptionData(DoubleBarrier.Type.KnockIn, 90.0, 110.0, Option.Type.Call, european, 100, 100.0, 0.0, 0.1, 0.50, 0.35, 12.2398, 1.0e-4), }; DayCounter dc = new Actual360(); Date today = Date.Today; SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); SimpleQuote rRate = new SimpleQuote(0.0); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); SimpleQuote vol = new SimpleQuote(0.0); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); for (int i = 0; i < values.Length; i++) { Date exDate = today + (int)(values[i].t * 360 + 0.5); Exercise exercise = new EuropeanExercise(exDate); spot.setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle <Quote>(spot), new Handle <YieldTermStructure>(qTS), new Handle <YieldTermStructure>(rTS), new Handle <BlackVolTermStructure>(volTS)); DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType, values[i].barrierlo, values[i].barrierhi, 0, // no rebate payoff, exercise); // Ikeda/Kunitomo engine IPricingEngine engine = new AnalyticDoubleBarrierEngine(stochProcess); opt.setPricingEngine(engine); double calculated = opt.NPV(); double expected = values[i].result; double error = Math.Abs(calculated - expected); if (error > values[i].tol) { REPORT_FAILURE("Ikeda/Kunitomo value", values[i].barrierType, values[i].barrierlo, values[i].barrierhi, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, expected, calculated, error, values[i].tol); } // Wulin Suo/Yong Wang engine engine = new WulinYongDoubleBarrierEngine(stochProcess); opt.setPricingEngine(engine); calculated = opt.NPV(); expected = values[i].result; error = Math.Abs(calculated - expected); if (error > values[i].tol) { REPORT_FAILURE("Wulin/Yong value", values[i].barrierType, values[i].barrierlo, values[i].barrierhi, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].v, expected, calculated, error, values[i].tol); } } }
public void testVannaVolgaDoubleBarrierValues() { // Testing double-barrier FX options against Vanna/Volga values SavedSettings backup = new SavedSettings(); DoubleBarrierFxOptionData[] values = { // BarrierType, barr.1, barr.2, rebate, type, strike, s, q, r, t, vol25Put, volAtm,vol25Call, vol, result, tol new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.14413, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.07456, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02710, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.00569, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Call, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.00013, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.13321, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.11638, 0.00017, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.22687, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.10088, 0.00353, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.31179, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08925, 0.02221, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.38843, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08463, 0.06049, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.1, 1.5, 0.0, Option.Type.Put, 1.46047, 1.30265, 0.0003541, 0.0033871, 1.0, 0.10087, 0.08925, 0.08463, 0.08412, 0.11103, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.19981, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.10389, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03555, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.00634, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Call, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.00000, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.06145, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.12511, 0.00000, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.19545, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.10890, 0.00436, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.32238, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09444, 0.03173, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.44298, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09197, 0.09346, 1.0e-4), new DoubleBarrierFxOptionData(DoubleBarrier.Type.KnockOut, 1.0, 1.6, 0.0, Option.Type.Put, 1.56345, 1.30265, 0.0009418, 0.0039788, 2.0, 0.10891, 0.09525, 0.09197, 0.09261, 0.17704, 1.0e-4), }; DayCounter dc = new Actual360(); Date today = new Date(05, Month.Mar, 2013); Settings.setEvaluationDate(today); SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); SimpleQuote rRate = new SimpleQuote(0.0); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); SimpleQuote vol25Put = new SimpleQuote(0.0); SimpleQuote volAtm = new SimpleQuote(0.0); SimpleQuote vol25Call = new SimpleQuote(0.0); for (int i = 0; i < values.Length; i++) { for (int j = 0; j <= 1; j++) { DoubleBarrier.Type barrierType = (DoubleBarrier.Type)j; spot.setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol25Put.setValue(values[i].vol25Put); volAtm.setValue(values[i].volAtm); vol25Call.setValue(values[i].vol25Call); StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); Date exDate = today + (int)(values[i].t * 365 + 0.5); Exercise exercise = new EuropeanExercise(exDate); Handle <DeltaVolQuote> volAtmQuote = new Handle <DeltaVolQuote>( new DeltaVolQuote(new Handle <Quote>(volAtm), DeltaVolQuote.DeltaType.Fwd, values[i].t, DeltaVolQuote.AtmType.AtmDeltaNeutral)); //always delta neutral atm Handle <DeltaVolQuote> vol25PutQuote = new Handle <DeltaVolQuote>(new DeltaVolQuote(-0.25, new Handle <Quote>(vol25Put), values[i].t, DeltaVolQuote.DeltaType.Fwd)); Handle <DeltaVolQuote> vol25CallQuote = new Handle <DeltaVolQuote>(new DeltaVolQuote(0.25, new Handle <Quote>(vol25Call), values[i].t, DeltaVolQuote.DeltaType.Fwd)); DoubleBarrierOption doubleBarrierOption = new DoubleBarrierOption(barrierType, values[i].barrier1, values[i].barrier2, values[i].rebate, payoff, exercise); double bsVanillaPrice = Utils.blackFormula(values[i].type, values[i].strike, spot.value() * qTS.discount(values[i].t) / rTS.discount(values[i].t), values[i].v * Math.Sqrt(values[i].t), rTS.discount(values[i].t)); IPricingEngine vannaVolgaEngine; vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine(volAtmQuote, vol25PutQuote, vol25CallQuote, new Handle <Quote>(spot), new Handle <YieldTermStructure>(rTS), new Handle <YieldTermStructure>(qTS), (process, series) => new WulinYongDoubleBarrierEngine(process, series), true, bsVanillaPrice); doubleBarrierOption.setPricingEngine(vannaVolgaEngine); double expected = 0; if (barrierType == DoubleBarrier.Type.KnockOut) { expected = values[i].result; } else if (barrierType == DoubleBarrier.Type.KnockIn) { expected = (bsVanillaPrice - values[i].result); } double calculated = doubleBarrierOption.NPV(); double error = Math.Abs(calculated - expected); if (error > values[i].tol) { REPORT_FAILURE_VANNAVOLGA("value", values[i].barrierType, values[i].barrier1, values[i].barrier2, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].vol25Put, values[i].volAtm, values[i].vol25Call, values[i].v, expected, calculated, error, values[i].tol); } vannaVolgaEngine = new VannaVolgaDoubleBarrierEngine(volAtmQuote, vol25PutQuote, vol25CallQuote, new Handle <Quote>(spot), new Handle <YieldTermStructure>(rTS), new Handle <YieldTermStructure>(qTS), (process, series) => new AnalyticDoubleBarrierEngine(process, series), true, bsVanillaPrice); doubleBarrierOption.setPricingEngine(vannaVolgaEngine); calculated = doubleBarrierOption.NPV(); error = Math.Abs(calculated - expected); double maxtol = 5.0e-3; // different engines have somewhat different results if (error > maxtol) { REPORT_FAILURE_VANNAVOLGA("value", values[i].barrierType, values[i].barrier1, values[i].barrier2, values[i].rebate, payoff, exercise, values[i].s, values[i].q, values[i].r, today, values[i].vol25Put, values[i].volAtm, values[i].vol25Call, values[i].v, expected, calculated, error, values[i].tol); } } } }
public void testHaugValues() { // Testing cash-or-nothing double barrier options against Haug's values DoubleBinaryOptionData[] values = { /* The data below are from * "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 181 * Note: book uses cost of carry b, instead of dividend rate q */ // barrierType, bar_lo, bar_hi, cash, spot, q, r, t, vol, value, tol new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.8716, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 8.9307, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.3272, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 1.9094, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 9.7961, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 7.2300, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.7100, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.4271, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 8.9054, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.6752, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.7960, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0059, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6323, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.0911, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 0.0002, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.2402, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 1.4076, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 3.8160, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0075, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9910, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.8098, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.6612, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.2656, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.7954, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.4024, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9266, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 2.6285, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 4.7523, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.9096, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.9675, 1e-4), // following values calculated with haug's VBA code new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0042, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.9450, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.5486, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 7.9663, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0797, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 2.6458, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 6.1658, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.4486, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.9704, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 6.2006, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.0798, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8699, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 6.2434, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 9.7847, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 9.8756, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 9.8758, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0041, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 0.7080, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 2.1581, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 80.00, 120.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.2061, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.0723, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 1.6663, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 3.3930, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 85.00, 115.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 4.8679, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 0.7080, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 3.4424, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 4.7496, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 90.00, 110.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0475, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.10, 3.6524, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.20, 5.1256, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.30, 5.0763, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 100.00, 0.02, 0.05, 0.25, 0.50, 5.0275, 1e-4), // degenerate cases new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockOut, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KnockIn, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KIKO, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 80.00, 0.02, 0.05, 0.25, 0.10, 0.0000, 1e-4), new DoubleBinaryOptionData(DoubleBarrier.Type.KOKI, 95.00, 105.00, 10.00, 110.00, 0.02, 0.05, 0.25, 0.10, 10.0000, 1e-4), }; DayCounter dc = new Actual360(); Date today = Date.Today; SimpleQuote spot = new SimpleQuote(100.0); SimpleQuote qRate = new SimpleQuote(0.04); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); SimpleQuote rRate = new SimpleQuote(0.01); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new CashOrNothingPayoff(Option.Type.Call, 0, values[i].cash); Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); Exercise exercise; if (values[i].barrierType == DoubleBarrier.Type.KIKO || values[i].barrierType == DoubleBarrier.Type.KOKI) { exercise = new AmericanExercise(today, exDate, true); } else { exercise = new EuropeanExercise(exDate); } spot.setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle <Quote>(spot), new Handle <YieldTermStructure>(qTS), new Handle <YieldTermStructure>(rTS), new Handle <BlackVolTermStructure>(volTS)); IPricingEngine engine = new AnalyticDoubleBarrierBinaryEngine(stochProcess); DoubleBarrierOption opt = new DoubleBarrierOption(values[i].barrierType, values[i].barrier_lo, values[i].barrier_hi, 0, payoff, exercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); double expected = values[i].result; double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, exercise, values[i].barrierType, values[i].barrier_lo, values[i].barrier_hi, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); } int steps = 500; // checking with binomial engine engine = new BinomialDoubleBarrierEngine( (d, end, step, strike) => new CoxRossRubinstein(d, end, step, strike), (args, process, grid) => new DiscretizedDoubleBarrierOption(args, process, grid), stochProcess, steps); opt.setPricingEngine(engine); calculated = opt.NPV(); expected = values[i].result; error = Math.Abs(calculated - expected); double tol = 0.22; if (error > tol) { REPORT_FAILURE("Binomial value", payoff, exercise, values[i].barrierType, values[i].barrier_lo, values[i].barrier_hi, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, tol); } } }