Eric, This is really helpful. I've been able to implement this plus the traversal of the "tree" matrix to get the option value. I had to use some creative looping to build the payoff matrix, but it gives me back the right values and it's pretty quick as well:
function option_value_tree_matrix(K::Float64, n::Int64, binom::Array, qu::Float64, qd::Float64, df::Float64, is_call::Bool, is_euro::Bool) payoffs = zeros(n + 1, n + 1) for i = 1:n + 1 payoffs[n+1 - (i - 1), i] = max(0, is_call ? binom[n+1 - (i - 1), i] - K : K - binom[n+1 - (i - 1), i]) end for i = n:-1:1, j = n - (i - 1):-1:1 payoffs[i,j] = (qu * payoffs[i, j+1] + qd * payoffs[i+1, j]) * df if ! is_euro payoffs[i,j] = check_early_exercise(payoffs[i,j], binom[i,j], K, is_call) end end return payoffs end binom here is the binomial tree matrix as you discussed above. I am wondering if flipping the matrix 90 deg to the left (rot90l is the method), and then using "diag" might be better/faster though... Chris On Saturday, October 24, 2015 at 8:34:12 PM UTC-4, Eric Forgy wrote: > > Hi Christopher, > > There may be a better way (and I'm sure my Julia code sucks), but in terms > of fitting a binary tree into a matrix (and n-tree into an n-array), this > is what I meant: > > julia> function build_tree(S0::Float64,pu::Float64,pd::Float64,N::Int64) > stockTree = zeros(N,N) > > u = 1 + pu > d = 1 - pd > for i = 1:N > for j = 1:N > stockTree[i,j] = S0 * u ^ (j-1) * d ^ (i-1) > end > end > > return stockTree > end > build_tree (generic function with 2 methods) > > julia> build_tree(50.0,.2,.2,5) > 5x5 Array{Float64,2}: > 50.0 60.0 72.0 86.4 103.68 > 40.0 48.0 57.6 69.12 82.944 > 32.0 38.4 46.08 55.296 66.3552 > 25.6 30.72 36.864 44.2368 53.0842 > 20.48 24.576 29.4912 35.3894 42.4673 > > > If you look at this with your head tilted sideways, you will see a binary > tree :) > > As a sidenote, I've considered (time permitting - and it is never > permitting) to develop a discrete stochastic calculus Julia package > following ideas from automatic differentiation, e.g. ForwardDiff.jl, that > can solve these tree pricing problems automatically following the "meta" > concepts in the paper I linked to. More generally, there is a unique > "calculus" (abstract differential algebra > <https://en.wikipedia.org/wiki/Differential_algebra>) associated with > every directed graph and conversely, given a differential algebra it is a > fun problem to find a directed graph that gives rise to that algebra. For > both exterior calculus and stochastic calculus, it turns out that the > binary tree is "unreasonably effective". > > On Saturday, October 24, 2015 at 11:48:26 PM UTC+8, Christopher Alexander > wrote: >> >> Eric, thanks for the response and pointers! In terms of constructing a >> Matrix, are you talking about something like this? >> >> *3x3 Array{Float64,2}:* >> >> * 50.0 40.0 32.0* >> >> * 0.0 60.0 48.0* >> >> * 0.0 0.0 72.0* >> >> >> The graph option is interesting too, I hadn't thought about that. Thanks >> for the link to the paper, this is extremely helpful! >> >> Thanks! >> >> Chris >> >> >> On Friday, October 23, 2015 at 8:35:53 PM UTC-4, Eric Forgy wrote: >>> >>> Hi Christopher, >>> >>> I am just learning then Julian way myself, but one thing that "might" be >>> better than an array of growing arrays is to note that a binary tree can be >>> laid into a matrix, i.e. Array{Float64,2}, by rotating it. This is nice in >>> case you ever need a ternary tree, which could be represented by >>> Array{Float64,3}, etc. >>> >>> Another thing you might consider is to treat the tree as a directed >>> graph and look at incorporating one of the Julia graph theory packages. >>> >>> On the topic, I have a paper (shameless plug alert!) you might be >>> interested in: >>> >>> - *Financial Modelling Using Discrete Stochastic Calculus* >>> <http://phorgyphynance.files.wordpress.com/2008/06/discretesc.pdf> >>> >>> More papers here <https://phorgyphynance.wordpress.com/my-papers/>. >>> >>> >>> On Saturday, October 24, 2015 at 7:50:59 AM UTC+8, Christopher Alexander >>> wrote: >>>> >>>> Hello all, >>>> >>>> I am trying to write a method that builds a binomial tree for option >>>> pricing. I am trying to set up my tree like this: >>>> >>>> function build_tree(s_opt::StockOption) >>>> u = 1 + s_opt.pu >>>> d = 1 - s_opt.pd >>>> # qu = (exp((s_opt.r - s_opt.div) * s_opt.dt) - d) / (u - d) >>>> # qd = 1 - qu >>>> >>>> # init array >>>> stockTree = Vector{Float64}[ zeros(m) for m = 1:s_opt.N + 1] >>>> >>>> for i = 1:s_opt.N + 1 >>>> for j = 1:i >>>> stockTree[i][j] = s_opt.S0 * u ^ (j-1) * d ^ (i - j) >>>> end >>>> end >>>> >>>> return stockTree >>>> end >>>> >>>> Is this the most "Julian" way to do this (I didn't find really any >>>> modules that would suit this purpose)? >>>> >>>> Here is what prints out: >>>> >>>> *3-element Array{Array{Float64,1},1}:* >>>> >>>> * [50.0] * >>>> >>>> * [40.0,60.0] * >>>> >>>> * [32.00000000000001,48.0,72.0]* >>>> >>>> I suppose also I could default the [1][1] state to the spot price (S0), >>>> so then I don't need to alter the looping range and instead start the >>>> range >>>> at 2. >>>> >>>> Thanks! >>>> >>>> Chris >>>> >>>