Skip to content

Instantly share code, notes, and snippets.

@djinn
Created August 23, 2023 06:18
Show Gist options
  • Save djinn/154175ccf9209d24e44b8cd624cfa910 to your computer and use it in GitHub Desktop.
Save djinn/154175ccf9209d24e44b8cd624cfa910 to your computer and use it in GitHub Desktop.
Calculating Value at Risk VaR using pure C++ code
#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