示例#1
0
        public void testFdmHestonBlackScholes()
        {
            //Testing FDM Heston with Black Scholes model...
            using (SavedSettings backup = new SavedSettings())
            {
                Settings.Instance.setEvaluationDate(new Date(28, 3, 2004));
                Date exerciseDate = new Date(26, 6, 2004);

                Handle <YieldTermStructure>    rTS   = new Handle <YieldTermStructure>(Utilities.flatRate(0.10, new Actual360()));
                Handle <YieldTermStructure>    qTS   = new Handle <YieldTermStructure>(Utilities.flatRate(0.0, new Actual360()));
                Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(rTS.currentLink().referenceDate(), 0.25, rTS.currentLink().dayCounter()));

                Exercise          exercise = new EuropeanExercise(exerciseDate);
                StrikedTypePayoff payoff   = new PlainVanillaPayoff(Option.Type.Put, 10);
                VanillaOption     option   = new VanillaOption(payoff, exercise);

                double[] strikes = new double[] { 8, 9, 10, 11, 12 };
                double   tol     = 0.0001;

                for (int i = 0; i < strikes.Length; ++i)
                {
                    Handle <Quote> s0 = new Handle <Quote>(new SimpleQuote(strikes[i]));
                    GeneralizedBlackScholesProcess bsProcess = new GeneralizedBlackScholesProcess(s0, qTS, rTS, volTS);
                    option.setPricingEngine(new AnalyticEuropeanEngine(bsProcess));

                    double expected = option.NPV();

                    HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, 0.0625, 1, 0.0625, 0.0001, 0.0);

                    // Hundsdorfer scheme
                    option.setPricingEngine(new FdHestonVanillaEngine(new HestonModel(hestonProcess),
                                                                      100, 400, 3));

                    double calculated = option.NPV();
                    if (Math.Abs(calculated - expected) > tol)
                    {
                        QAssert.Fail("Failed to reproduce expected npv"
                                     + "\n    strike:     " + strikes[i]
                                     + "\n    calculated: " + calculated
                                     + "\n    expected:   " + expected
                                     + "\n    tolerance:  " + tol);
                    }

                    // Explicit scheme
                    option.setPricingEngine(new FdHestonVanillaEngine(new HestonModel(hestonProcess),
                                                                      4000, 400, 3, 0,
                                                                      new FdmSchemeDesc().ExplicitEuler()));

                    calculated = option.NPV();
                    if (Math.Abs(calculated - expected) > tol)
                    {
                        QAssert.Fail("Failed to reproduce expected npv"
                                     + "\n    strike:     " + strikes[i]
                                     + "\n    calculated: " + calculated
                                     + "\n    expected:   " + expected
                                     + "\n    tolerance:  " + tol);
                    }
                }
            }
        }
 public CalibrationPair(VanillaOption first, Quote second) : this(NQuantLibcPINVOKE.new_CalibrationPair__SWIG_1(VanillaOption.getCPtr(first), Quote.getCPtr(second)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
示例#3
0
        [TestMethod] //TODO: fix this one
        public void TestFdAmericanOptionEngine()
        {
            var startDate = new Date(2010, 08, 31);
            var endDate   = new Date(2016, 08, 31);
            var calendar  = CalendarImpl.Get("chn");

            var option = new VanillaOption(startDate,
                                           endDate,
                                           OptionExercise.American,
                                           OptionType.Call,
                                           3.53,
                                           InstrumentType.Stock,
                                           calendar,
                                           new Act365(),
                                           CurrencyCode.CNY,
                                           CurrencyCode.CNY,
                                           calendar.BizDaysBetweenDatesInclEndDay(startDate, endDate).ToArray(),
                                           null,
                                           1.0
                                           );

            var engine = new FdAmericanOptionEngine(100);
            var result = engine.Calculate(option, TestMarket(), PricingRequest.All);

            Assert.AreEqual(result.Pv, 0.4459260143, 1e-8);
            Assert.AreEqual(result.Delta, 0.71918151, 1e-8);
            Assert.AreEqual(result.Gamma, 0.487730202, 1e-8);
            Assert.AreEqual(result.Vega, 0.0177395037, 1e-8);
            Assert.AreEqual(result.Theta, -0.00045427, 1e-8);
        }
示例#4
0
        public double ImpliedVolFromPremium(double targetPremium,
                                            VanillaOption option, MarketCondition market)
        {
            var timeIncrement = AnalyticalOptionPricerUtil.optionTimeToMaturityIncrement(option);
            var calculator    = ConfigureCalculator(option, market, timeIncrement: timeIncrement);

            return(calculator.SolveVol(targetPremium));
        }
 // Constructor
 public OptionPosition(StrikedTypePayoff payoff, Exercise exercise, DateTime TradeDate, double SpotAtStrikeDate, DayCounter dayCounter)
 {
     _option       = new VanillaOption(payoff, exercise);
     _dayCounter   = dayCounter;
     _expiryDate   = exercise.lastDate();
     _spotAtStrike = SpotAtStrikeDate;
     _tradeDate    = TradeDate;
 }
示例#6
0
        public void testOption()
        {
            /* a zero-coupon convertible bond with no credit spread is
             * equivalent to a call option. */

            // Testing zero-coupon convertible bonds against vanilla option

            CommonVars vars = new CommonVars();

            Exercise euExercise = new EuropeanExercise(vars.maturityDate);

            vars.settlementDays = 0;

            int            timeSteps     = 2001;
            IPricingEngine engine        = new BinomialConvertibleEngine <CoxRossRubinstein>(vars.process, timeSteps);
            IPricingEngine vanillaEngine = new BinomialVanillaEngine <CoxRossRubinstein>(vars.process, timeSteps);

            vars.creditSpread.linkTo(new SimpleQuote(0.0));

            double            conversionStrike = vars.redemption / vars.conversionRatio;
            StrikedTypePayoff payoff           = new PlainVanillaPayoff(Option.Type.Call, conversionStrike);

            Schedule schedule = new MakeSchedule().from(vars.issueDate)
                                .to(vars.maturityDate)
                                .withFrequency(Frequency.Once)
                                .withCalendar(vars.calendar)
                                .backwards().value();

            ConvertibleZeroCouponBond euZero = new ConvertibleZeroCouponBond(euExercise, vars.conversionRatio,
                                                                             vars.no_dividends, vars.no_callability,
                                                                             vars.creditSpread,
                                                                             vars.issueDate, vars.settlementDays,
                                                                             vars.dayCounter, schedule,
                                                                             vars.redemption);

            euZero.setPricingEngine(engine);

            VanillaOption euOption = new VanillaOption(payoff, euExercise);

            euOption.setPricingEngine(vanillaEngine);

            double tolerance = 5.0e-2 * (vars.faceAmount / 100.0);

            double expected = vars.faceAmount / 100.0 *
                              (vars.redemption * vars.riskFreeRate.link.discount(vars.maturityDate)
                               + vars.conversionRatio * euOption.NPV());
            double error = Math.Abs(euZero.NPV() - expected);

            if (error > tolerance)
            {
                QAssert.Fail("failed to reproduce plain-option price:"
                             + "\n    calculated: " + euZero.NPV()
                             + "\n    expected:   " + expected
                             + "\n    error:      " + error
                             + "\n    tolerance:      " + tolerance);
            }
        }
        public void testBjerksundStenslandValues()
        {
            // ("Testing Bjerksund and Stensland approximation for American options...");

            AmericanOptionData[] values = new AmericanOptionData[] {
                //      type, strike,   spot,    q,    r,    t,  vol,   value, tol
                // from "Option pricing formulas", Haug, McGraw-Hill 1998, pag 27
                new AmericanOptionData(Option.Type.Call, 40.00, 42.00, 0.08, 0.04, 0.75, 0.35, 5.2704),
                // from "Option pricing formulas", Haug, McGraw-Hill 1998, VBA code
                new AmericanOptionData(Option.Type.Put, 40.00, 36.00, 0.00, 0.06, 1.00, 0.20, 4.4531)
            };

            Date               today = Date.Today;
            DayCounter         dc    = new Actual360();
            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);

            double tolerance = 3.0e-3;

            for (int i = 0; i < values.Length; i++)
            {
                StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike);
                Date     exDate          = today + Convert.ToInt32(values[i].t * 360 + 0.5);
                Exercise exercise        = new AmericanExercise(today, 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 BjerksundStenslandApproximationEngine(stochProcess);

                VanillaOption option = new VanillaOption(payoff, exercise);
                option.setPricingEngine(engine);

                double calculated = option.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > tolerance)
                {
                    REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q,
                                   values[i].r, today, values[i].v, values[i].result,
                                   calculated, error, tolerance);
                }
            }
        }
        private void CommodityLookbackVanillaComparison(String ValuationDate = "2015-03-19", Double vol = 0.28, Double spot = 240, Double strike = 240,
                                                        Boolean isCall       = true, Boolean isFixed    = true)
        {
            var valuationDate = DateFromStr(ValuationDate);
            var maturityDate  = new Term("176D").Next(valuationDate);
            var calendar      = CalendarImpl.Get("chn");
            var obsDates      = new[] { new Date(2015, 4, 2), new Date(2015, 5, 4), new Date(2015, 6, 2), new Date(2015, 7, 2), new Date(2015, 8, 3), new Date(2015, 9, 2) };

            var option = new LookbackOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isFixed ? StrikeStyle.Fixed : StrikeStyle.Floating,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                new Dictionary <Date, double>(),
                notional: 1
                );

            var vanilla = new VanillaOption(
                valuationDate,
                maturityDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { maturityDate },
                obsDates,
                notional: 1
                );
            var market1 = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);
            var market2 = TestMarket(referenceDate: ValuationDate, vol: vol * 0.8, spot: spot);

            var analyticalEngine = new AnalyticalLookbackOptionEngine();
            var vanillaEngine    = new AnalyticalVanillaEuropeanOptionEngine();
            var analyticalResult = analyticalEngine.Calculate(option, market1, PricingRequest.All);
            var vanillaResult    = vanillaEngine.Calculate(vanilla, market1, PricingRequest.All);
            var volResult        = analyticalEngine.Calculate(option, market2, PricingRequest.All);

            //Floating Lookback Option >= ATM vanilla
            //High volatility Floating >= Low volatility Floating
            Assert.AreEqual(analyticalResult.Pv >= vanillaResult.Pv, true);
            Assert.AreEqual(analyticalResult.Pv >= volResult.Pv, true);
        }
