quantoengine.hpp
来自「有很多的函数库」· HPP 代码 · 共 200 行
HPP
200 行
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
Copyright (C) 2002, 2003, 2004 Ferdinando Ametrano
Copyright (C) 2007 StatPro Italia 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
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.
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.
*/
/*! \file quantoengine.hpp
\brief Quanto option engine
*/
#ifndef quantlib_quanto_engine_hpp
#define quantlib_quanto_engine_hpp
#include <ql/pricingengine.hpp>
#include <ql/processes/blackscholesprocess.hpp>
#include <ql/termstructures/yieldcurves/quantotermstructure.hpp>
#include <ql/instruments/payoffs.hpp>
namespace QuantLib {
//! %Arguments for quanto option calculation
template<class ArgumentsType>
class QuantoOptionArguments : public ArgumentsType {
public:
QuantoOptionArguments() : correlation(Null<Real>()) {}
void validate() const;
Real correlation;
Handle<YieldTermStructure> foreignRiskFreeTS;
Handle<BlackVolTermStructure> exchRateVolTS;
};
//! %Results from quanto option calculation
template<class ResultsType>
class QuantoOptionResults : public ResultsType {
public:
QuantoOptionResults() { reset() ;}
void reset() {
ResultsType::reset();
qvega = qrho = qlambda = Null<Real>();
}
Real qvega;
Real qrho;
Real qlambda;
};
//! Quanto engine base class
/*! \warning for the time being, this engine will only work with
simple Black-Scholes processes (i.e., no Merton.)
\ingroup quantoengines
\test
- the correctness of the returned value is tested by
reproducing results available in literature.
- the correctness of the returned greeks is tested by
reproducing numerical derivatives.
*/
template <class ArgumentsType, class ResultsType>
class QuantoEngine
: public GenericEngine<QuantoOptionArguments<ArgumentsType>,
QuantoOptionResults<ResultsType> > {
public:
QuantoEngine(const boost::shared_ptr<GenericEngine<ArgumentsType,
ResultsType> >&);
void calculate() const;
/*! Access to the arguments of the underlying engine is needed as
this engine is not able to set them completely. When necessary,
it must be done by the instrument: see QuantoForwardVanillaOption
for an example.
*/
ArgumentsType* underlyingArgs() const { return originalArguments_; }
protected:
boost::shared_ptr<GenericEngine<ArgumentsType,
ResultsType> > originalEngine_;
ArgumentsType* originalArguments_;
const ResultsType* originalResults_;
};
// template definitions
template <class ArgumentsType>
void QuantoOptionArguments<ArgumentsType>::validate() const {
ArgumentsType::validate();
QL_REQUIRE(!foreignRiskFreeTS.empty(),
"null foreign risk free term structure");
QL_REQUIRE(!exchRateVolTS.empty(),
"null exchange rate vol term structure");
QL_REQUIRE(correlation != Null<Real>(),
"null correlation given");
}
template<class ArgumentsType, class ResultsType>
QuantoEngine<ArgumentsType, ResultsType>::QuantoEngine(
const boost::shared_ptr<GenericEngine<ArgumentsType, ResultsType> >&
originalEngine)
: originalEngine_(originalEngine) {
QL_REQUIRE(originalEngine_, "null engine");
originalResults_ =
dynamic_cast<const ResultsType*>(originalEngine_->getResults());
originalArguments_ =
dynamic_cast<ArgumentsType*>(originalEngine_->getArguments());
}
template<class ArgumentsType, class ResultsType>
void QuantoEngine<ArgumentsType, ResultsType>::calculate() const {
// ATM exchangeRate level needed here
Real exchangeRateATMlevel = 1.0;
originalEngine_->reset();
// determine strike from payoff
boost::shared_ptr<StrikedTypePayoff> payoff =
boost::dynamic_pointer_cast<StrikedTypePayoff>(
this->arguments_.payoff);
QL_REQUIRE(payoff, "non-striked payoff given");
Real strike = payoff->strike();
originalArguments_->payoff = this->arguments_.payoff;
boost::shared_ptr<GeneralizedBlackScholesProcess> process =
boost::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
this->arguments_.stochasticProcess);
QL_REQUIRE(process, "Black-Scholes process required");
Handle<Quote> spot = process->stateVariable();
Handle<YieldTermStructure> riskFreeRate = process->riskFreeRate();
// dividendTS needs modification
Handle<YieldTermStructure> dividendYield(
boost::shared_ptr<YieldTermStructure>(
new QuantoTermStructure(process->dividendYield(),
process->riskFreeRate(),
this->arguments_.foreignRiskFreeTS,
process->blackVolatility(),
strike,
this->arguments_.exchRateVolTS,
exchangeRateATMlevel,
this->arguments_.correlation)));
Handle<BlackVolTermStructure> blackVol = process->blackVolatility();
originalArguments_->stochasticProcess =
boost::shared_ptr<StochasticProcess>(
new GeneralizedBlackScholesProcess(spot, dividendYield,
riskFreeRate, blackVol));
originalArguments_->exercise = this->arguments_.exercise;
originalArguments_->validate();
originalEngine_->calculate();
this->results_.value = originalResults_->value;
this->results_.delta = originalResults_->delta;
this->results_.gamma = originalResults_->gamma;
this->results_.theta = originalResults_->theta;
this->results_.rho = originalResults_->rho +
originalResults_->dividendRho;
this->results_.dividendRho = originalResults_->dividendRho;
Volatility exchangeRateFlatVol =
this->arguments_.exchRateVolTS->blackVol(
this->arguments_.exercise->lastDate(),
exchangeRateATMlevel);
this->results_.vega = originalResults_->vega +
this->arguments_.correlation * exchangeRateFlatVol *
originalResults_->dividendRho;
Volatility volatility = process->blackVolatility()->blackVol(
this->arguments_.exercise->lastDate(),
process->stateVariable()->value());
this->results_.qvega = this->arguments_.correlation *
process->blackVolatility()->blackVol(
this->arguments_.exercise->lastDate(),
process->stateVariable()->value()) *
originalResults_->dividendRho;
this->results_.qrho = - originalResults_->dividendRho;
this->results_.qlambda = exchangeRateFlatVol *
volatility * originalResults_->dividendRho;
}
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?