Пример #1
0
 public BarrierOption(Barrier.Type barrierType, double barrier, double rebate, StrikedTypePayoff payoff, Exercise exercise) : base(payoff, exercise)
 {
     partiRate_   = 1.0;
     barrierType_ = barrierType;
     barrier_     = barrier;
     rebate_      = rebate;
 }
Пример #2
0
 private void REPORT_FAILURE(string greekName,
                             StrikedTypePayoff payoff,
                             Exercise exercise,
                             Barrier.Type barrierType,
                             double barrier,
                             double s,
                             double q,
                             double r,
                             Date today,
                             double v,
                             double expected,
                             double calculated,
                             double error,
                             double tolerance)
 {
     QAssert.Fail(payoff.optionType() + " option with "
                  + barrierType + " barrier type:\n"
                  + "    barrier:          " + barrier + "\n"
                  + payoff + " payoff:\n"
                  + exercise + " "
                  + payoff.optionType()
                  + "    spot value: " + s + "\n"
                  + "    strike:           " + payoff.strike() + "\n"
                  + "    dividend yield:   " + q + "\n"
                  + "    risk-free rate:   " + r + "\n"
                  + "    reference date:   " + today + "\n"
                  + "    maturity:         " + exercise.lastDate() + "\n"
                  + "    volatility:       " + v + "\n\n"
                  + "    expected " + greekName + ":   " + expected + "\n"
                  + "    calculated " + greekName + ": " + calculated + "\n"
                  + "    error:            " + error + "\n"
                  + "    tolerance:        " + tolerance);
 }
 public BarrierOption(Barrier.Type barrierType, double barrier, double rebate, StrikedTypePayoff payoff, Exercise exercise) : this(NQuantLibcPINVOKE.new_BarrierOption((int)barrierType, barrier, rebate, StrikedTypePayoff.getCPtr(payoff), Exercise.getCPtr(exercise)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public DividendBarrierOption(Barrier.Type barrierType,
                              double barrier,
                              double rebate,
                              StrikedTypePayoff payoff,
                              Exercise exercise,
                              List <Date> dividendDates,
                              List <double> dividends)
     : base(barrierType, barrier, rebate, payoff, exercise)
 {
     cashFlow_ = Utils.DividendVector(dividendDates, dividends);
 }
Пример #5
0
            public double       tol;    // tolerance

            public BinaryOptionData(Barrier.Type barrierType, double barrier, double cash, Option.Type type, double strike,
                                    double s, double q, double r, double t, double v, double result, double tol) : this()
            {
                this.barrierType = barrierType;
                this.barrier     = barrier;
                this.cash        = cash;
                this.type        = type;
                this.strike      = strike;
                this.s           = s;
                this.q           = q;
                this.r           = r;
                this.t           = t;
                this.v           = v;
                this.result      = result;
                this.tol         = tol;
            }
Пример #6
0
        public BiasedBarrierPathPricer(Barrier.Type barrierType,
                                       double?barrier,
                                       double?rebate,
                                       Option.Type type,
                                       double strike,
                                       List <double> discounts)
            : base()
        {
            barrierType_ = barrierType;
            barrier_     = barrier;
            rebate_      = rebate;
            payoff_      = new PlainVanillaPayoff(type, strike);
            discounts_   = discounts;

            Utils.QL_REQUIRE(strike >= 0.0,
                             () => "strike less than zero not allowed");
            Utils.QL_REQUIRE(barrier > 0.0,
                             () => "barrier less/equal zero not allowed");
        }
Пример #7
0
 public BarrierPathPricer(
     Barrier.Type barrierType,
     double?barrier,
     double?rebate,
     Option.Type type,
     double strike,
     List <double> discounts,
     StochasticProcess1D diffProcess,
     IRNG sequenceGen)
 {
     barrierType_ = barrierType;
     barrier_     = barrier;
     rebate_      = rebate;
     diffProcess_ = diffProcess;
     sequenceGen_ = sequenceGen;
     payoff_      = new PlainVanillaPayoff(type, strike);
     discounts_   = discounts;
     Utils.QL_REQUIRE(strike >= 0.0, () => "strike less than zero not allowed");
     Utils.QL_REQUIRE(barrier > 0.0, () => "barrier less/equal zero not allowed");
 }
Пример #8
0
        static void Main(string[] args)
        {
            Calendar calendar = new TARGET();

            Date todaysDate     = new Date(22, 7, 2014);
            Date settlementDate = new Date(3, 6, 2014);

            Settings.setEvaluationDate(todaysDate);

            DayCounter dayCounter    = new Actual365Fixed();
            double     dividendYield = 0.0117;
            double     volatility    = 0.15517;

            Barrier.Type             type   = Barrier.Type.UpOut;
            QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 261.4);
            QLNet.EuropeanExercise   ex     = new EuropeanExercise(new Date(30, 11, 2015));

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

            double underlying   = 262.86;
            double riskFreeRate = 0.0243;

            Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying));

            // 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));
            var bsmProcess        = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

            QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess);
            barrierOption.setPricingEngine(engine);

            double kk = barrierOption.NPV();

            Console.WriteLine(kk);
            Console.WriteLine(kk / 261.4);
        }
