• TIME TO 2024 UK RANKINGS

  • C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

Binomial-tree for CoCo-bonds

Joined
10/12/11
Messages
28
Points
11
First off, not sure if this thread is posted in the right section. Anyway, here goes.

After reading the report Design of Contingent Capital with a Stock Price Trigger for Mandatory Conversion by Suresh Sundaresan and Zhenyu Wang, I decided to try and construct the binomial-tree they describe on page 16.

I've done my programming in R, and here is how I rationalized:

Okay - so I know, I need a binomial-tree/model with 2500 steps. That should be manageable. For the input I used:




C++:
# Sundaresan
 
# Binomial Tree
 
 
 
 
A0 <- 100 #Asset value at t=0
 
vol <- 0.06 #Asset volatility
 
B0 <- 90.43 #Bond value at t=0
 
r <- 0.02 #Risk-free rate
 
CC <- 6 #Par value of CoCo-bonds
 
steps <- 2500 #Steps in the model (=2500. Usually less when testing)
 
years <- 5 #TTM for debt
 
DaysPerYear <- 250 #Trading days in one year
 
t <- (years*DaysPerYear)/steps #t-step
 
u <- exp(vol*sqrt(t)) #The multiplicator for an up-movement
 
d <- exp(-vol*sqrt(t)) #The multiplicator for an down-movement
 
 
 
 
K <- 2 #Trigger-level (2% of A0 = 2)
 
m <- CC/K #Conversion ratio
 
 
 
 
A <- matrix(0,steps, steps)
 
A[1,1] <- A0 #Making sure the first value (at t=0) is A0
 
 
 
 
for(i in 2:steps)
 
{
 
A[1,i] <- A[1,i-1]*u*(1/(1+r/DaysPerYear))
 
for(j in 2:i) A[j,i] <- A[j-1,i-1]*d*(1/(1+r/DaysPerYear))
 
}
 
 
 
 
B <- A-B0
 
B[B<0] <- 0
 
 
 
 
SNoConv <- B-6
 
SNoConv[SNoConv<0] <- 0
 
 
 
 
SYesConv <- B/(1+m)
 
CCYesConv <- m*B/(1+m)
 
CCNoConv <- CCYesConv
 
 
 
 
for(j in 1:steps)
 
{
 
for(i in 1:steps)
 
{
 
if(SNoConv[i,j] <= 2) CCNoConv[i,j] <- m*SYesConv[i,j]
 
else CCNoConv[i,j] <- 6
 
}
 
}
 
 
 
 
SNoConv[,steps]; SYesConv[,steps]; CCNoConv[,steps]; CCYesConv[,steps]
 
 
 
 
WB_SNoConv <- matrix(0,steps,steps)
 
WB_SYesConv <- matrix(0,steps,steps)
 
WB_CCNoConv <- matrix(0,steps,steps)
 
WB_CCYesConv <- matrix(0,steps,steps)
 
WB_SNoConv[,steps] <- SNoConv[,steps]
 
WB_SYesConv[,steps] <- SYesConv[,steps]
 
WB_CCNoConv[,steps] <- CCNoConv[,steps]
 
WB_CCYesConv[,steps] <- CCYesConv[,steps]
 
 
 
 
for(j in steps:1)
 
{
 
for(i in steps:1)
 
{
 
WB_SNoConv[i-1,j-1]<- (WB_SNoConv[i,j]+WB_SNoConv[i-1,j])/2 * exp(-(r/(DaysPerYear))*t)
 
}
 
}


.. but that didn't really give me the right answer :/

NB: I know I'm using the entire lattice (matrix), but that shouldn't matter - as long as I specify that I only need the last column when working my way back.


..And finally we arrive at the big issue: Does anybody have a piece of programming/code, that can "work back" in an lattice/matrix?


Any inputs are very, very welcome. Also if you read the article, and want to share some interesting ideas that popped up in your head (related, tho). I'm also very interested to hear from you if you have alternatives to the binomial-model when the pay-off is path-dependent.


Thank you all in advance,

J
 
I bumping this thread. (Bum!)
Noone with a piece of binomial-tree-code?

Here's the code (again) in a little more accessible fashion:
Code:
# Sundaresan
# Binomial Tree

A0 <- 100 #Asset value at t=0
vol <- 0.06 #Asset volatility
B0 <- 90.43 #Bond value at t=0
r <- 0.02 #Risk-free rate
CC <- 6 #Par value of CoCo-bonds
steps <- 2500 #Steps in the model (=2500. Usually less when testing)
years <- 1 #TTM for debt
DaysPerYear <- 250 #Trading days in one year
t <- (years*DaysPerYear)/steps #t-step
u <- exp(vol*sqrt(t)) #The multiplicator for an up-movement
d <- exp(-vol*sqrt(t)) #The multiplicator for an down-movement

K <- 2 #Trigger-level (2% of A0 = 2)
m <- CC/K #Conversion ratio

A <- matrix(0,steps, steps)
A[1,1] <- A0 #Making sure the first value (at t=0) is A0

for(i in 2:steps)
{
    A[1,i] <- A[1,i-1]*u*(1/(1+r/DaysPerYear))

    for(j in 2:i) A[j,i] <- A[j-1,i-1]*d*(1/(1+r/DaysPerYear))

}

B <- A-B0
B[B<0] <- 0

SNoConv <- B-6
SNoConv[SNoConv<0] <- 0

SYesConv <- B/(1+m)
CCYesConv <- m*B/(1+m)
CCNoConv <- CCYesConv

for(j in 1:steps)
{
    for(i in 1:steps)
    {

        if(SNoConv[i,j] <= 2) CCNoConv[i,j] <- m*SYesConv[i,j]

        else CCNoConv[i,j] <- 6

    }

}