示例#9
0
        public void testCashOrNothingEuropeanValues()
        {
            // Testing European cash-or-nothing digital option

            DigitalOptionData[] values =
            {
                // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 88
                //        type, strike,  spot,    q,    r,    t,  vol,  value, tol
                new DigitalOptionData(Option.Type.Put, 80.00, 100.0, 0.06, 0.06, 0.75, 0.35, 2.6710, 1e-4, true)
            };

            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++)
            {
                StrikedTypePayoff payoff = new CashOrNothingPayoff(values[i].type, values[i].strike, 10.0);

                Date     exDate   = today + Convert.ToInt32(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);

                BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot),
                                                                                       new Handle <YieldTermStructure>(qTS),
                                                                                       new Handle <YieldTermStructure>(rTS),
                                                                                       new Handle <BlackVolTermStructure>(volTS));

                IPricingEngine engine = new AnalyticEuropeanEngine(stochProcess);

                VanillaOption opt = new VanillaOption(payoff, exercise);
                opt.setPricingEngine(engine);

                double calculated = opt.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > values[i].tol)
                {
                    REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q,
                                   values[i].r, today, values[i].v, values[i].result,
                                   calculated, error, values[i].tol, values[i].knockin);
                }
            }
        }
示例#10
0
        public void testFdmHestonAmerican()
        {
            //Testing FDM with American option in Heston model...

            using (SavedSettings backup = new SavedSettings())
            {
                Handle <Quote> s0 = new Handle <Quote>(new SimpleQuote(100.0));

                Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.05, new Actual365Fixed()));
                Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.0, new Actual365Fixed()));

                HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, 0.04, 2.5, 0.04, 0.66, -0.8);

                Settings.Instance.setEvaluationDate(new Date(28, 3, 2004));
                Date exerciseDate = new Date(28, 3, 2005);

                Exercise          exercise = new AmericanExercise(exerciseDate);
                StrikedTypePayoff payoff   = new PlainVanillaPayoff(Option.Type.Put, 100);

                VanillaOption  option = new VanillaOption(payoff, exercise);
                IPricingEngine engine = new FdHestonVanillaEngine(new HestonModel(hestonProcess), 200, 100, 50);
                option.setPricingEngine(engine);

                double tol           = 0.01;
                double npvExpected   = 5.66032;
                double deltaExpected = -0.30065;
                double gammaExpected = 0.02202;

                if (Math.Abs(option.NPV() - npvExpected) > tol)
                {
                    QAssert.Fail("Failed to reproduce expected npv"
                                 + "\n    calculated: " + option.NPV()
                                 + "\n    expected:   " + npvExpected
                                 + "\n    tolerance:  " + tol);
                }
                if (Math.Abs(option.delta() - deltaExpected) > tol)
                {
                    QAssert.Fail("Failed to reproduce expected delta"
                                 + "\n    calculated: " + option.delta()
                                 + "\n    expected:   " + deltaExpected
                                 + "\n    tolerance:  " + tol);
                }
                if (Math.Abs(option.gamma() - gammaExpected) > tol)
                {
                    QAssert.Fail("Failed to reproduce expected gamma"
                                 + "\n    calculated: " + option.gamma()
                                 + "\n    expected:   " + gammaExpected
                                 + "\n    tolerance:  " + tol);
                }
            }
        }
        private void ResetStrikeOptionParityCalc(String ValuationDate = "2017-12-20", Double vol = 0.28, Double spot = 2.0, Double strike = 1.03, Boolean isCall = true, Boolean isPercentage = true)
        {
            var valuationDate    = DateFromStr(ValuationDate);
            var strikefixingDate = valuationDate;
            var exerciseDate     = new Term("176D").Next(valuationDate);
            var calendar         = CalendarImpl.Get("chn");


            var option1 = new ResetStrikeOption(
                valuationDate,
                exerciseDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                isPercentage ? ResetStrikeType.PercentagePayoff : ResetStrikeType.NormalPayoff,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { exerciseDate },
                new[] { exerciseDate },
                strikefixingDate
                );

            var option2 = new VanillaOption(
                valuationDate,
                exerciseDate,
                OptionExercise.European,
                isCall ? OptionType.Call : OptionType.Put,
                strike,
                InstrumentType.EquityIndex,
                calendar,
                new Act365(),
                CurrencyCode.CNY,
                CurrencyCode.CNY,
                new[] { exerciseDate },
                new[] { exerciseDate }
                );
            var market = TestMarket(referenceDate: ValuationDate, vol: vol, spot: spot);

            var engine        = new AnalyticalResetStrikeOptionEngine();
            var result        = engine.Calculate(option1, market, PricingRequest.All);
            var engineVanilla = new AnalyticalVanillaEuropeanOptionEngine();
            var resultVanilla = engineVanilla.Calculate(option2, market, PricingRequest.All);

            var result1 = (isPercentage) ? result.Pv * strike : result.Pv;

            Assert.AreEqual(result1, resultVanilla.Pv, 1e-8);
        }
示例#12
0
        public void testFdValues()
        {
            //("Testing finite-difference engine for American options...");

            Date               today = Date.Today;
            DayCounter         dc    = new Actual360();
            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);

            double tolerance = 8.0e-2;

            for (int i = 0; i < juValues.Length; i++)
            {
                StrikedTypePayoff payoff = new PlainVanillaPayoff(juValues[i].type, juValues[i].strike);
                Date     exDate          = today + Convert.ToInt32(juValues[i].t * 360 + 0.5);
                Exercise exercise        = new AmericanExercise(today, exDate);

                spot.setValue(juValues[i].s);
                qRate.setValue(juValues[i].q);
                rRate.setValue(juValues[i].r);
                vol.setValue(juValues[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 FDAmericanEngine(stochProcess, 100, 100);

                VanillaOption option = new VanillaOption(payoff, exercise);
                option.setPricingEngine(engine);

                double calculated = option.NPV();
                double error      = Math.Abs(calculated - juValues[i].result);
                if (error > tolerance)
                {
                    REPORT_FAILURE("value", payoff, exercise, juValues[i].s, juValues[i].q,
                                   juValues[i].r, today, juValues[i].v, juValues[i].result,
                                   calculated, error, tolerance);
                }
            }
        }
示例#13
0
        static void Main(string[] args)
        {
            var date = new Date(Weekday.Fri, Month.Jul, 1990);

            try
            {
                var myOption = new VanillaOption();
                Console.WriteLine(myOption.Npv());
            }
            catch (NotImplementedException ex)
            {
                Console.WriteLine("Some {0}", ex.Message.ToString());
            }



            Console.ReadLine();
        }
示例#14
0
 public ConvertibleBond(Bond bond,
                        VanillaOption conversionOptions,
                        VanillaOption[] embeddedOptions,
                        PriceQuoteType[] strikePriceType
                        )
 {
     Bond             = bond;
     ConversionOption = conversionOptions;
     if (ConversionOption == null)
     {
         ConversionRatio = double.NaN;
     }
     else
     {
         ConversionRatio = Bond.Notional / ConversionOption.Strike;
     }
     EmbeddedOptions = embeddedOptions;
     StrikePriceType = strikePriceType;
 }
示例#15
0
        public void testFdmHestonIkonenToivanen()
        {
            //Testing FDM Heston for Ikonen and Toivanen tests...

            /* check prices of american puts as given in:
             * From Efficient numerical methods for pricing American options under
             * stochastic volatility, Samuli Ikonen, Jari Toivanen,
             * http://users.jyu.fi/~tene/papers/reportB12-05.pdf
             */
            using (SavedSettings backup = new SavedSettings())
            {
                Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.10, new Actual360()));
                Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.0, new Actual360()));

                Settings.Instance.setEvaluationDate(new Date(28, 3, 2004));
                Date              exerciseDate = new Date(26, 6, 2004);
                Exercise          exercise     = new AmericanExercise(exerciseDate);
                StrikedTypePayoff payoff       = new PlainVanillaPayoff(Option.Type.Put, 10);
                VanillaOption     option       = new VanillaOption(payoff, exercise);

                double[] strikes  = new double[] { 8, 9, 10, 11, 12 };
                double[] expected = new double[] { 2.00000, 1.10763, 0.520038, 0.213681, 0.082046 };
                double   tol      = 0.001;

                for (int i = 0; i < strikes.Length; ++i)
                {
                    Handle <Quote> s0            = new Handle <Quote>(new SimpleQuote(strikes[i]));
                    HestonProcess  hestonProcess = new HestonProcess(rTS, qTS, s0, 0.0625, 5, 0.16, 0.9, 0.1);
                    IPricingEngine engine        = new FdHestonVanillaEngine(new HestonModel(hestonProcess), 100, 400);
                    option.setPricingEngine(engine);

                    double calculated = option.NPV();
                    if (Math.Abs(calculated - expected[i]) > tol)
                    {
                        QAssert.Fail("Failed to reproduce expected npv"
                                     + "\n    strike:     " + strikes[i]
                                     + "\n    calculated: " + calculated
                                     + "\n    expected:   " + expected[i]
                                     + "\n    tolerance:  " + tol);
                    }
                }
            }
        }