Пример #9
0
            public double       v;  // volatility

            public NewBarrierOptionData(Barrier.Type _barrierType,
                                        double _barrier,
                                        double _rebate,
                                        Option.Type _type,
                                        double _strike,
                                        double _s,
                                        double _q,
                                        double _r,
                                        double _t,
                                        double _v)
            {
                barrierType = _barrierType;
                barrier     = _barrier;
                rebate      = _rebate;
                type        = _type;
                strike      = _strike;
                s           = _s;
                q           = _q;
                r           = _r;
                t           = _t;
                v           = _v;
            }
Пример #10
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");
            }
        }
Пример #11
0
        public override void calculate()
        {
            AmericanExercise ex = arguments_.exercise as AmericanExercise;

            Utils.QL_REQUIRE(ex != null, () => "non-American exercise given");
            Utils.QL_REQUIRE(ex.payoffAtExpiry(), () => "payoff must be at expiry");
            Utils.QL_REQUIRE(ex.dates()[0] <= process_.blackVolatility().link.referenceDate(), () =>
                             "American option with window exercise not handled yet");

            StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff;

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

            double spot = process_.stateVariable().link.value();

            Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given");

            double variance = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike());
            double?barrier  = arguments_.barrier;

            Utils.QL_REQUIRE(barrier > 0.0, () => "positive barrier value required");
            Barrier.Type barrierType = arguments_.barrierType;

            // KO degenerate cases
            if ((barrierType == Barrier.Type.DownOut && spot <= barrier) ||
                (barrierType == Barrier.Type.UpOut && spot >= barrier))
            {
                // knocked out, no value
                results_.value       = 0;
                results_.delta       = 0;
                results_.gamma       = 0;
                results_.vega        = 0;
                results_.theta       = 0;
                results_.rho         = 0;
                results_.dividendRho = 0;
                return;
            }

            // KI degenerate cases
            if ((barrierType == Barrier.Type.DownIn && spot <= barrier) ||
                (barrierType == Barrier.Type.UpIn && spot >= barrier))
            {
                // knocked in - is a digital european
                Exercise exercise = new EuropeanExercise(arguments_.exercise.lastDate());

                IPricingEngine engine = new AnalyticEuropeanEngine(process_);

                VanillaOption opt = new VanillaOption(payoff, exercise);
                opt.setPricingEngine(engine);
                results_.value       = opt.NPV();
                results_.delta       = opt.delta();
                results_.gamma       = opt.gamma();
                results_.vega        = opt.vega();
                results_.theta       = opt.theta();
                results_.rho         = opt.rho();
                results_.dividendRho = opt.dividendRho();
                return;
            }

            double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate());

            AnalyticBinaryBarrierEngine_helper helper = new AnalyticBinaryBarrierEngine_helper(
                process_, payoff, ex, arguments_);

            results_.value = helper.payoffAtExpiry(spot, variance, riskFreeDiscount);
        }
