|
| 1 | +# Roofline example: option pricing |
1 | 2 |
|
| 3 | +In this example we setup a roofline model methodology to test the resolution of a binomial tree using a slow implementation. |
| 4 | + |
| 5 | +```julia |
| 6 | +rfd_rt(r,t_per_p) = rfd(t) = exp(-r * t * t_per_p) |
| 7 | +up_st(sigma, t_per_p) = exp(sigma * sqrt(t_per_p)) |
| 8 | + |
| 9 | +struct _Parameters |
| 10 | + sigma :: Float64 |
| 11 | + periods :: Int |
| 12 | + t_per_p :: Float64 |
| 13 | + rfd :: Function |
| 14 | + up :: Float64 |
| 15 | + K :: Float64 |
| 16 | + S0 :: Float64 |
| 17 | + p :: Float64 |
| 18 | +end |
| 19 | + |
| 20 | +function setupProblem(sigma, t, periods_per_t, risk_free_rate, strike, price, p) :: _Parameters |
| 21 | + return _Parameters( |
| 22 | + sigma, |
| 23 | + t * periods_per_t, |
| 24 | + 1 / periods_per_t, |
| 25 | + rfd_rt(risk_free_rate, 1 / periods_per_t), |
| 26 | + up_st(sigma, 1 / periods_per_t), |
| 27 | + strike, |
| 28 | + price, |
| 29 | + p |
| 30 | + ) |
| 31 | +end |
| 32 | + |
| 33 | +function createBinomialTree(p :: _Parameters)::Tuple{Matrix,Array} |
| 34 | + |
| 35 | + nodes = (p.periods + 1) * p.periods ÷ 2 |
| 36 | + # A and b |
| 37 | + Tree = zeros(Float64, nodes, nodes) |
| 38 | + B = zeros(Float64, nodes) |
| 39 | + |
| 40 | + # Fill the body of the tree with the discounted expectations |
| 41 | + for period in 1:(p.periods-1) |
| 42 | + _nodes = ((period-1)*period÷2+1):((period+1)*(period+0)÷2) |
| 43 | + for node in _nodes |
| 44 | + Tree[node, node] = -1 |
| 45 | + Tree[node, node+period] = p.p * p.rfd(p.periods - period) |
| 46 | + Tree[node, node+period+1] = 1 - p.p * p.rfd(p.periods - period) |
| 47 | + end |
| 48 | + end |
| 49 | + |
| 50 | + # Fill the last level of the tree with the prices at maturity |
| 51 | + xa = ((p.periods - 1) * p.periods ÷ 2 + 1) |
| 52 | + xb = ((p.periods + 1) * (p.periods + 0) ÷ 2) |
| 53 | + down = 1 / p.up |
| 54 | + |
| 55 | + for node in xa:xb |
| 56 | + Tree[node, node] = 1 |
| 57 | + B[node] = max((p.S0 * p.up^(xb - node) * down^(node - xa)) - p.K, 0.0) |
| 58 | + end |
| 59 | + return Tree, B |
| 60 | +end |
| 61 | + |
| 62 | + |
| 63 | +function solveTree(A::Matrix, b::Array, periods::Int)::Array |
| 64 | + |
| 65 | + nodes = (periods + 1) * periods ÷ 2 |
| 66 | + X = zeros(Float64, nodes) |
| 67 | + # Last level nodes from a to b |
| 68 | + xa = ((periods - 1) * periods ÷ 2 + 1) |
| 69 | + xb = ((periods + 1) * (periods + 0) ÷ 2) |
| 70 | + for node in xa:xb |
| 71 | + X[node] = b[node] |
| 72 | + end |
| 73 | + # Tree core nodes |
| 74 | + for period in (periods-1):-1:1 |
| 75 | + _nodes = ((period-1)*period÷2+1):((period+1)*(period+0)÷2) |
| 76 | + for node in _nodes |
| 77 | + X[node] = A[node, node+period] * b[node+period] + A[node, node+period+1] * b[node+period+1] |
| 78 | + b[node] = X[node] |
| 79 | + end |
| 80 | + end |
| 81 | + |
| 82 | + return X |
| 83 | +end |
| 84 | + |
| 85 | +option_price(solution :: Array) = solution[1] |
| 86 | + |
| 87 | +``` |
| 88 | + |
| 89 | +The following is the recipe file that sets up the performance test suite: |
| 90 | + |
| 91 | +```julia |
| 92 | +using Test |
| 93 | +using PerfTest |
| 94 | + |
| 95 | +include("main3.jl") |
| 96 | + |
| 97 | +# CONFIG |
| 98 | +@perftest_config begin |
| 99 | + regression.enabled = false |
| 100 | + roofline.autoflops = true |
| 101 | + roofline.tolerance.min_percentage = 1.0 |
| 102 | +end |
| 103 | + |
| 104 | + |
| 105 | +@testset "Performance Tests" begin |
| 106 | + |
| 107 | + @testset "Tree construction" begin |
| 108 | + |
| 109 | + @testset "Periods" for n_periods in [16, 64, 128] |
| 110 | + |
| 111 | + param = setupProblem(0.04, 1, n_periods, 0.04, 100, 100, 0.5) |
| 112 | + |
| 113 | + @roofline actual_flops=:autoflop target_ratio=0.05 begin |
| 114 | + mem = ((:iterator + 1) * :iterator) |
| 115 | + :autoflop / mem |
| 116 | + end |
| 117 | + A, b = createBinomialTree(param) |
| 118 | + |
| 119 | + |
| 120 | + @perftest solveTree(A, b, param.periods) |
| 121 | + end |
| 122 | + end |
| 123 | +end |
| 124 | +``` |
| 125 | + |
| 126 | +The recipe file specifies the following: |
| 127 | + - The target will be evaluated using a roofline model |
| 128 | + - The basic regression methodology is disabled |
| 129 | + - The tolerance below the threshold will be zero |
| 130 | + - The autoflops feature is enabled |
| 131 | + - The roofline macro additionally receives how to calculate the flop count (actual_lops=:autoflop) and the threshold of the actual performance vs model performance is 5% |
0 commit comments