示例#16
0
        /// <summary>
        /// Runs option evaluation and logs exceptions
        /// </summary>
        /// <param name="option"></param>
        /// <returns></returns>
        private static double EvaluateOption(VanillaOption option)
        {
            try
            {
                var npv = option.NPV();

                if (double.IsNaN(npv) ||
                    double.IsInfinity(npv))
                {
                    npv = 0.0;
                }

                return(npv);
            }
            catch (Exception err)
            {
                Log.Debug("QLOptionPriceModel.EvaluateOption() error: " + err.Message);
                return(0.0);
            }
        }
示例#17
0
        public void TestCallableBond()
        {
            var bond = new Bond(
                "010001",
                new Date(2012, 05, 03),
                new Date(2017, 05, 03),
                100,
                CurrencyCode.CNY,
                new FixedCoupon(0.068),
                CalendarImpl.Get("chn_ib"),
                Frequency.Annual,
                Stub.LongEnd,
                new ActActIsma(),
                new ActAct(),
                BusinessDayConvention.None,
                BusinessDayConvention.ModifiedFollowing,
                null,
                TradingMarket.ChinaInterBank
                );

            var option = new VanillaOption(new Date(2012, 05, 03),
                                           new Date(2017, 05, 03),
                                           OptionExercise.European,
                                           OptionType.Put,
                                           106.8,
                                           InstrumentType.Bond,
                                           CalendarImpl.Get("chn_ib"),
                                           new Act365(),
                                           CurrencyCode.CNY,
                                           CurrencyCode.CNY,
                                           new[] { new Date(2015, 05, 03) },
                                           new[] { new Date(2015, 05, 03) }
                                           );

            var callableBond = new CallableBond(bond, new[] { option }, new[] { PriceQuoteType.Dirty });
            var market       = TestMarket();
            var engine       = new CallableBondEngine <HullWhite>(new HullWhite(0.1, 0.01), true, 40);
            var result       = engine.Calculate(callableBond, market, PricingRequest.All);

            Assert.AreEqual(107.0198942139, result.Pv, 1e-8);
        }
示例#18
0
        private void btnPrice_Click(object sender, EventArgs e)
        {
            try
            {
                var date = new Date(Weekday.Fri, (Month)cboMonth.SelectedItem, (int)cboMonth.SelectedItem);

                var fxOption = new VanillaOption((Exercise)cboExerciseType.SelectedItem, double.Parse(tbStrike.Text),
                                                 double.Parse(tbSpot.Text), double.Parse(tbCrossRfR.Text), double.Parse(tbBRfR.Text),
                                                 double.Parse(tbTtM.Text), double.Parse(tbVolatility.Text), date, (OptionPricing.ValuationMethod)cboValuationMethod.SelectedItem, (OptionPricing.Type)cboType.SelectedItem);

                tboPrice.Text = fxOption.Npv().ToString();
                tbDelta.Text  = fxOption.Delta().ToString();
                tbGamma.Text  = fxOption.Gamma().ToString();
                tbTheta.Text  = fxOption.Theta().ToString();
                tbVega.Text   = fxOption.Vega().ToString();
            }
            catch (NotImplementedException ex)
            {
                MessageBox.Show("{0}", ex.Message);
            }
        }
示例#19
0
        public void TestVanillaEuropeanCallMc()
        {
            var startDate    = new Date(2014, 03, 18);
            var maturityDate = new Date(2015, 03, 18);
            var market       = TestMarket();

            var call = new VanillaOption(startDate,
                                         maturityDate,
                                         OptionExercise.European,
                                         OptionType.Call,
                                         1.0,
                                         InstrumentType.Stock,
                                         CalendarImpl.Get("chn"),
                                         new Act365(),
                                         CurrencyCode.CNY,
                                         CurrencyCode.CNY,
                                         new[] { maturityDate },
                                         new[] { maturityDate });

            var mcengine = new GenericMonteCarloEngine(2, 200000);
            var result   = mcengine.Calculate(call, market, PricingRequest.All);

            var analyticalResult = new AnalyticalVanillaEuropeanOptionEngine().Calculate(call, market, PricingRequest.All);

            Console.WriteLine("{0},{1}", analyticalResult.Pv, result.Pv);
            Console.WriteLine("{0},{1}", analyticalResult.Delta, result.Delta);
            Console.WriteLine("{0},{1}", analyticalResult.Gamma, result.Gamma);
            Console.WriteLine("{0},{1}", analyticalResult.Vega, result.Vega);
            Console.WriteLine("{0},{1}", analyticalResult.Rho, result.Rho);
            Console.WriteLine("{0},{1}", analyticalResult.Theta, result.Theta);
            Assert.AreEqual(analyticalResult.Pv, result.Pv, 0.002);
            Assert.AreEqual(analyticalResult.Delta, result.Delta, 0.02);
            Assert.AreEqual(analyticalResult.Gamma, result.Gamma, 0.05);
            Assert.AreEqual(analyticalResult.Theta, result.Theta, 1e-5);
            Assert.AreEqual(analyticalResult.Rho, result.Rho, 1e-6);
            Assert.AreEqual(analyticalResult.Vega, result.Vega, 1e-4);
        }
