Skip to content

Commit

Permalink
Common template engine.
Browse files Browse the repository at this point in the history
  • Loading branch information
lballabio committed May 8, 2020
1 parent 65b2213 commit 10827f0
Show file tree
Hide file tree
Showing 15 changed files with 384 additions and 1,218 deletions.
12 changes: 3 additions & 9 deletions QuantLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1508,10 +1508,7 @@
<ClInclude Include="ql\pricingengines\lookback\analyticcontinuousfloatinglookback.hpp" />
<ClInclude Include="ql\pricingengines\lookback\analyticcontinuouspartialfixedlookback.hpp" />
<ClInclude Include="ql\pricingengines\lookback\analyticcontinuouspartialfloatinglookback.hpp" />
<ClInclude Include="ql\pricingengines\lookback\mclookbackfixedengine.hpp" />
<ClInclude Include="ql\pricingengines\lookback\mclookbackfloatingengine.hpp" />
<ClInclude Include="ql\pricingengines\lookback\mclookbackpartialfixedengine.hpp" />
<ClInclude Include="ql\pricingengines\lookback\mclookbackpartialfloatingengine.hpp" />
<ClInclude Include="ql\pricingengines\lookback\mclookbackengine.hpp" />
<ClInclude Include="ql\pricingengines\mclongstaffschwartzengine.hpp" />
<ClInclude Include="ql\pricingengines\mcsimulation.hpp" />
<ClInclude Include="ql\pricingengines\quanto\all.hpp" />
Expand Down Expand Up @@ -2526,10 +2523,7 @@
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuousfloatinglookback.cpp" />
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuouspartialfixedlookback.cpp" />
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuouspartialfloatinglookback.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackfixedengine.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackfloatingengine.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackpartialfixedengine.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackpartialfloatingengine.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\cvaswapengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\discountingswapengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\discretizedswap.cpp" />
Expand Down Expand Up @@ -2755,4 +2749,4 @@
<Import Project=".\Build.props" Condition="Exists('.\Build.props')" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
24 changes: 3 additions & 21 deletions QuantLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -2568,16 +2568,7 @@
<ClInclude Include="ql\pricingengines\lookback\analyticcontinuouspartialfloatinglookback.hpp">
<Filter>pricingengines\lookback</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\lookback\mclookbackfixedengine.hpp">
<Filter>pricingengines\lookback</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\lookback\mclookbackfloatingengine.hpp">
<Filter>pricingengines\lookback</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\lookback\mclookbackpartialfixedengine.hpp">
<Filter>pricingengines\lookback</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\lookback\mclookbackpartialfloatingengine.hpp">
<ClInclude Include="ql\pricingengines\lookback\mclookbackengine.hpp">
<Filter>pricingengines\lookback</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\bond\all.hpp">
Expand Down Expand Up @@ -5664,16 +5655,7 @@
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuouspartialfloatinglookback.cpp">
<Filter>pricingengines\lookback</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\lookback\mclookbackfixedengine.cpp">
<Filter>pricingengines\lookback</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\lookback\mclookbackkfloatingengine.cpp">
<Filter>pricingengines\lookback</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\lookback\mclookbackkpartialfixedengine.cpp">
<Filter>pricingengines\lookback</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\lookback\mclookbackpartialfloatingengine.cpp">
<ClCompile Include="ql\pricingengines\lookback\mclookbackengine.cpp">
<Filter>pricingengines\lookback</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\bond\bondfunctions.cpp">
Expand Down Expand Up @@ -6973,4 +6955,4 @@
<Filter>methods\finitedifferences\schemes</Filter>
</ClCompile>
</ItemGroup>
</Project>
</Project>
10 changes: 2 additions & 8 deletions ql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,7 @@ set(QuantLib_SRC
pricingengines/lookback/analyticcontinuousfloatinglookback.cpp
pricingengines/lookback/analyticcontinuouspartialfixedlookback.cpp
pricingengines/lookback/analyticcontinuouspartialfloatinglookback.cpp
pricingengines/lookback/mclookbackpartialfixedengine.cpp
pricingengines/lookback/mclookbackfixedengine.cpp
pricingengines/lookback/mclookbackpartialfloatingengine.cpp
pricingengines/lookback/mclookbackfloatingengine.cpp
pricingengines/lookback/mclookbackengine.cpp
pricingengines/swap/cvaswapengine.cpp
pricingengines/swap/discountingswapengine.cpp
pricingengines/swap/discretizedswap.cpp
Expand Down Expand Up @@ -1944,10 +1941,7 @@ set(QuantLib_HDR
pricingengines/lookback/analyticcontinuousfloatinglookback.hpp
pricingengines/lookback/analyticcontinuouspartialfixedlookback.hpp
pricingengines/lookback/analyticcontinuouspartialfloatinglookback.hpp
pricingengines/lookback/mclookbackpartialfixedengine.hpp
pricingengines/lookback/mclookbackfixedengine.hpp
pricingengines/lookback/mclookbackpartialfloatingengine.hpp
pricingengines/lookback/mclookbackfloatingengine.hpp
pricingengines/lookback/mclookbackengine.hpp
pricingengines/mclongstaffschwartzengine.hpp
pricingengines/mcsimulation.hpp
pricingengines/quanto/all.hpp
Expand Down
10 changes: 2 additions & 8 deletions ql/pricingengines/lookback/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,14 @@ this_include_HEADERS = \
analyticcontinuousfloatinglookback.hpp \
analyticcontinuouspartialfixedlookback.hpp \
analyticcontinuouspartialfloatinglookback.hpp \
mclookbackpartialfixedengine.hpp \
mclookbackfixedengine.hpp \
mclookbackfloatingengine.hpp \
mclookbackpartialfloatingengine.hpp
mclookbackengine.hpp

cpp_files = \
analyticcontinuousfixedlookback.cpp \
analyticcontinuousfloatinglookback.cpp \
analyticcontinuouspartialfixedlookback.cpp \
analyticcontinuouspartialfloatinglookback.cpp \
mclookbackpartialfixedengine.cpp \
mclookbackfixedengine.cpp \
mclookbackfloatingengine.cpp \
mclookbackpartialfloatingengine.cpp
mclookbackengine.cpp

if UNITY_BUILD

Expand Down
5 changes: 1 addition & 4 deletions ql/pricingengines/lookback/all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,5 @@
#include <ql/pricingengines/lookback/analyticcontinuousfloatinglookback.hpp>
#include <ql/pricingengines/lookback/analyticcontinuouspartialfixedlookback.hpp>
#include <ql/pricingengines/lookback/analyticcontinuouspartialfloatinglookback.hpp>
#include <ql/pricingengines/lookback/mclookbackpartialfixedengine.hpp>
#include <ql/pricingengines/lookback/mclookbackfixedengine.hpp>
#include <ql/pricingengines/lookback/mclookbackfloatingengine.hpp>
#include <ql/pricingengines/lookback/mclookbackpartialfloatingengine.hpp>
#include <ql/pricingengines/lookback/mclookbackengine.hpp>

252 changes: 252 additions & 0 deletions ql/pricingengines/lookback/mclookbackengine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
Copyright (C) 2020 Lew Wei Hao
This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/
QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/pricingengines/lookback/mclookbackengine.hpp>
#include <algorithm>

namespace QuantLib {

class LookbackFixedPathPricer : public PathPricer<Path> {
public:
LookbackFixedPathPricer(Option::Type type,
Real strike,
DiscountFactor discount);
Real operator()(const Path& path) const;
private:
PlainVanillaPayoff payoff_;
DiscountFactor discount_;
};

class LookbackPartialFixedPathPricer : public PathPricer<Path> {
public:
LookbackPartialFixedPathPricer(Time lookbackStart,
Option::Type type,
Real strike,
const DiscountFactor discount);
Real operator()(const Path& path) const;
private:
Time lookbackStart_;
PlainVanillaPayoff payoff_;
DiscountFactor discount_;
};

class LookbackFloatingPathPricer : public PathPricer<Path> {
public:
LookbackFloatingPathPricer(Option::Type type,
DiscountFactor discount);
Real operator()(const Path& path) const;
private:
FloatingTypePayoff payoff_;
DiscountFactor discount_;
};

class LookbackPartialFloatingPathPricer : public PathPricer<Path> {
public:
LookbackPartialFloatingPathPricer(Time lookbackEnd,
Option::Type type,
DiscountFactor discount);
Real operator()(const Path& path) const;
private:
Time lookbackEnd_;
FloatingTypePayoff payoff_;
DiscountFactor discount_;
};

namespace detail {

ext::shared_ptr<PathPricer<Path> >
mc_lookback_path_pricer(
const ContinuousFixedLookbackOption::arguments& args,
const GeneralizedBlackScholesProcess& process,
DiscountFactor discount) {
ext::shared_ptr<PlainVanillaPayoff> payoff =
ext::dynamic_pointer_cast<PlainVanillaPayoff>(args.payoff);
QL_REQUIRE(payoff, "non-plain payoff given");

return ext::shared_ptr<PathPricer<Path> >(
new LookbackFixedPathPricer(payoff->optionType(),
payoff->strike(),
discount));
}

ext::shared_ptr<PathPricer<Path> >
mc_lookback_path_pricer(
const ContinuousPartialFixedLookbackOption::arguments& args,
const GeneralizedBlackScholesProcess& process,
DiscountFactor discount) {
ext::shared_ptr<PlainVanillaPayoff> payoff =
ext::dynamic_pointer_cast<PlainVanillaPayoff>(args.payoff);
QL_REQUIRE(payoff, "non-plain payoff given");

Time lookbackStart = process.time(args.lookbackPeriodStart);

return ext::shared_ptr<PathPricer<Path> >(
new LookbackPartialFixedPathPricer(lookbackStart,
payoff->optionType(),
payoff->strike(),
discount));
}

ext::shared_ptr<PathPricer<Path> >
mc_lookback_path_pricer(
const ContinuousFloatingLookbackOption::arguments& args,
const GeneralizedBlackScholesProcess& process,
DiscountFactor discount) {
ext::shared_ptr<FloatingTypePayoff> payoff =
ext::dynamic_pointer_cast<FloatingTypePayoff>(args.payoff);
QL_REQUIRE(payoff, "non-floating payoff given");

return ext::shared_ptr<PathPricer<Path> >(
new LookbackFloatingPathPricer(payoff->optionType(),
discount));
}

ext::shared_ptr<PathPricer<Path> >
mc_lookback_path_pricer(
const ContinuousPartialFloatingLookbackOption::arguments& args,
const GeneralizedBlackScholesProcess& process,
DiscountFactor discount) {
ext::shared_ptr<FloatingTypePayoff> payoff =
ext::dynamic_pointer_cast<FloatingTypePayoff>(args.payoff);
QL_REQUIRE(payoff, "non-floating payoff given");

Time lookbackEnd = process.time(args.lookbackPeriodEnd);

return ext::shared_ptr<PathPricer<Path> >(
new LookbackPartialFloatingPathPricer(lookbackEnd,
payoff->optionType(),
discount));
}

}


LookbackFixedPathPricer::LookbackFixedPathPricer(
Option::Type type,
Real strike,
DiscountFactor discount)
: payoff_(type, strike), discount_(discount) {
QL_REQUIRE(strike>=0.0,
"strike less than zero not allowed");
}

Real LookbackFixedPathPricer::operator()(const Path& path) const {
QL_REQUIRE(!path.empty(), "the path cannot be empty");

Real underlying;
switch (payoff_.optionType()) {
case Option::Put:
underlying = *std::min_element(path.begin()+1, path.end());
break;
case Option::Call:
underlying = *std::max_element(path.begin()+1, path.end());
break;
default:
QL_FAIL("unknown option type");
}

return payoff_(underlying) * discount_;
}


LookbackPartialFixedPathPricer::LookbackPartialFixedPathPricer(
Time lookbackStart,
Option::Type type,
Real strike,
const DiscountFactor discount)
: lookbackStart_(lookbackStart), payoff_(type, strike), discount_(discount) {
QL_REQUIRE(strike>=0.0,
"strike less than zero not allowed");
}

Real LookbackPartialFixedPathPricer::operator()(const Path& path) const {
QL_REQUIRE(!path.empty(), "the path cannot be empty");

TimeGrid timeGrid = path.timeGrid();
Size startIndex = timeGrid.closestIndex(lookbackStart_);
Real underlying;
switch (payoff_.optionType()) {
case Option::Put:
underlying = *std::min_element(path.begin()+startIndex+1, path.end());
break;
case Option::Call:
underlying = *std::max_element(path.begin()+startIndex+1, path.end());
break;
default:
QL_FAIL("unknown option type");
}

return payoff_(underlying) * discount_;
}


LookbackFloatingPathPricer::LookbackFloatingPathPricer(
Option::Type type,
const DiscountFactor discount)
: payoff_(type), discount_(discount) {}

Real LookbackFloatingPathPricer::operator()(const Path& path) const {
QL_REQUIRE(!path.empty(), "the path cannot be empty");

Real terminalPrice = path.back();
Real strike;
switch (payoff_.optionType()) {
case Option::Call:
strike = *std::min_element(path.begin()+1, path.end());
break;
case Option::Put:
strike = *std::max_element(path.begin()+1, path.end());
break;
default:
QL_FAIL("unknown option type");
}

return payoff_(terminalPrice, strike) * discount_;
}


LookbackPartialFloatingPathPricer::LookbackPartialFloatingPathPricer(
Time lookbackEnd,
Option::Type type,
DiscountFactor discount)
: lookbackEnd_(lookbackEnd), payoff_(type), discount_(discount) {}

Real LookbackPartialFloatingPathPricer::operator()(const Path& path) const {
QL_REQUIRE(!path.empty(), "the path cannot be empty");

TimeGrid timeGrid = path.timeGrid();
Size endIndex = timeGrid.closestIndex(lookbackEnd_);
Real terminalPrice = path.back();
Real strike;

switch (payoff_.optionType()) {
case Option::Call:
strike = *std::min_element(path.begin()+1, path.begin()+endIndex+1);
break;
case Option::Put:
strike = *std::max_element(path.begin()+1, path.begin()+endIndex+1);
break;
default:
QL_FAIL("unknown option type");
}

return payoff_(terminalPrice, strike) * discount_;
}

}
Loading

0 comments on commit 10827f0

Please sign in to comment.