From f0e2323c3cd4e688b677fd69819669bc1a444522 Mon Sep 17 00:00:00 2001 From: anthonymakarewicz <138609270+anthonymakarewicz@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:56:59 +0200 Subject: [PATCH] added builders for each MCPricer --- CMakeLists.txt | 28 +- include/market_data/market_data.h | 2 + include/option/base_factory_option.h | 81 ++++ include/option/factory_option.h | 35 -- .../path_dependent/factory_american_option.h | 7 +- .../path_dependent/factory_asian_option.h | 11 +- .../path_dependent/factory_barrier_option.h | 11 +- .../path_dependent/factory_lookback_option.h | 11 +- .../single_path/factory_digital_option.h | 7 +- .../factory_double_digital_option.h | 7 +- .../single_path/factory_european_option.h | 12 +- include/solver/base_solver.h | 2 + include/solver/monte_carlo/base_mc.h | 27 ++ .../monte_carlo/base_mc_path_dependent.h | 21 + .../monte_carlo/builder/base_mc_builder.h | 30 ++ .../builder/base_mc_builder_path_dependent.h | 21 + .../monte_carlo/builder/mc_builder_american.h | 30 ++ .../monte_carlo/builder/mc_builder_asian.h | 36 ++ .../monte_carlo/builder/mc_builder_barrier.h | 35 ++ .../monte_carlo/builder/mc_builder_lookback.h | 35 ++ .../builder/mc_builder_single_path.h | 24 + include/solver/monte_carlo/generator.h | 2 +- include/solver/monte_carlo/mc_american.h | 28 ++ include/solver/monte_carlo/mc_asian.h | 59 +++ include/solver/monte_carlo/mc_barrier.h | 55 +++ include/solver/monte_carlo/mc_base_strategy.h | 443 ------------------ include/solver/monte_carlo/mc_lookback.h | 50 ++ include/solver/monte_carlo/mc_single_path.h | 26 + include/solver/monte_carlo/mc_solver.h | 31 +- main.cpp | 33 +- src/option/factory_option.cpp | 33 -- .../factory_american_option.cpp | 5 +- .../path_dependent/factory_asian_option.cpp | 9 +- .../path_dependent/factory_barrier_option.cpp | 9 +- .../factory_lookback_option.cpp | 9 +- .../single_path/factory_digital_option.cpp | 8 +- .../factory_double_digital_option.cpp | 6 +- .../single_path/factory_european_option.cpp | 5 +- src/solver/monte_carlo/base_mc.cpp | 13 + .../monte_carlo/base_mc_path_dependent.cpp | 21 + .../monte_carlo/builder/base_mc_builder.cpp | 27 ++ .../base_mc_builder_path_dependent.cpp | 16 + .../builder/mc_builder_american.cpp | 36 ++ .../monte_carlo/builder/mc_builder_asian.cpp | 39 ++ .../builder/mc_builder_barrier.cpp | 40 ++ .../builder/mc_builder_lookback.cpp | 43 ++ .../builder/mc_builder_single_path.cpp | 23 + src/solver/monte_carlo/mc_american.cpp | 80 ++++ src/solver/monte_carlo/mc_asian.cpp | 70 +++ src/solver/monte_carlo/mc_barrier.cpp | 79 ++++ src/solver/monte_carlo/mc_base_strategy.cpp | 24 - src/solver/monte_carlo/mc_lookback.cpp | 72 +++ src/solver/monte_carlo/mc_single_path.cpp | 30 ++ src/solver/monte_carlo/mc_solver.cpp | 19 + tests/integration/test_integration_option.cpp | 4 +- tests/unit/option/test_base_option.cpp | 7 +- 56 files changed, 1294 insertions(+), 633 deletions(-) create mode 100644 include/option/base_factory_option.h delete mode 100644 include/option/factory_option.h create mode 100644 include/solver/monte_carlo/base_mc.h create mode 100644 include/solver/monte_carlo/base_mc_path_dependent.h create mode 100644 include/solver/monte_carlo/builder/base_mc_builder.h create mode 100644 include/solver/monte_carlo/builder/base_mc_builder_path_dependent.h create mode 100644 include/solver/monte_carlo/builder/mc_builder_american.h create mode 100644 include/solver/monte_carlo/builder/mc_builder_asian.h create mode 100644 include/solver/monte_carlo/builder/mc_builder_barrier.h create mode 100644 include/solver/monte_carlo/builder/mc_builder_lookback.h create mode 100644 include/solver/monte_carlo/builder/mc_builder_single_path.h create mode 100644 include/solver/monte_carlo/mc_american.h create mode 100644 include/solver/monte_carlo/mc_asian.h create mode 100644 include/solver/monte_carlo/mc_barrier.h delete mode 100644 include/solver/monte_carlo/mc_base_strategy.h create mode 100644 include/solver/monte_carlo/mc_lookback.h create mode 100644 include/solver/monte_carlo/mc_single_path.h create mode 100644 src/solver/monte_carlo/base_mc.cpp create mode 100644 src/solver/monte_carlo/base_mc_path_dependent.cpp create mode 100644 src/solver/monte_carlo/builder/base_mc_builder.cpp create mode 100644 src/solver/monte_carlo/builder/base_mc_builder_path_dependent.cpp create mode 100644 src/solver/monte_carlo/builder/mc_builder_american.cpp create mode 100644 src/solver/monte_carlo/builder/mc_builder_asian.cpp create mode 100644 src/solver/monte_carlo/builder/mc_builder_barrier.cpp create mode 100644 src/solver/monte_carlo/builder/mc_builder_lookback.cpp create mode 100644 src/solver/monte_carlo/builder/mc_builder_single_path.cpp create mode 100644 src/solver/monte_carlo/mc_american.cpp create mode 100644 src/solver/monte_carlo/mc_asian.cpp create mode 100644 src/solver/monte_carlo/mc_barrier.cpp delete mode 100644 src/solver/monte_carlo/mc_base_strategy.cpp create mode 100644 src/solver/monte_carlo/mc_lookback.cpp create mode 100644 src/solver/monte_carlo/mc_single_path.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d56479d..c898687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ add_library(marketdata SHARED src/market_data/market_data.cpp src/market_data/market_data_observer.cpp src/market_data/stock_data.cpp + include/solver/monte_carlo/builder/mc_builder_american.h ) # Create dynamic library for payoff @@ -68,7 +69,6 @@ add_library(option SHARED src/option/path_dependent/barrier_option.cpp src/option/path_dependent/lookback_option.cpp # Factories - src/option/factory_option.cpp src/option/single_path/factory_european_option.cpp src/option/single_path/factory_digital_option.cpp src/option/single_path/factory_double_digital_option.cpp @@ -82,27 +82,35 @@ add_library(option SHARED add_library(solver SHARED src/solver/base_solver.cpp src/solver/monte_carlo/mc_solver.cpp - include/solver/monte_carlo/mc_base_strategy.h - src/solver/monte_carlo/mc_base_strategy.cpp - include/solver/monte_carlo/stock_price_model.h src/solver/monte_carlo/stock_price_model.cpp src/solver/monte_carlo/gbm_stock_price_model.cpp - include/solver/monte_carlo/gbm_stock_price_model.h - include/solver/monte_carlo/generator.h + src/solver/monte_carlo/base_mc.cpp + src/solver/monte_carlo/mc_single_path.cpp + src/solver/monte_carlo/base_mc_path_dependent.cpp + src/solver/monte_carlo/mc_asian.cpp + src/solver/monte_carlo/mc_barrier.cpp + src/solver/monte_carlo/mc_lookback.cpp + src/solver/monte_carlo/mc_american.cpp + src/solver/monte_carlo/builder/base_mc_builder.cpp + src/solver/monte_carlo/builder/mc_builder_single_path.cpp + src/solver/monte_carlo/builder/base_mc_builder_path_dependent.cpp + src/solver/monte_carlo/builder/mc_builder_asian.cpp + src/solver/monte_carlo/builder/mc_builder_barrier.cpp + src/solver/monte_carlo/builder/mc_builder_lookback.cpp + src/solver/monte_carlo/builder/mc_builder_american.cpp ) -# Link random library to the solver ONLY -target_link_libraries(solver PUBLIC Boost::random Eigen3::Eigen) - # Link the option library against marketdata and payoff target_link_libraries(option PUBLIC marketdata payoff) +# Link random library to the solver ONLY +target_link_libraries(solver PUBLIC option Boost::random Eigen3::Eigen) + # Create main executable add_executable(Option_pricer main.cpp) # Link the main executable to our dynamic libraries target_link_libraries(Option_pricer PUBLIC marketdata payoff option solver) -#target_link_libraries(Option_pricer marketdata payoff option solver) # Enable testing and add the tests directory enable_testing() diff --git a/include/market_data/market_data.h b/include/market_data/market_data.h index 7347f2f..e8f3061 100644 --- a/include/market_data/market_data.h +++ b/include/market_data/market_data.h @@ -14,6 +14,7 @@ #include "interface_market_data.h" namespace OptionPricer { + // Declare MarketData as Singleton class MarketData final: public IMarketData { public: @@ -67,6 +68,7 @@ namespace OptionPricer { std::unordered_map> stockDataMap_; // Map ticker symbol to StockData std::vector> observers_; // Use weak_ptr to avoid circular references }; + } #endif //MARKET_DATA_H diff --git a/include/option/base_factory_option.h b/include/option/base_factory_option.h new file mode 100644 index 0000000..35d5852 --- /dev/null +++ b/include/option/base_factory_option.h @@ -0,0 +1,81 @@ +#ifndef FACTORY_OPTION_H +#define FACTORY_OPTION_H + +#include +#include +#include "payoff/base_payoff.h" +#include "option/base_option.h" +#include "option/parameter_object.h" +#include "market_data/market_data.h" + +namespace OptionPricer { + + // Define a concept for an Option type + template + concept OptionTypeConcept = std::is_base_of_v; + + template class OptionFactory { + public: + virtual ~OptionFactory() = default; + + // Non-static create methods as we use virtual methods + [[nodiscard]] std::shared_ptr createCallOption(const ParameterObject& params); + [[nodiscard]] std::shared_ptr createPutOption(const ParameterObject& params); + + protected: + // Template method pattern + std::shared_ptr createOption(const ParameterObject& params, const PayoffType& type); + + // Can be overiden to add extra parameters + virtual std::string invalidParams(const std::string& option_type) const; + + // To be overidden in concrete factories + virtual std::unique_ptr createSpecificPayoff(const ParameterObject& params, + const PayoffType& type) = 0; + virtual std::shared_ptr createSpecificOption(const ParameterObject& params, + std::unique_ptr payoff, + const std::shared_ptr& marketData) = 0; + virtual std::string getType(const PayoffType& type) const = 0; + }; + + + template + std::shared_ptr OptionFactory::createCallOption(const ParameterObject ¶ms) { + return createOption(params, PayoffType::Call); + } + + template + std::shared_ptr OptionFactory::createPutOption(const ParameterObject ¶ms) { + return createOption(params, PayoffType::Put); + } + + template + std::shared_ptr OptionFactory::createOption(const ParameterObject ¶ms, + const PayoffType& type) { + auto marketData = MarketData::getInstance(); + std::shared_ptr option = nullptr; + + try { + auto payoff = createSpecificPayoff(params, type); + option = createSpecificOption(params, std::move(payoff), marketData); + } catch (const std::invalid_argument& e) { + const std::string err = std::string(e.what()) + "\n" + invalidParams(getType(type)); + throw std::invalid_argument(err); + } + + option->initialize(); + return option; + } + + template + std::string OptionFactory::invalidParams(const std::string &option_type) const { + return "Invalid parameters for " + option_type + "\n" + "Expected parameters:\n" + " - ticker (string) for ticker symbol\n" + " - T (double) for maturity\n" + " - K (double) for strike\n"; + } + +} + +#endif //FACTORY_OPTION_H \ No newline at end of file diff --git a/include/option/factory_option.h b/include/option/factory_option.h deleted file mode 100644 index 7c67315..0000000 --- a/include/option/factory_option.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef FACTORY_OPTION_H -#define FACTORY_OPTION_H - -#include -#include "payoff/base_payoff.h" -#include "option/base_option.h" -#include "option/parameter_object.h" - -namespace OptionPricer { - class OptionFactory { - public: - virtual ~OptionFactory(); - - // Non-static create methods as we use virtual methods - [[nodiscard]] std::shared_ptr