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
>>>>
>>>