SNoConv[,steps]; SYesConv[,steps]; CCNoConv[,steps]; CCYesConv[,steps]

SNoConv[1,1]; SYesConv[1,1]; CCNoConv[1,1]; CCYesConv[1,1]

WB_SNoConv <- matrix(0,steps,steps)
WB_SYesConv <- matrix(0,steps,steps)
WB_CCNoConv <- matrix(0,steps,steps)
WB_CCYesConv <- matrix(0,steps,steps)
WB_SNoConv[,steps] <- SNoConv[,steps]
WB_SYesConv[,steps] <- SYesConv[,steps]
WB_CCNoConv[,steps] <- CCNoConv[,steps]
WB_CCYesConv[,steps] <- CCYesConv[,steps]

for(j in steps:1)
{
    for(i in steps:1)
    {

        WB_SNoConv[i-1,j-1] <- (WB_SNoConv[i,j]+WB_SNoConv[i-1,j])/2 * exp(-(r/(DaysPerYear))*t)
        WB_SYesConv[i-1,j-1] <- (WB_SYesConv[i,j]+WB_SYesConv[i-1,j])/2 * exp(-(r/(DaysPerYear))*t)
        WB_CCNoConv[i-1,j-1] <- (WB_CCNoConv[i,j]+WB_CCNoConv[i-1,j])/2 * exp(-(r/(DaysPerYear))*t)
        WB_CCYesConv[i-1,j-1] <- (WB_CCYesConv[i,j]+WB_CCYesConv[i-1,j])/2 * exp(-(r/(DaysPerYear))*t)

    }

}
 
Okay, I just rechecked the code, and I've made some few adjustments (see bottom), which yields the results:

C++:
> WB_SNoConv[1,1]
[1] 2.262127
> WB_SYesConv[1,1]
[1] 1.570349
> WB_CCNoConv[1,1]
[1] 3.633149
> WB_CCYesConv[1,1]
[1] 4.711046

And I need:
Stock prices in the range [3.83, 4.45]
CC value in the range [5.12, 5.74]

So basically, both my results are a little too low. Can anyone see if I've made an obvious mistake? I will continue working on this. Thanks.

C++:
# Sundaresan
# Binomial Tree

# Initialization
A0 <- 100 #Asset value at t=0
vol <- 0.06 #Asset volatility
B0 <- 90.43 #Bond value at t=0
r <- 0.02 #Risk-free rate
CC <- 6 #Par value of CoCo-bonds
TTM <- 5 #TTM for debt (in years)
M <- TTM*2
DaysPerYear <- 250 #Trading days in one year
M <- M*DaysPerYear
t <- TTM*1/M #t-step
u <- exp(vol*sqrt(t)) #The multiplicator for an up-movement
d <- exp(-vol*sqrt(t)) #The multiplicator for an down-movement

p <- (exp(r*t)-d)/(u-d)

K <- 2 #Trigger-level (2% of A0 = 2)
m <- CC/K #Conversion ratio

A <- matrix(0,steps, steps)
A[1,1] <- A0 #Making sure the first value (at t=0) is A0

for(i in 2:steps)
{
    A[1,i] <- A[1,i-1]*u*exp(-r*t)

    for(j in 2:i) A[j,i] <- A[j-1,i-1]*d*exp(-r*t)

}

# Paying back debt (B0)
B <- A-B0
# If negative. Bank defaulted. Thus value for CC and Equity = 0
B[B<0] <- 0

# Share value if no conversion before maturity
SNoConv <- B-6
SNoConv[SNoConv<0] <- 0

# Share value if conversion before maturity
SYesConv <- B/(1+m)
# CC value if conversion before maturity
CCYesConv <- m*B/(1+m)
CCNoConv <- CCYesConv

for(j in 1:steps)
{
    for(i in 1:steps)
    {
        if(SNoConv[i,j] <= 2) CCNoConv[i,j] <- m*SYesConv[i,j]
        else CCNoConv[i,j] <- 6
    }

}
 
SNoConv[,steps]; SYesConv[,steps]; CCNoConv[,steps]; CCYesConv[,steps]

SNoConv[1,1]; SYesConv[1,1]; CCNoConv[1,1]; CCYesConv[1,1]

WB_SNoConv <- WB_SYesConv <- WB_CCNoConv <- WB_CCYesConv <- matrix(0,steps,steps)
WB_SNoConv[,steps] <- SNoConv[,steps]
WB_SYesConv[,steps] <- SYesConv[,steps]
WB_CCNoConv[,steps] <- CCNoConv[,steps]
WB_CCYesConv[,steps] <- CCYesConv[,steps]

for(j in steps:1)
{
    for(i in steps:1)
    {
        WB_SNoConv[i-1,j-1] <- (p*WB_SNoConv[i,j]+WB_SNoConv[i-1,j]*(1-p)) * exp(-r*t)
        WB_SYesConv[i-1,j-1] <- (p*WB_SYesConv[i,j]+WB_SYesConv[i-1,j]*(1-p)) * exp(-r*t)
        WB_CCNoConv[i-1,j-1] <- (p*WB_CCNoConv[i,j]+WB_CCNoConv[i-1,j]*(1-p)) * exp(-r*t)
        WB_CCYesConv[i-1,j-1] <- (p*WB_CCYesConv[i,j]+WB_CCYesConv[i-1,j]*(1-p)) * exp(-r*t)
    }

}

# Check
WB_SNoConv[1,1]
WB_SYesConv[1,1]
WB_CCNoConv[1,1]
WB_CCYesConv[1,1]
 
Okay guys, I will pay for tips or help that would yield a correct solution. Tell me your price, and I'll let you know if I'm interested or not. Muchas gracias.
 
Back
Top