示例#20
0
        static void Main(string[] args)
        {
            DateTime startTime = DateTime.Now;

            Option.Type optionType      = Option.Type.Put;
            double      underlyingPrice = 36;
            double      strikePrice     = 40;
            double      dividendYield   = 0.0;
            double      riskFreeRate    = 0.06;
            double      volatility      = 0.2;

            Date todaysDate = new Date(15, Month.May, 1998);

            Settings.instance().setEvaluationDate(todaysDate);

            Date settlementDate = new Date(17, Month.May, 1998);
            Date maturityDate   = new Date(17, Month.May, 1999);

            Calendar calendar = new TARGET();

            DateVector exerciseDates = new DateVector(4);

            for (int i = 1; i <= 4; i++)
            {
                Period forwardPeriod = new Period(3 * i, TimeUnit.Months);
                Date   forwardDate   = settlementDate.Add(forwardPeriod);
                exerciseDates.Add(forwardDate);
            }

            EuropeanExercise europeanExercise =
                new EuropeanExercise(maturityDate);
            BermudanExercise bermudanExercise =
                new BermudanExercise(exerciseDates);
            AmericanExercise americanExercise =
                new AmericanExercise(settlementDate, maturityDate);

            // bootstrap the yield/dividend/vol curves and create a
            // BlackScholesMerton stochastic process
            DayCounter dayCounter = new Actual365Fixed();
            YieldTermStructureHandle flatRateTSH =
                new YieldTermStructureHandle(
                    new FlatForward(settlementDate, riskFreeRate,
                                    dayCounter));
            YieldTermStructureHandle flatDividendTSH =
                new YieldTermStructureHandle(
                    new FlatForward(settlementDate, dividendYield,
                                    dayCounter));
            BlackVolTermStructureHandle flatVolTSH =
                new BlackVolTermStructureHandle(
                    new BlackConstantVol(settlementDate, calendar,
                                         volatility, dayCounter));

            QuoteHandle underlyingQuoteH =
                new QuoteHandle(new SimpleQuote(underlyingPrice));
            BlackScholesMertonProcess stochasticProcess =
                new BlackScholesMertonProcess(underlyingQuoteH,
                                              flatDividendTSH,
                                              flatRateTSH,
                                              flatVolTSH);

            PlainVanillaPayoff payoff =
                new PlainVanillaPayoff(optionType, strikePrice);

            // options
            VanillaOption europeanOption =
                new VanillaOption(payoff, europeanExercise);
            VanillaOption bermudanOption =
                new VanillaOption(payoff, bermudanExercise);
            VanillaOption americanOption =
                new VanillaOption(payoff, americanExercise);

            // report the parameters we are using
            ReportParameters(optionType, underlyingPrice, strikePrice,
                             dividendYield, riskFreeRate,
                             volatility, maturityDate);

            // write out the column headings
            ReportHeadings();

            #region Analytic Formulas

            // Black-Scholes for European
            try {
                europeanOption.setPricingEngine(
                    new AnalyticEuropeanEngine(stochasticProcess));
                ReportResults("Black-Scholes",
                              europeanOption.NPV(), null, null);
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Barone-Adesi and Whaley approximation for American
            try {
                americanOption.setPricingEngine(
                    new BaroneAdesiWhaleyEngine(stochasticProcess));
                ReportResults("Barone-Adesi/Whaley",
                              null, null, americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Bjerksund and Stensland approximation for American
            try {
                americanOption.setPricingEngine(
                    new BjerksundStenslandEngine(stochasticProcess));
                ReportResults("Bjerksund/Stensland",
                              null, null, americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Integral
            try {
                europeanOption.setPricingEngine(
                    new IntegralEngine(stochasticProcess));
                ReportResults("Integral",
                              europeanOption.NPV(), null, null);
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            uint timeSteps = 801;

            // Finite differences
            try {
                europeanOption.setPricingEngine(
                    new FDEuropeanEngine(stochasticProcess,
                                         timeSteps, timeSteps - 1));
                bermudanOption.setPricingEngine(
                    new FDBermudanEngine(stochasticProcess,
                                         timeSteps, timeSteps - 1));
                americanOption.setPricingEngine(
                    new FDAmericanEngine(stochasticProcess,
                                         timeSteps, timeSteps - 1));
                ReportResults("Finite differences",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            //Variance Gamma
            try
            {
                VarianceGammaProcess vgProcess = new VarianceGammaProcess(underlyingQuoteH,
                                                                          flatDividendTSH,
                                                                          flatRateTSH,
                                                                          volatility, 0.01, 0.0
                                                                          );
                europeanOption.setPricingEngine(
                    new VarianceGammaEngine(vgProcess));
                ReportResults("Variance-Gamma",
                              europeanOption.NPV(), null, null);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            #endregion Analytic Formulas

            #region Binomial Methods

            // Binomial Jarrow-Rudd
            try {
                europeanOption.setPricingEngine(
                    new BinomialJRVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialJRVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialJRVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Jarrow-Rudd",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Binomial Cox-Ross-Rubinstein
            try {
                europeanOption.setPricingEngine(
                    new BinomialCRRVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialCRRVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialCRRVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Cox-Ross-Rubinstein",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Additive Equiprobabilities
            try {
                europeanOption.setPricingEngine(
                    new BinomialEQPVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialEQPVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialEQPVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Additive Equiprobabilities",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Binomial Trigeorgis
            try {
                europeanOption.setPricingEngine(
                    new BinomialTrigeorgisVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialTrigeorgisVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialTrigeorgisVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Trigeorgis",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Binomial Tian
            try {
                europeanOption.setPricingEngine(
                    new BinomialTianVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialTianVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialTianVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Tian",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Binomial Leisen-Reimer
            try {
                europeanOption.setPricingEngine(
                    new BinomialLRVanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialLRVanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialLRVanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Leisen-Reimer",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // Binomial Joshi
            try {
                europeanOption.setPricingEngine(
                    new BinomialJ4VanillaEngine(stochasticProcess, timeSteps));
                bermudanOption.setPricingEngine(
                    new BinomialJ4VanillaEngine(stochasticProcess, timeSteps));
                americanOption.setPricingEngine(
                    new BinomialJ4VanillaEngine(stochasticProcess, timeSteps));
                ReportResults("Binomial Joshi",
                              europeanOption.NPV(),
                              bermudanOption.NPV(),
                              americanOption.NPV());
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            #endregion Binomial Methods

            #region Monte Carlo Methods

            // quantlib appears to use max numeric (int and real) values to test for 'null' (or rather 'default') values

            // MC (crude)
            try {
                int    mcTimeSteps       = 1;
                int    timeStepsPerYear  = int.MaxValue;
                bool   brownianBridge    = false;
                bool   antitheticVariate = false;
                int    requiredSamples   = int.MaxValue;
                double requiredTolerance = 0.02;
                int    maxSamples        = int.MaxValue;
                int    seed = 42;
                europeanOption.setPricingEngine(
                    new MCPREuropeanEngine(stochasticProcess,
                                           mcTimeSteps,
                                           timeStepsPerYear,
                                           brownianBridge,
                                           antitheticVariate,
                                           requiredSamples,
                                           requiredTolerance,
                                           maxSamples, seed));
                ReportResults("MC (crude)", europeanOption.NPV(), null, null);
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            // MC (Sobol)
            try {
                int    mcTimeSteps       = 1;
                int    timeStepsPerYear  = int.MaxValue;
                bool   brownianBridge    = false;
                bool   antitheticVariate = false;
                int    requiredSamples   = 32768; // 2^15
                double requiredTolerance = double.MaxValue;
                int    maxSamples        = int.MaxValue;
                int    seed = 0;
                europeanOption.setPricingEngine(
                    new MCLDEuropeanEngine(stochasticProcess,
                                           mcTimeSteps,
                                           timeStepsPerYear,
                                           brownianBridge,
                                           antitheticVariate,
                                           requiredSamples,
                                           requiredTolerance,
                                           maxSamples, seed));
                ReportResults("MC (Sobol)", europeanOption.NPV(), null, null);
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            #endregion Monte Carlo Methods

            DateTime endTime = DateTime.Now;
            TimeSpan delta   = endTime - startTime;
            Console.WriteLine();
            Console.WriteLine("Run completed in {0} s", delta.TotalSeconds);
            Console.WriteLine();
        }
示例#21
0
        public void testCashAtHitOrNothingAmericanGreeks()
        {
            // Testing American cash-(at-hit)-or-nothing digital option greeks

            SavedSettings backup = new SavedSettings();

            SortedDictionary <string, double> calculated = new SortedDictionary <string, double>();
            SortedDictionary <string, double> expected   = new SortedDictionary <string, double>();
            SortedDictionary <string, double> tolerance  = new SortedDictionary <string, double>(); // std::map<std::string,Real> calculated, expected, tolerance;

            tolerance["delta"] = 5.0e-5;
            tolerance["gamma"] = 5.0e-5;
            tolerance["rho"]   = 5.0e-5;

            Option.Type[] types      = { QLNet.Option.Type.Call, QLNet.Option.Type.Put };
            double[]      strikes    = { 50.0, 99.5, 100.5, 150.0 };
            double        cashPayoff = 100.0;

            double[] underlyings = { 100 };
            double[] qRates      = { 0.04, 0.05, 0.06 };
            double[] rRates      = { 0.01, 0.05, 0.15 };
            double[] vols        = { 0.11, 0.5, 1.2 };

            DayCounter dc    = new Actual360();
            Date       today = Date.Today;

            Settings.setEvaluationDate(today);

            SimpleQuote spot  = new SimpleQuote(0.0);
            SimpleQuote qRate = new SimpleQuote(0.0);
            Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(qRate, dc));
            SimpleQuote rRate = new SimpleQuote(0.0);
            Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(rRate, dc));
            SimpleQuote vol = new SimpleQuote(0.0);
            Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(vol, dc));

            // there is no cycling on different residual times
            Date     exDate     = today + 360;
            Exercise exercise   = new EuropeanExercise(exDate);
            Exercise amExercise = new AmericanExercise(today, exDate, false);

            Exercise[] exercises = { exercise, amExercise };

            BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot), qTS, rTS, volTS);

            IPricingEngine euroEngine = new AnalyticEuropeanEngine(stochProcess);

            IPricingEngine amEngine = new AnalyticDigitalAmericanEngine(stochProcess);

            IPricingEngine[] engines = { euroEngine, amEngine };

            bool knockin = true;

            for (int j = 0; j < engines.Length; j++)
            {
                for (int i1 = 0; i1 < types.Length; i1++)
                {
                    for (int i6 = 0; i6 < strikes.Length; i6++)
                    {
                        StrikedTypePayoff payoff = new CashOrNothingPayoff(types[i1], strikes[i6], cashPayoff);

                        VanillaOption opt = new VanillaOption(payoff, exercises[j]);
                        opt.setPricingEngine(engines[j]);

                        for (int i2 = 0; i2 < underlyings.Length; i2++)
                        {
                            for (int i4 = 0; i4 < qRates.Length; i4++)
                            {
                                for (int i3 = 0; i3 < rRates.Length; i3++)
                                {
                                    for (int i7 = 0; i7 < vols.Length; i7++)
                                    {
                                        // test data
                                        double u = underlyings[i2];
                                        double q = qRates[i4];
                                        double r = rRates[i3];
                                        double v = vols[i7];
                                        spot.setValue(u);
                                        qRate.setValue(q);
                                        rRate.setValue(r);
                                        vol.setValue(v);

                                        // theta, dividend rho and vega are not available for
                                        // digital option with american exercise. Greeks of
                                        // digital options with european payoff are tested
                                        // in the europeanoption.cpp test
                                        double value = opt.NPV();
                                        calculated["delta"] = opt.delta();
                                        calculated["gamma"] = opt.gamma();
                                        calculated["rho"]   = opt.rho();

                                        if (value > 1.0e-6)
                                        {
                                            // perturb spot and get delta and gamma
                                            double du = u * 1.0e-4;
                                            spot.setValue(u + du);
                                            double value_p = opt.NPV(),
                                                   delta_p = opt.delta();
                                            spot.setValue(u - du);
                                            double value_m = opt.NPV(),
                                                   delta_m = opt.delta();
                                            spot.setValue(u);
                                            expected["delta"] = (value_p - value_m) / (2 * du);
                                            expected["gamma"] = (delta_p - delta_m) / (2 * du);

                                            // perturb rates and get rho and dividend rho
                                            double dr = r * 1.0e-4;
                                            rRate.setValue(r + dr);
                                            value_p = opt.NPV();
                                            rRate.setValue(r - dr);
                                            value_m = opt.NPV();
                                            rRate.setValue(r);
                                            expected["rho"] = (value_p - value_m) / (2 * dr);

                                            // check
                                            //std::map<std::string,Real>::iterator it;
                                            foreach (var it in calculated)
                                            {
                                                string greek = it.Key;
                                                double expct = expected  [greek],
                                                       calcl = calculated[greek],
                                                       tol   = tolerance [greek];
                                                double error = Utilities.relativeError(expct, calcl, value);
                                                if (error > tol)
                                                {
                                                    REPORT_FAILURE(greek, payoff, exercise,
                                                                   u, q, r, today, v,
                                                                   expct, calcl, error, tol, knockin);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#22
0
        public void testBaroneAdesiWhaleyValues()
        {
            // ("Testing Barone-Adesi and Whaley approximation for American options...");

            /* The data below are from
             * "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag 24
             *
             * The following values were replicated only up to the second digit
             * by the VB code provided by Haug, which was used as base for the
             * C++ implementation
             *
             */
            AmericanOptionData[] values =
            {
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.10, 0.15,  0.0206),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.15,  1.8771),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.15, 10.0089),
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.10, 0.25,  0.3159),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.25,  3.1280),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.25, 10.3919),
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.10, 0.35,  0.9495),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.10, 0.35,  4.3777),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.10, 0.35, 11.1679),
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.50, 0.15,  0.8208),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.15,  4.0842),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.8087),
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.50, 0.25,  2.7437),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.25,  6.8015),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.25, 13.0170),
                new AmericanOptionData(Option.Type.Call, 100.00,  90.00, 0.10, 0.10, 0.50, 0.35,  5.0063),
                new AmericanOptionData(Option.Type.Call, 100.00, 100.00, 0.10, 0.10, 0.50, 0.35,  9.5106),
                new AmericanOptionData(Option.Type.Call, 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.5689),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.10, 0.15, 10.0000),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.10, 0.15,  1.8770),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.10, 0.15,  0.0410),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.10, 0.25, 10.2533),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.10, 0.25,  3.1277),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.10, 0.25,  0.4562),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.10, 0.35, 10.8787),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.10, 0.35,  4.3777),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.10, 0.35,  1.2402),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.50, 0.15, 10.5595),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.50, 0.15,  4.0842),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.50, 0.15,  1.0822),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.50, 0.25, 12.4419),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.50, 0.25,  6.8014),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.50, 0.25,  3.3226),
                new AmericanOptionData(Option.Type.Put,  100.00,  90.00, 0.10, 0.10, 0.50, 0.35, 14.6945),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.10, 0.10, 0.50, 0.35,  9.5104),
                new AmericanOptionData(Option.Type.Put,  100.00, 110.00, 0.10, 0.10, 0.50, 0.35,  5.8823),
                new AmericanOptionData(Option.Type.Put,  100.00, 100.00, 0.00, 0.00, 0.50, 0.15, 4.22949)
            };

            Date               today = Date.Today;
            DayCounter         dc    = new Actual360();
            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);

            double tolerance = 3.0e-3;

            for (int i = 0; i < values.Length; i++)
            {
                StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike);
                Date     exDate          = today + Convert.ToInt32(values[i].t * 360 + 0.5);
                Exercise exercise        = new AmericanExercise(today, 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 BaroneAdesiWhaleyApproximationEngine(stochProcess);

                VanillaOption option = new VanillaOption(payoff, exercise);
                option.setPricingEngine(engine);

                double calculated = option.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > tolerance)
                {
                    REPORT_FAILURE("value", payoff, exercise, values[i].s, values[i].q,
                                   values[i].r, today, values[i].v, values[i].result,
                                   calculated, error, tolerance);
                }
            }
        }