Пример #12
0
        public double payoffAtExpiry(double spot, double variance, double discount)
        {
            double dividendDiscount = process_.dividendYield().link.discount(exercise_.lastDate());

            Utils.QL_REQUIRE(spot > 0.0, () => "positive spot value required");
            Utils.QL_REQUIRE(discount > 0.0, () => "positive discount required");
            Utils.QL_REQUIRE(dividendDiscount > 0.0, () => "positive dividend discount required");
            Utils.QL_REQUIRE(variance >= 0.0, () => "negative variance not allowed");

            Option.Type type    = payoff_.optionType();
            double      strike  = payoff_.strike();
            double?     barrier = arguments_.barrier;

            Utils.QL_REQUIRE(barrier > 0.0, () => "positive barrier value required");
            Barrier.Type barrierType = arguments_.barrierType;

            double stdDev = Math.Sqrt(variance);
            double mu     = Math.Log(dividendDiscount / discount) / variance - 0.5;
            double K      = 0;

            // binary cash-or-nothing payoff?
            CashOrNothingPayoff coo = payoff_ as CashOrNothingPayoff;

            if (coo != null)
            {
                K = coo.cashPayoff();
            }

            // binary asset-or-nothing payoff?
            AssetOrNothingPayoff aoo = payoff_ as AssetOrNothingPayoff;

            if (aoo != null)
            {
                mu += 1.0;
                K   = spot * dividendDiscount / discount; // forward
            }

            double log_S_X   = Math.Log(spot / strike);
            double log_S_H   = Math.Log(spot / barrier.GetValueOrDefault());
            double log_H_S   = Math.Log(barrier.GetValueOrDefault() / spot);
            double log_H2_SX = Math.Log(barrier.GetValueOrDefault() * barrier.GetValueOrDefault() / (spot * strike));
            double H_S_2mu   = Math.Pow(barrier.GetValueOrDefault() / spot, 2 * mu);

            double eta = (barrierType == Barrier.Type.DownIn ||
                          barrierType == Barrier.Type.DownOut ? 1.0 : -1.0);
            double phi = (type == Option.Type.Call ? 1.0 : -1.0);

            double x1, x2, y1, y2;
            double cum_x1, cum_x2, cum_y1, cum_y2;

            if (variance >= Const.QL_EPSILON)
            {
                // we calculate using mu*stddev instead of (mu+1)*stddev
                // because cash-or-nothing don't need it. asset-or-nothing
                // mu is really mu+1
                x1 = phi * (log_S_X / stdDev + mu * stdDev);
                x2 = phi * (log_S_H / stdDev + mu * stdDev);
                y1 = eta * (log_H2_SX / stdDev + mu * stdDev);
                y2 = eta * (log_H_S / stdDev + mu * stdDev);

                CumulativeNormalDistribution f = new CumulativeNormalDistribution();
                cum_x1 = f.value(x1);
                cum_x2 = f.value(x2);
                cum_y1 = f.value(y1);
                cum_y2 = f.value(y2);
            }
            else
            {
                if (log_S_X > 0)
                {
                    cum_x1 = 1.0;
                }
                else
                {
                    cum_x1 = 0.0;
                }
                if (log_S_H > 0)
                {
                    cum_x2 = 1.0;
                }
                else
                {
                    cum_x2 = 0.0;
                }
                if (log_H2_SX > 0)
                {
                    cum_y1 = 1.0;
                }
                else
                {
                    cum_y1 = 0.0;
                }
                if (log_H_S > 0)
                {
                    cum_y2 = 1.0;
                }
                else
                {
                    cum_y2 = 0.0;
                }
            }

            double alpha = 0;

            switch (barrierType)
            {
            case Barrier.Type.DownIn:
                if (type == Option.Type.Call)
                {
                    // down-in and call
                    if (strike >= barrier)
                    {
                        // B3 (eta=1, phi=1)
                        alpha = H_S_2mu * cum_y1;
                    }
                    else
                    {
                        // B1-B2+B4 (eta=1, phi=1)
                        alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2;
                    }
                }
                else
                {
                    // down-in and put
                    if (strike >= barrier)
                    {
                        // B2-B3+B4 (eta=1, phi=-1)
                        alpha = cum_x2 + H_S_2mu * (-cum_y1 + cum_y2);
                    }
                    else
                    {
                        // B1 (eta=1, phi=-1)
                        alpha = cum_x1;
                    }
                }
                break;

            case Barrier.Type.UpIn:
                if (type == Option.Type.Call)
                {
                    // up-in and call
                    if (strike >= barrier)
                    {
                        // B1 (eta=-1, phi=1)
                        alpha = cum_x1;
                    }
                    else
                    {
                        // B2-B3+B4 (eta=-1, phi=1)
                        alpha = cum_x2 + H_S_2mu * (-cum_y1 + cum_y2);
                    }
                }
                else
                {
                    // up-in and put
                    if (strike >= barrier)
                    {
                        // B1-B2+B4 (eta=-1, phi=-1)
                        alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2;
                    }
                    else
                    {
                        // B3 (eta=-1, phi=-1)
                        alpha = H_S_2mu * cum_y1;
                    }
                }
                break;

            case Barrier.Type.DownOut:
                if (type == Option.Type.Call)
                {
                    // down-out and call
                    if (strike >= barrier)
                    {
                        // B1-B3 (eta=1, phi=1)
                        alpha = cum_x1 - H_S_2mu * cum_y1;
                    }
                    else
                    {
                        // B2-B4 (eta=1, phi=1)
                        alpha = cum_x2 - H_S_2mu * cum_y2;
                    }
                }
                else
                {
                    // down-out and put
                    if (strike >= barrier)
                    {
                        // B1-B2+B3-B4 (eta=1, phi=-1)
                        alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1 - cum_y2);
                    }
                    else
                    {
                        // always 0
                        alpha = 0;
                    }
                }
                break;

            case Barrier.Type.UpOut:
                if (type == Option.Type.Call)
                {
                    // up-out and call
                    if (strike >= barrier)
                    {
                        // always 0
                        alpha = 0;
                    }
                    else
                    {
                        // B1-B2+B3-B4 (eta=-1, phi=1)
                        alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1 - cum_y2);
                    }
                }
                else
                {
                    // up-out and put
                    if (strike >= barrier)
                    {
                        // B2-B4 (eta=-1, phi=-1)
                        alpha = cum_x2 - H_S_2mu * cum_y2;
                    }
                    else
                    {
                        // B1-B3 (eta=-1, phi=-1)
                        alpha = cum_x1 - H_S_2mu * cum_y1;
                    }
                }
                break;

            default:
                Utils.QL_FAIL("invalid barrier type");
                break;
            }

            return(discount * K * alpha);
        }
