double runTrial( size_t index, size_t numTradingDays, double dt, double sqrtDT, double const (&choleskyTrans)[NS][NS], double const (&drifts)[NS] ) { uint32_t seed = initialSeed( 4096 * (1+index) ); double amounts[NS]; for ( size_t i=0; i<NS; ++i ) amounts[i] = 100.0; for ( size_t day=0; day<numTradingDays; ++day ) { double Z[NS]; randomNormalVec( Z, seed ); double X[NS]; multMatVec( choleskyTrans, Z, X ); for ( size_t i=0; i<NS; ++i ) amounts[i] *= exp(drifts[i]*dt + X[i]*sqrtDT); } double value = 0.0; for ( size_t i=0; i<NS; ++i ) value += amounts[i]; return value; }
int main( int argc, char **argv ) { size_t const numTradingDays = 252; double const dt = 1.0 / numTradingDays; double const sqrtDT = sqrt( dt ); double priceMeans[NS]; for ( size_t i=0; i<NS; ++i ) priceMeans[i] = 25.0/numTradingDays; double priceDevs[NS]; for ( size_t i=0; i<NS; ++i ) priceDevs[i] = 25.0/numTradingDays; uint32_t seed = initialSeed(0); double priceCorrelations[NS][NS]; randomCorrelation( priceCorrelations, seed ); double priceCovariance[NS][NS]; for ( size_t i=0; i<NS; ++i ) { for ( size_t j=0; j<NS; ++j ) { priceCovariance[i][j] = priceDevs[i] * priceDevs[j] * priceCorrelations[i][j]; } } double choleskyTrans[NS][NS]; computeCholeskyTrans( priceCovariance, choleskyTrans ); double drifts[NS]; for ( size_t i=0; i<NS; ++i ) drifts[i] = priceMeans[i] - priceCovariance[i][i]/2.0; size_t const numTrials = 1048576; double *trialResults = new double[numTrials]; for ( size_t trial=0; trial<numTrials; ++trial ) { trialResults[trial] = runTrial( trial, numTradingDays, dt, sqrtDT, choleskyTrans, drifts ); } qsort( trialResults, numTrials, sizeof(double), doubleCompare ); printf( "VaR = %.16f\n", 100.0*NS - trialResults[(size_t)floor( 0.05 * numTrials )] ); delete [] trialResults; return 0; }
int main( int argc, char **argv ) { size_t const numTrials = 1048576; double *trialResults = new double[numTrials]; FixedArgs fixedArgs; fixedArgs.numTradingDays = 252; fixedArgs.dt = 1.0 / fixedArgs.numTradingDays; fixedArgs.sqrtDT = sqrt( fixedArgs.dt ); double priceMeans[NS]; for ( size_t i=0; i<NS; ++i ) priceMeans[i] = 25.0/fixedArgs.numTradingDays; double priceDevs[NS]; for ( size_t i=0; i<NS; ++i ) priceDevs[i] = 25.0/fixedArgs.numTradingDays; uint32_t seed = initialSeed(0); double priceCorrelations[NS][NS]; randomCorrelation( priceCorrelations, seed ); double priceCovariance[NS][NS]; for ( size_t i=0; i<NS; ++i ) { for ( size_t j=0; j<NS; ++j ) { priceCovariance[i][j] = priceDevs[i] * priceDevs[j] * priceCorrelations[i][j]; } } computeCholeskyTrans( priceCovariance, fixedArgs.choleskyTrans ); for ( size_t i=0; i<NS; ++i ) fixedArgs.drifts[i] = priceMeans[i] - priceCovariance[i][i]/2.0; Args args[CORES]; pthread_t threads[CORES-1]; for ( size_t core=0; core<CORES; ++core ) { if ( core == 0 ) args[core].startIndex = 0; else args[core].startIndex = args[core-1].endIndex; if ( core+1 == CORES ) args[core].endIndex = numTrials; else args[core].endIndex = args[core].startIndex + numTrials/CORES; args[core].fixedArgs = &fixedArgs; args[core].trialResults = trialResults; if ( core+1 == CORES ) threadEntry( &args[core] ); else pthread_create( &threads[core], 0, &threadEntry, &args[core] ); } for ( size_t core=0; core<CORES-1; ++core ) pthread_join( threads[core], 0 ); qsort( trialResults, numTrials, sizeof(double), doubleCompare ); printf( "VaR = %.16f\n", 100.0*NS - trialResults[(size_t)floor( 0.05 * numTrials )] ); delete [] trialResults; return 0; }