diff --git a/QuantLib.vcxproj b/QuantLib.vcxproj index 5fd1389b66c..589e1f39327 100644 --- a/QuantLib.vcxproj +++ b/QuantLib.vcxproj @@ -142,7 +142,7 @@ AnySuitable false Speed - .;%(AdditionalIncludeDirectories) + C:\Program Files\boost\boost_1_61_0;.;%(AdditionalIncludeDirectories) NDEBUG;WIN32;_LIB;_SCL_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -490,6 +490,7 @@ + @@ -497,12 +498,14 @@ + + @@ -843,6 +846,7 @@ + @@ -910,6 +914,7 @@ + @@ -1770,14 +1775,17 @@ + + + @@ -2031,6 +2039,7 @@ + diff --git a/QuantLib.vcxproj.filters b/QuantLib.vcxproj.filters index 6022d9e5f30..23185e11b34 100644 --- a/QuantLib.vcxproj.filters +++ b/QuantLib.vcxproj.filters @@ -984,6 +984,9 @@ math\interpolations + + math\interpolations + math\interpolations @@ -1182,6 +1185,9 @@ math\randomnumbers + + math\randomnumbers + math\solvers1D @@ -4039,6 +4045,9 @@ experimental\models + + experimental\models + termstructures\volatility\equityfx @@ -4048,6 +4057,9 @@ experimental\finitedifferences + + experimental\finitedifferences + termstructures\volatility\equityfx @@ -4090,6 +4102,9 @@ termstructures\volatility\equityfx + + methods\finitedifferences\operators + indexes\ibor @@ -4569,6 +4584,9 @@ math\randomnumbers + + math\randomnumbers + math\optimization @@ -6566,6 +6584,9 @@ experimental\finitedifferences + + experimental\finitedifferences + experimental\models @@ -6611,5 +6632,11 @@ experimental\math + + experimental\models + + + methods\finitedifferences\operators + - \ No newline at end of file + diff --git a/QuantLib_vc14.sln b/QuantLib_vc14.sln index ac21bfbe694..5bcfcc4d3eb 100644 --- a/QuantLib_vc14.sln +++ b/QuantLib_vc14.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantLib", "QuantLib.vcxproj", "{AD0A27DA-91DA-46A2-ACBD-296C419ED3AA}" EndProject @@ -83,7 +83,6 @@ Global {A613045C-34AF-4706-AA3C-730C92524F74}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {A613045C-34AF-4706-AA3C-730C92524F74}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {A613045C-34AF-4706-AA3C-730C92524F74}.Release|Win32.ActiveCfg = Release|Win32 - {A613045C-34AF-4706-AA3C-730C92524F74}.Release|Win32.Build.0 = Release|Win32 {A613045C-34AF-4706-AA3C-730C92524F74}.Release|x64.ActiveCfg = Release|x64 {A613045C-34AF-4706-AA3C-730C92524F74}.Release|x64.Build.0 = Release|x64 {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -99,7 +98,6 @@ Global {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release|Win32.ActiveCfg = Release|Win32 - {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release|Win32.Build.0 = Release|Win32 {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release|x64.ActiveCfg = Release|x64 {4EAC6A0E-20F2-4B5A-8250-7E930CCE3AD0}.Release|x64.Build.0 = Release|x64 {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -115,7 +113,6 @@ Global {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release|Win32.ActiveCfg = Release|Win32 - {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release|Win32.Build.0 = Release|Win32 {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release|x64.ActiveCfg = Release|x64 {EF6D982C-CF99-4442-B297-776DBECFAFC9}.Release|x64.Build.0 = Release|x64 {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -131,7 +128,6 @@ Global {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release|Win32.ActiveCfg = Release|Win32 - {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release|Win32.Build.0 = Release|Win32 {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release|x64.ActiveCfg = Release|x64 {7C32702E-ED12-49F1-B476-656DD1EBCE66}.Release|x64.Build.0 = Release|x64 {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -147,7 +143,6 @@ Global {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release|Win32.ActiveCfg = Release|Win32 - {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release|Win32.Build.0 = Release|Win32 {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release|x64.ActiveCfg = Release|x64 {B96E9E0A-99DA-4E9F-B8D0-941F46CDF634}.Release|x64.Build.0 = Release|x64 {1B660588-A923-4D84-9092-16DA67869773}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -163,7 +158,6 @@ Global {1B660588-A923-4D84-9092-16DA67869773}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {1B660588-A923-4D84-9092-16DA67869773}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {1B660588-A923-4D84-9092-16DA67869773}.Release|Win32.ActiveCfg = Release|Win32 - {1B660588-A923-4D84-9092-16DA67869773}.Release|Win32.Build.0 = Release|Win32 {1B660588-A923-4D84-9092-16DA67869773}.Release|x64.ActiveCfg = Release|x64 {1B660588-A923-4D84-9092-16DA67869773}.Release|x64.Build.0 = Release|x64 {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -179,7 +173,6 @@ Global {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release|Win32.ActiveCfg = Release|Win32 - {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release|Win32.Build.0 = Release|Win32 {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release|x64.ActiveCfg = Release|x64 {7FF22935-8C7D-4903-908C-B77A9CDBA840}.Release|x64.Build.0 = Release|x64 {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -195,7 +188,6 @@ Global {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release|Win32.ActiveCfg = Release|Win32 - {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release|Win32.Build.0 = Release|Win32 {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release|x64.ActiveCfg = Release|x64 {940A0AFC-9F9F-4797-A0FF-99543F67C1D9}.Release|x64.Build.0 = Release|x64 {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -211,7 +203,6 @@ Global {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release|Win32.ActiveCfg = Release|Win32 - {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release|Win32.Build.0 = Release|Win32 {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release|x64.ActiveCfg = Release|x64 {C3E22CAD-0CAF-42DC-ADE0-B2FF4F644BCE}.Release|x64.Build.0 = Release|x64 {4E262A25-90B4-449A-BFC0-95311CADF91D}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -227,7 +218,6 @@ Global {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release|Win32.ActiveCfg = Release|Win32 - {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release|Win32.Build.0 = Release|Win32 {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release|x64.ActiveCfg = Release|x64 {4E262A25-90B4-449A-BFC0-95311CADF91D}.Release|x64.Build.0 = Release|x64 {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -243,7 +233,6 @@ Global {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release|Win32.ActiveCfg = Release|Win32 - {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release|Win32.Build.0 = Release|Win32 {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release|x64.ActiveCfg = Release|x64 {0214688B-CE8A-4446-9BDD-1AE7F486EB8B}.Release|x64.Build.0 = Release|x64 {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -259,7 +248,6 @@ Global {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release|Win32.ActiveCfg = Release|Win32 - {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release|Win32.Build.0 = Release|Win32 {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release|x64.ActiveCfg = Release|x64 {65F5530B-D97E-4BDB-949F-9C31C56104B0}.Release|x64.Build.0 = Release|x64 {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -275,7 +263,6 @@ Global {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release|Win32.ActiveCfg = Release|Win32 - {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release|Win32.Build.0 = Release|Win32 {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release|x64.ActiveCfg = Release|x64 {C8AFC9D1-704C-4AB5-911B-3C93C27C63D0}.Release|x64.Build.0 = Release|x64 {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -291,7 +278,6 @@ Global {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release|Win32.ActiveCfg = Release|Win32 - {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release|Win32.Build.0 = Release|Win32 {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release|x64.ActiveCfg = Release|x64 {47CE2A41-091A-42A3-B40D-F6F0DD689349}.Release|x64.Build.0 = Release|x64 {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -307,7 +293,6 @@ Global {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release|Win32.ActiveCfg = Release|Win32 - {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release|Win32.Build.0 = Release|Win32 {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release|x64.ActiveCfg = Release|x64 {B62FC7BE-C1BC-4AB0-BB11-BBF627CC3BA6}.Release|x64.Build.0 = Release|x64 {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -323,7 +308,6 @@ Global {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release|Win32.ActiveCfg = Release|Win32 - {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release|Win32.Build.0 = Release|Win32 {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release|x64.ActiveCfg = Release|x64 {D3E10D43-57DF-42D7-AEA6-44AD48CAE119}.Release|x64.Build.0 = Release|x64 {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -339,7 +323,6 @@ Global {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release|Win32.ActiveCfg = Release|Win32 - {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release|Win32.Build.0 = Release|Win32 {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release|x64.ActiveCfg = Release|x64 {E4098DFF-FD34-48A6-955F-C1E3F97FBA26}.Release|x64.Build.0 = Release|x64 {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -355,7 +338,6 @@ Global {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release|Win32.ActiveCfg = Release|Win32 - {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release|Win32.Build.0 = Release|Win32 {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release|x64.ActiveCfg = Release|x64 {43A17E5B-EC94-4EB5-9D68-788BF234AE1F}.Release|x64.Build.0 = Release|x64 {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Debug (static runtime)|Win32.ActiveCfg = Debug (static runtime)|Win32 @@ -371,7 +353,6 @@ Global {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release (static runtime)|x64.ActiveCfg = Release (static runtime)|x64 {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release (static runtime)|x64.Build.0 = Release (static runtime)|x64 {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release|Win32.ActiveCfg = Release|Win32 - {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release|Win32.Build.0 = Release|Win32 {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release|x64.ActiveCfg = Release|x64 {D85EA161-361A-4CAC-8B77-39E174FCFFE2}.Release|x64.Build.0 = Release|x64 EndGlobalSection diff --git a/ql/experimental/finitedifferences/Makefile.am b/ql/experimental/finitedifferences/Makefile.am index 1ce3f470f3b..adb45e05dff 100644 --- a/ql/experimental/finitedifferences/Makefile.am +++ b/ql/experimental/finitedifferences/Makefile.am @@ -29,6 +29,7 @@ this_include_HEADERS = \ fdmvppstepcondition.hpp \ fdmvppstepconditionfactory.hpp \ fdmzabrop.hpp \ + fdornsteinuhlenbeckvanillaengine.hpp \ fdsimpleextoujumpswingengine.hpp \ fdsimpleextoustorageengine.hpp \ fdsimpleklugeextouvppengine.hpp \ @@ -60,6 +61,7 @@ libMultiDimFDM_la_SOURCES = \ fdmvppstepcondition.cpp \ fdmvppstepconditionfactory.cpp \ fdmzabrop.cpp \ + fdornsteinuhlenbeckvanillaengine.cpp \ fdsimpleextoujumpswingengine.cpp \ fdsimpleextoustorageengine.cpp \ fdsimpleklugeextouvppengine.cpp \ diff --git a/ql/experimental/finitedifferences/all.hpp b/ql/experimental/finitedifferences/all.hpp index 9756dad2bec..d11c1061667 100644 --- a/ql/experimental/finitedifferences/all.hpp +++ b/ql/experimental/finitedifferences/all.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.cpp b/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.cpp new file mode 100644 index 00000000000..cda4590b4b6 --- /dev/null +++ b/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.cpp @@ -0,0 +1,125 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2016 Klaus Spanderen + + This file is part of QuantLib, a free-software/open-source library + for financial quantitative analysts and developers - http://quantlib.org/ + + QuantLib is free software: you can redistribute it and/or modify it + under the terms of the QuantLib license. You should have received a + copy of the license along with this program; if not, please email + . The license is also available online at + . + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the license for more details. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace QuantLib { + + namespace { + class FdmOUInnerValue : public FdmInnerValueCalculator { + public: + FdmOUInnerValue( + const boost::shared_ptr& payoff, + const boost::shared_ptr& mesher, + Size direction) + : payoff_(payoff), mesher_(mesher), direction_ (direction) { } + + + Real innerValue(const FdmLinearOpIterator& iter, Time t) { + const Real s = mesher_->location(iter, direction_); + return payoff_->operator()(s); + } + + Real avgInnerValue(const FdmLinearOpIterator& iter, Time t) { + return innerValue(iter, t); + } + + private: + const boost::shared_ptr payoff_; + const boost::shared_ptr mesher_; + const Size direction_; + }; + } + + FdOrnsteinUhlenbeckVanillaEngine::FdOrnsteinUhlenbeckVanillaEngine( + const boost::shared_ptr& process, + const boost::shared_ptr& rTS, + Size tGrid, Size xGrid, Size dampingSteps, + Real epsilon, + const FdmSchemeDesc& schemeDesc) + : process_(process), + rTS_(rTS), + tGrid_(tGrid), xGrid_(xGrid), dampingSteps_(dampingSteps), + epsilon_(epsilon), + schemeDesc_(schemeDesc) { + registerWith(process_); + registerWith(rTS); + } + + void FdOrnsteinUhlenbeckVanillaEngine::calculate() const { + + // 1. Mesher + const boost::shared_ptr payoff = + boost::dynamic_pointer_cast(arguments_.payoff); + + const DayCounter dc = rTS_->dayCounter(); + const Date referenceDate = rTS_->referenceDate(); + + const Time maturity = dc.yearFraction( + referenceDate, arguments_.exercise->lastDate()); + + const boost::shared_ptr equityMesher( + new FdmSimpleProcess1dMesher( + xGrid_, process_, maturity, 1, epsilon_)); + + const boost::shared_ptr mesher ( + new FdmMesherComposite(equityMesher)); + + // 2. Calculator + const boost::shared_ptr calculator( + new FdmOUInnerValue(payoff, mesher, 0)); + + // 3. Step conditions + const boost::shared_ptr conditions = + FdmStepConditionComposite::vanillaComposite( + arguments_.cashFlow, arguments_.exercise, + mesher, calculator, + referenceDate, dc); + + // 4. Boundary conditions + const FdmBoundaryConditionSet boundaries; + + // 5. Solver + FdmSolverDesc solverDesc = { mesher, boundaries, conditions, calculator, + maturity, tGrid_, dampingSteps_ }; + + const boost::shared_ptr op( + new FdmOrnsteinUhlenbackOp(mesher, process_, rTS_, boundaries, 0)); + + const boost::shared_ptr solver( + new Fdm1DimSolver(solverDesc, schemeDesc_, op)); + + const Real spot = process_->x0(); + + results_.value = solver->interpolateAt(spot); + results_.delta = solver->derivativeX(spot); + results_.gamma = solver->derivativeXX(spot); + results_.theta = solver->thetaAt(spot); + } +} diff --git a/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.hpp b/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.hpp new file mode 100644 index 00000000000..dc57f05f9d0 --- /dev/null +++ b/ql/experimental/finitedifferences/fdornsteinuhlenbeckvanillaengine.hpp @@ -0,0 +1,58 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2016 Klaus Spanderen + + 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 fdblackscholesvanillaengine.hpp + \brief Finite-Differences Black Scholes vanilla option engine +*/ + +#ifndef quantlib_fd_ornstein_uhlenbeck_vanilla_engine_hpp +#define quantlib_fd_ornstein_uhlenbeck_vanilla_engine_hpp + +#include +#include +#include + +namespace QuantLib { + + class YieldTermStructure; + class OrnsteinUhlenbeckProcess; + + class FdOrnsteinUhlenbeckVanillaEngine + : public DividendVanillaOption::engine { + public: + // Constructor + FdOrnsteinUhlenbeckVanillaEngine( + const boost::shared_ptr&, + const boost::shared_ptr& rTS, + Size tGrid = 100, Size xGrid = 100, Size dampingSteps = 0, + Real epsilon = 0.0001, + const FdmSchemeDesc& schemeDesc = FdmSchemeDesc::Douglas()); + + void calculate() const; + + private: + const boost::shared_ptr process_; + const boost::shared_ptr rTS_; + const Size tGrid_, xGrid_, dampingSteps_; + const Real epsilon_; + const FdmSchemeDesc schemeDesc_; + }; +} + +#endif diff --git a/ql/experimental/models/Makefile.am b/ql/experimental/models/Makefile.am index 908bf285243..9f82e08975a 100644 --- a/ql/experimental/models/Makefile.am +++ b/ql/experimental/models/Makefile.am @@ -5,11 +5,13 @@ this_includedir=${includedir}/${subdir} this_include_HEADERS = \ all.hpp \ hestonslvfdmmodel.hpp \ - hestonslvmcmodel.hpp + hestonslvmcmodel.hpp \ + normalclvmodel.hpp libModels_la_SOURCES = \ hestonslvfdmmodel.cpp \ - hestonslvmcmodel.cpp + hestonslvmcmodel.cpp \ + normalclvmodel.cpp noinst_LTLIBRARIES = libModels.la diff --git a/ql/experimental/models/all.hpp b/ql/experimental/models/all.hpp index 018f8a7fe42..e72242b050c 100644 --- a/ql/experimental/models/all.hpp +++ b/ql/experimental/models/all.hpp @@ -3,4 +3,5 @@ #include #include +#include diff --git a/ql/experimental/models/hestonslvfdmmodel.cpp b/ql/experimental/models/hestonslvfdmmodel.cpp index d75e14275b8..684e8a50411 100644 --- a/ql/experimental/models/hestonslvfdmmodel.cpp +++ b/ql/experimental/models/hestonslvfdmmodel.cpp @@ -281,10 +281,6 @@ namespace QuantLib { registerWith(hestonModel_); } - void HestonSLVFDMModel::update() { - notifyObservers(); - } - boost::shared_ptr HestonSLVFDMModel::hestonProcess() const { return hestonModel_->process(); } diff --git a/ql/experimental/models/hestonslvfdmmodel.hpp b/ql/experimental/models/hestonslvfdmmodel.hpp index 5ec07a560ca..06f1ee714d4 100644 --- a/ql/experimental/models/hestonslvfdmmodel.hpp +++ b/ql/experimental/models/hestonslvfdmmodel.hpp @@ -77,8 +77,6 @@ class SimpleQuote; const bool logging = false, const std::vector& mandatoryDates = std::vector()); - void update(); - boost::shared_ptr hestonProcess() const; boost::shared_ptr localVol() const; boost::shared_ptr leverageFunction() const; diff --git a/ql/experimental/models/hestonslvmcmodel.cpp b/ql/experimental/models/hestonslvmcmodel.cpp index 5f695592121..e01e1057f30 100644 --- a/ql/experimental/models/hestonslvmcmodel.cpp +++ b/ql/experimental/models/hestonslvmcmodel.cpp @@ -71,10 +71,6 @@ namespace QuantLib { std::max(Size(2), Size(gridTimes.back()*timeStepsPerYear))); } - void HestonSLVMCModel::update() { - notifyObservers(); - } - boost::shared_ptr HestonSLVMCModel::hestonProcess() const { return hestonModel_->process(); } diff --git a/ql/experimental/models/hestonslvmcmodel.hpp b/ql/experimental/models/hestonslvmcmodel.hpp index 8e87d75100b..5203e15510f 100644 --- a/ql/experimental/models/hestonslvmcmodel.hpp +++ b/ql/experimental/models/hestonslvmcmodel.hpp @@ -52,8 +52,6 @@ namespace QuantLib { Size calibrationPaths = (1 << 15), const std::vector& mandatoryDates = std::vector()); - void update(); - boost::shared_ptr hestonProcess() const; boost::shared_ptr localVol() const; boost::shared_ptr leverageFunction() const; diff --git a/ql/experimental/models/normalclvmodel.cpp b/ql/experimental/models/normalclvmodel.cpp new file mode 100644 index 00000000000..92065fd95a0 --- /dev/null +++ b/ql/experimental/models/normalclvmodel.cpp @@ -0,0 +1,201 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2016 Klaus Spanderen + + 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 normalclvmodel.cpp +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace QuantLib { + + NormalCLVModel::NormalCLVModel( + const boost::shared_ptr& bsProcess, + const boost::shared_ptr& ouProcess, + const std::vector& maturityDates, + Size lagrangeOrder, Real pMax, Real pMin) + : x_(M_SQRT2*GaussHermiteIntegration(lagrangeOrder).x()), + sigma_( (pMax != Null()) + ? x_.back() / InverseCumulativeNormal()(pMax) + : (pMin != Null()) + ? x_.front() / InverseCumulativeNormal()(pMin) + : 1.0), + bsProcess_ (bsProcess), + ouProcess_ (ouProcess), + maturityDates_(maturityDates), + pricingEngine_(boost::make_shared(bsProcess_)) { + + registerWith(bsProcess_); + registerWith(ouProcess_); + + maturityTimes_.reserve(maturityDates.size()); + std::transform(maturityDates_.begin(), maturityDates_.end(), + std::back_inserter(maturityTimes_), + boost::bind(&GeneralizedBlackScholesProcess::time, + bsProcess_, _1)); + std::sort(maturityTimes_.begin(), maturityTimes_.end()); + } + + Real NormalCLVModel::cdf(const Date& d, Real k) const { + //k = std::max(k, 1e-3*bsProcess_->x0()); + + const Handle volTS + = bsProcess_->blackVolatility(); + + const Real dk = 1e-3*k; + const Real dvol_dk + = (volTS->blackVol(d, k+dk) - volTS->blackVol(d, k-dk)) / (2*dk); + + const DiscountFactor df + = bsProcess_->riskFreeRate()->discount(d); + + const boost::shared_ptr exercise + = boost::make_shared(d); + + if (bsProcess_->x0() <=k) { + VanillaOption option( + boost::make_shared(Option::Call, k), + exercise); + option.setPricingEngine(pricingEngine_); + + return 1.0 + ( option.strikeSensitivity() + + option.vega() * dvol_dk) /df; + } + else { + VanillaOption option( + boost::make_shared(Option::Put, k), + exercise); + option.setPricingEngine(pricingEngine_); + + return ( option.strikeSensitivity() + + option.vega() * dvol_dk) /df; + + } + } + + + Real NormalCLVModel::invCDF(const Date& d, Real q) const { + const Real fwd = bsProcess_->x0() + / bsProcess_->riskFreeRate()->discount(d, true) + * bsProcess_->dividendYield()->discount(d, true); + + const Volatility atmVol = + bsProcess_->blackVolatility()->blackVol(d, fwd, true); + + const Real atmX = InverseCumulativeNormal()(q); + const Time t = bsProcess_->time(d); + + const Real guess = fwd*std::exp(atmVol*atmX*std::sqrt(t)); + + + Real lower = guess; + while (guess/lower < 65535.0 && cdf(d, lower) > q) + lower*=0.5; + + Real upper = guess; + while (upper/guess < 65535.0 && cdf(d, upper) < q) upper*=2; + + QL_REQUIRE(guess/lower < 65535.0 && upper/guess < 65535.0, + "Could not find an start interval with (" + << lower << ", " << upper << ") -> (" + << cdf(d, lower) << ", " << cdf(d, upper) << ")"); + + return Brent().solve( + compose(std::bind2nd(std::minus(), q), + boost::function( + boost::bind(&NormalCLVModel::cdf, this, d, _1))), + 1e-10, 0.5*(lower+upper), lower, upper); + } + + Disposable NormalCLVModel::collocationPointsX(const Date& d) const { + const Time t = bsProcess_->time(d); + + const Real expectation + = ouProcess_->expectation(0.0, ouProcess_->x0(), t); + const Real stdDeviation + = ouProcess_->stdDeviation(0.0, ouProcess_->x0(), t); + + return expectation + stdDeviation*x_; + } + + Disposable NormalCLVModel::collocationPointsY(const Date& d) const { + Array s(x_.size()); + + CumulativeNormalDistribution N; + for (Size i=0, n=s.size(); i < n; ++i) { + s[i] = invCDF(d, N(x_[i]/sigma_)); + } + + return s; + } + + + boost::function NormalCLVModel::g() const { + calculate(); + return g_; + } + + NormalCLVModel::MappingFunction::MappingFunction( + const NormalCLVModel& model) + : y_(model.x_.size()), + sigma_(model.sigma_), + ouProcess_(model.ouProcess_), + data_(boost::make_shared(model)) { + + for (Size i=0; i < data_->s_.columns(); ++i) { + const Array y = model.collocationPointsY(model.maturityDates_[i]); + std::copy(y.begin(), y.end(), data_->s_.column_begin(i)); + } + + for (Size i=0; i < data_->s_.rows(); ++i) { + data_->interpl_.push_back( + LinearInterpolation(data_->t_.begin(), data_->t_.end(), + data_->s_.row_begin(i))); + } + } + + + Real NormalCLVModel::MappingFunction::operator()(Time t, Real x) const { + for (Size i=0; i < y_.size(); ++i) { + y_[i] = data_->interpl_[i](t, true); + } + + const Real expectation + = ouProcess_->expectation(0.0, ouProcess_->x0(), t); + const Real stdDeviation + = ouProcess_->stdDeviation(0.0, ouProcess_->x0(), t); + + const Real r = sigma_*(x-expectation)/stdDeviation; + + return data_->lagrangeInterpl_.value(y_, r); + } + + void NormalCLVModel::performCalculations() const { + g_ = boost::function(MappingFunction(*this)); + } +} diff --git a/ql/experimental/models/normalclvmodel.hpp b/ql/experimental/models/normalclvmodel.hpp new file mode 100644 index 00000000000..c7df1c74365 --- /dev/null +++ b/ql/experimental/models/normalclvmodel.hpp @@ -0,0 +1,120 @@ +/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + Copyright (C) 2016 Klaus Spanderen + + 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 normalclvmodel.hpp + \brief CLV model with a normally distributed kernel process +*/ + +#ifndef quantlib_normal_clv_mc_model_hpp +#define quantlib_normal_clv_mc_model_hpp + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace QuantLib { + /*! References: + + A. Grzelak, 2016, The CLV Framework - + A Fresh Look at Efficient Pricing with Smile + + http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2747541 + */ + + class PricingEngine; + + class NormalCLVModel : public LazyObject { + public: + NormalCLVModel( + const boost::shared_ptr& bsProcess, + const boost::shared_ptr& ouProcess, + const std::vector& maturityDates, + Size lagrangeOrder, + Real pMax = Null(), + Real pMin = Null()); + + // cumulative distribution function of the BS process + Real cdf(const Date& d, Real x) const; + + // inverse cumulative distribution function of the BS process + Real invCDF(const Date& d, Real q) const; + + // collocation points of the Ornstein-Uhlenbeck process + Disposable collocationPointsX(const Date& d) const; + + // collocation points for the underlying Y + Disposable collocationPointsY(const Date& d) const; + + // CLV mapping function + boost::function g() const; + + protected: + void performCalculations() const; + + private: + class MappingFunction : public std::binary_function { + public: + MappingFunction(const NormalCLVModel& model); + + Real operator()(Time t, Real x) const; + + private: + mutable Array y_; + const Volatility sigma_; + const boost::shared_ptr ouProcess_; + + struct InterpolationData { + InterpolationData(const NormalCLVModel& model) + : s_(model.x_.size(), model.maturityDates_.size()), + x_(model.x_), + t_(model.maturityTimes_), + lagrangeInterpl_(x_.begin(), x_.end(), x_.begin()) {} + + Matrix s_; + std::vector interpl_; + + const Array x_; + const std::vector