#pragma once #include #include #include #include #include #include #include #include #include //Precision to use for calculations typedef struct OptionData_ { float s; // spot price float strike; // strike price float r; // risk-free interest rate float divq; // dividend rate float v; // volatility float t; // time to maturity or option expiration in years // (1yr = 1.0, 6mos = 0.5, 3mos = 0.25, ..., etc) char OptionType; // Option type. "P"=PUT, "C"=CALL float divs; // dividend vals (not used in this test) float DGrefval; // DerivaGem Reference Value } OptionData; extern OptionData *optdata; extern float *prices; extern int numOptions; extern int NUM_RUNS; extern int* otype; extern float* sptprice; extern float* strike; extern float* rate; extern float* volatility; extern float* otime; extern int numError; extern float* BUFFER; extern int* BUFFER2; //////////////////////////////////////////////////////////////////////////////// // Cumulative Normal Distribution Function // See Hull, Section 11.8, P.243-244 //////////////////////////////////////////////////////////////////////////////// #define inv_sqrt_2xPI 0.39894228040143270286 inline float CNDF( float InputX ) { int sign; float OutputX; float xInput; float xNPrimeofX; float expValues; float xK2; float xK2_2, xK2_3; float xK2_4, xK2_5; float xLocal, xLocal_1; float xLocal_2, xLocal_3; // Check for negative value of InputX if (InputX < 0.0) { InputX = -InputX; sign = 1; } else { sign = 0; } xInput = InputX; // Compute NPrimeX term common to both four & six decimal accuracy calcs expValues = std::exp(-0.5f * InputX * InputX); xNPrimeofX = expValues; xNPrimeofX = xNPrimeofX * inv_sqrt_2xPI; xK2 = 0.2316419 * xInput; xK2 = 1.0 + xK2; xK2 = 1.0 / xK2; xK2_2 = xK2 * xK2; xK2_3 = xK2_2 * xK2; xK2_4 = xK2_3 * xK2; xK2_5 = xK2_4 * xK2; xLocal_1 = xK2 * 0.319381530; xLocal_2 = xK2_2 * (-0.356563782); xLocal_3 = xK2_3 * 1.781477937; xLocal_2 = xLocal_2 + xLocal_3; xLocal_3 = xK2_4 * (-1.821255978); xLocal_2 = xLocal_2 + xLocal_3; xLocal_3 = xK2_5 * 1.330274429; xLocal_2 = xLocal_2 + xLocal_3; xLocal_1 = xLocal_2 + xLocal_1; xLocal = xLocal_1 * xNPrimeofX; xLocal = 1.0 - xLocal; OutputX = xLocal; if (sign) { OutputX = 1.0 - OutputX; } return OutputX; } inline float BlkSchlsEqEuroNoDiv( float sptprice, float strike, float rate, float volatility, float time, int otype, float) { float OptionPrice; // local private working variables for the calculation //float xStockPrice; // These two variables are not used //float xStrikePrice; float xRiskFreeRate; float xVolatility; float xTime; float xSqrtTime; float logValues; float xLogTerm; float xD1; float xD2; float xPowerTerm; float xDen; float d1; float d2; float FutureValueX; float NofXd1; float NofXd2; float NegNofXd1; float NegNofXd2; //xStockPrice = sptprice; //xStrikePrice = strike; xRiskFreeRate = rate; xVolatility = volatility; xTime = time; xSqrtTime = std::sqrt(xTime); logValues = std::log(sptprice/strike); xLogTerm = logValues; xPowerTerm = xVolatility * xVolatility; xPowerTerm = xPowerTerm * 0.5; xD1 = xRiskFreeRate + xPowerTerm; xD1 = xD1 * xTime; xD1 = xD1 + xLogTerm; xDen = xVolatility * xSqrtTime; xD1 = xD1 / xDen; xD2 = xD1 - xDen; d1 = xD1; d2 = xD2; NofXd1 = CNDF( d1 ); NofXd2 = CNDF( d2 ); FutureValueX = strike * ( std::exp( -(rate)*(time) ) ); if (otype == 0) { OptionPrice = (sptprice * NofXd1) - (FutureValueX * NofXd2); } else { NegNofXd1 = (1.0 - NofXd1); NegNofXd2 = (1.0 - NofXd2); OptionPrice = (FutureValueX * NegNofXd2) - (sptprice * NegNofXd1); } return OptionPrice; } inline void check_error(unsigned i, float price) { float priceDelta = optdata[i].DGrefval - price; if(std::fabs(priceDelta) >= 1e-4 ){ printf("Error on %d. Computed=%.5f, Ref=%.5f, Delta=%.5f\n", i, price, optdata[i].DGrefval, priceDelta); numError ++; } } // Sequential version inline void bs_seq(float *seq_prices) { int i, j; float price; for (j=0; j(malloc(numOptions*sizeof(OptionData))); prices = static_cast(malloc(numOptions*sizeof(float))); for(int i=0; i(malloc(5 * numOptions * sizeof(float) + PAD)); sptprice = reinterpret_cast(((unsigned long long)BUFFER + PAD) & ~(LINESIZE - 1)); strike = sptprice + numOptions; rate = strike + numOptions; volatility = rate + numOptions; otime = volatility + numOptions; BUFFER2 = static_cast(malloc(numOptions * sizeof(float) + PAD)); //otype = (int *) (((unsigned long long)BUFFER2 + PAD) & ~(LINESIZE - 1)); otype = reinterpret_cast(((unsigned long long)BUFFER2 + PAD) & ~(LINESIZE - 1)); for(auto i=0; i