示例#23
0
        public void testAssetAtExpiryOrNothingAmericanValues()
        {
            // Testing American asset-(at-expiry)-or-nothing digital option

            DigitalOptionData[] values =
            {
                //        type, strike,   spot,    q,    r,   t,  vol,   value, tol
                // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 7,8,11,12
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.00, 0.10, 0.5, 0.20,                     64.8426, 1e-04, true),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.00, 0.10, 0.5, 0.20,                     77.7017, 1e-04, true),
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.00, 0.10, 0.5, 0.20,                     40.1574, 1e-04, false),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.00, 0.10, 0.5, 0.20,                     17.2983, 1e-04, false),
                // data from Haug VBA code results
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.01, 0.10, 0.5, 0.20,                     65.5291, 1e-04, true),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.01, 0.10, 0.5, 0.20,                     76.5951, 1e-04, true),
                // in the money options (guaranteed discounted payoff = forward * riskFreeDiscount
                //                                                    = spot * dividendDiscount)
                new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20,                    105.0000, 1e-12, true),
                new DigitalOptionData(Option.Type.Put,  100.00,  95.00, 0.00, 0.10, 0.5, 0.20,                     95.0000, 1e-12, true),
                new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.01, 0.10, 0.5, 0.20, 105.0000 * Math.Exp(-0.005), 1e-12, true),
                new DigitalOptionData(Option.Type.Put,  100.00,  95.00, 0.01, 0.10, 0.5, 0.20,  95.0000 * Math.Exp(-0.005), 1e-12, true)
            };

            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 AssetOrNothingPayoff(values[i].type, values[i].strike);

                Date     exDate     = today + Convert.ToInt32(values[i].t * 360 + 0.5);
                Exercise amExercise = new AmericanExercise(today, exDate, true);

                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;
                if (values[i].knockin)
                {
                    engine = new AnalyticDigitalAmericanEngine(stochProcess);
                }
                else
                {
                    engine = new AnalyticDigitalAmericanKOEngine(stochProcess);
                }

                VanillaOption opt = new VanillaOption(payoff, amExercise);
                opt.setPricingEngine(engine);

                double calculated = opt.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > values[i].tol)
                {
                    REPORT_FAILURE("value", payoff, amExercise, values[i].s,
                                   values[i].q, values[i].r, today, values[i].v,
                                   values[i].result, calculated, error, values[i].tol, values[i].knockin);
                }
            }
        }