Пример #13
0
        public override void calculate()
        {
            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            if (payoff == null)
            {
                throw new ApplicationException("non-plain payoff given");
            }
            if (!(payoff.strike() > 0.0))
            {
                throw new ApplicationException("strike must be positive");
            }

            // 추가된 부분.. 2014-07-23
            this.partiRate_ = arguments_.partiRate;

            double strike = payoff.strike();
            double spot   = process_.x0();

            if (!(spot >= 0.0))
            {
                throw new ApplicationException("negative or null underlying given");
            }
            if (triggered(spot))
            {
                throw new ApplicationException("barrier touched");
            }

            Barrier.Type barrierType = arguments_.barrierType;

            switch (payoff.optionType())
            {
            case Option.Type.Call:
                switch (barrierType)
                {
                case Barrier.Type.DownIn:
                    if (strike >= barrier())
                    {
                        results_.value = C(1, 1) + E(1);
                    }
                    else
                    {
                        results_.value = A(1) - B(1) + D(1, 1) + E(1);
                    }
                    break;

                case Barrier.Type.UpIn:
                    if (strike >= barrier())
                    {
                        results_.value = A(1) + E(-1);
                    }
                    else
                    {
                        results_.value = B(1) - C(-1, 1) + D(-1, 1) + E(-1);
                    }
                    break;

                case Barrier.Type.DownOut:
                    if (strike >= barrier())
                    {
                        results_.value = A(1) - C(1, 1) + F(1);
                    }
                    else
                    {
                        results_.value = B(1) - D(1, 1) + F(1);
                    }
                    break;

                case Barrier.Type.UpOut:
                    if (strike >= barrier())
                    {
                        results_.value = F(-1);
                    }
                    else
                    {
                        results_.value = A(1) - B(1) + C(-1, 1) - D(-1, 1) + F(-1);
                    }
                    break;
                }
                break;

            case Option.Type.Put:
                switch (barrierType)
                {
                case Barrier.Type.DownIn:
                    if (strike >= barrier())
                    {
                        results_.value = B(-1) - C(1, -1) + D(1, -1) + E(1);
                    }
                    else
                    {
                        results_.value = A(-1) + E(1);
                    }
                    break;

                case Barrier.Type.UpIn:
                    if (strike >= barrier())
                    {
                        results_.value = A(-1) - B(-1) + D(-1, -1) + E(-1);
                    }
                    else
                    {
                        results_.value = C(-1, -1) + E(-1);
                    }
                    break;

                case Barrier.Type.DownOut:
                    if (strike >= barrier())
                    {
                        results_.value = A(-1) - B(-1) + C(1, -1) - D(1, -1) + F(1);
                    }
                    else
                    {
                        results_.value = F(1);
                    }
                    break;

                case Barrier.Type.UpOut:
                    if (strike >= barrier())
                    {
                        results_.value = B(-1) - D(-1, -1) + F(-1);
                    }
                    else
                    {
                        results_.value = A(-1) - C(-1, -1) + F(-1);
                    }
                    break;
                }
                break;

            default:
                throw new ApplicationException("unknown type");
            }
        }
