Create option pricing engine structure, test architecture.
Some checks failed
C++ CI / build (push) Has been cancelled
Some checks failed
C++ CI / build (push) Has been cancelled
This commit is contained in:
2
tests/stubs/FakeMarketData.cpp
Normal file
2
tests/stubs/FakeMarketData.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
// Minimal TU to satisfy CMake for test stubs
|
||||
#include "FakeMarketData.hpp"
|
||||
38
tests/stubs/FakeMarketData.hpp
Normal file
38
tests/stubs/FakeMarketData.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by David Doebel on 07.03.2026.
|
||||
//
|
||||
#ifndef QUANTENGINE_FAKEMARKETDATA_HPP
|
||||
#define QUANTENGINE_FAKEMARKETDATA_HPP
|
||||
#include "MarketData.hpp"
|
||||
#include "FlatYieldCurve.hpp"
|
||||
#include "FlatVolatilitySurface.hpp"
|
||||
|
||||
class FakeMarketData : public MarketData {
|
||||
public:
|
||||
FakeMarketData() = default;
|
||||
|
||||
FakeMarketData(const FakeMarketData &other)
|
||||
{
|
||||
}
|
||||
|
||||
FakeMarketData(FakeMarketData &&other) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
FakeMarketData & operator=(const FakeMarketData &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
FakeMarketData & operator=(FakeMarketData &&other) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
double spot() const {return 100.0;}
|
||||
YieldCurve& yield_curve(){return *yieldCurve_; };
|
||||
VolatilitySurface& volatility_surface(){return *volatilitySurface_; };
|
||||
|
||||
private:
|
||||
std::unique_ptr<FlatYieldCurve> yieldCurve_ = std::make_unique<FlatYieldCurve>();
|
||||
std::unique_ptr<FlatVolatilitySurface> volatilitySurface_ = std::make_unique<FlatVolatilitySurface>();
|
||||
};
|
||||
#endif
|
||||
2
tests/stubs/FlatVolatilitySurface.cpp
Normal file
2
tests/stubs/FlatVolatilitySurface.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
// Minimal TU to satisfy CMake for test stubs
|
||||
#include "FlatVolatilitySurface.hpp"
|
||||
11
tests/stubs/FlatVolatilitySurface.hpp
Normal file
11
tests/stubs/FlatVolatilitySurface.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by David Doebel on 07.03.2026.
|
||||
//
|
||||
#ifndef QUANTENGINE_FLATVOLATILITYSURFACE_HPP
|
||||
#define QUANTENGINE_FLATVOLATILITYSURFACE_HPP
|
||||
#include "VolatilitySurface.hpp"
|
||||
|
||||
class FlatVolatilitySurface : public VolatilitySurface {
|
||||
double sigma(double K, double T) {return 0.2;}
|
||||
};
|
||||
#endif
|
||||
2
tests/stubs/FlatYieldCurve.cpp
Normal file
2
tests/stubs/FlatYieldCurve.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
// Minimal TU to satisfy CMake for test stubs
|
||||
#include "FlatYieldCurve.hpp"
|
||||
16
tests/stubs/FlatYieldCurve.hpp
Normal file
16
tests/stubs/FlatYieldCurve.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by David Doebel on 07.03.2026.
|
||||
//
|
||||
#ifndef QUANTENGINE_FLATYIELDCURVE_HPP
|
||||
#define QUANTENGINE_FLATYIELDCURVE_HPP
|
||||
#include "YieldCurve.hpp"
|
||||
#include <cmath>
|
||||
|
||||
class FlatYieldCurve : public YieldCurve{
|
||||
|
||||
double discount(double t) override {return std::exp(-rate_ * t); };
|
||||
double zeroRate(double t) override {return rate_; }
|
||||
private:
|
||||
double rate_ = 0.01;
|
||||
};
|
||||
#endif
|
||||
49
tests/test_black_scholes.cpp
Normal file
49
tests/test_black_scholes.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Created by David Doebel on 06.03.2026.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "BlackScholesProcess.hpp"
|
||||
#include "MonteCarloEngine.hpp"
|
||||
#include "Instrument.hpp"
|
||||
#include "Option.hpp"
|
||||
#include "Payoff.hpp"
|
||||
|
||||
#include "stubs/FlatYieldCurve.hpp"
|
||||
#include "stubs/FlatVolatilitySurface.hpp"
|
||||
#include "stubs/FakeMarketData.hpp"
|
||||
|
||||
TEST(BlackScholesProcess, ExpectedValue) {
|
||||
// Market setup (via test stubs): S0=100, r=1%, sigma=20%
|
||||
const double K = 100.0;
|
||||
const double T = 1.0;
|
||||
const int numPaths = 300000; // enough for stable MC estimate
|
||||
|
||||
// Build Black-Scholes process with fake flat market data
|
||||
auto processCall = std::make_unique<BlackScholesProcess>(std::make_unique<FakeMarketData>());
|
||||
auto processPut = std::make_unique<BlackScholesProcess>(std::make_unique<FakeMarketData>());
|
||||
|
||||
// RNG shared between engines is fine
|
||||
auto rng = std::make_shared<MersenneTwister>();
|
||||
|
||||
// Pricing engines
|
||||
auto mcCall = std::make_unique<MonteCarloEngine>(numPaths, std::move(processCall), rng);
|
||||
auto mcPut = std::make_unique<MonteCarloEngine>(numPaths, std::move(processPut), rng);
|
||||
|
||||
// Instruments (European vanilla) with call and put payoffs
|
||||
Instrument callInstr(T, std::make_unique<CallPayoff>(K), std::move(mcCall));
|
||||
Instrument putInstr(T, std::make_unique<PutPayoff>(K), std::move(mcPut));
|
||||
|
||||
const double callPrice = callInstr.price();
|
||||
const double putPrice = putInstr.price();
|
||||
|
||||
// Ground truth Black–Scholes prices provided
|
||||
const double callGT = 10.450583572;
|
||||
const double putGT = 5.573526022;
|
||||
|
||||
// Monte Carlo tolerance
|
||||
const double tol = 0.10; // 10 cents tolerance
|
||||
|
||||
ASSERT_NEAR(callPrice, callGT, tol);
|
||||
ASSERT_NEAR(putPrice, putGT, tol);
|
||||
}
|
||||
Reference in New Issue
Block a user