double uo_put_ql(const Date& todaysDate_, const Date& settlementDate_, const Date& maturity_, Real spot_, Real strike, Real barrier_, Real rebate_, Spread dividendYield, Rate riskFreeRate, Volatility volatility ) { // set up dates Calendar calendar = TARGET(); Date todaysDate = todaysDate_; Date settlementDate = settlementDate_; Date maturity = maturity_; Settings::instance().evaluationDate() = todaysDate_; DayCounter dc = Actual360(); Real barrier = barrier_; Real rebate = rebate_; Handle <Quote > spot(boost::shared_ptr<SimpleQuote>(new SimpleQuote(spot_))); Handle<YieldTermStructure> qTS(boost::shared_ptr<YieldTermStructure>( new FlatForward(settlementDate, dividendYield, dc))); Handle<YieldTermStructure> rTS(boost::shared_ptr<YieldTermStructure>( new FlatForward(settlementDate, riskFreeRate, dc))); Handle<BlackVolTermStructure> volTS(boost::shared_ptr<BlackVolTermStructure>( new BlackConstantVol(settlementDate, calendar, volatility, dc))); boost::shared_ptr<BlackScholesMertonProcess> stochProcess(new BlackScholesMertonProcess(spot, qTS, rTS, volTS)); boost::shared_ptr<PricingEngine> engine( new AnalyticBarrierEngine(stochProcess)); Option::Type type = Option::Put; boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, strike)); boost::shared_ptr<Exercise> exercise(new EuropeanExercise(maturity)); BarrierOption option( Barrier::UpOut, barrier, rebate, payoff, exercise); option.setPricingEngine(engine); return option.NPV(); }
void AnalyticBSMHullWhiteEngine::calculate() const { QL_REQUIRE(process_->x0() > 0.0, "negative or null underlying given"); const boost::shared_ptr<StrikedTypePayoff> payoff = boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff); QL_REQUIRE(payoff, "non-striked payoff given"); const boost::shared_ptr<Exercise> exercise = arguments_.exercise; Time t = process_->riskFreeRate()->dayCounter().yearFraction( process_->riskFreeRate()->referenceDate(), exercise->lastDate()); const Real a = model_->params()[0]; const Real sigma = model_->params()[1]; const Real eta = process_->blackVolatility()->blackVol(exercise->lastDate(), payoff->strike()); Real varianceOffset; if (a*t > std::pow(QL_EPSILON, 0.25)) { const Real v = sigma*sigma/(a*a) *(t + 2/a*std::exp(-a*t) - 1/(2*a)*std::exp(-2*a*t) - 3/(2*a)); const Real mu = 2*rho_*sigma*eta/a*(t-1/a*(1-std::exp(-a*t))); varianceOffset = v + mu; } else { // low-a algebraic limit const Real v = sigma*sigma*t*t*t*(1/3.0-0.25*a*t+7/60.0*a*a*t*t); const Real mu = rho_*sigma*eta*t*t*(1-a*t/3.0+a*a*t*t/12.0); varianceOffset = v + mu; } Handle<BlackVolTermStructure> volTS( boost::shared_ptr<BlackVolTermStructure>( new ShiftedBlackVolTermStructure(varianceOffset, process_->blackVolatility()))); boost::shared_ptr<GeneralizedBlackScholesProcess> adjProcess( new GeneralizedBlackScholesProcess(process_->stateVariable(), process_->dividendYield(), process_->riskFreeRate(), volTS)); boost::shared_ptr<AnalyticEuropeanEngine> bsmEngine( new AnalyticEuropeanEngine(adjProcess)); VanillaOption(payoff, exercise).setupArguments( bsmEngine->getArguments()); bsmEngine->calculate(); results_ = *dynamic_cast<const OneAssetOption::results*>( bsmEngine->getResults()); }