├── CEV.cpp ├── CIR.cpp ├── CKLS.cpp ├── HJM.cpp ├── HW.cpp ├── HoLee.cpp ├── Vasicek.cpp └── readme.md /CEV.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the CEV model 8 | void simulateCEV(const double& alpha, const double& beta, const double& gamma, const double& sigma, 9 | const double& r0, const double& T, const double& dt, const std::string& outputPath) { 10 | // Set up random number generation 11 | std::random_device rd; 12 | std::mt19937 generator(rd()); 13 | std::normal_distribution normalDistribution(0.0, 1.0); 14 | 15 | // Calculate the number of time steps 16 | int numSteps = static_cast(T / dt); 17 | 18 | // Initialize vectors to store time and interest rate values 19 | std::vector time(numSteps + 1); 20 | std::vector interestRate(numSteps + 1); 21 | 22 | // Initialize the initial interest rate 23 | interestRate[0] = r0; 24 | 25 | // Simulate the CEV model 26 | for (int i = 1; i <= numSteps; ++i) { 27 | // Update time 28 | time[i] = i * dt; 29 | 30 | // Generate a random increment 31 | double dW = normalDistribution(generator); 32 | 33 | // Update the interest rate using the CEV SDE 34 | interestRate[i] = interestRate[i - 1] + (beta * std::pow(interestRate[i - 1], gamma - 1.0) + alpha * interestRate[i - 1]) * dt 35 | + sigma * std::pow(interestRate[i - 1], gamma / 2.0) * std::sqrt(dt) * dW; 36 | } 37 | 38 | // Output the results to a CSV file 39 | std::ofstream outputFile(outputPath); 40 | outputFile << "Time,InterestRate\n"; 41 | for (int i = 0; i <= numSteps; ++i) { 42 | outputFile << time[i] << "," << interestRate[i] << "\n"; 43 | } 44 | outputFile.close(); 45 | } 46 | 47 | int main() { 48 | // Parameters for the CEV model 49 | double alpha = 0.1; 50 | double beta = 0.2; 51 | double gamma = 0.5; 52 | double sigma = 0.02; 53 | double r0 = 0.05; 54 | double T = 1.0; 55 | double dt = 0.01; 56 | std::string outputPath = "cev_simulation.csv"; 57 | 58 | // Simulate the CEV model 59 | simulateCEV(alpha, beta, gamma, sigma, r0, T, dt, outputPath); 60 | 61 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /CIR.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the Cox-Ingersoll-Ross model 8 | void simulateCIR(const double& alpha, const double& beta, const double& sigma, 9 | const double& r0, const double& T, const double& dt, const std::string& outputPath) { 10 | // Set up random number generation 11 | std::random_device rd; 12 | std::mt19937 generator(rd()); 13 | std::normal_distribution normalDistribution(0.0, 1.0); 14 | 15 | // Calculate the number of time steps 16 | int numSteps = static_cast(T / dt); 17 | 18 | // Initialize vectors to store time and interest rate values 19 | std::vector time(numSteps + 1); 20 | std::vector interestRate(numSteps + 1); 21 | 22 | // Initialize the initial interest rate 23 | interestRate[0] = r0; 24 | 25 | // Simulate the Cox-Ingersoll-Ross model 26 | for (int i = 1; i <= numSteps; ++i) { 27 | // Update time 28 | time[i] = i * dt; 29 | 30 | // Generate a random increment 31 | double dW = normalDistribution(generator); 32 | 33 | // Update the interest rate using the CIR SDE 34 | interestRate[i] = std::max(0.0, interestRate[i - 1] + beta * (alpha - interestRate[i - 1]) * dt 35 | + sigma * std::sqrt(std::max(0.0, interestRate[i - 1])) * std::sqrt(dt) * dW); 36 | } 37 | 38 | // Output the results to a CSV file 39 | std::ofstream outputFile(outputPath); 40 | outputFile << "Time,InterestRate\n"; 41 | for (int i = 0; i <= numSteps; ++i) { 42 | outputFile << time[i] << "," << interestRate[i] << "\n"; 43 | } 44 | outputFile.close(); 45 | } 46 | 47 | int main() { 48 | // Parameters for the Cox-Ingersoll-Ross model 49 | double alpha = 0.1; 50 | double beta = 0.2; 51 | double sigma = 0.02; 52 | double r0 = 0.05; 53 | double T = 1.0; 54 | double dt = 0.01; 55 | std::string outputPath = "cir_simulation.csv"; 56 | 57 | // Simulate the Cox-Ingersoll-Ross model 58 | simulateCIR(alpha, beta, sigma, r0, T, dt, outputPath); 59 | 60 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /CKLS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the CKLS model 8 | void simulateCKLS(const double& alpha, const double& beta, const double& gamma, const double& sigma, 9 | const double& r0, const double& T, const double& dt, const std::string& outputPath) { 10 | // Set up random number generation 11 | std::random_device rd; 12 | std::mt19937 generator(rd()); 13 | std::normal_distribution normalDistribution(0.0, 1.0); 14 | 15 | // Calculate the number of time steps 16 | int numSteps = static_cast(T / dt); 17 | 18 | // Initialize vectors to store time and interest rate values 19 | std::vector time(numSteps + 1); 20 | std::vector interestRate(numSteps + 1); 21 | 22 | // Initialize the initial interest rate 23 | interestRate[0] = r0; 24 | 25 | // Simulate the CKLS model 26 | for (int i = 1; i <= numSteps; ++i) { 27 | // Update time 28 | time[i] = i * dt; 29 | 30 | // Generate a random increment 31 | double dW = normalDistribution(generator); 32 | 33 | // Update the interest rate using the CKLS SDE 34 | interestRate[i] = interestRate[i - 1] + (alpha - beta * interestRate[i - 1]) * dt 35 | + sigma * std::pow(std::abs(interestRate[i - 1]), gamma) * std::sqrt(dt) * dW; 36 | } 37 | 38 | // Output the results to a CSV file 39 | std::ofstream outputFile(outputPath); 40 | outputFile << "Time,InterestRate\n"; 41 | for (int i = 0; i <= numSteps; ++i) { 42 | outputFile << time[i] << "," << interestRate[i] << "\n"; 43 | } 44 | outputFile.close(); 45 | } 46 | 47 | int main() { 48 | // Parameters for the CKLS model 49 | double alpha = 0.1; 50 | double beta = 0.2; 51 | double gamma = 0.5; 52 | double sigma = 0.02; 53 | double r0 = 0.05; 54 | double T = 1.0; 55 | double dt = 0.01; 56 | std::string outputPath = "ckls_simulation.csv"; 57 | 58 | // Simulate the CKLS model 59 | simulateCKLS(alpha, beta, gamma, sigma, r0, T, dt, outputPath); 60 | 61 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /HJM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the HJM model 8 | void simulateHJM(const double& alpha, const double& sigma, const double& T, const double& dt, int num_paths) { 9 | // Set up random number generation 10 | std::random_device rd; 11 | std::mt19937 generator(rd()); 12 | std::normal_distribution normalDistribution(0.0, 1.0); 13 | 14 | // Calculate the number of time steps 15 | int num_steps = static_cast(T / dt); 16 | 17 | // Initialize vectors to store time and forward rate values 18 | std::vector time(num_steps + 1); 19 | std::vector> forward_rates(num_paths, std::vector(num_steps + 1)); 20 | 21 | // Simulate the HJM model 22 | for (int i = 1; i <= num_steps; ++i) { 23 | // Update time 24 | time[i] = i * dt; 25 | 26 | // Generate a random increment 27 | double dW = normalDistribution(generator); 28 | 29 | // Update the forward rate using the HJM SDE 30 | for (int path = 0; path < num_paths; ++path) { 31 | forward_rates[path][i] = forward_rates[path][i - 1] + alpha * dt + sigma * std::sqrt(dt) * dW; 32 | } 33 | } 34 | 35 | // Output the results to a CSV file 36 | std::ofstream outputFile("hjm_simulation.csv"); 37 | outputFile << "Time,ForwardRate1,ForwardRate2,...,ForwardRateN\n"; 38 | for (int i = 0; i <= num_steps; ++i) { 39 | outputFile << time[i]; 40 | for (int path = 0; path < num_paths; ++path) { 41 | outputFile << "," << forward_rates[path][i]; 42 | } 43 | outputFile << "\n"; 44 | } 45 | outputFile.close(); 46 | } 47 | 48 | int main() { 49 | // Parameters for the HJM model 50 | double alpha = 0.1; 51 | double sigma = 0.02; 52 | double T = 1.0; 53 | double dt = 0.01; 54 | int num_paths = 5; 55 | 56 | // Simulate the HJM model 57 | simulateHJM(alpha, sigma, T, dt, num_paths); 58 | 59 | std::cout << "Simulation completed. Results saved to hjm_simulation.csv" << std::endl; 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /HW.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the Hull and White model 8 | void simulateHullAndWhite(const double& r0, const std::vector& theta, 9 | const std::vector& alpha, const std::vector& sigma, 10 | const double& T, const double& dt, const std::string& outputPath) { 11 | // Set up random number generation 12 | std::random_device rd; 13 | std::mt19937 generator(rd()); 14 | std::normal_distribution normalDistribution(0.0, 1.0); 15 | 16 | // Calculate the number of time steps 17 | int numSteps = static_cast(T / dt); 18 | 19 | // Initialize vectors to store time and interest rate values 20 | std::vector time(numSteps + 1); 21 | std::vector interestRate(numSteps + 1); 22 | 23 | // Initialize the initial interest rate 24 | interestRate[0] = r0; 25 | 26 | // Simulate the Hull and White model 27 | for (int i = 1; i <= numSteps; ++i) { 28 | // Update time 29 | time[i] = i * dt; 30 | 31 | // Generate random increments 32 | double dW = normalDistribution(generator); 33 | 34 | // Calculate the integral terms for the explicit solution 35 | double integral1 = 0.0; 36 | double integral2 = 0.0; 37 | double integral3 = 0.0; 38 | 39 | for (int j = 0; j < i; ++j) { 40 | double u = j * dt; 41 | integral1 += alpha[j] * dt; 42 | integral2 += theta[j] * std::exp(-integral1); 43 | integral3 += sigma[j] * std::exp(-integral1) * dW; 44 | } 45 | 46 | // Update the interest rate using the Hull and White SDE 47 | interestRate[i] = r0 * std::exp(-integral1) + integral2 + integral3; 48 | } 49 | 50 | // Output the results to a CSV file 51 | std::ofstream outputFile(outputPath); 52 | outputFile << "Time,InterestRate\n"; 53 | for (int i = 0; i <= numSteps; ++i) { 54 | outputFile << time[i] << "," << interestRate[i] << "\n"; 55 | } 56 | outputFile.close(); 57 | } 58 | 59 | int main() { 60 | // Parameters for the Hull and White model 61 | double r0 = 0.02; // Replace with the desired initial interest rate 62 | std::vector theta = {0.03, 0.02, 0.025}; // Replace with the desired deterministic function of time 63 | std::vector alpha = {0.01, 0.015, 0.012}; // Replace with the desired deterministic function of time 64 | std::vector sigma = {0.01, 0.015, 0.02}; // Replace with the desired deterministic function of time 65 | double T = 1.0; 66 | double dt = 0.01; 67 | std::string outputPath = "hull_and_white_simulation.csv"; 68 | 69 | // Simulate the Hull and White model 70 | simulateHullAndWhite(r0, theta, alpha, sigma, T, dt, outputPath); 71 | 72 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /HoLee.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the Ho and Lee model 8 | void simulateHoAndLee(const double& theta, const double& sigma, const double& T, const double& dt, const std::string& outputPath) { 9 | // Set up random number generation 10 | std::random_device rd; 11 | std::mt19937 generator(rd()); 12 | std::normal_distribution normalDistribution(0.0, 1.0); 13 | 14 | // Calculate the number of time steps 15 | int numSteps = static_cast(T / dt); 16 | 17 | // Initialize vectors to store time and interest rate values 18 | std::vector time(numSteps + 1); 19 | std::vector interestRate(numSteps + 1); 20 | 21 | // Initialize the initial interest rate 22 | interestRate[0] = 0.0; 23 | 24 | // Simulate the Ho and Lee model 25 | for (int i = 1; i <= numSteps; ++i) { 26 | // Update time 27 | time[i] = i * dt; 28 | 29 | // Generate a random increment 30 | double dW = normalDistribution(generator); 31 | 32 | // Update the interest rate using the Ho and Lee SDE 33 | interestRate[i] = interestRate[i - 1] + theta * time[i] * dt + sigma * std::sqrt(dt) * dW; 34 | } 35 | 36 | // Output the results to a CSV file 37 | std::ofstream outputFile(outputPath); 38 | outputFile << "Time,InterestRate\n"; 39 | for (int i = 0; i <= numSteps; ++i) { 40 | outputFile << time[i] << "," << interestRate[i] << "\n"; 41 | } 42 | outputFile.close(); 43 | } 44 | 45 | int main() { 46 | // Parameters for the Ho and Lee model 47 | double theta = 0.02; // Replace with the desired deterministic function of time 48 | double sigma = 0.01; 49 | double T = 1.0; 50 | double dt = 0.01; 51 | std::string outputPath = "ho_and_lee_simulation.csv"; 52 | 53 | // Simulate the Ho and Lee model 54 | simulateHoAndLee(theta, sigma, T, dt, outputPath); 55 | 56 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Vasicek.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Function to simulate the Vasicek model 8 | void simulateVasicek(const double& a, const double& b, const double& sigma, 9 | const double& r0, const double& T, const double& dt, const std::string& outputPath) { 10 | // Set up random number generation 11 | std::random_device rd; 12 | std::mt19937 generator(rd()); 13 | std::normal_distribution normalDistribution(0.0, 1.0); 14 | 15 | // Calculate the number of time steps 16 | int numSteps = static_cast(T / dt); 17 | 18 | // Initialize vectors to store time and interest rate values 19 | std::vector time(numSteps + 1); 20 | std::vector interestRate(numSteps + 1); 21 | 22 | // Initialize the initial interest rate 23 | interestRate[0] = r0; 24 | 25 | // Simulate the Vasicek model 26 | for (int i = 1; i <= numSteps; ++i) { 27 | // Update time 28 | time[i] = i * dt; 29 | 30 | // Generate a random increment 31 | double dW = normalDistribution(generator); 32 | 33 | // Update the interest rate using the Vasicek SDE 34 | interestRate[i] = interestRate[i - 1] + (a - b * interestRate[i - 1]) * dt 35 | + sigma * std::sqrt(dt) * dW; 36 | } 37 | 38 | // Output the results to a CSV file 39 | std::ofstream outputFile(outputPath); 40 | outputFile << "Time,InterestRate\n"; 41 | for (int i = 0; i <= numSteps; ++i) { 42 | outputFile << time[i] << "," << interestRate[i] << "\n"; 43 | } 44 | outputFile.close(); 45 | } 46 | 47 | int main() { 48 | // Parameters for the Vasicek model 49 | double a = 0.1; 50 | double b = 0.2; 51 | double sigma = 0.02; 52 | double r0 = 0.05; 53 | double T = 1.0; 54 | double dt = 0.01; 55 | std::string outputPath = "vasicek_simulation.csv"; 56 | 57 | // Simulate the Vasicek model 58 | simulateVasicek(a, b, sigma, r0, T, dt, outputPath); 59 | 60 | std::cout << "Simulation completed. Results saved to " << outputPath << std::endl; 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Interest Rate Models in C++ 2 | 3 | This repository contains C++ code implementations for various interest rate models. The models covered include: 4 | 5 | 1. **Vasicek Model** 6 | - Description: The Vasicek model captures the mean reversion property of interest rates based on the Ornstein–Uhlenbeck process. 7 | - Code: [vasicek_model.cpp](Vasicek.cpp) 8 | 9 | 2. **Cox–Ingersoll–Ross (CIR) Model** 10 | - Description: The CIR model addresses the positivity problem encountered with the Vasicek model, introducing a nonconstant volatility. 11 | - Code: [cir_model.cpp](CIR.cpp) 12 | 13 | 3. **Constant Elasticity of Variance (CEV) Model** 14 | - Description: The CEV model accounts for nonconstant volatilities that can vary as a power of the underlying asset price. 15 | - Code: [cev_model.cpp](CEV.cpp) 16 | 17 | 4. **Hull-White (HW) Model** 18 | - Description: The Hull-White model is an extension of the Vasicek model, introducing time-dependent interest rate volatility. 19 | - Code: [hull_white_model.cpp](HW.cpp) 20 | 21 | 5. **Ho and Lee (HoLee) Model** 22 | - Description: The Ho and Lee model is based on a deterministic function of time, extending the Merton model. 23 | - Code: [ho_lee_model.cpp](HoLee.cpp) 24 | 25 | 6. **Chan–Karolyi–Longstaff–Sanders (CKLS) Model** 26 | - Description: The CKLS model is a parametrized interest rate model designed to account for nonconstant volatilities. 27 | - Code: [ckls_model.cpp](CKLS.cpp) 28 | - 29 | 7. **Heath–Jarrow–Morton (HJM) Model** 30 | - Description: The HJM model represents the instantaneous forward rate with a stochastic differential equation, allowing for a multi-factor term structure model. 31 | - Code: [hjm_model.cpp](HJM.cpp) 32 | 33 | 34 | ## Usage 35 | 36 | Each model has its own C++ file in the repository. To use a specific model, you can refer to the corresponding C++ file and adjust the parameters as needed for your application. 37 | 38 | ## Instructions 39 | 40 | 1. Clone the repository: 41 | 42 | ```bash 43 | git clone https://github.com/AIM-IT4/interest-rate-models-cpp.git 44 | --------------------------------------------------------------------------------