示例#24
0
        public void testCashAtExpiryOrNothingAmericanValues()
        {
            // Testing American cash-(at-expiry)-or-nothing digital option

            DigitalOptionData[] values =
            {
                //        type, strike,   spot,    q,    r,   t,  vol,   value, tol
                // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 5,6,9,10
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.00, 0.10,  0.5,  0.20,                    9.3604,  1e-4, true),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.00, 0.10,  0.5,  0.20,                   11.2223,  1e-4, true),
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.00, 0.10,  0.5,  0.20,                    4.9081,  1e-4, false),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.00, 0.10,  0.5,  0.20,                    3.0461,  1e-4, false),
                // in the money options (guaranteed discounted payoff)
                new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10,  0.5,  0.20, 15.0000 * Math.Exp(-0.05), 1e-12, true),
                new DigitalOptionData(Option.Type.Put,  100.00,  95.00, 0.00, 0.10,  0.5,  0.20, 15.0000 * Math.Exp(-0.05), 1e-12, true),
                // out of bonds case
                new DigitalOptionData(Option.Type.Call,   2.37,   2.33, 0.07, 0.43, 0.19, 0.005,                    0.0000,  1e-4, false),
            };

            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(values[i].type, values[i].strike, 15.0);

                Date     exDate     = today + Convert.ToInt32(values[i].t * 360 + 0.5);
                Exercise amExercise = new AmericanExercise(today, exDate, true);

                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;
                if (values[i].knockin)
                {
                    engine = new AnalyticDigitalAmericanEngine(stochProcess);
                }
                else
                {
                    engine = new AnalyticDigitalAmericanKOEngine(stochProcess);
                }

                VanillaOption opt = new VanillaOption(payoff, amExercise);
                opt.setPricingEngine(engine);

                double calculated = opt.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > values[i].tol)
                {
                    REPORT_FAILURE("value", payoff, amExercise, values[i].s,
                                   values[i].q, values[i].r, today, values[i].v,
                                   values[i].result, calculated, error, values[i].tol, values[i].knockin);
                }
            }
        }
示例#25
0
        public void testCashAtHitOrNothingAmericanValues()
        {
            // Testing American cash-(at-hit)-or-nothing digital option

            DigitalOptionData[] values =
            {
                //        type, strike,   spot,    q,    r,   t,  vol,   value, tol
                // "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 - pag 95, case 1,2
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.00, 0.10, 0.5, 0.20,  9.7264,  1e-4, true),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.00, 0.10, 0.5, 0.20, 11.6553,  1e-4, true),

                // the following cases are not taken from a reference paper or book
                // in the money options (guaranteed immediate payoff)
                new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true),
                new DigitalOptionData(Option.Type.Put,  100.00,  95.00, 0.00, 0.10, 0.5, 0.20, 15.0000, 1e-16, true),
                // non null dividend (cross-tested with MC simulation)
                new DigitalOptionData(Option.Type.Put,  100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 12.2715,  1e-4, true),
                new DigitalOptionData(Option.Type.Call, 100.00,  95.00, 0.20, 0.10, 0.5, 0.20,  8.9109,  1e-4, true),
                new DigitalOptionData(Option.Type.Call, 100.00, 105.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true),
                new DigitalOptionData(Option.Type.Put,  100.00,  95.00, 0.20, 0.10, 0.5, 0.20, 15.0000, 1e-16, true)
            };

            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++)
            {
                StrikedTypePayoff payoff = new CashOrNothingPayoff(values[i].type, values[i].strike, 15.00);

                Date     exDate     = today + Convert.ToInt32(values[i].t * 360 + 0.5);
                Exercise amExercise = new AmericanExercise(today, 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 AnalyticDigitalAmericanEngine(stochProcess);

                VanillaOption opt = new VanillaOption(payoff, amExercise);
                opt.setPricingEngine(engine);

                double calculated = opt.NPV();
                double error      = Math.Abs(calculated - values[i].result);
                if (error > values[i].tol)
                {
                    REPORT_FAILURE("value", payoff, amExercise, values[i].s,
                                   values[i].q, values[i].r, today, values[i].v,
                                   values[i].result, calculated, error, values[i].tol, values[i].knockin);
                }
            }
        }
示例#26
0
        //public override void calculate(Excel_instrumentViewModel excel_inst)
        //{
        //    //#region Setting

        //    //Excel_compositeOptionViewModel compOptionVM = excel_interface as Excel_compositeOptionViewModel;

        //    //if (compOptionVM == null)
        //    //{
        //    //    //error
        //    //}

        //    //Calendar calendar = new TARGET();

        //    //Date todaysDate = todaysDate = ProgramVariable.ReferenceDate_;

        //    //Date settlementDate = todaysDate;

        //    //Settings.setEvaluationDate(todaysDate);

        //    //DayCounter dayCounter = new Actual365Fixed();

        //    //if (this.Excel_underlyingCalcInfo_paraViewModel_.Excel_underlyingInfo_paraViewModel_.Count == 0)
        //    //{
        //    //    //error
        //    //}

        //    //Excel_geometricBMViewModel gbm = this.Excel_underlyingCalcInfo_paraViewModel_.Excel_underlyingInfo_paraViewModel_[0].Excel_underlyingModel_paraViewModel_ as Excel_geometricBMViewModel;

        //    //double currentValue = Convert.ToDouble(gbm.CurrentValue_);

        //    //SimpleQuote quote = new SimpleQuote(currentValue);
        //    //Handle<Quote> underlyingH = new Handle<Quote>(quote);

        //    //double drift = Convert.ToDouble(gbm.Drift_);
        //    //double dividendYield = Convert.ToDouble(gbm.Dividend_);

        //    //double volatility = Convert.ToDouble(gbm.Volatility_);

        //    //SimpleQuote volQuote = new SimpleQuote(volatility);
        //    //Handle<Quote> volH = new Handle<Quote>(volQuote);

        //    //var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, drift, dayCounter));
        //    //var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
        //    //Handle<BlackVolTermStructure> flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volH, dayCounter));

        //    //BlackScholesMertonProcess bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

        //    //double value = 0.0;

        //    //DateTime exDate = compOptionVM.ExerciseDate_;

        //    //List<QLNet.OneAssetOption> optionList = new List<QLNet.OneAssetOption>();

        //    //foreach (Excel_compositeOption_subtypeViewModel item in compOptionVM.Excel_compositeOption_subtypeViewModelList_)
        //    //{
        //    //    optionList.Add(this.option(item, bsmProcess, exDate));
        //    //}

        //    ////------------------------------------------------

        //    //foreach (var item in optionList)
        //    //{
        //    //    value = value + item.NPV();
        //    //}

        //    //if (this.Separable_)
        //    //{
        //    //    double matrutiryPayAmt = 0.0;

        //    //    Excel_yieldCurveViewModel e_ycvm
        //    //        = this.Excel_discountCurve_paraViewModel_.discountYieldCurve("KRW");

        //    //    QLNet.YieldTermStructure yts = e_ycvm.yieldCurve();

        //    //    value += matrutiryPayAmt;
        //    //}

        //    //#endregion

        //    //#region Calculation

        //    //quote.setValue(currentValue*1.01);
        //    //double sup = optionList[0].NPV();

        //    //quote.setValue(currentValue * 0.99);
        //    //double sdown = optionList[0].NPV();

        //    //double delta = (sup - sdown) / (currentValue * 0.02);

        //    //double gamma = (sup * sup - 2 * value + sdown * sdown) / (currentValue * 0.01 * currentValue * 0.01);

        //    //quote.setValue(currentValue);

        //    //volQuote.setValue(volatility - 0.01);
        //    //double voldown = optionList[0].NPV();

        //    //volQuote.setValue(volatility + 0.01);
        //    //double volup = optionList[0].NPV();

        //    //double vega = (volup - voldown) / 2;

        //    //#endregion

        //    //#region Result

        //    //this.Excel_resultViewModel_.Price_ = value.ToString();

        //    //double baseUnderlyingValue = Convert.ToDouble(
        //    //    excel_interface.Excel_underlyingCalcInfoViewModel_.Excel_underlyingInfoViewModel_[0].BasePrice_);

        //    //this.Excel_resultViewModel_.PercentPrice_ = (100 * value / baseUnderlyingValue).ToString();

        //    //double notional = Convert.ToDouble(excel_interface.Excel_issueInfoViewModel_.Notional_);

        //    //this.Excel_resultViewModel_.EvalAmount_ = ( notional * ( value / baseUnderlyingValue) ).ToString();

        //    //#endregion

        //    //double gamma = optionList[0].gamma();
        //    //double vega = optionList[0].vega();

        //}

        private QLNet.OneAssetOption option(Excel_compositeOption_subtypeViewModel compositeOptionVM,
                                            BlackScholesMertonProcess bsmProcess,
                                            DateTime exDate)
        {
            Date exerciseDate = new Date(exDate);

            if (compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_VANILLACALLPUT")
            {
                Excel_vanillaCallPutViewModel e_vcpvm = compositeOptionVM as Excel_vanillaCallPutViewModel;

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, e_vcpvm.StrikeValue_);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.VanillaOption vanillaOption = new VanillaOption(payoff, ex);

                return(vanillaOption);
            }
            else if (compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_UPINOUTCALL" ||
                     compositeOptionVM.Excel_Type_.ToUpper() == "EXCEL_DOWNINOUTCALL")
            {
                Excel_upInOutCallViewModel e_uiocvm = compositeOptionVM as Excel_upInOutCallViewModel;

                Barrier.Type type = Barrier.Type.UpOut;

                if (e_uiocvm.InOut_.ToString() == "IN")
                {
                    type = Barrier.Type.UpIn;
                }

                double strikeValue  = e_uiocvm.StrikeValue_;
                double barrierValue = e_uiocvm.BarrierValue_;
                double partiRate    = Convert.ToDouble(e_uiocvm.PartiRate_) / 100.0;
                double rebateValue  = Convert.ToDouble(e_uiocvm.RebateCouponValue_);

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, strikeValue);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.BarrierOption barrierOption = new QLNet.BarrierOption(type, barrierValue, partiRate, rebateValue, payoff, ex);

                QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);

                barrierOption.setPricingEngine(engine);

                return(barrierOption);
            }
            else if (compositeOptionVM.Excel_Type_.ToUpper() == "")
            {
                Barrier.Type type = Barrier.Type.DownOut;

                QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 261.4);

                QLNet.EuropeanExercise ex = new EuropeanExercise(exerciseDate);

                QLNet.BarrierOption barrierOption = new QLNet.BarrierOption(type, 313.68, 0.32, 0.0, payoff, ex);

                QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);

                barrierOption.setPricingEngine(engine);

                return(barrierOption);
            }
            else
            {
                throw new Exception("unknown compositeOptionType");
            }
        }
