Post Reply 
Program to calculate bonds
05-31-2015, 08:27 PM (This post was last modified: 06-01-2015 04:24 PM by salvomic.)
Post: #1
Program to calculate bonds
hi,
I'm making a program to calculate price or yield for Bonds (with regulation annually, semiannually and so on, financial or actual year calculation).
Thanks to Dale (DrD) for som tips about "Solve" Wink
I need help (Franz?) to test and improve it, as I think my formulas are "enough" correct, but perhaps not 100%...
I'm comparing it with some results given by HP 12C (see here the Guide), but they differs for 0.2 or less from results of my program; maybe there is only a problem or rounding (or not)...
For "zero coupon" bonds input 0 as "coupon", to calculate the price.

After the program will be enough robust I'll implement better menu and a formula for Options and Black Schole formula (but for that I need more help, hi)...

Thank you in advance for help!

Salvo

EDIT: the program is now in the Software Library of the Forum

The code:
Code:

smenu();

EXPORT Bonds()
BEGIN
smenu();
END;

EXPORT Price()
// by Salvo Micciché 2015
// For Zero Coupon bonds input 0 in "Coupon" field
BEGIN
  local mesg, days1, days2, toReg, N, finAct;
  local sd, sm, sy, md, mm, my, ann, nextReg;
  local coupon, yi, years, price, inter, dayPer;
  local m1, d1;
  input ({ {sd,[0],{15,15,1}}, 
  {sm,{"1","2","3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}, {40,15,1}}, 
  {sy,[0],{70,20,1}},
  {md,[0],{15,15,2}}, 
  {mm,{"1","2","3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}, {40,15,2}}, 
  {my,[0],{70,20,2}},
  {coupon,[0],{40,15,4}}, {yi,[0], {75,15,4}},
  {ann,[0], {40,15,5}}, {finAct,2,{85,2, 5}}
  }, 
  "Price of Bond (maturity 100)", {"sd", "sm", "sy", "md", "mm", "my", 
  "Coupon", "y%", "ann", "Financial"}, 
  {"Settlement day", "Settlement month", "Settlement year (purchase)", 
  "Maturity day", "Maturity month", "Maturity year (regulation)", 
  "Coupon payment % (0 for zero coupon)", "yield %", "n. of annuality (i.e 2=semi)", "Financial year (360)"}, 
  {1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, {1, 0, 2015, 1, 0, 2015, 6.75, 4.75, 2, 0} );

  sd:=EVAL(sd); sm:=EVAL(sm);
  md:=EVAL(md); mm:=EVAL(mm);
  sy:=EVAL(sy); my:=EVAL(my);
  days1 := sy+sm/100+sd/10000;
  days2 := my+mm/100+md/10000;
  toReg := sy+mm/100+md/10000; // days to the regulation
  years := my-sy; // years to the maturity
  IF years<1 THEN years:= 1; END;
  IF (finAct==0) THEN
  N:= DDAYS(days1, days2);
  IF (days1>toReg) THEN nextReg:=DATEADD(toReg,IP(365/ann)); ELSE nextReg:=toReg; END;
  toReg := DDAYS(days1, nextReg);
  dayPer := IP(365/ann);
  ELSE
  N:= 30*12*years;
  IF (days1>toReg) THEN nextReg:=DATEADD(toReg,IP(360/ann)); ELSE nextReg:=toReg; END;
  m1:=IP(FP(nextReg)*100); d1:=FP(FP(nextReg)*100)*100;
  toReg:= 30*(m1-sm)+d1-sd;
  dayPer:= IP(360/ann);
  END; // if

  price := (coupon/ann)*( (1-1/(1+(yi/(ann*100)))^(ann*years)) / (yi/(ann*100)) ) + 100/(1+(yi/(ann*100)))^(ann*years);
  inter := (coupon/ann)*((dayPer - toReg)/dayPer);
  IF (coupon == 0) THEN // Zero Coupon
  RECT_P();
    TEXTOUT_P("Zero Coupon", 10, 50);
    TEXTOUT_P("from " + sd + "-" + sm + "-" + sy + " to " + md + "-" + mm + "-" + my , 10, 65 );
    TEXTOUT_P("Price of Bond: " + price, 10, 85);
    TEXTOUT_P("Paid " + ann + " times per year", 10, 105);
    TEXTOUT_P("Press ESC to continue", 10, 130);
  ELSE
  RECT_P();
    TEXTOUT_P("Days: " + N + " to the end (" + years + " years)", 10, 50);
   TEXTOUT_P("from " + sd + "-" + sm + "-" + sy + " to " + md + "-" + mm + "-" + my , 10, 65 );
    TEXTOUT_P("Days to next regulation " + toReg, 10, 85);
    TEXTOUT_P("Price of Bond: " + price, 10, 105);
    TEXTOUT_P("Paid " + ann + " times per year", 10, 125);
    TEXTOUT_P("Interest: " + inter, 10, 145);
    TEXTOUT_P("paid for " + EVAL(dayPer-toReg) + " days", 10, 165);
    TEXTOUT_P("Press ESC to continue", 10, 190);
  END; //if
  WAIT;
smenu();
  RETURN {ROUND(price, 3), ROUND(inter,3), ROUND(price+inter,3)};

END;

EXPORT Yield()
BEGIN
  local mesg, days1, days2, toReg, N, finAct;
  local sd, sm, sy, md, mm, my, years, yield;
  local coupon, price, ann, inter, dayPer, nextReg;
  local d1, m1;
  input ({ {sd,[0],{15,15,1}}, 
  {sm,{"1","2","3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}, {40,15,1}}, 
  {sy,[0],{70,20,1}},
  {md,[0],{15,15,2}}, 
  {mm,{"1","2","3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}, {40,15,2}}, 
  {my,[0],{70,20,2}},
  {coupon,[0],{40,15,4}}, {price,[0], {75,15,4}},
  {ann,[0], {40,15,5}}, {finAct,2,{85,2, 5}}
  }, 
  "Bond YTM: yield to maturity", {"sd", "sm", "sy", "md", "mm", "my", 
  "Coupon", "Price", "annu", "Financial"}, 
  {"Settlement day", "Settlement month", "Settlement year (purchase)", 
  "Maturity day", "Maturity month", "Maturity year (regulation)", 
  "Coupon payment % (0 for zero coupon)", "Price now", "n. of annuality (i.e 2=semi)", "Financial year (360)"}, 
  {1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, {1, 0, 2015, 1, 0, 2015, 6.75, 120, 2, 0} );

  sd:=EVAL(sd); sm:=EVAL(sm);
  md:=EVAL(md); mm:=EVAL(mm);
  sy:=EVAL(sy); my:=EVAL(my);
  days1 := sy+sm/100+sd/10000;
  days2 := my+mm/100+md/10000;
  toReg := sy+mm/100+md/10000; // days to the regulation
  years := my-sy; // years to the maturity
  IF years<1 THEN years:= 1; END;
  IF (finAct==0) THEN
  N:= DDAYS(days1, days2);
  IF (days1>toReg) THEN nextReg:=DATEADD(toReg,IP(365/ann)); ELSE nextReg:=toReg; END;
  toReg := DDAYS(days1, nextReg);
  dayPer := IP(365/ann);
  ELSE
  N:= 30*12*years;
  IF (days1>toReg) THEN nextReg:=DATEADD(toReg,IP(360/ann)); ELSE nextReg:=toReg; END;
  m1:=IP(FP(nextReg)*100); d1:=FP(FP(nextReg)*100)*100;
  toReg:= 30*(m1-sm)+d1-sd;
  dayPer:= IP(360/ann);
  END; // if

  C:= coupon; A:= ann; Y:= years; P:= price;
  // yield := Solve.SOLVE((C/A)*( (1-1/(1+(X/A))^(A*Y)) / (X/A) ) + 100/(1+(X/A))^(A*Y) = P, X);
  yield := FNROOT((C/A)*( (1-1/(1+(X/A))^(A*Y)) / (X/A) ) + 100/(1+(X/A))^(A*Y) = P, X);
  IF (coupon==0) THEN // Zero Coupon
RECT_P();
    TEXTOUT_P("Zero Coupon", 10, 50);
    TEXTOUT_P("from " + sd + "-" + sm + "-" + sy + " to " + md + "-" + mm + "-" + my , 10, 65 );
    TEXTOUT_P("Price of Bond: " + price, 10, 85);
    TEXTOUT_P("paid " + ann + " times per year", 10, 105);
    TEXTOUT_P("Yield to Maturity: " + ROUND(100*yield,3) + "%", 10, 125);
    TEXTOUT_P("Press ESC to continue", 10, 150);
  ELSE
RECT_P();
    TEXTOUT_P("Days: " + N + " to the end (" + years + " years)", 10, 50);
    TEXTOUT_P("from " + sd + "-" + sm + "-" + sy + " to " + md + "-" + mm + "-" + my , 10, 65 );
   TEXTOUT_P("Days to next regulation " + toReg, 10, 85);
    TEXTOUT_P("Price of Bond: " + price, 10, 105);
   TEXTOUT_P("paid " + ann + " times per year", 10, 125);
    TEXTOUT_P("Yield to Maturity: " + ROUND(100*yield,3) + "%", 10, 145);
    TEXTOUT_P("Press ESC to continue", 10, 170);
  END; //if
  WAIT;
  smenu();
  RETURN ROUND(100*yield,3);

END;

smenu()
BEGIN
  local ch;
  CHOOSE(ch, "Bonds: price, YTM, interest", "Price", "Yield", "Quit");
  CASE
   IF ch==1 THEN Price(); END;
   IF ch==2 THEN Yield(); END;
   IF ch==3 THEN RETURN; END;
  DEFAULT
  END; // case
END;

∫aL√0mic (IT9CLU), HP Prime 50g 41CX 71b 42s 12C 15C - DM42 WP34s :: Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-31-2015, 08:44 PM
Post: #2
RE: Program to calculate bonds
(05-31-2015 08:27 PM)salvomic Wrote:  I need help (Franz?) to test and improve it, as I think my formulas are "enough" correct, but perhaps not 100%...
Sorry but I have no idea of bonds - that's one part of financial mathematics which is of no interest for me.

Franz
Visit this user's website Find all posts by this user
Quote this message in a reply
05-31-2015, 08:49 PM (This post was last modified: 06-01-2015 01:51 PM by salvomic.)
Post: #3
RE: Program to calculate bonds
(05-31-2015 08:44 PM)fhub Wrote:  
(05-31-2015 08:27 PM)salvomic Wrote:  I need help (Franz?) to test and improve it, as I think my formulas are "enough" correct, but perhaps not 100%...
Sorry but I have no idea of bonds - that's one part of financial mathematics which is of no interest for me.
Franz

ok...
yes, I'm bored of bond also, but I was asked by someone to make a program like that, and I'm trying...

Thank you the same.

Salvo

∫aL√0mic (IT9CLU), HP Prime 50g 41CX 71b 42s 12C 15C - DM42 WP34s :: Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)