From bd88e67f4e37eb1aa34fc5cf500b4a27eb76958f Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Thu, 24 Aug 2023 16:19:26 +0200 Subject: [PATCH 1/4] Move Margrabe option from experimental to core --- QuantLib.vcxproj | 10 ++- QuantLib.vcxproj.filters | 33 +++++-- cmake/GenerateHeaders.cmake | 7 ++ configure.ac | 1 + ql/CMakeLists.txt | 10 ++- ql/experimental/exoticoptions/Makefile.am | 8 +- ql/experimental/exoticoptions/all.hpp | 3 - .../analyticamericanmargrabeengine.hpp | 39 +------- .../analyticeuropeanmargrabeengine.hpp | 39 +------- .../exoticoptions/margrabeoption.hpp | 80 +---------------- ql/instruments/Makefile.am | 2 + ql/instruments/all.hpp | 1 + .../margrabeoption.cpp | 4 +- ql/instruments/margrabeoption.hpp | 90 +++++++++++++++++++ ql/pricingengines/Makefile.am | 3 +- ql/pricingengines/all.hpp | 1 + ql/pricingengines/exotic/Makefile.am | 47 ++++++++++ ql/pricingengines/exotic/all.hpp | 6 ++ .../analyticamericanmargrabeengine.cpp | 2 +- .../exotic/analyticamericanmargrabeengine.hpp | 56 ++++++++++++ .../analyticeuropeanmargrabeengine.cpp | 2 +- .../exotic/analyticeuropeanmargrabeengine.hpp | 56 ++++++++++++ test-suite/margrabeoption.cpp | 6 +- test-suite/quantlibtestsuite.cpp | 2 +- 24 files changed, 327 insertions(+), 181 deletions(-) rename ql/{experimental/exoticoptions => instruments}/margrabeoption.cpp (97%) create mode 100644 ql/instruments/margrabeoption.hpp create mode 100644 ql/pricingengines/exotic/Makefile.am create mode 100644 ql/pricingengines/exotic/all.hpp rename ql/{experimental/exoticoptions => pricingengines/exotic}/analyticamericanmargrabeengine.cpp (98%) create mode 100644 ql/pricingengines/exotic/analyticamericanmargrabeengine.hpp rename ql/{experimental/exoticoptions => pricingengines/exotic}/analyticeuropeanmargrabeengine.cpp (98%) create mode 100644 ql/pricingengines/exotic/analyticeuropeanmargrabeengine.hpp diff --git a/QuantLib.vcxproj b/QuantLib.vcxproj index b2a2293dd9c..2000809f276 100644 --- a/QuantLib.vcxproj +++ b/QuantLib.vcxproj @@ -937,6 +937,7 @@ + @@ -1526,6 +1527,9 @@ + + + @@ -2013,10 +2017,8 @@ - - @@ -2032,7 +2034,6 @@ - @@ -2196,6 +2197,7 @@ + @@ -2583,6 +2585,8 @@ + + diff --git a/QuantLib.vcxproj.filters b/QuantLib.vcxproj.filters index ca2d75b3d24..61a5ef7cafa 100644 --- a/QuantLib.vcxproj.filters +++ b/QuantLib.vcxproj.filters @@ -187,6 +187,9 @@ {4b67a796-2576-42be-89cc-b751a07e3973} + + {50c1f3c8-4281-11ee-be56-0242ac120002} + {25671919-a7a3-4197-943c-23a5df4e8146} @@ -858,6 +861,9 @@ instruments + + instruments + instruments @@ -2418,6 +2424,15 @@ pricingengines\basket + + pricingengines\exotic + + + pricingengines\exotic + + + pricingengines\exotic + pricingengines\forward @@ -4712,6 +4727,9 @@ instruments + + instruments + instruments @@ -5813,6 +5831,12 @@ pricingengines\cliquet + + pricingengines\exotic + + + pricingengines\exotic + pricingengines\lookback @@ -6212,15 +6236,9 @@ experimental\fx - - experimental\exoticoptions - experimental\exoticoptions - - experimental\exoticoptions - experimental\exoticoptions @@ -6263,9 +6281,6 @@ experimental\exoticoptions - - experimental\exoticoptions - experimental\exoticoptions diff --git a/cmake/GenerateHeaders.cmake b/cmake/GenerateHeaders.cmake index b87ebb20d8e..acc2171577f 100644 --- a/cmake/GenerateHeaders.cmake +++ b/cmake/GenerateHeaders.cmake @@ -49,6 +49,13 @@ function(generate_dir_headers source_dir binary_dir) list(FILTER children_hpp EXCLUDE REGEX "amortizingcmsratebond.hpp") endif () + # Same for some headers in experimental/exoticoptions + if (${source_dir} MATCHES "experimental" AND ${source_dir} MATCHES "exoticoptions") + list(FILTER children_hpp EXCLUDE REGEX "margrabeoption.hpp") + list(FILTER children_hpp EXCLUDE REGEX "analyticamericanmargrabeengine.hpp") + list(FILTER children_hpp EXCLUDE REGEX "analyticeuropeanmargrabeengine.hpp") + endif () + list(FILTER children_hpp EXCLUDE REGEX "riskybond.hpp") list(FILTER children_hpp EXCLUDE REGEX "composite.hpp") list(FILTER children_hpp EXCLUDE REGEX "lexicographicalview.hpp") diff --git a/configure.ac b/configure.ac index 6b6bbd8d3d9..5a8130ab663 100644 --- a/configure.ac +++ b/configure.ac @@ -615,6 +615,7 @@ AC_CONFIG_FILES([ ql/pricingengines/capfloor/Makefile ql/pricingengines/cliquet/Makefile ql/pricingengines/credit/Makefile + ql/pricingengines/exotic/Makefile ql/pricingengines/forward/Makefile ql/pricingengines/inflation/Makefile ql/pricingengines/lookback/Makefile diff --git a/ql/CMakeLists.txt b/ql/CMakeLists.txt index e7b7d4ebb52..886edaaeed8 100644 --- a/ql/CMakeLists.txt +++ b/ql/CMakeLists.txt @@ -123,10 +123,8 @@ set(QL_SOURCES experimental/credit/riskyassetswap.cpp experimental/credit/riskyassetswapoption.cpp experimental/credit/syntheticcdo.cpp - experimental/exoticoptions/analyticamericanmargrabeengine.cpp experimental/exoticoptions/analyticcomplexchooserengine.cpp experimental/exoticoptions/analyticcompoundoptionengine.cpp - experimental/exoticoptions/analyticeuropeanmargrabeengine.cpp experimental/exoticoptions/analyticholderextensibleoptionengine.cpp experimental/exoticoptions/analyticpartialtimebarrieroptionengine.cpp experimental/exoticoptions/analyticpdfhestonengine.cpp @@ -142,7 +140,6 @@ set(QL_SOURCES experimental/exoticoptions/himalayaoption.cpp experimental/exoticoptions/holderextensibleoption.cpp experimental/exoticoptions/kirkspreadoptionengine.cpp - experimental/exoticoptions/margrabeoption.cpp experimental/exoticoptions/mceverestengine.cpp experimental/exoticoptions/mchimalayaengine.cpp experimental/exoticoptions/mcpagodaengine.cpp @@ -308,6 +305,7 @@ set(QL_SOURCES instruments/makeswaption.cpp instruments/makevanillaswap.cpp instruments/makeyoyinflationcapfloor.cpp + instruments/margrabeoption.cpp instruments/multiassetoption.cpp instruments/nonstandardswap.cpp instruments/nonstandardswaption.cpp @@ -700,6 +698,8 @@ set(QL_SOURCES pricingengines/credit/integralcdsengine.cpp pricingengines/credit/isdacdsengine.cpp pricingengines/credit/midpointcdsengine.cpp + pricingengines/exotic/analyticamericanmargrabeengine.cpp + pricingengines/exotic/analyticeuropeanmargrabeengine.cpp pricingengines/forward/mcforwardeuropeanbsengine.cpp pricingengines/forward/mcforwardeuropeanhestonengine.cpp pricingengines/greeks.cpp @@ -1352,6 +1352,7 @@ set(QL_HEADERS instruments/makeswaption.hpp instruments/makevanillaswap.hpp instruments/makeyoyinflationcapfloor.hpp + instruments/margrabeoption.hpp instruments/multiassetoption.hpp instruments/nonstandardswap.hpp instruments/nonstandardswaption.hpp @@ -1898,6 +1899,8 @@ set(QL_HEADERS pricingengines/credit/integralcdsengine.hpp pricingengines/credit/isdacdsengine.hpp pricingengines/credit/midpointcdsengine.hpp + pricingengines/exotic/analyticamericanmargrabeengine.hpp + pricingengines/exotic/analyticeuropeanmargrabeengine.hpp pricingengines/forward/forwardengine.hpp pricingengines/forward/forwardperformanceengine.hpp pricingengines/forward/mcforwardeuropeanbsengine.hpp @@ -2308,6 +2311,7 @@ set(QL_GENERATED_HEADERS ${PROJECT_BINARY_DIR}/ql/pricingengines/capfloor/all.hpp ${PROJECT_BINARY_DIR}/ql/pricingengines/cliquet/all.hpp ${PROJECT_BINARY_DIR}/ql/pricingengines/credit/all.hpp + ${PROJECT_BINARY_DIR}/ql/pricingengines/exotic/all.hpp ${PROJECT_BINARY_DIR}/ql/pricingengines/forward/all.hpp ${PROJECT_BINARY_DIR}/ql/pricingengines/inflation/all.hpp ${PROJECT_BINARY_DIR}/ql/pricingengines/lookback/all.hpp diff --git a/ql/experimental/exoticoptions/Makefile.am b/ql/experimental/exoticoptions/Makefile.am index 30e86410e52..a42be6d0098 100644 --- a/ql/experimental/exoticoptions/Makefile.am +++ b/ql/experimental/exoticoptions/Makefile.am @@ -36,10 +36,8 @@ this_include_HEADERS = \ writerextensibleoption.hpp cpp_files = \ - analyticamericanmargrabeengine.cpp \ analyticcomplexchooserengine.cpp \ analyticcompoundoptionengine.cpp \ - analyticeuropeanmargrabeengine.cpp \ analyticholderextensibleoptionengine.cpp \ analyticpartialtimebarrieroptionengine.cpp \ analyticpdfhestonengine.cpp \ @@ -55,7 +53,6 @@ cpp_files = \ himalayaoption.cpp \ holderextensibleoption.cpp \ kirkspreadoptionengine.cpp \ - margrabeoption.cpp \ mceverestengine.cpp \ mchimalayaengine.cpp \ mcpagodaengine.cpp \ @@ -92,7 +89,10 @@ all.hpp: Makefile.am echo "/* This file is automatically generated; do not edit. */" > ${srcdir}/$@ echo "/* Add the files to be included into Makefile.am instead. */" >> ${srcdir}/$@ echo >> ${srcdir}/$@ - for i in $(filter-out all.hpp, $(this_include_HEADERS)); do \ + for i in $(filter-out all.hpp \ + margrabeoption.hpp \ + analyticamericanmargrabeengine.hpp \ + analyticeuropeanmargrabeengine.hpp, $(this_include_HEADERS)); do \ echo "#include <${subdir}/$$i>" >> ${srcdir}/$@; \ done echo >> ${srcdir}/$@ diff --git a/ql/experimental/exoticoptions/all.hpp b/ql/experimental/exoticoptions/all.hpp index e60b5fbeb49..b42058d3318 100644 --- a/ql/experimental/exoticoptions/all.hpp +++ b/ql/experimental/exoticoptions/all.hpp @@ -1,10 +1,8 @@ /* This file is automatically generated; do not edit. */ /* Add the files to be included into Makefile.am instead. */ -#include #include #include -#include #include #include #include @@ -20,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/ql/experimental/exoticoptions/analyticamericanmargrabeengine.hpp b/ql/experimental/exoticoptions/analyticamericanmargrabeengine.hpp index 3cbefe76a2b..c8658a2c819 100644 --- a/ql/experimental/exoticoptions/analyticamericanmargrabeengine.hpp +++ b/ql/experimental/exoticoptions/analyticamericanmargrabeengine.hpp @@ -17,40 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file analyticamericanmargrabeengine.hpp - \brief Analytic engine for American Margrabe option -*/ - -#ifndef quantlib_analytic_american_margrabe_engine_hpp -#define quantlib_analytic_american_margrabe_engine_hpp - -#include -#include - -namespace QuantLib { - - //! Analytic engine for American Margrabe option - /*! This class implements formulae from - "The Value of an American Option to Exchange One Asset for Another", - W. Margrabe, - Journal of Finance, 33, 177-86. - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - class AnalyticAmericanMargrabeEngine : public MargrabeOption::engine { - public: - AnalyticAmericanMargrabeEngine(ext::shared_ptr process1, - ext::shared_ptr process2, - Real correlation); - void calculate() const override; - - private: - ext::shared_ptr process1_; - ext::shared_ptr process2_; - Real rho_; - }; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.hpp b/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.hpp index 6ef8611fc99..77b1b9f02ce 100644 --- a/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.hpp +++ b/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.hpp @@ -17,40 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file analyticeuropeanmargrabeengine.hpp - \brief Analytic engine for European Margrabe option -*/ - -#ifndef quantlib_analytic_european_margrabe_engine_hpp -#define quantlib_analytic_european_margrabe_engine_hpp - -#include -#include - -namespace QuantLib { - - //! Analytic engine for European Margrabe option - /*! This class implements formulae from - "The Value of an Option to Exchange One Asset for Another", - W. Margrabe, - Journal of Finance, 33 (March 1978), 177-186. - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - class AnalyticEuropeanMargrabeEngine : public MargrabeOption::engine { - public: - AnalyticEuropeanMargrabeEngine(ext::shared_ptr process1, - ext::shared_ptr process2, - Real correlation); - void calculate() const override; - - private: - ext::shared_ptr process1_; - ext::shared_ptr process2_; - Real rho_; - }; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/margrabeoption.hpp b/ql/experimental/exoticoptions/margrabeoption.hpp index 33a903c0d10..4f758cb247c 100644 --- a/ql/experimental/exoticoptions/margrabeoption.hpp +++ b/ql/experimental/exoticoptions/margrabeoption.hpp @@ -17,81 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file margrabeoption.hpp - \brief Margrabe option on two assets -*/ - -#ifndef quantlib_margrabe_option_hpp -#define quantlib_margrabe_option_hpp - -#include - -namespace QuantLib { - - //! Margrabe option on two assets - /*! This option gives the holder the right to exchange Q2 stocks - of the second asset for Q1 stocks of the first at expiration. - - \ingroup instruments - */ - class MargrabeOption : public MultiAssetOption { - public: - class arguments; - class results; - class engine; - MargrabeOption(Integer Q1, - Integer Q2, - const ext::shared_ptr&); - void setupArguments(PricingEngine::arguments*) const override; - Real delta1() const; - Real delta2() const; - Real gamma1() const; - Real gamma2() const; - void fetchResults(const PricingEngine::results*) const override; - - protected: - Integer Q1_; - Integer Q2_; - mutable Real delta1_, delta2_, gamma1_, gamma2_; - }; - - //! Extra %arguments for Margrabe option - class MargrabeOption::arguments - : public MultiAssetOption::arguments { - public: - arguments() : Q1(Null()), - Q2(Null()) {} - void validate() const override; - Integer Q1; - Integer Q2; - }; - - //! Extra %results for Margrabe option - class MargrabeOption::results - : public MultiAssetOption::results { - public: - results() : delta1(Null()), - delta2(Null()), - gamma1(Null()), - gamma2(Null()) {} - Real delta1; - Real delta2; - Real gamma1; - Real gamma2; - void reset() override { - MultiAssetOption::results::reset(); - delta1 = Null(); - delta2 = Null(); - gamma1 = Null(); - gamma2 = Null(); - } - }; - - //! %Margrabe option %engine base class - class MargrabeOption::engine - : public GenericEngine {}; -} - +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/instruments/Makefile.am b/ql/instruments/Makefile.am index 5f0340e31f7..e2d45d44c17 100644 --- a/ql/instruments/Makefile.am +++ b/ql/instruments/Makefile.am @@ -47,6 +47,7 @@ this_include_HEADERS = \ makeswaption.hpp \ makevanillaswap.hpp \ makeyoyinflationcapfloor.hpp \ + margrabeoption.hpp \ multiassetoption.hpp \ nonstandardswap.hpp \ nonstandardswaption.hpp \ @@ -110,6 +111,7 @@ cpp_files = \ makeswaption.cpp \ makevanillaswap.cpp \ makeyoyinflationcapfloor.cpp \ + margrabeoption.cpp \ multiassetoption.cpp \ nonstandardswap.cpp \ nonstandardswaption.cpp \ diff --git a/ql/instruments/all.hpp b/ql/instruments/all.hpp index 69542fa7264..83567ebc816 100644 --- a/ql/instruments/all.hpp +++ b/ql/instruments/all.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/ql/experimental/exoticoptions/margrabeoption.cpp b/ql/instruments/margrabeoption.cpp similarity index 97% rename from ql/experimental/exoticoptions/margrabeoption.cpp rename to ql/instruments/margrabeoption.cpp index 174ae358545..80a269c477b 100644 --- a/ql/experimental/exoticoptions/margrabeoption.cpp +++ b/ql/instruments/margrabeoption.cpp @@ -17,7 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -#include +#include #include namespace QuantLib { @@ -54,7 +54,6 @@ namespace QuantLib { } void MargrabeOption::setupArguments(PricingEngine::arguments* args) const { - MultiAssetOption::setupArguments(args); auto* moreArgs = dynamic_cast(args); @@ -65,7 +64,6 @@ namespace QuantLib { } void MargrabeOption::arguments::validate() const { - MultiAssetOption::arguments::validate(); QL_REQUIRE(Q1 != Null(), "unspecified quantity for asset 1"); diff --git a/ql/instruments/margrabeoption.hpp b/ql/instruments/margrabeoption.hpp new file mode 100644 index 00000000000..27152c5a6ea --- /dev/null +++ b/ql/instruments/margrabeoption.hpp @@ -0,0 +1,90 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file margrabeoption.hpp + \brief Margrabe option on two assets +*/ + +#ifndef quantlib_margrabe_option_hpp +#define quantlib_margrabe_option_hpp + +#include + +namespace QuantLib { + + //! Margrabe option on two assets + /*! This option gives the holder the right to exchange Q2 stocks + of the second asset for Q1 stocks of the first at expiration. + + \ingroup instruments + */ + class MargrabeOption : public MultiAssetOption { + public: + class arguments; + class results; + class engine; + MargrabeOption(Integer Q1, + Integer Q2, + const ext::shared_ptr&); + void setupArguments(PricingEngine::arguments*) const override; + Real delta1() const; + Real delta2() const; + Real gamma1() const; + Real gamma2() const; + void fetchResults(const PricingEngine::results*) const override; + + protected: + Integer Q1_; + Integer Q2_; + mutable Real delta1_, delta2_, gamma1_, gamma2_; + }; + + //! Extra %arguments for Margrabe option + class MargrabeOption::arguments : public MultiAssetOption::arguments { + public: + arguments() = default; + void validate() const override; + Integer Q1 = Null(); + Integer Q2 = Null(); + }; + + //! Extra %results for Margrabe option + class MargrabeOption::results : public MultiAssetOption::results { + public: + results() = default; + Real delta1 = Null(); + Real delta2 = Null(); + Real gamma1 = Null(); + Real gamma2 = Null(); + void reset() override { + MultiAssetOption::results::reset(); + delta1 = Null(); + delta2 = Null(); + gamma1 = Null(); + gamma2 = Null(); + } + }; + + //! %Margrabe option %engine base class + class MargrabeOption::engine : public GenericEngine {}; +} + + +#endif diff --git a/ql/pricingengines/Makefile.am b/ql/pricingengines/Makefile.am index 4223c7c7329..8032668b00e 100644 --- a/ql/pricingengines/Makefile.am +++ b/ql/pricingengines/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS = asian barrier basket bond capfloor cliquet credit \ +SUBDIRS = asian barrier basket bond capfloor cliquet credit exotic \ forward inflation lookback quanto swap swaption vanilla AM_CPPFLAGS = -I${top_builddir} -I${top_srcdir} @@ -56,6 +56,7 @@ libPricingEngines_la_LIBADD = \ capfloor/libCapFloorEngines.la \ cliquet/libCliquetEngines.la \ credit/libCreditEngines.la \ + exotic/libExoticEngines.la \ forward/libForwardEngines.la \ inflation/libInflationEngines.la \ lookback/libLookbackEngines.la \ diff --git a/ql/pricingengines/all.hpp b/ql/pricingengines/all.hpp index 1957b59509e..bcf05ac19c6 100644 --- a/ql/pricingengines/all.hpp +++ b/ql/pricingengines/all.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/ql/pricingengines/exotic/Makefile.am b/ql/pricingengines/exotic/Makefile.am new file mode 100644 index 00000000000..b3a4a56389a --- /dev/null +++ b/ql/pricingengines/exotic/Makefile.am @@ -0,0 +1,47 @@ + +AM_CPPFLAGS = -I${top_builddir} -I${top_srcdir} + +this_includedir=${includedir}/${subdir} +this_include_HEADERS = \ + all.hpp \ + analyticamericanmargrabeengine.hpp \ + analyticeuropeanmargrabeengine.hpp + +cpp_files = \ + analyticamericanmargrabeengine.cpp \ + analyticeuropeanmargrabeengine.cpp + +if UNITY_BUILD + +nodist_libExoticEngines_la_SOURCES = unity.cpp + +unity.cpp: Makefile.am + echo "/* This file is automatically generated; do not edit. */" > $@ + echo "/* Add the files to be included into Makefile.am instead. */" >> $@ + echo >> $@ + for i in $(cpp_files); do \ + echo "#include \"${subdir}/$$i\"" >> $@; \ + done + +EXTRA_DIST = $(cpp_files) + +else + +libExoticEngines_la_SOURCES = $(cpp_files) + +endif + +noinst_LTLIBRARIES = libExoticEngines.la + +all.hpp: Makefile.am + echo "/* This file is automatically generated; do not edit. */" > ${srcdir}/$@ + echo "/* Add the files to be included into Makefile.am instead. */" >> ${srcdir}/$@ + echo >> ${srcdir}/$@ + for i in $(filter-out all.hpp, $(this_include_HEADERS)); do \ + echo "#include <${subdir}/$$i>" >> ${srcdir}/$@; \ + done + echo >> ${srcdir}/$@ + subdirs='$(SUBDIRS)'; for i in $$subdirs; do \ + echo "#include <${subdir}/$$i/all.hpp>" >> ${srcdir}/$@; \ + done + diff --git a/ql/pricingengines/exotic/all.hpp b/ql/pricingengines/exotic/all.hpp new file mode 100644 index 00000000000..d479fab5b4b --- /dev/null +++ b/ql/pricingengines/exotic/all.hpp @@ -0,0 +1,6 @@ +/* This file is automatically generated; do not edit. */ +/* Add the files to be included into Makefile.am instead. */ + +#include +#include + diff --git a/ql/experimental/exoticoptions/analyticamericanmargrabeengine.cpp b/ql/pricingengines/exotic/analyticamericanmargrabeengine.cpp similarity index 98% rename from ql/experimental/exoticoptions/analyticamericanmargrabeengine.cpp rename to ql/pricingengines/exotic/analyticamericanmargrabeengine.cpp index c87ce565654..65aeb87daaf 100644 --- a/ql/experimental/exoticoptions/analyticamericanmargrabeengine.cpp +++ b/ql/pricingengines/exotic/analyticamericanmargrabeengine.cpp @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include #include diff --git a/ql/pricingengines/exotic/analyticamericanmargrabeengine.hpp b/ql/pricingengines/exotic/analyticamericanmargrabeengine.hpp new file mode 100644 index 00000000000..a4b3bb35e6e --- /dev/null +++ b/ql/pricingengines/exotic/analyticamericanmargrabeengine.hpp @@ -0,0 +1,56 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file analyticamericanmargrabeengine.hpp + \brief Analytic engine for American Margrabe option +*/ + +#ifndef quantlib_analytic_american_margrabe_engine_hpp +#define quantlib_analytic_american_margrabe_engine_hpp + +#include +#include + +namespace QuantLib { + + //! Analytic engine for American Margrabe option + /*! This class implements formulae from + "The Value of an American Option to Exchange One Asset for Another", + W. Margrabe, + Journal of Finance, 33, 177-86. + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + class AnalyticAmericanMargrabeEngine : public MargrabeOption::engine { + public: + AnalyticAmericanMargrabeEngine(ext::shared_ptr process1, + ext::shared_ptr process2, + Real correlation); + void calculate() const override; + + private: + ext::shared_ptr process1_; + ext::shared_ptr process2_; + Real rho_; + }; + +} + +#endif diff --git a/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.cpp b/ql/pricingengines/exotic/analyticeuropeanmargrabeengine.cpp similarity index 98% rename from ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.cpp rename to ql/pricingengines/exotic/analyticeuropeanmargrabeengine.cpp index 75272330117..afc4d8dab5c 100644 --- a/ql/experimental/exoticoptions/analyticeuropeanmargrabeengine.cpp +++ b/ql/pricingengines/exotic/analyticeuropeanmargrabeengine.cpp @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include #include diff --git a/ql/pricingengines/exotic/analyticeuropeanmargrabeengine.hpp b/ql/pricingengines/exotic/analyticeuropeanmargrabeengine.hpp new file mode 100644 index 00000000000..d8eff12f9f9 --- /dev/null +++ b/ql/pricingengines/exotic/analyticeuropeanmargrabeengine.hpp @@ -0,0 +1,56 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file analyticeuropeanmargrabeengine.hpp + \brief Analytic engine for European Margrabe option +*/ + +#ifndef quantlib_analytic_european_margrabe_engine_hpp +#define quantlib_analytic_european_margrabe_engine_hpp + +#include +#include + +namespace QuantLib { + + //! Analytic engine for European Margrabe option + /*! This class implements formulae from + "The Value of an Option to Exchange One Asset for Another", + W. Margrabe, + Journal of Finance, 33 (March 1978), 177-186. + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + class AnalyticEuropeanMargrabeEngine : public MargrabeOption::engine { + public: + AnalyticEuropeanMargrabeEngine(ext::shared_ptr process1, + ext::shared_ptr process2, + Real correlation); + void calculate() const override; + + private: + ext::shared_ptr process1_; + ext::shared_ptr process2_; + Real rho_; + }; + +} + +#endif diff --git a/test-suite/margrabeoption.cpp b/test-suite/margrabeoption.cpp index 9f871d45289..f8c7eae87b4 100644 --- a/test-suite/margrabeoption.cpp +++ b/test-suite/margrabeoption.cpp @@ -20,9 +20,9 @@ #include "margrabeoption.hpp" #include "utilities.hpp" #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/test-suite/quantlibtestsuite.cpp b/test-suite/quantlibtestsuite.cpp index e9b0294a55c..8925de2f48f 100644 --- a/test-suite/quantlibtestsuite.cpp +++ b/test-suite/quantlibtestsuite.cpp @@ -428,6 +428,7 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(LinearLeastSquaresRegressionTest::suite()); test->add(LookbackOptionTest::suite(speed)); test->add(LowDiscrepancyTest::suite()); + test->add(MargrabeOptionTest::suite()); test->add(MarketModelTest::suite(speed)); test->add(MarketModelCmsTest::suite(speed)); test->add(MarketModelSmmTest::suite(speed)); @@ -510,7 +511,6 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(HimalayaOptionTest::suite()); test->add(InflationCPICapFloorTest::suite()); test->add(InflationVolTest::suite()); - test->add(MargrabeOptionTest::suite()); test->add(NoArbSabrTest::suite()); test->add(NormalCLVModelTest::experimental(speed)); test->add(NthToDefaultTest::suite(speed)); From 5dfcdca0283b4d59d9dd82c784407dff46f30fdf Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Thu, 24 Aug 2023 18:03:17 +0200 Subject: [PATCH 2/4] Move compound option from experimental to core --- QuantLib.vcxproj | 6 +- QuantLib.vcxproj.filters | 18 ++-- cmake/GenerateHeaders.cmake | 2 + ql/CMakeLists.txt | 6 +- ql/experimental/exoticoptions/Makefile.am | 6 +- ql/experimental/exoticoptions/all.hpp | 2 - .../analyticcompoundoptionengine.hpp | 84 +-------------- .../exoticoptions/compoundoption.hpp | 49 +-------- ql/instruments/Makefile.am | 2 + ql/instruments/all.hpp | 1 + .../compoundoption.cpp | 2 +- ql/instruments/compoundoption.hpp | 66 ++++++++++++ ql/pricingengines/exotic/Makefile.am | 2 + ql/pricingengines/exotic/all.hpp | 1 + .../exotic}/analyticcompoundoptionengine.cpp | 2 +- .../exotic/analyticcompoundoptionengine.hpp | 101 ++++++++++++++++++ test-suite/compoundoption.cpp | 4 +- test-suite/quantlibtestsuite.cpp | 2 +- 18 files changed, 209 insertions(+), 147 deletions(-) rename ql/{experimental/exoticoptions => instruments}/compoundoption.cpp (97%) create mode 100644 ql/instruments/compoundoption.hpp rename ql/{experimental/exoticoptions => pricingengines/exotic}/analyticcompoundoptionengine.cpp (99%) create mode 100644 ql/pricingengines/exotic/analyticcompoundoptionengine.hpp diff --git a/QuantLib.vcxproj b/QuantLib.vcxproj index 2000809f276..b4553130279 100644 --- a/QuantLib.vcxproj +++ b/QuantLib.vcxproj @@ -910,6 +910,7 @@ + @@ -1529,6 +1530,7 @@ + @@ -2018,7 +2020,6 @@ - @@ -2027,7 +2028,6 @@ - @@ -2172,6 +2172,7 @@ + @@ -2586,6 +2587,7 @@ + diff --git a/QuantLib.vcxproj.filters b/QuantLib.vcxproj.filters index 61a5ef7cafa..6922e64616a 100644 --- a/QuantLib.vcxproj.filters +++ b/QuantLib.vcxproj.filters @@ -807,6 +807,9 @@ instruments + + instruments + instruments @@ -2430,6 +2433,9 @@ pricingengines\exotic + + pricingengines\exotic + pricingengines\exotic @@ -4679,6 +4685,9 @@ instruments + + instruments + instruments @@ -5834,6 +5843,9 @@ pricingengines\exotic + + pricingengines\exotic + pricingengines\exotic @@ -6602,12 +6614,6 @@ experimental\barrieroption - - experimental\exoticoptions - - - experimental\exoticoptions - experimental\inflation diff --git a/cmake/GenerateHeaders.cmake b/cmake/GenerateHeaders.cmake index acc2171577f..a41d580b1fd 100644 --- a/cmake/GenerateHeaders.cmake +++ b/cmake/GenerateHeaders.cmake @@ -54,6 +54,8 @@ function(generate_dir_headers source_dir binary_dir) list(FILTER children_hpp EXCLUDE REGEX "margrabeoption.hpp") list(FILTER children_hpp EXCLUDE REGEX "analyticamericanmargrabeengine.hpp") list(FILTER children_hpp EXCLUDE REGEX "analyticeuropeanmargrabeengine.hpp") + list(FILTER children_hpp EXCLUDE REGEX "compoundoption.hpp") + list(FILTER children_hpp EXCLUDE REGEX "analyticcompoundoptionengine.hpp") endif () list(FILTER children_hpp EXCLUDE REGEX "riskybond.hpp") diff --git a/ql/CMakeLists.txt b/ql/CMakeLists.txt index 886edaaeed8..6b15f93021c 100644 --- a/ql/CMakeLists.txt +++ b/ql/CMakeLists.txt @@ -124,7 +124,6 @@ set(QL_SOURCES experimental/credit/riskyassetswapoption.cpp experimental/credit/syntheticcdo.cpp experimental/exoticoptions/analyticcomplexchooserengine.cpp - experimental/exoticoptions/analyticcompoundoptionengine.cpp experimental/exoticoptions/analyticholderextensibleoptionengine.cpp experimental/exoticoptions/analyticpartialtimebarrieroptionengine.cpp experimental/exoticoptions/analyticpdfhestonengine.cpp @@ -133,7 +132,6 @@ set(QL_SOURCES experimental/exoticoptions/analytictwoassetcorrelationengine.cpp experimental/exoticoptions/analyticwriterextensibleoptionengine.cpp experimental/exoticoptions/complexchooseroption.cpp - experimental/exoticoptions/compoundoption.cpp experimental/exoticoptions/continuousarithmeticasianlevyengine.cpp experimental/exoticoptions/continuousarithmeticasianvecerengine.cpp experimental/exoticoptions/everestoption.cpp @@ -280,6 +278,7 @@ set(QL_SOURCES instruments/claim.cpp instruments/cliquetoption.cpp instruments/compositeinstrument.cpp + instruments/compoundoption.cpp instruments/cpicapfloor.cpp instruments/cpiswap.cpp instruments/creditdefaultswap.cpp @@ -699,6 +698,7 @@ set(QL_SOURCES pricingengines/credit/isdacdsengine.cpp pricingengines/credit/midpointcdsengine.cpp pricingengines/exotic/analyticamericanmargrabeengine.cpp + pricingengines/exotic/analyticcompoundoptionengine.cpp pricingengines/exotic/analyticeuropeanmargrabeengine.cpp pricingengines/forward/mcforwardeuropeanbsengine.cpp pricingengines/forward/mcforwardeuropeanhestonengine.cpp @@ -1325,6 +1325,7 @@ set(QL_HEADERS instruments/claim.hpp instruments/cliquetoption.hpp instruments/compositeinstrument.hpp + instruments/compoundoption.hpp instruments/cpicapfloor.hpp instruments/cpiswap.hpp instruments/creditdefaultswap.hpp @@ -1900,6 +1901,7 @@ set(QL_HEADERS pricingengines/credit/isdacdsengine.hpp pricingengines/credit/midpointcdsengine.hpp pricingengines/exotic/analyticamericanmargrabeengine.hpp + pricingengines/exotic/analyticcompoundoptionengine.hpp pricingengines/exotic/analyticeuropeanmargrabeengine.hpp pricingengines/forward/forwardengine.hpp pricingengines/forward/forwardperformanceengine.hpp diff --git a/ql/experimental/exoticoptions/Makefile.am b/ql/experimental/exoticoptions/Makefile.am index a42be6d0098..fd6f78163dd 100644 --- a/ql/experimental/exoticoptions/Makefile.am +++ b/ql/experimental/exoticoptions/Makefile.am @@ -37,7 +37,6 @@ this_include_HEADERS = \ cpp_files = \ analyticcomplexchooserengine.cpp \ - analyticcompoundoptionengine.cpp \ analyticholderextensibleoptionengine.cpp \ analyticpartialtimebarrieroptionengine.cpp \ analyticpdfhestonengine.cpp \ @@ -46,7 +45,6 @@ cpp_files = \ analytictwoassetcorrelationengine.cpp \ analyticwriterextensibleoptionengine.cpp \ complexchooseroption.cpp \ - compoundoption.cpp \ continuousarithmeticasianlevyengine.cpp \ continuousarithmeticasianvecerengine.cpp \ everestoption.cpp \ @@ -92,7 +90,9 @@ all.hpp: Makefile.am for i in $(filter-out all.hpp \ margrabeoption.hpp \ analyticamericanmargrabeengine.hpp \ - analyticeuropeanmargrabeengine.hpp, $(this_include_HEADERS)); do \ + analyticeuropeanmargrabeengine.hpp \ + compoundoption.hpp \ + analyticcompoundoptionengine.hpp, $(this_include_HEADERS)); do \ echo "#include <${subdir}/$$i>" >> ${srcdir}/$@; \ done echo >> ${srcdir}/$@ diff --git a/ql/experimental/exoticoptions/all.hpp b/ql/experimental/exoticoptions/all.hpp index b42058d3318..7cb3eb3cc99 100644 --- a/ql/experimental/exoticoptions/all.hpp +++ b/ql/experimental/exoticoptions/all.hpp @@ -2,7 +2,6 @@ /* Add the files to be included into Makefile.am instead. */ #include -#include #include #include #include @@ -11,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/ql/experimental/exoticoptions/analyticcompoundoptionengine.hpp b/ql/experimental/exoticoptions/analyticcompoundoptionengine.hpp index d9b342c11c8..23d6603bf27 100644 --- a/ql/experimental/exoticoptions/analyticcompoundoptionengine.hpp +++ b/ql/experimental/exoticoptions/analyticcompoundoptionengine.hpp @@ -17,85 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file analyticcompoundoptionengine.hpp - \brief Analytic compound option engines -*/ - -#ifndef quantlib_analytic_compound_option_engine_hpp -#define quantlib_analytic_compound_option_engine_hpp - -#include -#include -#include - -namespace QuantLib { - - //! Pricing engine for compound options using analytical formulae - /*! The formulas are taken from "Foreign Exchange Risk", - Uwe Wystup, Risk 2002, where closed form Greeks are available. - (not available in Haug 2007). - Value: Page 84, Greeks: Pages 94-95. - - \test the correctness of the returned value is tested by - reproducing results available in literature. - */ - class AnalyticCompoundOptionEngine : public CompoundOption::engine { - public: - explicit AnalyticCompoundOptionEngine( - ext::shared_ptr process); - void calculate() const override; - - private: - CumulativeNormalDistribution N_; - NormalDistribution n_; - ext::shared_ptr process_; - - // helper methods - Time residualTimeMother() const; - Time residualTimeDaughter() const; - Time residualTimeMotherDaughter() const; - - Date maturityMother() const; - Date maturityDaughter() const; - - Real dPlus() const; - Real dMinus() const; - - Real dPlusTau12(Real S) const; - Real dMinusTau12() const; - - Real strikeDaughter() const; - Real strikeMother() const; - - Real spot() const; - - Real volatilityDaughter() const; - Real volatilityMother() const; - - Real riskFreeRateDaughter() const; - Real dividendRateDaughter() const; - - Real stdDeviationDaughter() const; - Real stdDeviationMother() const; - - Real typeDaughter() const; - Real typeMother() const; - - Real transformX(Real X) const; - Real e(Real X) const; - - DiscountFactor riskFreeDiscountDaughter() const; - DiscountFactor riskFreeDiscountMother() const; - DiscountFactor riskFreeDiscountMotherDaughter() const; - - DiscountFactor dividendDiscountDaughter() const; - DiscountFactor dividendDiscountMother() const; - DiscountFactor dividendDiscountMotherDaughter() const; - - ext::shared_ptr payoffMother() const; - ext::shared_ptr payoffDaughter() const; - }; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/compoundoption.hpp b/ql/experimental/exoticoptions/compoundoption.hpp index a995fdfa21c..e3b27458cb8 100644 --- a/ql/experimental/exoticoptions/compoundoption.hpp +++ b/ql/experimental/exoticoptions/compoundoption.hpp @@ -17,50 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file compoundoption.hpp - \brief Compound option on a single asset -*/ - -#ifndef quantlib_compound_option_hpp -#define quantlib_compound_option_hpp - -#include -#include -#include - -namespace QuantLib { - - //! %Compound option on a single asset. - /*! \ingroup instruments */ - class CompoundOption : public OneAssetOption { - public: - class arguments; - class engine; - // Mother is the compound Option. - // Daughter is the option which plays the role of the underlying. - CompoundOption(const ext::shared_ptr& motherPayoff, - const ext::shared_ptr& motherExercise, - ext::shared_ptr daughterPayoff, - ext::shared_ptr daughterExercise); - void setupArguments(PricingEngine::arguments*) const override; - - private: - ext::shared_ptr daughterPayoff_; - ext::shared_ptr daughterExercise_; - }; - - class CompoundOption::arguments : public OneAssetOption::arguments { - public: - ext::shared_ptr daughterPayoff; - ext::shared_ptr daughterExercise; - void validate() const override; - }; - - //! %Compound-option %engine base class - class CompoundOption::engine - : public GenericEngine {}; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/instruments/Makefile.am b/ql/instruments/Makefile.am index e2d45d44c17..3bbc358463c 100644 --- a/ql/instruments/Makefile.am +++ b/ql/instruments/Makefile.am @@ -20,6 +20,7 @@ this_include_HEADERS = \ claim.hpp \ cliquetoption.hpp \ compositeinstrument.hpp \ + compoundoption.hpp \ cpicapfloor.hpp \ cpiswap.hpp \ creditdefaultswap.hpp \ @@ -86,6 +87,7 @@ cpp_files = \ claim.cpp \ cliquetoption.cpp \ compositeinstrument.cpp \ + compoundoption.cpp \ cpicapfloor.cpp \ cpiswap.cpp \ creditdefaultswap.cpp \ diff --git a/ql/instruments/all.hpp b/ql/instruments/all.hpp index 83567ebc816..22a4c207bbf 100644 --- a/ql/instruments/all.hpp +++ b/ql/instruments/all.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/ql/experimental/exoticoptions/compoundoption.cpp b/ql/instruments/compoundoption.cpp similarity index 97% rename from ql/experimental/exoticoptions/compoundoption.cpp rename to ql/instruments/compoundoption.cpp index df041746c05..530cdd5aef7 100644 --- a/ql/experimental/exoticoptions/compoundoption.cpp +++ b/ql/instruments/compoundoption.cpp @@ -17,7 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -#include +#include #include namespace QuantLib { diff --git a/ql/instruments/compoundoption.hpp b/ql/instruments/compoundoption.hpp new file mode 100644 index 00000000000..08f5bdce0b3 --- /dev/null +++ b/ql/instruments/compoundoption.hpp @@ -0,0 +1,66 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2009 Dimitri Reiswich + + 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. +*/ + +/*! \file compoundoption.hpp + \brief Compound option on a single asset +*/ + +#ifndef quantlib_compound_option_hpp +#define quantlib_compound_option_hpp + +#include +#include +#include + +namespace QuantLib { + + //! %Compound option (i.e., option on option) on a single asset. + /*! \ingroup instruments */ + class CompoundOption : public OneAssetOption { + public: + class arguments; + class engine; + /*! The mother option is the compound option. + The daughter option is its underlying option. + */ + CompoundOption(const ext::shared_ptr& motherPayoff, + const ext::shared_ptr& motherExercise, + ext::shared_ptr daughterPayoff, + ext::shared_ptr daughterExercise); + void setupArguments(PricingEngine::arguments*) const override; + + private: + ext::shared_ptr daughterPayoff_; + ext::shared_ptr daughterExercise_; + }; + + class CompoundOption::arguments : public OneAssetOption::arguments { + public: + ext::shared_ptr daughterPayoff; + ext::shared_ptr daughterExercise; + void validate() const override; + }; + + //! %Compound-option %engine base class + class CompoundOption::engine : public GenericEngine {}; + +} + +#endif diff --git a/ql/pricingengines/exotic/Makefile.am b/ql/pricingengines/exotic/Makefile.am index b3a4a56389a..faefadf1283 100644 --- a/ql/pricingengines/exotic/Makefile.am +++ b/ql/pricingengines/exotic/Makefile.am @@ -5,10 +5,12 @@ this_includedir=${includedir}/${subdir} this_include_HEADERS = \ all.hpp \ analyticamericanmargrabeengine.hpp \ + analyticcompoundoptionengine.hpp \ analyticeuropeanmargrabeengine.hpp cpp_files = \ analyticamericanmargrabeengine.cpp \ + analyticcompoundoptionengine.cpp \ analyticeuropeanmargrabeengine.cpp if UNITY_BUILD diff --git a/ql/pricingengines/exotic/all.hpp b/ql/pricingengines/exotic/all.hpp index d479fab5b4b..62f004097ae 100644 --- a/ql/pricingengines/exotic/all.hpp +++ b/ql/pricingengines/exotic/all.hpp @@ -2,5 +2,6 @@ /* Add the files to be included into Makefile.am instead. */ #include +#include #include diff --git a/ql/experimental/exoticoptions/analyticcompoundoptionengine.cpp b/ql/pricingengines/exotic/analyticcompoundoptionengine.cpp similarity index 99% rename from ql/experimental/exoticoptions/analyticcompoundoptionengine.cpp rename to ql/pricingengines/exotic/analyticcompoundoptionengine.cpp index 8c3c1b7c5f0..253c2e8d476 100644 --- a/ql/experimental/exoticoptions/analyticcompoundoptionengine.cpp +++ b/ql/pricingengines/exotic/analyticcompoundoptionengine.cpp @@ -17,7 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -#include +#include #include #include #include diff --git a/ql/pricingengines/exotic/analyticcompoundoptionengine.hpp b/ql/pricingengines/exotic/analyticcompoundoptionengine.hpp new file mode 100644 index 00000000000..9083b4f9c89 --- /dev/null +++ b/ql/pricingengines/exotic/analyticcompoundoptionengine.hpp @@ -0,0 +1,101 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2009 Dimitri Reiswich + + 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. +*/ + +/*! \file analyticcompoundoptionengine.hpp + \brief Analytic compound option engines +*/ + +#ifndef quantlib_analytic_compound_option_engine_hpp +#define quantlib_analytic_compound_option_engine_hpp + +#include +#include +#include + +namespace QuantLib { + + //! Pricing engine for compound options using analytical formulae + /*! The formulas are taken from "Foreign Exchange Risk", + Uwe Wystup, Risk 2002, where closed form Greeks are available. + (not available in Haug 2007). + Value: Page 84, Greeks: Pages 94-95. + + \test the correctness of the returned value is tested by + reproducing results available in literature. + */ + class AnalyticCompoundOptionEngine : public CompoundOption::engine { + public: + explicit AnalyticCompoundOptionEngine( + ext::shared_ptr process); + void calculate() const override; + + private: + CumulativeNormalDistribution N_; + NormalDistribution n_; + ext::shared_ptr process_; + + // helper methods + Time residualTimeMother() const; + Time residualTimeDaughter() const; + Time residualTimeMotherDaughter() const; + + Date maturityMother() const; + Date maturityDaughter() const; + + Real dPlus() const; + Real dMinus() const; + + Real dPlusTau12(Real S) const; + Real dMinusTau12() const; + + Real strikeDaughter() const; + Real strikeMother() const; + + Real spot() const; + + Real volatilityDaughter() const; + Real volatilityMother() const; + + Real riskFreeRateDaughter() const; + Real dividendRateDaughter() const; + + Real stdDeviationDaughter() const; + Real stdDeviationMother() const; + + Real typeDaughter() const; + Real typeMother() const; + + Real transformX(Real X) const; + Real e(Real X) const; + + DiscountFactor riskFreeDiscountDaughter() const; + DiscountFactor riskFreeDiscountMother() const; + DiscountFactor riskFreeDiscountMotherDaughter() const; + + DiscountFactor dividendDiscountDaughter() const; + DiscountFactor dividendDiscountMother() const; + DiscountFactor dividendDiscountMotherDaughter() const; + + ext::shared_ptr payoffMother() const; + ext::shared_ptr payoffDaughter() const; + }; + +} + +#endif diff --git a/test-suite/compoundoption.cpp b/test-suite/compoundoption.cpp index a3a06c0779f..98afeb6ce40 100644 --- a/test-suite/compoundoption.cpp +++ b/test-suite/compoundoption.cpp @@ -19,8 +19,8 @@ #include "compoundoption.hpp" #include "utilities.hpp" -#include -#include +#include +#include #include #include #include diff --git a/test-suite/quantlibtestsuite.cpp b/test-suite/quantlibtestsuite.cpp index 8925de2f48f..23986b0719e 100644 --- a/test-suite/quantlibtestsuite.cpp +++ b/test-suite/quantlibtestsuite.cpp @@ -378,6 +378,7 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(CliquetOptionTest::suite()); test->add(CmsTest::suite()); test->add(CmsNormalTest::suite()); + test->add(CompoundOptionTest::suite()); test->add(ConvertibleBondTest::suite()); test->add(CovarianceTest::suite()); test->add(CPISwapTest::suite()); @@ -498,7 +499,6 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(CmsSpreadTest::suite()); test->add(CommodityUnitOfMeasureTest::suite()); test->add(CompiledBoostVersionTest::suite()); - test->add(CompoundOptionTest::suite()); test->add(CreditRiskPlusTest::suite()); test->add(DoubleBarrierOptionTest::suite(speed)); test->add(DoubleBinaryOptionTest::suite()); From 9946744d6cac9411c08e576e04487258e27be2cc Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Fri, 25 Aug 2023 11:39:19 +0200 Subject: [PATCH 3/4] Move chooser options from experimental to core --- QuantLib.vcxproj | 12 ++- QuantLib.vcxproj.filters | 36 ++++++--- cmake/GenerateHeaders.cmake | 4 + ql/CMakeLists.txt | 12 ++- ql/experimental/exoticoptions/Makefile.am | 10 +-- ql/experimental/exoticoptions/all.hpp | 4 - .../analyticcomplexchooserengine.hpp | 45 +----------- .../analyticsimplechooserengine.hpp | 31 +------- .../exoticoptions/complexchooseroption.hpp | 51 +------------ .../exoticoptions/simplechooseroption.hpp | 49 +------------ ql/instruments/Makefile.am | 4 + ql/instruments/all.hpp | 2 + .../complexchooseroption.cpp | 8 +- ql/instruments/complexchooseroption.hpp | 73 +++++++++++++++++++ .../simplechooseroption.cpp | 15 ++-- ql/instruments/simplechooseroption.hpp | 64 ++++++++++++++++ ql/pricingengines/exotic/Makefile.am | 8 +- ql/pricingengines/exotic/all.hpp | 2 + .../exotic}/analyticcomplexchooserengine.cpp | 44 ++++++----- .../exotic/analyticcomplexchooserengine.hpp | 62 ++++++++++++++++ .../exotic}/analyticsimplechooserengine.cpp | 5 +- .../exotic/analyticsimplechooserengine.hpp | 44 +++++++++++ test-suite/chooseroption.cpp | 8 +- 23 files changed, 354 insertions(+), 239 deletions(-) rename ql/{experimental/exoticoptions => instruments}/complexchooseroption.cpp (89%) create mode 100644 ql/instruments/complexchooseroption.hpp rename ql/{experimental/exoticoptions => instruments}/simplechooseroption.cpp (74%) create mode 100644 ql/instruments/simplechooseroption.hpp rename ql/{experimental/exoticoptions => pricingengines/exotic}/analyticcomplexchooserengine.cpp (80%) create mode 100644 ql/pricingengines/exotic/analyticcomplexchooserengine.hpp rename ql/{experimental/exoticoptions => pricingengines/exotic}/analyticsimplechooserengine.cpp (95%) create mode 100644 ql/pricingengines/exotic/analyticsimplechooserengine.hpp diff --git a/QuantLib.vcxproj b/QuantLib.vcxproj index b4553130279..a4efc7bcc40 100644 --- a/QuantLib.vcxproj +++ b/QuantLib.vcxproj @@ -909,6 +909,7 @@ + @@ -949,6 +950,7 @@ + @@ -1530,8 +1532,10 @@ + + @@ -2019,15 +2023,12 @@ - - - @@ -2039,7 +2040,6 @@ - @@ -2171,6 +2171,7 @@ + @@ -2209,6 +2210,7 @@ + @@ -2587,8 +2589,10 @@ + + diff --git a/QuantLib.vcxproj.filters b/QuantLib.vcxproj.filters index 6922e64616a..6f8cacb3663 100644 --- a/QuantLib.vcxproj.filters +++ b/QuantLib.vcxproj.filters @@ -804,6 +804,9 @@ instruments + + instruments + instruments @@ -891,6 +894,9 @@ instruments + + instruments + instruments @@ -2433,12 +2439,18 @@ pricingengines\exotic + + pricingengines\exotic + pricingengines\exotic pricingengines\exotic + + pricingengines\exotic + pricingengines\forward @@ -4682,6 +4694,9 @@ instruments + + instruments + instruments @@ -4763,6 +4778,9 @@ instruments + + instruments + instruments @@ -5843,12 +5861,18 @@ pricingengines\exotic + + pricingengines\exotic + pricingengines\exotic pricingengines\exotic + + pricingengines\exotic + pricingengines\lookback @@ -6248,9 +6272,6 @@ experimental\fx - - experimental\exoticoptions - experimental\exoticoptions @@ -6260,9 +6281,6 @@ experimental\exoticoptions - - experimental\exoticoptions - experimental\exoticoptions @@ -6272,9 +6290,6 @@ experimental\exoticoptions - - experimental\exoticoptions - experimental\exoticoptions @@ -6308,9 +6323,6 @@ experimental\exoticoptions - - experimental\exoticoptions - experimental\exoticoptions diff --git a/cmake/GenerateHeaders.cmake b/cmake/GenerateHeaders.cmake index a41d580b1fd..d29488cedc0 100644 --- a/cmake/GenerateHeaders.cmake +++ b/cmake/GenerateHeaders.cmake @@ -56,6 +56,10 @@ function(generate_dir_headers source_dir binary_dir) list(FILTER children_hpp EXCLUDE REGEX "analyticeuropeanmargrabeengine.hpp") list(FILTER children_hpp EXCLUDE REGEX "compoundoption.hpp") list(FILTER children_hpp EXCLUDE REGEX "analyticcompoundoptionengine.hpp") + list(FILTER children_hpp EXCLUDE REGEX "simplechooseroption.hpp") + list(FILTER children_hpp EXCLUDE REGEX "analyticsimplechooserengine.hpp") + list(FILTER children_hpp EXCLUDE REGEX "complexchooseroption.hpp") + list(FILTER children_hpp EXCLUDE REGEX "analyticcomplexchooserengine.hpp") endif () list(FILTER children_hpp EXCLUDE REGEX "riskybond.hpp") diff --git a/ql/CMakeLists.txt b/ql/CMakeLists.txt index 6b15f93021c..34e7332439f 100644 --- a/ql/CMakeLists.txt +++ b/ql/CMakeLists.txt @@ -123,15 +123,12 @@ set(QL_SOURCES experimental/credit/riskyassetswap.cpp experimental/credit/riskyassetswapoption.cpp experimental/credit/syntheticcdo.cpp - experimental/exoticoptions/analyticcomplexchooserengine.cpp experimental/exoticoptions/analyticholderextensibleoptionengine.cpp experimental/exoticoptions/analyticpartialtimebarrieroptionengine.cpp experimental/exoticoptions/analyticpdfhestonengine.cpp - experimental/exoticoptions/analyticsimplechooserengine.cpp experimental/exoticoptions/analytictwoassetbarrierengine.cpp experimental/exoticoptions/analytictwoassetcorrelationengine.cpp experimental/exoticoptions/analyticwriterextensibleoptionengine.cpp - experimental/exoticoptions/complexchooseroption.cpp experimental/exoticoptions/continuousarithmeticasianlevyengine.cpp experimental/exoticoptions/continuousarithmeticasianvecerengine.cpp experimental/exoticoptions/everestoption.cpp @@ -143,7 +140,6 @@ set(QL_SOURCES experimental/exoticoptions/mcpagodaengine.cpp experimental/exoticoptions/pagodaoption.cpp experimental/exoticoptions/partialtimebarrieroption.cpp - experimental/exoticoptions/simplechooseroption.cpp experimental/exoticoptions/twoassetbarrieroption.cpp experimental/exoticoptions/twoassetcorrelationoption.cpp experimental/exoticoptions/writerextensibleoption.cpp @@ -277,6 +273,7 @@ set(QL_SOURCES instruments/capfloor.cpp instruments/claim.cpp instruments/cliquetoption.cpp + instruments/complexchooseroption.cpp instruments/compositeinstrument.cpp instruments/compoundoption.cpp instruments/cpicapfloor.cpp @@ -315,6 +312,7 @@ set(QL_SOURCES instruments/quantobarrieroption.cpp instruments/quantoforwardvanillaoption.cpp instruments/quantovanillaoption.cpp + instruments/simplechooseroption.cpp instruments/simplifynotificationgraph.cpp instruments/stickyratchet.cpp instruments/stock.cpp @@ -698,8 +696,10 @@ set(QL_SOURCES pricingengines/credit/isdacdsengine.cpp pricingengines/credit/midpointcdsengine.cpp pricingengines/exotic/analyticamericanmargrabeengine.cpp + pricingengines/exotic/analyticcomplexchooserengine.cpp pricingengines/exotic/analyticcompoundoptionengine.cpp pricingengines/exotic/analyticeuropeanmargrabeengine.cpp + pricingengines/exotic/analyticsimplechooserengine.cpp pricingengines/forward/mcforwardeuropeanbsengine.cpp pricingengines/forward/mcforwardeuropeanhestonengine.cpp pricingengines/greeks.cpp @@ -1324,6 +1324,7 @@ set(QL_HEADERS instruments/capfloor.hpp instruments/claim.hpp instruments/cliquetoption.hpp + instruments/complexchooseroption.hpp instruments/compositeinstrument.hpp instruments/compoundoption.hpp instruments/cpicapfloor.hpp @@ -1364,6 +1365,7 @@ set(QL_HEADERS instruments/quantobarrieroption.hpp instruments/quantoforwardvanillaoption.hpp instruments/quantovanillaoption.hpp + instruments/simplechooseroption.hpp instruments/simplifynotificationgraph.hpp instruments/stickyratchet.hpp instruments/stock.hpp @@ -1901,8 +1903,10 @@ set(QL_HEADERS pricingengines/credit/isdacdsengine.hpp pricingengines/credit/midpointcdsengine.hpp pricingengines/exotic/analyticamericanmargrabeengine.hpp + pricingengines/exotic/analyticcomplexchooserengine.hpp pricingengines/exotic/analyticcompoundoptionengine.hpp pricingengines/exotic/analyticeuropeanmargrabeengine.hpp + pricingengines/exotic/analyticsimplechooserengine.hpp pricingengines/forward/forwardengine.hpp pricingengines/forward/forwardperformanceengine.hpp pricingengines/forward/mcforwardeuropeanbsengine.hpp diff --git a/ql/experimental/exoticoptions/Makefile.am b/ql/experimental/exoticoptions/Makefile.am index fd6f78163dd..3bbbe2bd090 100644 --- a/ql/experimental/exoticoptions/Makefile.am +++ b/ql/experimental/exoticoptions/Makefile.am @@ -36,15 +36,12 @@ this_include_HEADERS = \ writerextensibleoption.hpp cpp_files = \ - analyticcomplexchooserengine.cpp \ analyticholderextensibleoptionengine.cpp \ analyticpartialtimebarrieroptionengine.cpp \ analyticpdfhestonengine.cpp \ - analyticsimplechooserengine.cpp \ analytictwoassetbarrierengine.cpp \ analytictwoassetcorrelationengine.cpp \ analyticwriterextensibleoptionengine.cpp \ - complexchooseroption.cpp \ continuousarithmeticasianlevyengine.cpp \ continuousarithmeticasianvecerengine.cpp \ everestoption.cpp \ @@ -56,7 +53,6 @@ cpp_files = \ mcpagodaengine.cpp \ pagodaoption.cpp \ partialtimebarrieroption.cpp \ - simplechooseroption.cpp \ twoassetbarrieroption.cpp \ twoassetcorrelationoption.cpp \ writerextensibleoption.cpp @@ -92,7 +88,11 @@ all.hpp: Makefile.am analyticamericanmargrabeengine.hpp \ analyticeuropeanmargrabeengine.hpp \ compoundoption.hpp \ - analyticcompoundoptionengine.hpp, $(this_include_HEADERS)); do \ + analyticcompoundoptionengine.hpp \ + simplechooseroption.hpp \ + analyticsimplechooserengine.hpp \ + complexchooseroption.hpp \ + analyticcomplexchooserengine.hpp, $(this_include_HEADERS)); do \ echo "#include <${subdir}/$$i>" >> ${srcdir}/$@; \ done echo >> ${srcdir}/$@ diff --git a/ql/experimental/exoticoptions/all.hpp b/ql/experimental/exoticoptions/all.hpp index 7cb3eb3cc99..90f4d6a936d 100644 --- a/ql/experimental/exoticoptions/all.hpp +++ b/ql/experimental/exoticoptions/all.hpp @@ -1,15 +1,12 @@ /* This file is automatically generated; do not edit. */ /* Add the files to be included into Makefile.am instead. */ -#include #include #include #include -#include #include #include #include -#include #include #include #include @@ -21,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/ql/experimental/exoticoptions/analyticcomplexchooserengine.hpp b/ql/experimental/exoticoptions/analyticcomplexchooserengine.hpp index 3b5478c1f5b..8f7d91d31ca 100644 --- a/ql/experimental/exoticoptions/analyticcomplexchooserengine.hpp +++ b/ql/experimental/exoticoptions/analyticcomplexchooserengine.hpp @@ -17,46 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file analyticcomplexchooserengine.hpp - \brief Analytic engine for complex chooser option -*/ - -#ifndef quantlib_analytic_complex_chooser_engine_hpp -#define quantlib_analytic_complex_chooser_engine_hpp - -#include -#include -#include - -namespace QuantLib { - - class AnalyticComplexChooserEngine : public ComplexChooserOption::engine { - public: - explicit AnalyticComplexChooserEngine( - ext::shared_ptr process); - void calculate() const override; - - private: - ext::shared_ptr process_; - Real strike(Option::Type optionType) const; - Time choosingTime() const; - Time putMaturity() const; - Time callMaturity() const; - Volatility volatility(Time t) const; - - Rate dividendYield(Time t) const; - DiscountFactor dividendDiscount(Time t) const; - - Rate riskFreeRate(Time t) const; - DiscountFactor riskFreeDiscount(Time t) const; - - BlackScholesCalculator bsCalculator(Real spot, - Option::Type optionType) const; - Real CriticalValueChooser() const; - Real ComplexChooser() const; - }; - -} - +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/analyticsimplechooserengine.hpp b/ql/experimental/exoticoptions/analyticsimplechooserengine.hpp index 5788ed0a59a..c1c389f8044 100644 --- a/ql/experimental/exoticoptions/analyticsimplechooserengine.hpp +++ b/ql/experimental/exoticoptions/analyticsimplechooserengine.hpp @@ -17,32 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file analyticsimplechooserengine.hpp - \brief Analytic engine for simple chooser option -*/ - -#ifndef quantlib_analytic_simple_chooser_engine_hpp -#define quantlib_analytic_simple_chooser_engine_hpp - -#include -#include - -namespace QuantLib { - - //! Pricing engine for European Simple Chooser option - /*! This class implements a Simple Chooser Option - option, with European exercise. - */ - class AnalyticSimpleChooserEngine : public SimpleChooserOption::engine { - public: - explicit AnalyticSimpleChooserEngine( - ext::shared_ptr process); - void calculate() const override; - - private: - ext::shared_ptr process_; - }; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/complexchooseroption.hpp b/ql/experimental/exoticoptions/complexchooseroption.hpp index 0e7fdcae777..673a3d76a82 100644 --- a/ql/experimental/exoticoptions/complexchooseroption.hpp +++ b/ql/experimental/exoticoptions/complexchooseroption.hpp @@ -17,52 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file complexchooseroption.hpp - \brief Complex chooser option -*/ - -#ifndef quantlib_complex_chooser_option_hpp -#define quantlib_complex_chooser_option_hpp - -#include - -namespace QuantLib{ - - class GeneralizedBlackScholesProcess; - - class ComplexChooserOption : public OneAssetOption { - public: - class arguments; - class engine; - ComplexChooserOption(Date choosingDate, - Real strikeCall, - Real strikePut, - const ext::shared_ptr& exerciseCall, - const ext::shared_ptr& exercisePut); - void setupArguments(PricingEngine::arguments*) const override; - - protected: - Date choosingDate_; - Real strikeCall_; - Real strikePut_; - const ext::shared_ptr& exerciseCall_; - const ext::shared_ptr& exercisePut_; - }; - - class ComplexChooserOption::arguments : public OneAssetOption::arguments { - public: - void validate() const override; - Date choosingDate; - Real strikeCall; - Real strikePut; - ext::shared_ptr exerciseCall; - ext::shared_ptr exercisePut; - }; - - class ComplexChooserOption::engine - : public GenericEngine {}; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/experimental/exoticoptions/simplechooseroption.hpp b/ql/experimental/exoticoptions/simplechooseroption.hpp index f8794ea62cf..32e032bc24a 100644 --- a/ql/experimental/exoticoptions/simplechooseroption.hpp +++ b/ql/experimental/exoticoptions/simplechooseroption.hpp @@ -17,50 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -/*! \file simplechooseroption.hpp - \brief Simple chooser option on a single asset -*/ - -#ifndef quantlib_simple_chooser_option_hpp -#define quantlib_simple_chooser_option_hpp - -#include - -namespace QuantLib { - - //! Simple chooser option - /*! This option gives the holder the right to choose, at a future - date prior to exercise, whether the option should be a call or - a put. The exercise date and strike are the same for both - call and put option. - */ - class SimpleChooserOption : public OneAssetOption { - public: - class arguments; - class engine; - SimpleChooserOption(Date choosingDate, - Real strike, - const ext::shared_ptr& exercise); - void setupArguments(PricingEngine::arguments*) const override; - - protected: - Date choosingDate_; - }; - - //! Extra %arguments for single chooser option - class SimpleChooserOption::arguments - : public OneAssetOption::arguments { - public: - arguments() : choosingDate(Null()) {} - void validate() const override; - Date choosingDate; - }; - - //! Simple chooser option %engine base class - class SimpleChooserOption::engine - : public GenericEngine {}; - -} +// Deprecated in version 1.32 +#pragma message("Warning: this file will disappear in a future release; include instead.") -#endif +#include diff --git a/ql/instruments/Makefile.am b/ql/instruments/Makefile.am index 3bbc358463c..a223dbbf1d6 100644 --- a/ql/instruments/Makefile.am +++ b/ql/instruments/Makefile.am @@ -19,6 +19,7 @@ this_include_HEADERS = \ capfloor.hpp \ claim.hpp \ cliquetoption.hpp \ + complexchooseroption.hpp \ compositeinstrument.hpp \ compoundoption.hpp \ cpicapfloor.hpp \ @@ -59,6 +60,7 @@ this_include_HEADERS = \ quantobarrieroption.hpp \ quantoforwardvanillaoption.hpp \ quantovanillaoption.hpp \ + simplechooseroption.hpp \ simplifynotificationgraph.hpp \ stickyratchet.hpp \ stock.hpp \ @@ -86,6 +88,7 @@ cpp_files = \ capfloor.cpp \ claim.cpp \ cliquetoption.cpp \ + complexchooseroption.cpp \ compositeinstrument.cpp \ compoundoption.cpp \ cpicapfloor.cpp \ @@ -124,6 +127,7 @@ cpp_files = \ quantobarrieroption.cpp \ quantoforwardvanillaoption.cpp \ quantovanillaoption.cpp \ + simplechooseroption.cpp \ simplifynotificationgraph.cpp \ stickyratchet.cpp \ stock.cpp \ diff --git a/ql/instruments/all.hpp b/ql/instruments/all.hpp index 22a4c207bbf..2c3821c0b79 100644 --- a/ql/instruments/all.hpp +++ b/ql/instruments/all.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include #include diff --git a/ql/experimental/exoticoptions/complexchooseroption.cpp b/ql/instruments/complexchooseroption.cpp similarity index 89% rename from ql/experimental/exoticoptions/complexchooseroption.cpp rename to ql/instruments/complexchooseroption.cpp index 5bf3663c4e9..f930c017c88 100644 --- a/ql/experimental/exoticoptions/complexchooseroption.cpp +++ b/ql/instruments/complexchooseroption.cpp @@ -17,7 +17,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -#include +#include #include #include @@ -29,8 +29,7 @@ namespace QuantLib { Real strikePut, const ext::shared_ptr& exerciseCall, const ext::shared_ptr& exercisePut) - : OneAssetOption(ext::make_shared(Option::Call, - strikeCall), + : OneAssetOption(ext::make_shared(Option::Call, strikeCall), exerciseCall), choosingDate_(choosingDate), strikeCall_(strikeCall), @@ -38,8 +37,7 @@ namespace QuantLib { exerciseCall_(exerciseCall), exercisePut_(exercisePut) {} - void ComplexChooserOption::setupArguments( - PricingEngine::arguments* args) const { + void ComplexChooserOption::setupArguments(PricingEngine::arguments* args) const { OneAssetOption::setupArguments(args); auto* moreArgs = dynamic_cast(args); QL_REQUIRE(moreArgs != nullptr, "wrong argument type"); diff --git a/ql/instruments/complexchooseroption.hpp b/ql/instruments/complexchooseroption.hpp new file mode 100644 index 00000000000..948275bf7f9 --- /dev/null +++ b/ql/instruments/complexchooseroption.hpp @@ -0,0 +1,73 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2014 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file complexchooseroption.hpp + \brief Complex chooser option +*/ + +#ifndef quantlib_complex_chooser_option_hpp +#define quantlib_complex_chooser_option_hpp + +#include + +namespace QuantLib{ + + //! Complex chooser option + /*! This option gives the holder the right to choose, at a future + date prior to exercise, whether the option should be a call or + a put. The exercise date and strike are different for the + call and put option. + */ + class ComplexChooserOption : public OneAssetOption { + public: + class arguments; + class engine; + ComplexChooserOption(Date choosingDate, + Real strikeCall, + Real strikePut, + const ext::shared_ptr& exerciseCall, + const ext::shared_ptr& exercisePut); + void setupArguments(PricingEngine::arguments*) const override; + + private: + Date choosingDate_; + Real strikeCall_; + Real strikePut_; + ext::shared_ptr exerciseCall_; + ext::shared_ptr exercisePut_; + }; + + //! Extra %arguments for complex chooser option + class ComplexChooserOption::arguments : public OneAssetOption::arguments { + public: + void validate() const override; + Date choosingDate; + Real strikeCall; + Real strikePut; + ext::shared_ptr exerciseCall; + ext::shared_ptr exercisePut; + }; + + //! Complex-chooser-option %engine base class + class ComplexChooserOption::engine : public GenericEngine {}; + +} + +#endif diff --git a/ql/experimental/exoticoptions/simplechooseroption.cpp b/ql/instruments/simplechooseroption.cpp similarity index 74% rename from ql/experimental/exoticoptions/simplechooseroption.cpp rename to ql/instruments/simplechooseroption.cpp index b24c3529158..59d0e340f97 100644 --- a/ql/experimental/exoticoptions/simplechooseroption.cpp +++ b/ql/instruments/simplechooseroption.cpp @@ -17,23 +17,20 @@ FOR A PARTICULAR PURPOSE. See the license for more details. */ -#include +#include #include #include namespace QuantLib { - SimpleChooserOption::SimpleChooserOption( - Date choosingDate, - Real strike, - const ext::shared_ptr& exercise) - : OneAssetOption(ext::shared_ptr( - new PlainVanillaPayoff(Option::Call, strike)), + SimpleChooserOption::SimpleChooserOption(Date choosingDate, + Real strike, + const ext::shared_ptr& exercise) + : OneAssetOption(ext::make_shared(Option::Call, strike), exercise), choosingDate_(choosingDate) {} - void SimpleChooserOption::setupArguments( - PricingEngine::arguments* args) const { + void SimpleChooserOption::setupArguments(PricingEngine::arguments* args) const { OneAssetOption::setupArguments(args); auto* moreArgs = dynamic_cast(args); QL_REQUIRE(moreArgs != nullptr, "wrong argument type"); diff --git a/ql/instruments/simplechooseroption.hpp b/ql/instruments/simplechooseroption.hpp new file mode 100644 index 00000000000..f3091b3ee4e --- /dev/null +++ b/ql/instruments/simplechooseroption.hpp @@ -0,0 +1,64 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file simplechooseroption.hpp + \brief Simple chooser option on a single asset +*/ + +#ifndef quantlib_simple_chooser_option_hpp +#define quantlib_simple_chooser_option_hpp + +#include + +namespace QuantLib { + + //! Simple chooser option + /*! This option gives the holder the right to choose, at a future + date prior to exercise, whether the option should be a call or + a put. The exercise date and strike are the same for both + call and put option. + */ + class SimpleChooserOption : public OneAssetOption { + public: + class arguments; + class engine; + SimpleChooserOption(Date choosingDate, + Real strike, + const ext::shared_ptr& exercise); + void setupArguments(PricingEngine::arguments*) const override; + + private: + Date choosingDate_; + }; + + //! Extra %arguments for single chooser option + class SimpleChooserOption::arguments : public OneAssetOption::arguments { + public: + arguments() : choosingDate(Null()) {} + void validate() const override; + Date choosingDate; + }; + + //! Simple-chooser-option %engine base class + class SimpleChooserOption::engine : public GenericEngine {}; + +} + +#endif diff --git a/ql/pricingengines/exotic/Makefile.am b/ql/pricingengines/exotic/Makefile.am index faefadf1283..c8e04e3280f 100644 --- a/ql/pricingengines/exotic/Makefile.am +++ b/ql/pricingengines/exotic/Makefile.am @@ -5,13 +5,17 @@ this_includedir=${includedir}/${subdir} this_include_HEADERS = \ all.hpp \ analyticamericanmargrabeengine.hpp \ + analyticcomplexchooserengine.hpp \ analyticcompoundoptionengine.hpp \ - analyticeuropeanmargrabeengine.hpp + analyticeuropeanmargrabeengine.hpp \ + analyticsimplechooserengine.hpp cpp_files = \ analyticamericanmargrabeengine.cpp \ + analyticcomplexchooserengine.cpp \ analyticcompoundoptionengine.cpp \ - analyticeuropeanmargrabeengine.cpp + analyticeuropeanmargrabeengine.cpp \ + analyticsimplechooserengine.cpp if UNITY_BUILD diff --git a/ql/pricingengines/exotic/all.hpp b/ql/pricingengines/exotic/all.hpp index 62f004097ae..39cc48f53b2 100644 --- a/ql/pricingengines/exotic/all.hpp +++ b/ql/pricingengines/exotic/all.hpp @@ -2,6 +2,8 @@ /* Add the files to be included into Makefile.am instead. */ #include +#include #include #include +#include diff --git a/ql/experimental/exoticoptions/analyticcomplexchooserengine.cpp b/ql/pricingengines/exotic/analyticcomplexchooserengine.cpp similarity index 80% rename from ql/experimental/exoticoptions/analyticcomplexchooserengine.cpp rename to ql/pricingengines/exotic/analyticcomplexchooserengine.cpp index b3508d0708b..653b67ae97b 100644 --- a/ql/experimental/exoticoptions/analyticcomplexchooserengine.cpp +++ b/ql/pricingengines/exotic/analyticcomplexchooserengine.cpp @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include @@ -36,45 +36,42 @@ namespace QuantLib { } void AnalyticComplexChooserEngine::calculate() const { - results_.value = ComplexChooser(); - } - - Real AnalyticComplexChooserEngine::ComplexChooser() const{ Real S = process_->x0(); Real b; Real v; Real Xc = arguments_.strikeCall; Real Xp = arguments_.strikePut; Time T = choosingTime(); - Time Tc = callMaturity()-choosingTime(); - Time Tp = putMaturity()-choosingTime(); + Time Tc = callMaturity() - T; + Time Tp = putMaturity() - T; - Real i = CriticalValueChooser(); + Real i = criticalValue(); - b = riskFreeRate(choosingTime()) - dividendYield(choosingTime()); + b = riskFreeRate(T) - dividendYield(T); v = volatility(T); Real d1 = (log(S / i) + (b + pow(v, 2) / 2)*T) / (v*sqrt(T)); Real d2 = d1 - v*sqrt(T); - b = riskFreeRate(callMaturity()) - dividendYield(callMaturity()); + b = riskFreeRate(T + Tc) - dividendYield(T + Tc); v = volatility(Tc); Real y1 = (log(S / Xc) + (b + pow(v, 2) / 2)*Tc) / (v*sqrt(Tc)); - b = riskFreeRate(putMaturity()) - dividendYield(putMaturity()); + b = riskFreeRate(T + Tp) - dividendYield(T + Tp); v = volatility(Tp); Real y2 = (log(S / Xp) + (b + pow(v, 2) / 2)*Tp) / (v*sqrt(Tp)); Real rho1 = sqrt(T / Tc); Real rho2 = sqrt(T / Tp); - b = riskFreeRate(callMaturity()) - dividendYield(callMaturity()); - Real r = riskFreeRate(callMaturity()); + b = riskFreeRate(T + Tc) - dividendYield(T + Tc); + Real r = riskFreeRate(T + Tc); Real ComplexChooser = S * exp((b - r)*Tc) * BivariateCumulativeNormalDistributionDr78(rho1)(d1, y1) - Xc * exp(-r*Tc)*BivariateCumulativeNormalDistributionDr78(rho1)(d2, y1 - v * sqrt(Tc)) ; - b = riskFreeRate(putMaturity()) - dividendYield(putMaturity()); - r = riskFreeRate(putMaturity()); - ComplexChooser-= S * exp((b - r)*Tp) * BivariateCumulativeNormalDistributionDr78(rho2)(-d1, -y2); - ComplexChooser+= Xp * exp(-r*Tp) * BivariateCumulativeNormalDistributionDr78(rho2)(-d2, -y2 + v * sqrt(Tp)); - return ComplexChooser; + b = riskFreeRate(T + Tp) - dividendYield(T + Tp); + r = riskFreeRate(T + Tp); + ComplexChooser -= S * exp((b - r)*Tp) * BivariateCumulativeNormalDistributionDr78(rho2)(-d1, -y2); + ComplexChooser += Xp * exp(-r*Tp) * BivariateCumulativeNormalDistributionDr78(rho2)(-d2, -y2 + v * sqrt(Tp)); + + results_.value = ComplexChooser; } BlackScholesCalculator AnalyticComplexChooserEngine::bsCalculator( @@ -82,20 +79,21 @@ namespace QuantLib { Real vol; DiscountFactor growth; DiscountFactor discount; + Time T = choosingTime(); - //payoff + // payoff ext::shared_ptr vanillaPayoff; if (optionType == Option::Call){ //TC-T - Time t=callMaturity()-choosingTime()-choosingTime(); + Time t=callMaturity()-2*T; vanillaPayoff = ext::make_shared( Option::Call, strike(Option::Call)); - //QuantLib requires sigma * sqrt(T) rather than just sigma/volatility + //QuantLib requires sigma * sqrt(t) rather than just sigma/volatility vol = volatility(t) * std::sqrt(t); growth = dividendDiscount(t); discount = riskFreeDiscount(t); } else{ - Time t=putMaturity()-choosingTime()-choosingTime(); + Time t=putMaturity()-2*T; vanillaPayoff = ext::make_shared( Option::Put, strike(Option::Put)); vol = volatility(t) * std::sqrt(t); @@ -107,7 +105,7 @@ namespace QuantLib { return bs; } - Real AnalyticComplexChooserEngine::CriticalValueChooser() const{ + Real AnalyticComplexChooserEngine::criticalValue() const{ Real Sv = process_->x0(); BlackScholesCalculator bs=bsCalculator(Sv,Option::Call); diff --git a/ql/pricingengines/exotic/analyticcomplexchooserengine.hpp b/ql/pricingengines/exotic/analyticcomplexchooserengine.hpp new file mode 100644 index 00000000000..2c86a35b7dd --- /dev/null +++ b/ql/pricingengines/exotic/analyticcomplexchooserengine.hpp @@ -0,0 +1,62 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2014 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file analyticcomplexchooserengine.hpp + \brief Analytic engine for complex chooser option +*/ + +#ifndef quantlib_analytic_complex_chooser_engine_hpp +#define quantlib_analytic_complex_chooser_engine_hpp + +#include +#include +#include + +namespace QuantLib { + + class AnalyticComplexChooserEngine : public ComplexChooserOption::engine { + public: + explicit AnalyticComplexChooserEngine( + ext::shared_ptr process); + void calculate() const override; + + private: + ext::shared_ptr process_; + + Real strike(Option::Type optionType) const; + Time choosingTime() const; + Time putMaturity() const; + Time callMaturity() const; + Volatility volatility(Time t) const; + + Rate dividendYield(Time t) const; + DiscountFactor dividendDiscount(Time t) const; + + Rate riskFreeRate(Time t) const; + DiscountFactor riskFreeDiscount(Time t) const; + + BlackScholesCalculator bsCalculator(Real spot, + Option::Type optionType) const; + Real criticalValue() const; + }; + +} + + +#endif diff --git a/ql/experimental/exoticoptions/analyticsimplechooserengine.cpp b/ql/pricingengines/exotic/analyticsimplechooserengine.cpp similarity index 95% rename from ql/experimental/exoticoptions/analyticsimplechooserengine.cpp rename to ql/pricingengines/exotic/analyticsimplechooserengine.cpp index de62e45c67d..637b8896d81 100644 --- a/ql/experimental/exoticoptions/analyticsimplechooserengine.cpp +++ b/ql/pricingengines/exotic/analyticsimplechooserengine.cpp @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include #include @@ -43,8 +43,7 @@ namespace QuantLib { "Risk-free rate and volatility must" "have the same day counter"); Real spot = process_->stateVariable()->value(); - ext::shared_ptr payoff = - ext::dynamic_pointer_cast(arguments_.payoff); + auto payoff = ext::dynamic_pointer_cast(arguments_.payoff); QL_REQUIRE(payoff, "non-plain payoff given"); Real strike = payoff->strike(); Volatility volatility = process_->blackVolatility()->blackVol( diff --git a/ql/pricingengines/exotic/analyticsimplechooserengine.hpp b/ql/pricingengines/exotic/analyticsimplechooserengine.hpp new file mode 100644 index 00000000000..4a411c107e5 --- /dev/null +++ b/ql/pricingengines/exotic/analyticsimplechooserengine.hpp @@ -0,0 +1,44 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis + + 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. +*/ + +/*! \file analyticsimplechooserengine.hpp + \brief Analytic engine for simple chooser option +*/ + +#ifndef quantlib_analytic_simple_chooser_engine_hpp +#define quantlib_analytic_simple_chooser_engine_hpp + +#include +#include + +namespace QuantLib { + + //! Pricing engine for European simple chooser option + class AnalyticSimpleChooserEngine : public SimpleChooserOption::engine { + public: + explicit AnalyticSimpleChooserEngine(ext::shared_ptr process); + void calculate() const override; + + private: + ext::shared_ptr process_; + }; + +} + +#endif diff --git a/test-suite/chooseroption.cpp b/test-suite/chooseroption.cpp index 8da5a8dcf07..98777822de0 100644 --- a/test-suite/chooseroption.cpp +++ b/test-suite/chooseroption.cpp @@ -20,10 +20,10 @@ #include "chooseroption.hpp" #include "utilities.hpp" #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include From fad2b0b811f774d5012be981d62dc0d071bf032c Mon Sep 17 00:00:00 2001 From: Luigi Ballabio Date: Fri, 25 Aug 2023 18:48:21 +0200 Subject: [PATCH 4/4] Move tests to correct section --- test-suite/quantlibtestsuite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-suite/quantlibtestsuite.cpp b/test-suite/quantlibtestsuite.cpp index 23986b0719e..f28008fbe89 100644 --- a/test-suite/quantlibtestsuite.cpp +++ b/test-suite/quantlibtestsuite.cpp @@ -375,6 +375,7 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(CapFloorTest::suite()); test->add(CapFlooredCouponTest::suite()); test->add(CashFlowsTest::suite()); + test->add(ChooserOptionTest::suite()); test->add(CliquetOptionTest::suite()); test->add(CmsTest::suite()); test->add(CmsNormalTest::suite()); @@ -495,7 +496,6 @@ test_suite* init_unit_test_suite(int, char* []) { test->add(CatBondTest::suite()); test->add(CdoTest::suite(speed)); test->add(CdsOptionTest::suite()); - test->add(ChooserOptionTest::suite()); test->add(CmsSpreadTest::suite()); test->add(CommodityUnitOfMeasureTest::suite()); test->add(CompiledBoostVersionTest::suite());