示例#27
0
        public void calculate(double[] p, GBMParaViewModel para)
        {
            this.xData_ = p;
            this.yData_ = new double[p.Length];

            double sellBuySign = 1.0;

            if (this.sellBuy_ == "매도")
            {
                sellBuySign = -1.0;
            }
            else
            {
            }

            // set up dates
            Calendar calendar = new TARGET();
            //Date todaysDate = new Date(DateTime.Now);
            Date settlementDate = new Date(para.ReferenceDate_);

            Settings.setEvaluationDate(settlementDate);

            // our options
            Option.Type type = this.callPutEnum_;

            double underlying    = para.CurrentPrice_;
            double strike        = this.strike_;
            double dividendYield = para.Dividend_ / 100;
            double riskFreeRate  = para.Drift_ / 100;

            if (this.callPutEnum_ == Option.Type.Call)
            {
                this.imVol_ = para.Call_Interpolation_.value(this.strike_);
            }
            else if (this.callPutEnum_ == Option.Type.Put)
            {
                this.imVol_ = para.Put_Interpolation_.value(this.strike_);
            }

            double volatility = (this.imVol_) / 100;

            Date maturity = new Date(this.maturiry_.AddDays(1));


            if (this.callPutEnum_ == 0)
            {
                this.deltaCal_ = 1.0;
                this.gammaCal_ = 0.0;
                this.vegaCal_  = 0.0;
                this.thetaCal_ = 0.0;
                this.rhoCal_   = 0.0;

                this.deltaPosition_ = sellBuySign * this.unit_ * 500000 * underlying;

                this.deltaRisk_ = this.deltaPosition_ * 0.09;
                this.gammaRisk_ = 0.0;
                this.vegaRisk_  = 0.0;

                this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;
                this.deepOTM_   = 0.0;

                //this.remainDays_ = maturity - settlementDate;
                this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;

                return;
            }

            DayCounter dayCounter = new Actual365Fixed();

            Exercise europeanExercise = new EuropeanExercise(maturity);

            SimpleQuote quote = new SimpleQuote(underlying);

            Handle <Quote> underlyingH = new Handle <Quote>(quote);

            // bootstrap the yield/dividend/vol curves
            var flatTermStructure    = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
            var flatDividendTS       = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            var flatVolTS            = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter));
            StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike);
            var bsmProcess           = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            // options
            VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise);

            // Analytic formulas:
            // Black-Scholes for European
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));

            this.npv_      = Math.Round(europeanOption.NPV(), 6);
            this.deltaCal_ = sellBuySign * Math.Round(europeanOption.delta(), 6);
            this.gammaCal_ = sellBuySign * Math.Round(europeanOption.gamma(), 6);
            this.vegaCal_  = sellBuySign * Math.Round(europeanOption.vega() / 100, 6);
            this.thetaCal_ = sellBuySign * Math.Round(europeanOption.theta() / 365, 6);
            this.rhoCal_   = sellBuySign * Math.Round(europeanOption.rho() / 100, 6);

            this.deltaPosition_ = Math.Round(this.deltaCal_ * this.unit_ * 500000 * underlying, 0);
            this.deltaRisk_     = Math.Round(this.deltaPosition_ * 0.09, 0);
            this.gammaRisk_     = Math.Round(0.5 * this.gammaCal_ * (underlying * underlying * 0.08 * 0.08) * this.unit_ * 500000, 0);
            this.vegaRisk_      = Math.Round(this.vegaCal_ * this.imVol_ * 0.25 * this.unit_ * 500000, 0);

            this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_;

            this.deepOTM_ = 0.0;
            //this.remainDays_ = maturity - settlementDate;
            this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1;


            for (int i = 0; i < this.xData_.Length; i++)
            {
                quote.setValue(this.xData_[i]);
                this.yData_[i] = 500000.0 * (double)this.unit_ * europeanOption.NPV();
            }
        }
示例#28
0
        public void testCrankNicolsonWithDamping()
        {
            SavedSettings backup = new SavedSettings();

            DayCounter dc    = new Actual360();
            Date       today = Date.Today;

            SimpleQuote           spot  = new SimpleQuote(100.0);
            YieldTermStructure    qTS   = Utilities.flatRate(today, 0.06, dc);
            YieldTermStructure    rTS   = Utilities.flatRate(today, 0.06, dc);
            BlackVolTermStructure volTS = Utilities.flatVol(today, 0.35, dc);

            StrikedTypePayoff payoff =
                new CashOrNothingPayoff(Option.Type.Put, 100, 10.0);

            double   maturity = 0.75;
            Date     exDate   = today + Convert.ToInt32(maturity * 360 + 0.5);
            Exercise exercise = new EuropeanExercise(exDate);

            BlackScholesMertonProcess process = new
                                                BlackScholesMertonProcess(new Handle <Quote>(spot),
                                                                          new Handle <YieldTermStructure>(qTS),
                                                                          new Handle <YieldTermStructure>(rTS),
                                                                          new Handle <BlackVolTermStructure>(volTS));
            IPricingEngine engine =
                new AnalyticEuropeanEngine(process);

            VanillaOption opt = new VanillaOption(payoff, exercise);

            opt.setPricingEngine(engine);
            double expectedPV    = opt.NPV();
            double expectedGamma = opt.gamma();

            // fd pricing using implicit damping steps and Crank Nicolson
            int        csSteps = 25, dampingSteps = 3, xGrid = 400;
            List <int> dim = new InitializedList <int>(1, xGrid);

            FdmLinearOpLayout layout       = new FdmLinearOpLayout(dim);
            Fdm1dMesher       equityMesher =
                new FdmBlackScholesMesher(
                    dim[0], process, maturity, payoff.strike(),
                    null, null, 0.0001, 1.5,
                    new Pair <double?, double?>(payoff.strike(), 0.01));

            FdmMesher mesher =
                new FdmMesherComposite(equityMesher);

            FdmBlackScholesOp map =
                new FdmBlackScholesOp(mesher, process, payoff.strike());

            FdmInnerValueCalculator calculator =
                new FdmLogInnerValue(payoff, mesher, 0);

            object rhs = new Vector(layout.size());
            Vector x   = new Vector(layout.size());
            FdmLinearOpIterator endIter = layout.end();

            for (FdmLinearOpIterator iter = layout.begin(); iter != endIter;
                 ++iter)
            {
                (rhs as Vector)[iter.index()] = calculator.avgInnerValue(iter, maturity);
                x[iter.index()] = mesher.location(iter, 0);
            }

            FdmBackwardSolver solver = new FdmBackwardSolver(map, new FdmBoundaryConditionSet(),
                                                             new FdmStepConditionComposite(),
                                                             new FdmSchemeDesc().Douglas());

            solver.rollback(ref rhs, maturity, 0.0, csSteps, dampingSteps);

            MonotonicCubicNaturalSpline spline = new MonotonicCubicNaturalSpline(x, x.Count, rhs as Vector);

            double s               = spot.value();
            double calculatedPV    = spline.value(Math.Log(s));
            double calculatedGamma = (spline.secondDerivative(Math.Log(s))
                                      - spline.derivative(Math.Log(s))) / (s * s);

            double relTol = 2e-3;

            if (Math.Abs(calculatedPV - expectedPV) > relTol * expectedPV)
            {
                QAssert.Fail("Error calculating the PV of the digital option" +
                             "\n rel. tolerance:  " + relTol +
                             "\n expected:        " + expectedPV +
                             "\n calculated:      " + calculatedPV);
            }
            if (Math.Abs(calculatedGamma - expectedGamma) > relTol * expectedGamma)
            {
                QAssert.Fail("Error calculating the Gamma of the digital option" +
                             "\n rel. tolerance:  " + relTol +
                             "\n expected:        " + expectedGamma +
                             "\n calculated:      " + calculatedGamma);
            }
        }
