public override void calculate() { Utils.QL_REQUIRE(process_.x0() > 0.0, () => "negative or null underlying given"); StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given"); Exercise exercise = arguments_.exercise; double t = process_.riskFreeRate().link.dayCounter().yearFraction(process_.riskFreeRate().link.referenceDate(), exercise.lastDate()); double a = model_.link.parameters()[0]; double sigma = model_.link.parameters()[1]; double eta = process_.blackVolatility().link.blackVol(exercise.lastDate(), payoff.strike()); double varianceOffset; if (a * t > Math.Pow(Const.QL_EPSILON, 0.25)) { double v = sigma * sigma / (a * a) * (t + 2 / a * Math.Exp(-a * t) - 1 / (2 * a) * Math.Exp(-2 * a * t) - 3 / (2 * a)); double mu = 2 * rho_ * sigma * eta / a * (t - 1 / a * (1 - Math.Exp(-a * t))); varianceOffset = v + mu; } else { // low-a algebraic limit double v = sigma * sigma * t * t * t * (1 / 3.0 - 0.25 * a * t + 7 / 60.0 * a * a * t * t); double mu = rho_ * sigma * eta * t * t * (1 - a * t / 3.0 + a * a * t * t / 12.0); varianceOffset = v + mu; } Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>( new ShiftedBlackVolTermStructure(varianceOffset, process_.blackVolatility())); GeneralizedBlackScholesProcess adjProcess = new GeneralizedBlackScholesProcess(process_.stateVariable(), process_.dividendYield(), process_.riskFreeRate(), volTS); AnalyticEuropeanEngine bsmEngine = new AnalyticEuropeanEngine(adjProcess); VanillaOption option = new VanillaOption(payoff, exercise); option.setupArguments(bsmEngine.getArguments()); bsmEngine.calculate(); results_ = bsmEngine.getResults() as OneAssetOption.Results; }
protected override void performCalculations() { exerciseDate_ = calendar_.advance(termStructure_.link.referenceDate(), maturity_); tau_ = termStructure_.link.timeFromReference(exerciseDate_); type_ = strikePrice_ * termStructure_.link.discount(tau_) >= s0_.link.value() * dividendYield_.link.discount(tau_) ? Option.Type.Call : Option.Type.Put; StrikedTypePayoff payoff = new PlainVanillaPayoff(type_, strikePrice_); Exercise exercise = new EuropeanExercise(exerciseDate_); option_ = new VanillaOption(payoff, exercise); base.performCalculations(); }
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); }