예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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);
            }
        }