Created
August 23, 2023 06:18
-
-
Save djinn/154175ccf9209d24e44b8cd624cfa910 to your computer and use it in GitHub Desktop.
Calculating Value at Risk VaR using pure C++ code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <random> | |
#include <algorithm> | |
#include <numeric> | |
#include <thread> | |
#include <mutex> | |
const int num_simulations = 10000; // Number of Monte Carlo simulations | |
const int num_days = 252; // Number of trading days in a year | |
const double initial_portfolio_value = 1000000.0; // Initial portfolio value | |
std::mutex mutex; | |
std::vector<double> portfolio_returns; | |
// Function to simulate daily portfolio returns | |
double simulatePortfolioReturn(double mean_return, double volatility) { | |
std::random_device rd; | |
std::mt19937 gen(rd()); | |
std::normal_distribution<double> distribution(mean_return, volatility); | |
return distribution(gen); | |
} | |
// Function to run Monte Carlo simulations for a portion of the total simulations | |
void monteCarloSimulation(int num_simulations_per_thread, double mean_return, double volatility) { | |
std::vector<double> thread_returns; | |
for (int i = 0; i < num_simulations_per_thread; ++i) { | |
double portfolio_value = initial_portfolio_value; | |
for (int day = 0; day < num_days; ++day) { | |
double daily_return = simulatePortfolioReturn(mean_return, volatility); | |
portfolio_value *= (1.0 + daily_return); | |
} | |
double portfolio_return = (portfolio_value - initial_portfolio_value) / initial_portfolio_value; | |
thread_returns.push_back(portfolio_return); | |
} | |
std::lock_guard<std::mutex> lock(mutex); | |
portfolio_returns.insert(portfolio_returns.end(), thread_returns.begin(), thread_returns.end()); | |
} | |
int main() { | |
double mean_return = 0.0006; // Average daily return (0.06%) | |
double volatility = 0.02; // Daily volatility (2%) | |
const int num_threads = std::thread::hardware_concurrency(); | |
const int simulations_per_thread = num_simulations / num_threads; | |
std::vector<std::thread> threads; | |
for (int i = 0; i < num_threads; ++i) { | |
threads.emplace_back(monteCarloSimulation, simulations_per_thread, mean_return, volatility); | |
} | |
for (auto& thread : threads) { | |
thread.join(); | |
} | |
// Sort portfolio returns in ascending order | |
std::sort(portfolio_returns.begin(), portfolio_returns.end()); | |
// Calculate VaR at a specified confidence level (e.g., 95%) | |
double confidence_level = 0.95; | |
int index = static_cast<int>((1.0 - confidence_level) * num_simulations); | |
double VaR = -portfolio_returns[index] * initial_portfolio_value; | |
// Display the VaR result | |
std::cout << "Value at Risk (VaR) at " << (confidence_level * 100) << "% confidence level: $" << VaR << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment