/* ** Version 01 ** Date : 20/07/2001 ** -------------------------------------------------------------------------- ** Copyright K.Cuthbertson and D. Nitzsche ** "Financial Engineering:Derivatives and Risk Manangement" - J. Wiley 2001 ** ** INTEREST RATE DERIVATIVES ** ** Calculating payoffs from interst rate cap. ** */ new ; cls ; /* ofile = "c:\\kcdn\\output.out" ; output file = ^ofile reset ; */ format /m1/rdn 16,8 ; output on ; screen on ; " ------------------------------------------------------------------------ " ; " " ; " FILE : Chp15 Tab3 Int rate cap.txt " ; " ================================== " ; " " ; " Version 20/07/2001 " ; " " ; " Copyright K.Cuthbertson and D. Nitzsche " ; " 'Financial Engineering:Derivatives and Risk Manangement' - J. Wiley 2001 " ; " " ; " INTEREST RATE DERIVATIVES " ; " Calculating payoffs from interest rate cap " ; " " ; " ------------------------------------------------------------------------ " ; output off ; screen off ; " ---------------------------------------------------------- " ; " " ; " Definitions of Variables Used " ; " ----------------------------- " ; " " ; " Loan = Loan " ; " P_cap = Premium cap (buy) " ; " K_cap = Strike rate (cap) " ; " " ; " Loan_ma = Maturity of loan (days) " ; " Day_y = Day count (per Year) " ; " Reset_d = Reset dates (days) " ; " ---------------------------------------------------------- " ; /* ----------------------------------------- START USER DATA INPUT ---------------------------- */ /* ** The number of dates the user has to input has to be equal to (Loan_ma / Reset_d) + 1 ** and the number of interest rates has to match the LIBOR rates at those dates ** see Cuthbertson and Nitzsche 'Financial Engineering : Derivatives and Risk ** Management' Chp. 15 */ Loan = 20000000 ; P_cap = 60000 ; K_cap = 0.1 ; Loan_ma = 360 ; Day_y = 360 ; Reset_d = 90 ; Size = Round(Loan_ma/Reset_d) + 1 ; @ Size represents the number of Dates @ @ Size has to match the number of dates below @ @ Number of LIBOR dates are Size - 1 @ days = zeros(Size,1) ; cum_days = zeros(Size,1) ; r = zeros(Size,1) ; declare matrix DD ; let DD[1,3] = 2000 4 10 ; @ Date @ let DDN[1,3] = 2000 7 10 ; DD = DD|DDN ; let DDN[1,3] = 2000 10 10 ; DD = DD|DDN ; let DDN[1,3] = 2001 1 10 ; DD = DD|DDN ; let DDN[1,3] = 2001 4 10 ; DD = DD|DDN ; r[1] = 0.100 ; r[2] = 0.107 ; r[3] = 0.123 ; r[4] = 0.116 ; /* ---------------------------------------- END USER DATA INPUT ------------------------------- */ RDD = rows(DD) ; screen on ; if RDD < Size ; errorlog "ERROR : CHECK THE NUMBER OF PAYMENTS AND THE NUMBER OF DATE ENTRIES DO NOT MATCH" ; end; elseif RDD > Size ; errorlog "ERROR : CHECK THE NUMBER OF PAYMENTS AND THE NUMBER OF DATE ENTRIES DO NOT MATCH" ; end ; endif ; screen off ; /* ------------------------------------- STARTING THE CALCULATION ----------------------------- */ Inter = zeros(Size,1) ; Cap_pay = zeros(Size,1) ; Principal = zeros(Size,1) ; NCF_y = zeros(Size,1) ; NCF_n = zeros(Size,1) ; n = 1 ; Cap_pay[n,1] = -P_cap ; do until n > Size-1 ; days[n+1,.] = etdays(DD[n,.]',DD[n+1,.]') ; cum_days[n+1,.] = days[n+1,.]+cum_days[n,.] ; Inter[n+1,1] = Loan*r[n]*(days[n+1,1]/Day_y) ; n = n+1 ; endo ; n = 2 ; do until n > Size-1 ; Cap_pay[n+1,.] = Loan*(days[n+1,.]/day_y)*(r[n,1]-K_cap) ; n = n+1 ; endo ; @ ----------------------- Principal payment is only made at maturity -------------------------- @ n = Size ; Principal[n,1] = Loan ; @ ---------------------------------Adding up the relevant Columns ----------------------------- @ NCF_y = Principal - Cap_pay + Inter ; NCF_n = Inter + Principal ; @ Changeing the first Net Cash Flow - to allow for payment @ n = 1 ; NCF_y[n,1] = Loan+Cap_pay[n,1] ; NCF_n[n,1] = Loan ; NCF_y[2:Size,1] = -NCF_y[2:Size,1] ; NCF_n[2:Size,1] = -NCF_n[2:Size,1] ; @ Calculating the Effective Rate of return - IRR @ TT = seqa(1,1,Size-1) ; CF = -NCF_y ; {IRR,f1,lagr,retcode} = sqpSolve(&fct,0.1) ; irr_yq = IRR ; irr_ya = (1 + irr_yq)^(Day_y/Reset_d) -1 ; CF = -NCF_n ; {IRR,f1,lagr,retcode} = sqpSolve(&fct,0.1) ; irr_nq = IRR ; irr_na = (1 + irr_nq)^(Day_y/Reset_d) -1 ; proc fct(r) ; local Disc, PV, NPV, NPV_min ; Disc = 1/(1+r)^TT[1:Size-1,.] ; PV = CF[2:Size,.].*Disc ; NPV = CF[1,1] + sumc(PV) ; NPV_min = NPV*NPV ; retp(NPV_min) ; endp ; /* ----------------------------------------- PRINTING THE OUTPUT ----------------------------- */ output on ; screen on ; mask = 1~1~1~1~1~1~1~1~1~1 ; let fmt[10,3] = "-*.*lf" 3 0 " *.*lf" 3 0 "*.*lf" 6 0 " *.*lf" 10 0 " *.*lf" 15 4 " *.*lf" 14 2 " *.*lf" 14 2 " *.*lf" 17 2 " *.*lf" 18 2 " *.*lf" 18 2 ; cap_tab = DD[.,3]~DD[.,2]~DD[.,1]~days~r~Inter~Cap_pay~Principal~NCF_y~NCF_n ; @@ " "; @@ " TABLE 15.03 : INTEREST RATE CAP " ; @@ " =============================== " ; @@ ""; @@ ftos(Loan,"Loan : %*.*lf",36,2) ; @@ ftos(P_cap,"Cap Premium : %*.*lf",29,2) ; @@ ftos(K_cap,"Strike rate : %*.*lf",29,2) ; @@ ""; @@ ftos(Loan_ma,"Maturity of the loan (days) : %*.*lf",10,0) ; @@ ftos(Day_y,"Days in the year (for cap) : %*.*lf",11,0) ; @@ ftos(Reset_d,"Reset dates (days) : %*.*lf",19,0) ; @@ ""; @@ ""; @@ "---------------------------------------------------------------------------------------------------------------------- " ; @@ " Date Days between LIBOR Interest Cap Principal Net Cash Flows " ; @@ " Dates Due Payments Repayment with Cap withput Cap " ; @@ "---------------------------------------------------------------------------------------------------------------------- " ; @@ call printfm(cap_tab, mask, fmt) ; @@ "---------------------------------------------------------------------------------------------------------------------- " ; @@ "" ; @@ "" ; @@ "The effective annual rate of return is : " @@ "" ; @@ " with cap (per period / per annuam) " irr_yq~irr_ya ; @@ " without cap (per period / per annum) " irr_nq~irr_na ; @@ "" ; end ;