/* Copyright (C) 2003 Niels Elken Sønderby Copyright (C) 2003 Ferdinando Ametrano Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl 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 ferdinando@ametrano.net The license is also available online at http://quantlib.org/html/license.html 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. */ /* NesQuant is an extension to QuantLib http://www.nielses.dk/quantlib/nesquant */ /*! \file mcsvjdengine.hpp \brief SVJD pricing engine using Monte Carlo \fullpath nq/PricingEngines/%mcsvjdengine.cpp */ #ifndef nesquant_mcsvjd_engine_h #define nesquant_mcsvjd_engine_h #include #include #include #include #include #include #include #include using namespace QuantLib; using namespace QuantLib::PricingEngines; using namespace QuantLib::MonteCarlo; using namespace QuantLib::TermStructures; using namespace QuantLib::Calendars; using namespace QuantLib::DayCounters; using QuantLib::Math::Statistics; using NesQuant::SVJDArguments; namespace NesQuant { template class MCSVJDEngine : public GenericEngine, public McSimulation, S> { public: void calculate() const; typedef typename McSimulation,S>::path_generator_type path_generator_type; typedef typename McSimulation,S>::path_pricer_type path_pricer_type; typedef typename McSimulation,S>::stats_type stats_type; // constructor MCSVJDEngine(Size maxTimeStepsPerYear, bool antitheticVariate = false, bool controlVariate = false, Size requiredSamples = Null(), double requiredTolerance = Null(), Size maxSamples = Null(), long seed = 0); // McSimulation implementation Handle pathGenerator() const; Handle pathPricer() const; TimeGrid timeGrid() const; // data members Size maxTimeStepsPerYear_; Size requiredSamples_, maxSamples_; double requiredTolerance_; long seed_; }; // inline definitions template inline MCSVJDEngine::MCSVJDEngine(Size maxTimeStepsPerYear, bool antitheticVariate, bool controlVariate, Size requiredSamples, double requiredTolerance, Size maxSamples, long seed) : McSimulation,S>(antitheticVariate, false), maxTimeStepsPerYear_(maxTimeStepsPerYear), requiredSamples_(requiredSamples), maxSamples_(maxSamples), requiredTolerance_(requiredTolerance), seed_(seed) { QL_REQUIRE(!controlVariate, "MCSVJDEngine: controlVariate not supported"); } // template definitions template inline Handle::path_generator_type> MCSVJDEngine::pathGenerator() const { TimeGrid grid = timeGrid(); typename RNG::rsg_type gen = RNG::make_sequence_generator(grid.size(), seed_); Time length = arguments_.maturity; Size timeSteps = grid.size(); return Handle (new GaussianSVJDPathGenerator( arguments_.riskFreeRate, arguments_.dividendYield, arguments_.volatility, arguments_.volatilityOfVolatility, arguments_.steadyStateVolatility, arguments_.meanReversionRate, arguments_.correlationUnderlyingVolatility, arguments_.jumpIntensity, arguments_.jumpMean, arguments_.jumpStandardDeviation, length, timeSteps, gen)); } template inline void MCSVJDEngine::calculate() const { QL_REQUIRE(requiredTolerance_ != Null() || int(requiredSamples_) != Null(), "MCSVJDEngine::calculate: " "neither tolerance nor number of samples set"); //! Initialize the one-factor Monte Carlo mcModel_ = Handle, S> >( new MonteCarloModel< SingleAsset, S>( pathGenerator(), pathPricer(), S(), antitheticVariate_)); if (requiredTolerance_ != Null()) { if (int(maxSamples_) != Null()) value(requiredTolerance_, maxSamples_); else value(requiredTolerance_); } else { valueWithSamples(requiredSamples_); } results_.value = mcModel_->sampleAccumulator().mean(); if (RNG::allowsErrorEstimate) results_.errorEstimate = mcModel_->sampleAccumulator().errorEstimate(); } template inline Handle::path_pricer_type> MCSVJDEngine::pathPricer() const { RelinkableHandle ts(Handle (new FlatForward(Date::todaysDate(), TARGET().advance(Date::todaysDate(), 2, Days), arguments_.riskFreeRate, Actual365()))); return Handle::path_pricer_type>( new EuropeanPathPricer(arguments_.type, arguments_.underlying, arguments_.strike, ts)); } template inline TimeGrid MCSVJDEngine::timeGrid() const { return TimeGrid(arguments_.maturity, Size(arguments_.maturity * maxTimeStepsPerYear_)); } } #endif