Skip to content

Commit

Permalink
added VG, Heston, and Kou models
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonymakarewicz committed Aug 23, 2024
1 parent 0055281 commit 7241271
Show file tree
Hide file tree
Showing 76 changed files with 1,238 additions and 662 deletions.
43 changes: 31 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,23 @@ set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

# Specify the target architecture for macOS
if(APPLE)
# Detect the processor architecture
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "Build architectures for Mac OS X" FORCE)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Build architectures for Mac OS X" FORCE)
else()
message(WARNING "Unknown architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}. Defaulting to x86_64.")
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Build architectures for Mac OS X" FORCE)
endif()
endif()


# Set the Vcpkg toolchain file
set(CMAKE_TOOLCHAIN_FILE "/Users/anthony/.vcpkg-clion/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file")
#set(CMAKE_TOOLCHAIN_FILE "/Users/anthony/.vcpkg-clion/vcpkg/scripts/buildsystems/vcpkg.cmake"
# CACHE STRING "Vcpkg toolchain file")

find_package(Boost REQUIRED COMPONENTS random)
find_package(Eigen3 REQUIRED)
Expand Down Expand Up @@ -81,17 +95,29 @@ add_library(option SHARED
add_library(model SHARED
src/model/gbm_model.cpp
src/model/base_model.cpp
src/model/heston_model.cpp
src/model/discretization/base_cir_discretization.cpp
src/model/discretization/explicit_euler_cir_discretization.cpp
src/model/discretization/milstein_cir_discretization.cpp
src/model/merton_jump_diffusion_model.cpp
src/model/kou_model.cpp
src/model/variance_gamma_model.cpp
)

# Create dynamic library for random
add_library(random SHARED
src/random/distribution/base_distribution.cpp
src/random/distribution/standard_normal_distribution.cpp
src/random/number_generator/base_generator.cpp
src/random/number_generator/random_generator.cpp
src/random/number_generator/pseudo_random_generator.cpp
src/random/number_generator/base_quasi_random_generator.cpp
src/random/number_generator/faure_quasi_random_generator.cpp
src/random/number_generator/sobol_quasi_random_generator.cpp
src/random/distribution/poisson_distrib.cpp
src/random/distribution/normal_distrib.cpp
src/random/distribution/continuous_uniform_distrib.cpp
src/random/distribution/exponential_distr.cpp
src/random/distribution/gamma_distrib.cpp
)

# Create dynamic library for solver
Expand All @@ -100,14 +126,12 @@ add_library(solver SHARED
src/solver/monte_carlo/mc_solver.cpp
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_american.cpp
Expand All @@ -124,14 +148,9 @@ add_library(solver SHARED
src/solver/monte_carlo/basis_function/laguerre.cpp
)

# 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 random model Boost::random Eigen3::Eigen)

target_link_libraries(model PUBLIC option)

target_link_libraries(model PUBLIC option random)
target_link_libraries(solver PUBLIC option model Boost::random Eigen3::Eigen)

# Create main executable
add_executable(Option_pricer main.cpp)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ make test
│ │ ├── base_generator.cpp
│ │ ├── base_quasi_random_generator.cpp
│ │ ├── faure_quasi_random_generator.cpp
│ │ ├── random_generator.cpp
│ │ ├── pseudo_random_generator.cpp
│ │ └── sobol_quasi_random_generator.cpp
│ └── solver
│ ├── base_solver.cpp
Expand Down
19 changes: 14 additions & 5 deletions include/model/base_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@
#define STOCK_PRICE_MODEL_H

#include <string>
#include <random/number_generator/base_generator.h>
#include "market_data/interface_market_data.h"

namespace OptionPricer {

class StockModel {
public:
StockModel(const std::string& ticker, std::shared_ptr<IMarketData> marketData);
virtual ~StockModel();
StockModel(const std::string& ticker,
std::shared_ptr<IMarketData> marketData,
std::shared_ptr<NumberGenerator> generator);

[[nodiscard]] virtual double simulatePriceAtMaturity(const double& T, const double& z) const = 0;
[[nodiscard]] virtual double simulateStepPrice(const double& dt, const double& z) const = 0;
virtual ~StockModel();
unsigned int getSteps() const;
[[nodiscard]] std::shared_ptr<NumberGenerator> getGenerator() const;

[[nodiscard]] virtual double simulatePriceAtMaturity(const double& T) const = 0;
[[nodiscard]] virtual std::vector<double> simulatePrices(const double& T) const = 0;
[[nodiscard]] virtual double simulatePriceBackward(const double& S_next,
const double& t_j,
const double& t_jp1) const;
protected:
std::string ticker_;
std::shared_ptr<const StockData> stockData_; // Cache StockData for consultation
std::shared_ptr<IMarketData> marketData_;
std::shared_ptr<const StockData> stockData_; // Cache StockData for consultation
std::shared_ptr<NumberGenerator> generator_;
};

}
Expand Down
18 changes: 18 additions & 0 deletions include/model/discretization/base_cir_discretization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef BASE_CIR_DISCRETIZATION_H
#define BASE_CIR_DISCRETIZATION_H

#include <algorithm>

namespace OptionPricer {

class CIRDiscretization {
public:
virtual ~CIRDiscretization();
virtual double apply(const double &v, const double &dt,
const double &kappa, const double &theta,
const double &sigma_v, const double &z) const = 0;
};

}

#endif //BASE_CIR_DISCRETIZATION_H
17 changes: 17 additions & 0 deletions include/model/discretization/explicit_euler_cir_discretization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef EXPLICIT_EULER_CIR_DISCRETIZATION_H
#define EXPLICIT_EULER_CIR_DISCRETIZATION_H

#include "model/discretization/base_cir_discretization.h"

namespace OptionPricer {

class CIRExplicitEulerDiscretization : public CIRDiscretization {
public:
double apply(const double &v, const double &dt,
const double &kappa, const double &theta,
const double &sigma_v, const double &z) const override;
};

}

#endif //EXPLICIT_EULER_CIR_DISCRETIZATION_H
16 changes: 16 additions & 0 deletions include/model/discretization/milstein_cir_discretization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef MILSTEIN_CIR_DISCRETIZATION_H
#define MILSTEIN_CIR_DISCRETIZATION_H

#include "model/discretization/explicit_euler_cir_discretization.h"

namespace OptionPricer {

class CIRMilsteinDiscretization : public CIRExplicitEulerDiscretization {
public:
double apply(const double &v, const double &dt, const double &kappa, const double &theta, const double &sigma_v,
const double &z) const override;
};

}

#endif //MILSTEIN_CIR_DISCRETIZATION_H
15 changes: 9 additions & 6 deletions include/model/gbm_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@

#include <cmath>
#include <random>
#include <model/base_model.h>
#include <market_data/interface_market_data.h>
#include "model/base_model.h"

namespace OptionPricer {

class GeometricBrownianMotionModel : public StockModel {
class GeometricBrownianMotionModel final: public StockModel {
public:
GeometricBrownianMotionModel(const std::string& ticker, std::shared_ptr<IMarketData> marketData);
using StockModel::StockModel;
~GeometricBrownianMotionModel() override;

[[nodiscard]] double simulatePriceAtMaturity(const double& T, const double& z) const override;
[[nodiscard]] double simulateStepPrice(const double& dt, const double& z) const override;
[[nodiscard]] double simulatePriceAtMaturity(const double& T) const override;
[[nodiscard]] std::vector<double> simulatePrices(const double& T) const override;
[[nodiscard]] double simulatePriceBackward(const double &S_next,
const double &t_j,
const double &t_jp1) const override;
};

}
Expand Down
36 changes: 36 additions & 0 deletions include/model/heston_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef HESTON_MODEL_H
#define HESTON_MODEL_H

#include "model/base_model.h"
#include "model/discretization/base_cir_discretization.h"

namespace OptionPricer {

class HestonModel final : public StockModel {
public:
HestonModel(const std::string& ticker,
std::shared_ptr<IMarketData> marketData,
std::shared_ptr<NumberGenerator> generator,
const double& kappa, const double& theta, const double& sigma_v,
const double& rho, const double& v0,
std::shared_ptr<CIRDiscretization> varDiscretization = nullptr);
~HestonModel() override;

[[nodiscard]] double simulatePriceAtMaturity(const double& T) const override;
[[nodiscard]] std::vector<double> simulatePrices(const double& T) const override;

private:
double kappa_; // Mean reversion rate
double theta_; // Long-term variance
double sigma_v_; // Volatility of variance
double rho_; // Correlation between the two Brownian motions
double v0_; // Initial variance
std::shared_ptr<CIRDiscretization> varDiscretization_; // Discretization scheme for the variance process
};

}




#endif //HESTON_MODEL_H
33 changes: 33 additions & 0 deletions include/model/kou_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef KOU_MODEL_H
#define KOU_MODEL_H

#include "model/base_model.h"

namespace OptionPricer {

class KouModel final: public StockModel {
public:
/* This class implements the Kou model which is an extension of the Merton Jump Diffusion model
* which introduce asymmetry of jumps for modeling the skewness and kurtosis of stock returns.
*/
KouModel(const std::string& ticker,
std::shared_ptr<IMarketData> marketData,
std::shared_ptr<NumberGenerator> generator,
const double& lambda, const double& p,
const double& eta1, const double& eta2);

~KouModel() override;

double simulatePriceAtMaturity(const double& T) const override;
std::vector<double> simulatePrices(const double& T) const override;

private:
double lambda_; // Jump intensity
double p_; // Probability of upward jump
double eta1_; // Rate of upward jumps
double eta2_; // Rate of downward jumps
};

}

#endif //KOU_MODEL_H
28 changes: 28 additions & 0 deletions include/model/merton_jump_diffusion_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef MERTON_JUMP_DIFFUSION_MODEL_H
#define MERTON_JUMP_DIFFUSION_MODEL_H

#include "model/base_model.h"

namespace OptionPricer {

class MertonJumpDiffusionModel final : public StockModel {
public:
MertonJumpDiffusionModel(const std::string& ticker,
std::shared_ptr<IMarketData> marketData,
std::shared_ptr<NumberGenerator> generator,
const double& lambda, const double& muJ, const double& sigmaJ);

~MertonJumpDiffusionModel() override;

double simulatePriceAtMaturity(const double& T) const override;
std::vector<double> simulatePrices(const double& T) const override;

private:
double lambda_; // intensity of the Poisson process (mean number of jumps per unit time)
double muJ_; // mean of the jump size distribution
double sigmaJ_; // standard deviation of the jump size distribution
};

}

#endif // MERTON_JUMP_DIFFUSION_MODEL_H
29 changes: 29 additions & 0 deletions include/model/variance_gamma_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef VARIANCE_GAMMA_MODEL_H
#define VARIANCE_GAMMA_MODEL_H

#include "model/base_model.h"

namespace OptionPricer {

class VarianceGammaModel : public StockModel {
public:
VarianceGammaModel(const std::string& ticker,
std::shared_ptr<IMarketData> marketData,
std::shared_ptr<NumberGenerator> generator,
const double& sigma, const double& nu, const double& theta);

~VarianceGammaModel() override;

[[nodiscard]] double simulatePriceAtMaturity(const double& T) const override;
[[nodiscard]] std::vector<double> simulatePrices(const double& T) const override;

private:
double sigma_; // Volatility parameter
double nu_; // Variance rate of the Gamma process
double theta_; // Drift of the Brownian motion
double omega_; // Drift correction term
};

}

#endif //VARIANCE_GAMMA_MODEL_H
12 changes: 8 additions & 4 deletions include/payoff/base_payoff.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@
#include <string>

namespace OptionPricer {

enum class PayoffType {
Call, Put, DoubleDigital
Call,
Put,
DoubleDigital
};

inline std::string PayoffTypeToString(const PayoffType& type) {
switch (type) {
case PayoffType::Call: return "Call";
case PayoffType::Put: return "Put";
case PayoffType::DoubleDigital: return "DoubleDigital";
using enum PayoffType;
case Call: return "Call";
case Put: return "Put";
case DoubleDigital: return "DoubleDigital";
// Add other cases as needed
default: return "Unknown";
}
Expand Down
3 changes: 2 additions & 1 deletion include/random/distribution/base_distribution.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

namespace OptionPricer {

// Maybe inheriting discrete and continuous and make operator() return either int or double
class Distribution {
public:
virtual ~Distribution();
[[nodiscard]] virtual double inv_cdf(const double& quantile) const = 0;
virtual double operator()(std::mt19937& gen) = 0;
virtual double operator()(std::mt19937& gen) const = 0;
};

}
Expand Down
Loading

0 comments on commit 7241271

Please sign in to comment.