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; }
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); }
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; }
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"); }
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"); }
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); }
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; }
//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"); } }
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); }
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); }
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"); } }
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; } }