private static void GeneratePaths(float[] paths, float r, float sigma, float dt, int numSims, int numTimesteps) { // int tid = (BlockIndex.X * BlockDimension.X) + ThreadIndex.X; int step = GridDimension.X * BlockDimension.X; // Compute parameters float drift = (r - (0.5f * sigma * sigma)) * dt; float diffusion = sigma * DeviceMath.Sqrt(dt); // Simulate the paths for (int i = tid; i < numSims; i += step) { // Current output index int output = i; // Simulate the path float s = 1.0f; for (int t = 0; t < numTimesteps; t++, output += numSims) { s *= DeviceMath.Exp(drift + (diffusion * NormalRNG.NextFloat())); paths[output] = s; } } }
private static void BlackScholesGPUKernel(float[] callResult, float[] putResult, float[] stockPrice, float[] optionStrike, float[] optionYears, float riskFree, float volatility) { // Thread index int ThreadId = BlockDimension.X * BlockIndex.X + ThreadIndex.X; // Total number of threads in execution grid int TotalThreads = BlockDimension.X * GridDimension.X; // No matter how small execution grid is, or how many options we're processing, // by using this loop we'll get perfect memory coalescing for (int OptionIndex = ThreadId; OptionIndex < callResult.Length; OptionIndex += TotalThreads) { float s = stockPrice[OptionIndex]; float x = optionStrike[OptionIndex]; float t = optionYears[OptionIndex]; // Calculate the square root of the time to option expiration, in years float SqrtT = DeviceMath.Sqrt(t); // Calculate the Black-Scholes parameters float d1 = (DeviceMath.Log(s / x) + (riskFree + 0.5f * volatility * volatility) * t) / (volatility * SqrtT); float d2 = d1 - volatility * SqrtT; // Plug the parameters into the Cumulative Normal Distribution (CND) float K1 = 1.0f / (1.0f + 0.2316419f * DeviceMath.Abs(d1)); float CndD1 = RSQRT2PI * DeviceMath.Exp(-0.5f * d1 * d1) * (K1 * (A1 + K1 * (A2 + K1 * (A3 + K1 * (A4 + K1 * A5))))); if (d1 > 0) { CndD1 = 1.0f - CndD1; } float K2 = 1.0f / (1.0f + 0.2316419f * DeviceMath.Abs(d2)); float CndD2 = RSQRT2PI * DeviceMath.Exp(-0.5f * d2 * d2) * (K2 * (A1 + K2 * (A2 + K2 * (A3 + K2 * (A4 + K2 * A5))))); if (d2 > 0) { CndD2 = 1.0f - CndD2; } // Calculate the discount rate float ExpRT = DeviceMath.Exp(-1.0f * riskFree * t); // Calculate the values of the call and put options callResult[OptionIndex] = s * CndD1 - x * ExpRT * CndD2; putResult[OptionIndex] = x * ExpRT * (1.0f - CndD2) - s * (1.0f - CndD1); } }