Esempio n. 1
0
    def test_pseudo(self):
        from pyculib import rand
        prng = rand.PRNG()
        prng.seed = 0xbeef
        N = 10
        ary = np.zeros(N, dtype=np.float32)
        prng.uniform(ary, N)
        self.assertTrue(any(ary != 0))

        iary = np.zeros(N, dtype=np.uint32)
        prng.poisson(iary, N)
        self.assertTrue(any(iary != 0))
Esempio n. 2
0
def montecarlo(paths, dt, interest, volatility):
    c0 = interest - 0.5 * volatility**2
    c1 = volatility * np.sqrt(dt)

    prng = curand.PRNG(rndtype=curand.PRNG.XORWOW)
    d_noises = cuda.device_array(paths.shape[0])

    d_current = cuda.to_device(paths[:, 0])
    d_next = cuda.device_array(paths.shape[0])

    for j in range(1, paths.shape[1]):  #for each time step
        #prices = paths[:, j - 1]            #last prices # Now no slicing needed
        #gaussian noise for simulation
        #noises = np.random.normal(0., 1., prices.size)
        prng.normal(d_noises, 0., 1.)
        #simulate
        d_next = step(d_current, dt, c0, c1, d_noises)

        d_next.copy_to_host(paths[:, j])

        d_next, d_current = d_current, d_next
Esempio n. 3
0
def cuda_jit_montecarlo(timespan, n):
    """Compute the Monte Carlo scenarios

    :param timespan: Array of the time discretization
    :param n: Number of Monte Carlo paths
    :type timespan: M+1 array
    :type n: int
    :returns: (sorting_value, basis, expect_basis, expect_brownian_basis, riskfree_price,
              riskfree_delta, adjusted_price, adjusted_delta)
    :rtypes: (N x (M+1) array, N x Q x M array, N x Q x M array, N x Q x q x M array,
    N x 1 array, N x q array, Nx 1 array, N x q array)
    """
    no_of_timesteps = timespan.shape[0]  # M+1
    stock_data = np.ones((n, 1)) * INITIAL_VALUE
    sorting_value = np.empty((n, no_of_timesteps))
    basis = np.empty((n, BASIS_ORDER, no_of_timesteps - 1))
    expect_basis = np.empty((n, BASIS_ORDER, no_of_timesteps - 1))
    expect_brownian_basis = np.empty(
        (n, BASIS_ORDER, NUM_OF_BROWNIAN_MOTION, no_of_timesteps - 1))
    riskfree_price = np.zeros((n, 1))
    riskfree_delta = np.zeros((n, NUM_OF_BROWNIAN_MOTION))
    adjusted_price = np.zeros((n, 1))
    adjusted_delta = np.zeros((n, NUM_OF_BROWNIAN_MOTION))

    blksz = 256
    gridsz = int(math.ceil(float(n) / blksz))

    # instantiate a CUDA stream for queueing async CUDA cmds
    stream = cuda.stream()

    # instantiate a cuRAND PRNG
    prng = rand.PRNG(rndtype=rand.PRNG.MRG32K3A,
                     seed=int(time.time()),
                     stream=stream)

    # Allocate device side array
    d_normdist = cuda.device_array(n * NUM_OF_BROWNIAN_MOTION,
                                   dtype=np.double,
                                   stream=stream)
    d_drift = cuda.device_array((n, NUM_OF_ASSETS),
                                dtype=np.double,
                                stream=stream)
    d_volatility = \
    cuda.device_array((n, NUM_OF_ASSETS, NUM_OF_BROWNIAN_MOTION), dtype=np.double, stream=stream)
    d_sorting_value = cuda.device_array_like(sorting_value[:, 0],
                                             stream=stream)
    d_weighted_stock = cuda.device_array_like(stock_data, stream=stream)
    d_basis = cuda.device_array(n, dtype=np.double, stream=stream)
    d_basis_expectation = cuda.device_array(n, dtype=np.double, stream=stream)
    d_basis_brownian_expectation = cuda.device_array(n,
                                                     dtype=np.double,
                                                     stream=stream)
    d_price = cuda.device_array((n, 1), dtype=np.double, stream=stream)
    d_delta = cuda.device_array((n, NUM_OF_BROWNIAN_MOTION),
                                dtype=np.double,
                                stream=stream)

    step_cfg = cuda_jit_step_euler[gridsz, blksz,
                                   stream]  # The forward simulation scheme

    for k in range(no_of_timesteps):
        # Calculate the time interval
        current_time = timespan[k]
        if k != 0:
            previous_time = timespan[k - 1]
            dt = current_time - previous_time
        if k != no_of_timesteps - 1:
            next_time = timespan[k + 1]
            forward_time_interval = next_time - current_time

        if k == 0:
            # transfer the initial prices
            d_last = cuda.to_device(stock_data, stream=stream)
        else:
            # call cuRAND to populate d_normdist with gaussian noises
            prng.normal(d_normdist, mean=0, sigma=1)
            # invoke step kernel asynchronously
            step_cfg(d_last, dt, d_drift, d_volatility, d_normdist)

        # Calculate the stock model parameters.
        cuda_jit_drift[gridsz, blksz, stream](d_last, MU_BAR, d_drift)
        cuda_jit_volatility[gridsz, blksz,
                            stream](d_last, SIGMA_BAR, CHOLESKY_DECOMPOSITION,
                                    d_volatility)

        # Calculate the sorting value
        cuda_sorting_method[gridsz, blksz, stream](WEIGHT, d_last,
                                                   d_sorting_value)
        sorting_value[:, k] = d_sorting_value.copy_to_host()

        # Calculate the basis function and its two types of expectations
        if k != 0:
            cuda_weighted_stock[gridsz, blksz, stream](WEIGHT, d_last,
                                                       d_weighted_stock)
            for j in range(BASIS_ORDER):
                basis_partition = star_and_bin_array(j, NUM_OF_ASSETS)
                cuda_jit_basis[gridsz, blksz,
                               stream](d_weighted_stock, basis_partition, j,
                                       d_basis)
                basis[:, j, k - 1] = d_basis.copy_to_host()
        if k != no_of_timesteps - 1:
            expect_basis[:, 0, k] = 1.
            expect_brownian_basis[:, 0, :, k] = 0.
            for j in range(1, BASIS_ORDER):
                basis_partition = star_and_bin_array(j, NUM_OF_ASSETS)
                basis_gradient_partition = star_and_bin_array(
                    j - 1, NUM_OF_ASSETS)
                cuda_basis_expect[gridsz, blksz,
                                  stream](WEIGHT, d_last, current_time,
                                          d_drift, d_volatility,
                                          forward_time_interval, j,
                                          basis_partition, d_basis_expectation)
                expect_basis[:, j, k] = d_basis_expectation.copy_to_host()
                for l in range(d_volatility.shape[2]):
                    cuda_basis_brownian_expect[gridsz, blksz, stream](
                        WEIGHT, d_last, current_time, d_drift, d_volatility,
                        forward_time_interval, j, l, basis_gradient_partition,
                        d_basis_brownian_expectation)
                    expect_brownian_basis[:, j, l,
                                          k] = d_basis_brownian_expectation.copy_to_host(
                                          )

        stream.synchronize()  # This ensure all GPU work is completed

    #  Calculate the termianl conditions
    cuda_payoff[gridsz, blksz, stream](d_last, WEIGHT, STRIKE, d_price)
    cuda_terminal_delta[gridsz, blksz, stream](d_last, WEIGHT, STRIKE,
                                               d_volatility, d_delta)
    riskfree_price[:, :] = d_price.copy_to_host()
    riskfree_price *= BUY_SELL
    adjusted_price[:, :] = d_price.copy_to_host()
    adjusted_price *= BUY_SELL
    riskfree_delta[:, :] = d_delta.copy_to_host()
    riskfree_delta *= BUY_SELL
    adjusted_delta[:, :] = d_delta.copy_to_host()
    adjusted_delta *= BUY_SELL

    return sorting_value, basis, expect_basis, expect_brownian_basis, riskfree_price, riskfree_delta, adjusted_price, adjusted_delta
