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