Пример #14
0
        public override void calculate()
        {
            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");
            Utils.QL_REQUIRE(payoff.strike() > 0.0, () => "strike must be positive");

            double strike = payoff.strike();
            double spot   = process_.x0();

            Utils.QL_REQUIRE(spot >= 0.0, () => "negative or null underlying given");
            Utils.QL_REQUIRE(!triggered(spot), () => "barrier touched");

            Barrier.Type barrierType = arguments_.barrierType;

            switch (payoff.optionType())
            {
            case Option.Type.Call:
                switch (barrierType)
                {
                case Barrier.Type.DownIn:
                    if (strike >= barrier())
                    {
                        results_.value = C(1, 1) + E(1);
                    }
                    else
                    {
                        results_.value = A(1) - B(1) + D(1, 1) + E(1);
                    }
                    break;

                case Barrier.Type.UpIn:
                    if (strike >= barrier())
                    {
                        results_.value = A(1) + E(-1);
                    }
                    else
                    {
                        results_.value = B(1) - C(-1, 1) + D(-1, 1) + E(-1);
                    }
                    break;

                case Barrier.Type.DownOut:
                    if (strike >= barrier())
                    {
                        results_.value = A(1) - C(1, 1) + F(1);
                    }
                    else
                    {
                        results_.value = B(1) - D(1, 1) + F(1);
                    }
                    break;

                case Barrier.Type.UpOut:
                    if (strike >= barrier())
                    {
                        results_.value = F(-1);
                    }
                    else
                    {
                        results_.value = A(1) - B(1) + C(-1, 1) - D(-1, 1) + F(-1);
                    }
                    break;
                }
                break;

            case Option.Type.Put:
                switch (barrierType)
                {
                case Barrier.Type.DownIn:
                    if (strike >= barrier())
                    {
                        results_.value = B(-1) - C(1, -1) + D(1, -1) + E(1);
                    }
                    else
                    {
                        results_.value = A(-1) + E(1);
                    }
                    break;

                case Barrier.Type.UpIn:
                    if (strike >= barrier())
                    {
                        results_.value = A(-1) - B(-1) + D(-1, -1) + E(-1);
                    }
                    else
                    {
                        results_.value = C(-1, -1) + E(-1);
                    }
                    break;

                case Barrier.Type.DownOut:
                    if (strike >= barrier())
                    {
                        results_.value = A(-1) - B(-1) + C(1, -1) - D(1, -1) + F(1);
                    }
                    else
                    {
                        results_.value = F(1);
                    }
                    break;

                case Barrier.Type.UpOut:
                    if (strike >= barrier())
                    {
                        results_.value = B(-1) - D(-1, -1) + F(-1);
                    }
                    else
                    {
                        results_.value = A(-1) - C(-1, -1) + F(-1);
                    }
                    break;
                }
                break;

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