示例#29
0
        public void testFdGreeks <Engine>() where Engine : IFDEngine, new()
        {
            using (SavedSettings backup = new SavedSettings())
            {
                Dictionary <string, double> calculated = new Dictionary <string, double>(),
                                            expected   = new Dictionary <string, double>(),
                                            tolerance  = new Dictionary <string, double>();

                tolerance.Add("delta", 7.0e-4);
                tolerance.Add("gamma", 2.0e-4);
                //tolerance["theta"]  = 1.0e-4;

                Option.Type[] types       = new Option.Type[] { Option.Type.Call, Option.Type.Put };
                double[]      strikes     = { 50.0, 99.5, 100.0, 100.5, 150.0 };
                double[]      underlyings = { 100.0 };
                double[]      qRates      = { 0.04, 0.05, 0.06 };
                double[]      rRates      = { 0.01, 0.05, 0.15 };
                int[]         years       = { 1, 2 };
                double[]      vols        = { 0.11, 0.50, 1.20 };

                Date today = Date.Today;
                Settings.setEvaluationDate(today);

                DayCounter         dc    = new Actual360();
                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 < types.Length; i++)
                {
                    for (int j = 0; j < strikes.Length; j++)
                    {
                        for (int k = 0; k < years.Length; k++)
                        {
                            Date                      exDate       = today + new Period(years[k], TimeUnit.Years);
                            Exercise                  exercise     = new AmericanExercise(today, exDate);
                            StrikedTypePayoff         payoff       = new PlainVanillaPayoff(types[i], strikes[j]);
                            BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot),
                                                                                                   new Handle <YieldTermStructure>(qTS),
                                                                                                   new Handle <YieldTermStructure>(rTS),
                                                                                                   new Handle <BlackVolTermStructure>(volTS));

                            IPricingEngine engine = new Engine().factory(stochProcess);

                            VanillaOption option = new VanillaOption(payoff, exercise);
                            option.setPricingEngine(engine);

                            for (int l = 0; l < underlyings.Length; l++)
                            {
                                for (int m = 0; m < qRates.Length; m++)
                                {
                                    for (int n = 0; n < rRates.Length; n++)
                                    {
                                        for (int p = 0; p < vols.Length; p++)
                                        {
                                            double u = underlyings[l];
                                            double q = qRates[m],
                                                   r = rRates[n];
                                            double v = vols[p];
                                            spot.setValue(u);
                                            qRate.setValue(q);
                                            rRate.setValue(r);
                                            vol.setValue(v);

                                            double value = option.NPV();
                                            calculated.Add("delta", option.delta());
                                            calculated.Add("gamma", option.gamma());
                                            //calculated["theta"]  = option.theta();

                                            if (value > spot.value() * 1.0e-5)
                                            {
                                                // perturb spot and get delta and gamma
                                                double du = u * 1.0e-4;
                                                spot.setValue(u + du);
                                                double value_p = option.NPV(),
                                                       delta_p = option.delta();
                                                spot.setValue(u - du);
                                                double value_m = option.NPV(),
                                                       delta_m = option.delta();
                                                spot.setValue(u);
                                                expected.Add("delta", (value_p - value_m) / (2 * du));
                                                expected.Add("gamma", (delta_p - delta_m) / (2 * du));

                                                /*
                                                 * // perturb date and get theta
                                                 * Time dT = dc.yearFraction(today-1, today+1);
                                                 * Settings::instance().setEvaluationDate(today-1);
                                                 * value_m = option.NPV();
                                                 * Settings::instance().setEvaluationDate(today+1);
                                                 * value_p = option.NPV();
                                                 * Settings::instance().setEvaluationDate(today);
                                                 * expected["theta"] = (value_p - value_m)/dT;
                                                 */

                                                // compare
                                                foreach (string greek in calculated.Keys)
                                                {
                                                    double expct      = expected[greek],
                                                                calcl = calculated[greek],
                                                                tol   = tolerance[greek];
                                                    double error      = Utilities.relativeError(expct, calcl, u);
                                                    if (error > tol)
                                                    {
                                                        REPORT_FAILURE(greek, payoff, exercise,
                                                                       u, q, r, today, v,
                                                                       expct, calcl, error, tol);
                                                    }
                                                }
                                            }
                                            calculated.Clear();
                                            expected.Clear();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#30
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(VanillaOption obj) {
   return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
 }
示例#31
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Option.Type optionType;
            if (CallorPut.Text == "Call")
            {
                optionType = Option.Type.Call;
            }
            else
            {
                optionType = Option.Type.Put;
            }


            double underlyingPrice = Convert.ToDouble(Stockprice.Text);
            double strikePrice     = Convert.ToDouble(Strikeprice.Text);
            double dividendYield   = 0.0;
            double riskFreeRate    = Convert.ToDouble(Intrate.Text);
            double volatility      = Convert.ToDouble(Resultvol.Text) / 100;
            Date   todaydate       = Date.todaysDate();
            string expd            = Datepick.Text;
            Date   maturityDate    = new Date();

            if (expd[1].ToString() is "/")
            {
                expd = '0' + expd;
            }
            if (expd[4].ToString() is "/")
            {
                expd = expd.Substring(0, 3) + '0' + expd.Substring(3);
            }
            maturityDate = DateParser.parseFormatted(expd, "%m/%d/%Y");



            Settings.instance().setEvaluationDate(todaydate);

            Date settlementDate = new Date();

            settlementDate = todaydate;



            QuantLib.Calendar calendar = new TARGET();

            AmericanExercise americanExercise =
                new AmericanExercise(settlementDate, maturityDate);

            EuropeanExercise europeanExercise =
                new EuropeanExercise(maturityDate);

            DayCounter dayCounter = new Actual365Fixed();
            YieldTermStructureHandle flatRateTSH =
                new YieldTermStructureHandle(
                    new FlatForward(settlementDate, riskFreeRate,
                                    dayCounter));
            YieldTermStructureHandle flatDividendTSH =
                new YieldTermStructureHandle(
                    new FlatForward(settlementDate, dividendYield,
                                    dayCounter));
            BlackVolTermStructureHandle flatVolTSH =
                new BlackVolTermStructureHandle(
                    new BlackConstantVol(settlementDate, calendar,
                                         volatility, dayCounter));

            QuoteHandle underlyingQuoteH =
                new QuoteHandle(new SimpleQuote(underlyingPrice));

            BlackScholesMertonProcess stochasticProcess =
                new BlackScholesMertonProcess(underlyingQuoteH,
                                              flatDividendTSH,
                                              flatRateTSH,
                                              flatVolTSH);

            PlainVanillaPayoff payoff =
                new PlainVanillaPayoff(optionType, strikePrice);

            VanillaOption americanOption =
                new VanillaOption(payoff, americanExercise);

            VanillaOption americanOption2 =
                new VanillaOption(payoff, americanExercise);

            VanillaOption europeanOption =
                new VanillaOption(payoff, europeanExercise);

            //americanOption.setPricingEngine(
            //                 new BaroneAdesiWhaleyEngine(stochasticProcess));

            //americanOption2.setPricingEngine(
            //                 new BinomialVanillaEngine(stochasticProcess, "coxrossrubinstein",1000));

            europeanOption.setPricingEngine(
                new AnalyticEuropeanEngine(stochasticProcess));

            //double opprice = Math.Round(americanOption2.NPV(),3);



            Date         divdate1 = new Date(14, Month.December, 2019);
            DoubleVector divpay   = new DoubleVector();
            DateVector   divDates = new DateVector();
            //divpay.Add(.0001);
            //divDates.Add(divdate1);
            DividendVanillaOption americanOption1 = new DividendVanillaOption(payoff, americanExercise, divDates, divpay);

            FDDividendAmericanEngine engine = new FDDividendAmericanEngine(stochasticProcess);

            americanOption1.setPricingEngine(engine);
            double opprice4 = americanOption1.NPV();
            //double vol1 = americanOption1.impliedVolatility(opprice4, stochasticProcess, .001);
            double delta1         = Math.Round(americanOption1.delta(), 2);
            double gamma1         = Math.Round(americanOption1.gamma(), 2);
            double theta1         = Math.Round(europeanOption.theta() / 365, 2);
            double vega1          = Math.Round(europeanOption.vega() / 100, 2);
            double oppricedisplay = Math.Round(opprice4, 3);

            Resultam.Text       = oppricedisplay.ToString();
            Resultam_Delta.Text = delta1.ToString();
            Resultam_Gamma.Text = gamma1.ToString();
            Resultam_Theta.Text = theta1.ToString();
            Resultam_Vega.Text  = vega1.ToString();
        }