/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2003 Ferdinando Ametrano This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email . The license is also available online at . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ #include #include #include namespace QuantLib { void AnalyticEuropeanEngine::calculate() const { QL_REQUIRE(arguments_.exercise->type() == Exercise::European, "not an European option"); boost::shared_ptr payoff = boost::dynamic_pointer_cast(arguments_.payoff); QL_REQUIRE(payoff, "non-striked payoff given"); boost::shared_ptr process = boost::dynamic_pointer_cast( arguments_.stochasticProcess); QL_REQUIRE(process, "Black-Scholes process required"); Real variance = process->blackVolatility()->blackVariance( arguments_.exercise->lastDate(), payoff->strike()); DiscountFactor dividendDiscount = process->dividendYield()->discount(arguments_.exercise->lastDate()); DiscountFactor riskFreeDiscount = process->riskFreeRate()->discount(arguments_.exercise->lastDate()); Real spot = process->stateVariable()->value(); Real forwardPrice = spot * dividendDiscount / riskFreeDiscount; BlackCalculator black(payoff, forwardPrice, std::sqrt(variance), riskFreeDiscount); results_.value = black.value(); results_.delta = black.delta(spot); results_.deltaForward = black.deltaForward(); results_.elasticity = black.elasticity(spot); results_.gamma = black.gamma(spot); DayCounter rfdc = process->riskFreeRate()->dayCounter(); DayCounter divdc = process->dividendYield()->dayCounter(); DayCounter voldc = process->blackVolatility()->dayCounter(); Time t = rfdc.yearFraction(process->riskFreeRate()->referenceDate(), arguments_.exercise->lastDate()); results_.rho = black.rho(t); t = divdc.yearFraction(process->dividendYield()->referenceDate(), arguments_.exercise->lastDate()); results_.dividendRho = black.dividendRho(t); t = voldc.yearFraction(process->blackVolatility()->referenceDate(), arguments_.exercise->lastDate()); results_.vega = black.vega(t); try { results_.theta = black.theta(spot, t); results_.thetaPerDay = black.thetaPerDay(spot, t); } catch (Error&) { results_.theta = Null(); results_.thetaPerDay = Null(); } results_.strikeSensitivity = black.strikeSensitivity(); results_.itmCashProbability = black.itmCashProbability(); } }