8

Is it possible using FinancialBond function to calculate the yield of a bond paying a gradual coupon ?

An example :

A bond with maturity of 7 years pays 4.125% the first 3 years, then 6% the next two and finally 7.75% the last two. The actual price of the bond is 102.35% and it is redeemed at par.

I know the answer using TimeValue and Cashflow functions. It is 5.14601% But I want to know if it is possible to calculate it straight from the FinancialBond function.

F'x
  • 10,817
  • 3
  • 52
  • 92
  • 1
    It will be helpful if you register your account. Right now you have three different ones, with your reputation points fragmented across them. – Verbeia Apr 20 '12 at 09:25
  • Please register your account so that you will have no trouble commenting on answers to your questions. Once you have done so, please flag your post and I shall be merging your unregistered accounts into your registered account. – J. M.'s missing motivation Apr 20 '12 at 14:01
  • 1
    Please also stop posting clarifications to your question as "answers". – Verbeia Apr 23 '12 at 21:58

2 Answers2

6

The More Information section of the help file says

  • The coupon may be specified as a single rate or a time-dependent payment function.

So, you should use

"Coupon" -> (Piecewise[{{.04125, #1 < 3}, {.06, 3 <= #1 < 5}, {.0775, 5 <= #1 < 7}}] &)

For example,

FinancialBond[{"FaceValue"->100,
 "Coupon" -> (Piecewise[{{.04125, #1 < 3}, {.06, 3 <= #1 < 5}, {.0775, 5 <= #1 < 7}}] &),
 "Maturity"->5},{"InterestRate"->r,"Settlement"->0}]

outputs

(* 100/(1+r)^5+(0.00125 (224.+375. r+345. r^2+165. r^3+33. r^4))/(1.+r)^5 *)
Eli Lansey
  • 7,499
  • 3
  • 36
  • 73
  • This is not what I need. I'm not talking about an interest specification, but about a coupon changing over time. How do I define the time-dependent coupon ? As a list, it should be {.04125,.04125,.04125,.06,.06,.0775,.0775}. How get I such a list in "Coupon" ->... The purpose is to calculate the yield of such a bond using FindRoot[...] where within the function FinancialBond, the "InterestRate"->r (unknown) and the FindRoot equals 1.0425 or 1042.5 if I start with a FaceValue of 1,000. That's my problem. – Jean-Pierre Avermaete Apr 18 '12 at 20:46
  • Not sure I understand. Can you give an example of the calculation, but with a constant coupon? – Eli Lansey Apr 18 '12 at 20:51
  • FindRoot[FinancialBond[{"FaceValue" -> 100, "Coupon" -> Piecewise[{{.04125, #1 <= 3}, {.06, 3 < #1 <= 5}, {.0775, 5 < #1 <= 7}}] &, "Maturity" -> 7}, {"InterestRate" -> r, "Settlement" -> 0}] == 104.25, {r, 0.05}] – Jean-Pierre Avermaete Apr 18 '12 at 21:16
  • Sorry, I post it to quickly. When I try to solve the function sent before, this is the error message I get : FindRoot::nlnum: "The function value !({(-104.25\) + FinancialBond[{\"FaceValue\" -> 100., "Coupon" -> Piecewise[{<<3>>}] &, "Maturity" -> 7.}, {\"InterestRate\" -> 0.05, "Settlement" -> 0.}]}\) is not a list of numbers with dimensions {1} at {r} = {0.05}." and nothing happens. When I use your Piecewise solution and give the appropriate yield, the function doesn't work either. – Jean-Pierre Avermaete Apr 18 '12 at 21:19
  • Just to keep things simple. The issue here is that the code:

    FinancialBond[{"FaceValue" -> 100, "Coupon" -> Piecewise[{{.04125, #1 <= 3}, {.06, 3 < #1 <= 5}, {.0775, 5 < #1 <= 7}}] &, "Maturity" -> 7}, InterestRate" -> r, "Settlement" -> 0}]

    Does not evaluate. FindRoot doesn't have anything to do with this.

    – Searke Apr 18 '12 at 21:30
  • An example, Eli, with a constant coupon : – Jean-Pierre Avermaete Apr 18 '12 at 21:30
  • Sorry again, I'm not accustomed with the return button ;o) FindRoot[FinancialBond[{"FaceValue"->100,"Coupon"->5,"Maturity"->5},{"InterestRate"->r,"Settlement"->0}]==104.25,{r,0.05}] gives the answer : {r->0.04415}. I want to be able to do it the same way but with a gradual coupon, so I can derive with the property "Rules" all the other characteristics (duration, convexity and so on). Is it possible ? – Jean-Pierre Avermaete Apr 18 '12 at 21:37
  • I'll update more fully later, but I fixed the code above (I needed parentheses). – Eli Lansey Apr 18 '12 at 23:47
  • @Eli Lansey, That's what I get : FindRoot[TimeValue[{"FaceValue" -> 100, "Coupon" -> (Piecewise[{{0.04125, #1 <= 3}, {0.06, 3 < #1 <= 5}, {0.0775, 5 < #1 <= 7}}] &), "Maturity" -> 7}, {"InterestRate" -> r, "Settlement" -> 0}] == 102.35, {r, 0.05}] FindRoot::nlnum: The function value {-102.35+TimeValue[{FaceValue->100.,Coupon->(Piecewise[{<<3>>}]&),Maturity->7.},{InterestRate->0.05,Settlement->0.}]} is not a list of numbers with dimensions {1} at {r} = {0.05}. >> – Jean-Pierre Avermaete Apr 20 '12 at 17:01
1

Thanks to Sean Clarke from the Support department of Mathematica, I've got my solution. The way to solve such problem is to define the Coupon as a function. It becomes :

In[3]:= FindRoot[
 FinancialBond[{"FaceValue" -> 1, 
    "Coupon" -> 
     Function[t, 
      Which[t <= 3, .04125, 4 <= t <= 5, .06, 6 <= t <= 7, .0775]], 
    "Maturity" -> 7}, {"InterestRate" -> r, "Settlement" -> 0}] == 
  1.0235, {r, .05}]

Out[3]= {r -> 0.0514601}

I've tried other kind of gradual coupon bonds and this approach works perfectly. Thanks everybody for the replies.

István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • 2
    This is basically the same as my answer, just using Which rather than Piecewise. Also, I can't seem to get this to run as typed here. – Eli Lansey Apr 19 '12 at 22:34
  • @EliLansey, ... and your answer with Piecewise is about 10x faster. – kglr Apr 20 '12 at 00:07
  • kguler & Eli Lansey, I've tried once again your approach, but it doesn't work. I still get the same error message I mentioned before. How can you say that it's about ten times faster when it doesn't work ? Can you send me the exact formulation so I can test it ? – Jean-Pierre Avermaete Apr 20 '12 at 08:05
  • @Jean-PierreAvermaete What exactly is the error message you get? Are you doing a cut-and-paste on the code, or re-typing it? – Eli Lansey Apr 20 '12 at 14:45
  • @Jean-PierreAvermaete, for Which versus Piecewise you can try FindRoot[FinancialBond[{"FaceValue" -> 1, "Coupon" -> (Piecewise[{{0.04125, # <= 3}, {0.06, 4 <= # <= 5}, {0.0775, 6 <= # <= 7}}] &), "Maturity" -> 7}, {"InterestRate" -> r, "Settlement" -> 0}] == 1.0235, {r, 0.05}]//Timing and FindRoot[FinancialBond[{"FaceValue" -> 1, "Coupon" -> Function[t, Which[t <= 3, .04125, 4 <= t <= 5, .06, 6 <= t <= 7, .0775]], "Maturity" -> 7}, {"InterestRate" -> r, "Settlement" -> 0}] == 1.0235, {r, .05}] //Timing. – kglr Apr 21 '12 at 06:45
  • @kguler, thanks for the way to see which of both functions is the fastest, but the first version (with Piecewise) doesn't work at all. That's to problem ! – Jean-Pierre Avermaete Apr 21 '12 at 07:51
  • Jean-Pierre, assuming you cut and pasted the code for the first method and still got an error message, it may well be a version or OS related issue (I am using Mma 8.0.4 on Vista); and it will be useful for all of us to learn about the specific error message you are getting. – kglr Apr 21 '12 at 12:34