Пример #1
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option");

            EuropeanExercise exercise = arguments_.exercise as EuropeanExercise;

            Utils.QL_REQUIRE(exercise != null, () => "not an European Option");

            SpreadBasketPayoff spreadPayoff = arguments_.payoff as SpreadBasketPayoff;

            Utils.QL_REQUIRE(spreadPayoff != null, () => " spread payoff expected");

            PlainVanillaPayoff payoff = spreadPayoff.basePayoff() as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");
            double strike = payoff.strike();

            double f1 = process1_.stateVariable().link.value();
            double f2 = process2_.stateVariable().link.value();

            // use atm vols
            double variance1 = process1_.blackVolatility().link.blackVariance(exercise.lastDate(), f1);
            double variance2 = process2_.blackVolatility().link.blackVariance(exercise.lastDate(), f2);

            double riskFreeDiscount = process1_.riskFreeRate().link.discount(exercise.lastDate());

            Func <double, double> Square = x => x * x;
            double f = f1 / (f2 + strike);
            double v = Math.Sqrt(variance1
                                 + variance2 * Square(f2 / (f2 + strike))
                                 - 2 * rho_ * Math.Sqrt(variance1 * variance2)
                                 * (f2 / (f2 + strike)));

            BlackCalculator black = new BlackCalculator(new PlainVanillaPayoff(payoff.optionType(), 1.0), f, v, riskFreeDiscount);

            results_.value = (f2 + strike) * black.value();
        }
Пример #2
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European Option");

            EuropeanExercise exercise = arguments_.exercise as EuropeanExercise;

            Utils.QL_REQUIRE(exercise != null, () => "not an European Option");

            BasketPayoff basket_payoff = arguments_.payoff as BasketPayoff;

            MinBasketPayoff min_basket = arguments_.payoff as MinBasketPayoff;

            MaxBasketPayoff max_basket = arguments_.payoff as MaxBasketPayoff;

            Utils.QL_REQUIRE(min_basket != null || max_basket != null, () => "unknown basket type");

            PlainVanillaPayoff payoff = basket_payoff.basePayoff() as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");

            double strike = payoff.strike();

            double variance1 = process1_.blackVolatility().link.blackVariance(exercise.lastDate(), strike);
            double variance2 = process2_.blackVolatility().link.blackVariance(exercise.lastDate(), strike);

            double riskFreeDiscount = process1_.riskFreeRate().link.discount(exercise.lastDate());

            // cannot handle non zero dividends, so don't believe this...
            double dividendDiscount1 = process1_.dividendYield().link.discount(exercise.lastDate());
            double dividendDiscount2 = process2_.dividendYield().link.discount(exercise.lastDate());

            double forward1 = process1_.stateVariable().link.value() * dividendDiscount1 / riskFreeDiscount;
            double forward2 = process2_.stateVariable().link.value() * dividendDiscount2 / riskFreeDiscount;

            if (max_basket != null)
            {
                switch (payoff.optionType())
                {
                // euro call on a two asset max basket
                case Option.Type.Call:
                    results_.value = euroTwoAssetMaxBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2,
                                                               rho_);

                    break;

                // euro put on a two asset max basket
                case Option.Type.Put:
                    results_.value = strike * riskFreeDiscount -
                                     euroTwoAssetMaxBasketCall(forward1, forward2, 0.0,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_) +
                                     euroTwoAssetMaxBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_);
                    break;

                default:
                    Utils.QL_FAIL("unknown option type");
                    break;
                }
            }
            else if (min_basket != null)
            {
                switch (payoff.optionType())
                {
                // euro call on a two asset min basket
                case Option.Type.Call:
                    results_.value = euroTwoAssetMinBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2,
                                                               rho_);
                    break;

                // euro put on a two asset min basket
                case Option.Type.Put:
                    results_.value = strike * riskFreeDiscount -
                                     euroTwoAssetMinBasketCall(forward1, forward2, 0.0,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_) +
                                     euroTwoAssetMinBasketCall(forward1, forward2, strike,
                                                               riskFreeDiscount,
                                                               variance1, variance2, rho_);
                    break;

                default:
                    Utils.QL_FAIL("unknown option type");
                    break;
                }
            }
            else
            {
                Utils.QL_FAIL("unknown type");
            }
        }