Esempio n. 4
0
import numpy as np
from numba import vectorize
import numpy as np
from pyculib import rand as curand

@vectorize(['float32(float32, float32)'], target='cuda')
def Add(a, b):
  return a + b
# Initialize arrays
N = 100000
A = np.ones(N, dtype=np.float32)
B = np.ones(A.shape, dtype=A.dtype)
C = np.empty_like(A, dtype=A.dtype)
# Add arrays on GPU
C = Add(A, B)

prng = curand.PRNG(rndtype=curand.PRNG.XORWOW)
rand = np.empty(100000)
prng.uniform(rand)
print(rand[:10])
Esempio n. 5
0
def generate_pos_2d(lcurve, rcurve, target_area, ly, ry, n, seed):
    nl = ly.size - 1
    nr = ry.size - 1
    assert (len(lcurve) == nl)
    assert (len(rcurve) == nr)
    if min(ly) != min(ry):
        assert (min(ly) == min(ry))
    if max(ly) != max(ry):
        assert (max(ly) == max(ry))

    def collect_2d(n, x, y):
        selected = np.ones(n, dtype=bool)
        for i in range(n):
            for j in range(nl):
                if ly[j] < y[i] and y[i] < ly[j + 1]:
                    if lcurve[j].check(y[i]) > x[i]:
                        selected[i] = False
                        break
            if selected[i]:
                for j in range(nr):
                    if ry[j] < y[i] and y[i] < ry[j + 1]:
                        if rcurve[j].check(y[i]) < x[i]:
                            selected[i] = False
                            break
        pos = np.array([x[selected], y[selected]])
        return pos, sum(selected)

    xmax = max([r.xmax() for r in rcurve])
    xmin = min([l.xmin() for l in lcurve])
    ymax = max(ly)
    ymin = min(ly)
    storming_area = (xmax - xmin) * (ymax - ymin)
    #print(xmax,xmin,ymax,ymin, storming_area)

    ratio = storming_area / target_area
    #print(ratio)
    # to do: if ratio > some threshold rotate the coordinates and implement methods for the corresponding change for the Class of curves, too
    ntmp = np.ceil(n * ratio).astype(int)
    i = 0
    pos = np.empty((2, n), dtype=float)
    prng = rand.PRNG(rndtype=rand.PRNG.XORWOW, seed=seed)
    #qrng = rand.QRNG(rndtype=rand.QRNG.SCRAMBLED_SOBOL32, ndim=2)
    #count = 0
    while (i < n):
        #irands = np.empty((2,ntmp), dtype='uint32')
        rands = np.empty(ntmp, dtype=float)

        prng.uniform(rands)
        #qrng.generate(irands)
        #rands = irands[0,:]/np.iinfo(np.dtype('uint32')).max
        x = xmin + (xmax - xmin) * rands

        prng.uniform(rands)
        #qrng.generate(irands)
        #rands = irands[1,:]/np.iinfo(np.dtype('uint32')).max
        y = ymin + (ymax - ymin) * rands

        acquired_pos, nselected = collect_2d(ntmp, x, y)
        if i + nselected > n:
            nselected = n - i
        pos[:, i:i + nselected] = acquired_pos[:, :nselected]
        i += nselected
        ntmp = np.ceil((n - i) * ratio).astype(int)
        #count += 1
    #print(count)
    return pos