File: black_scholes_options.py

package info (click to toggle)
python-arrayfire 3.3.20160624-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 764 kB
  • ctags: 826
  • sloc: python: 3,999; makefile: 205
file content (80 lines) | stat: -rw-r--r-- 1,902 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/python

#######################################################
# Copyright (c) 2015, ArrayFire
# All rights reserved.
#
# This file is distributed under 3-clause BSD license.
# The complete license agreement can be obtained at:
# http://arrayfire.com/licenses/BSD-3-Clause
########################################################

import arrayfire as af
from time import time
import math
import sys

sqrt2 = math.sqrt(2.0)

def cnd(x):
    temp = (x > 0)
    return temp * (0.5 + af.erf(x/sqrt2)/2) + (1 - temp) * (0.5 - af.erf((-x)/sqrt2)/2)

def black_scholes(S, X, R, V, T):
    # S = Underlying stock price
    # X = Strike Price
    # R = Risk free rate of interest
    # V = Volatility
    # T = Time to maturity

    d1 = af.log(S / X)
    d1 = d1 + (R + (V * V) * 0.5) * T
    d1 = d1 / (V * af.sqrt(T))

    d2 = d1 - (V * af.sqrt(T))
    cnd_d1 = cnd(d1)
    cnd_d2 = cnd(d2)

    C = S * cnd_d1 - (X * af.exp((-R) * T) * cnd_d2)
    P = X * af.exp((-R) * T) * (1 - cnd_d2) - (S * (1 -cnd_d1))

    return (C, P)

if __name__ == "__main__":
    if (len(sys.argv) > 1):
        af.set_device(int(sys.argv[1]))
    af.info()

    M = 4000

    S = af.randu(M, 1)
    X = af.randu(M, 1)
    R = af.randu(M, 1)
    V = af.randu(M, 1)
    T = af.randu(M, 1)

    (C, P) = black_scholes(S, X, R, V, T)
    af.eval(C)
    af.eval(P)
    af.sync()

    num_iter = 100
    for N in range(50, 501, 50):
        S = af.randu(M, N)
        X = af.randu(M, N)
        R = af.randu(M, N)
        V = af.randu(M, N)
        T = af.randu(M, N)
        af.sync()

        print("Input data size: %d elements" % (M * N))

        start = time()
        for i in range(num_iter):
            (C, P) = black_scholes(S, X, R, V, T)
            af.eval(C)
            af.eval(P)
        af.sync()
        sec = (time() - start) / num_iter

        print("Mean GPU Time: %0.6f ms\n\n" % (1000.0 * sec))