/* ** 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 collar. ** */ new ; cls ; /* ofile = "c:\\kcdn\\output.out" ; output file = ^ofile reset ; */ format /m1/rdn 16,8 ; output on ; screen on ; " ------------------------------------------------------------------------ " ; " " ; " FILE : Chp15 Tab5 Int rate collar.txt " ; " ===================================== " ; " " ; " Version 20/07/2001 " ; " " ; " Copyright K.Cuthbertson and D. Nitzsche " ; " 'Financial Engineering:Derivatives and Risk Manangement' - J. Wiley 2001 " ; " " ; " INTEREST ARTE DERIVATIVES " ; " Calculating payoffs from interest rate collar " ; " " ; " ------------------------------------------------------------------------ " ; output off ; screen off ; " ---------------------------------------------------------- " ; " " ; " Definitions of Variables Used " ; " ----------------------------- " ; " " ; " Dep = Deposit " ; " P_floor = Premium floor (short) " ; " P_cap = Premium cap (long) " ; " " ; " K_floor = Strike rate (floor) - decimal " ; " K_cap = Strike rate (cap) - decimal " ; " " ; " Day_y = Day count (per Year) " ; " Reset_d = Reset dates (days) " ; " " ; " Size = Number of Dates " ; " ---------------------------------------------------------- " ; /* ----------------------------------------- START USER DATA INPUT ----------------------------- */ /* The number of dates the user has to input has to be equal to the parameter Size ** 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 */ Dep = 100000000 ; P_floor = 500000 ; P_cap = 350000 ; K_floor = 0.08 ; K_cap = 0.1 ; Day_y = 360 ; Reset_d = 90 ; Size = 7 ; @ 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 ; let DDN[1,3] = 2001 7 10 ; DD = DD|DDN ; let DDN[1,3] = 2001 10 10 ; DD = DD|DDN ; r[1] = 0.105 ; @ Interest rates - r1 @ r[2] = 0.115 ; r[3] = 0.100 ; r[4] = 0.090 ; r[5] = 0.078 ; r[6] = 0.077 ; /* --------------------------------------- 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) ; Floor_pay = zeros(Size,1) ; Cap_pay = zeros(Size,1) ; Principal = zeros(Size,1) ; NCF_collar = zeros(Size,1) ; NCF_cap = zeros(Size,1) ; NCF_n = zeros(Size,1) ; n = 1 ; Floor_pay[n,1] = P_floor ; 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] = Dep*r[n]*(days[n+1,1]/Day_y) ; n = n+1 ; endo ; n = 2 ; do until n > Size-1 ; if Dep*(days[n+1,.]/day_y)*(r[n,1]-K_cap) > 0 ; Cap_pay[n+1,.] = Dep*(days[n+1,.]/day_y)*(r[n,1]-K_cap) ; else ; Cap_pay[n+1,.] = 0 ; endif ; if Dep*(days[n+1,.]/day_y)*(K_floor - r[n,1]) > 0 ; Floor_pay[n+1,.] = -(Dep*(days[n+1,.]/day_y)*(K_floor - r[n,1])) ; else ; Floor_pay[n+1,.] = 0 ; endif ; n = n+1 ; endo ; @ ------------------------- Principal payment is only being made at maturity ------------------- @ n = Size ; Principal[n,1] = Dep ; @ ---------------------------------- Adding up the relevant Columns ---------------------------- @ NCF_collar = -Inter + Floor_pay + Cap_pay - Principal ; NCF_cap = -Inter + Cap_pay - Principal ; NCF_n = -Inter - Principal ; @ --------------------------- Changing first Net Cash Flow - to allow for payment -------------- @ NCF_collar[1,1] = Dep+NCF_collar[1,1] ; NCF_cap[1,1] = Dep+NCF_cap[1,1] ; NCF_n[1,1] = Dep[1,1] ; @ ------------------------- Calculating the Effective Rate of return - IRR --------------------- @ TT = seqa(1,1,Size-1) ; CF = -NCF_collar ; {IRR,f1,lagr,retcode} = sqpSolve(&fct,0.1) ; irr_collarq = IRR ; irr_collara = (1 + irr_collarq)^(Day_y/Reset_d) -1 ; CF = -NCF_cap ; {IRR,f1,lagr,retcode} = sqpSolve(&fct,0.1) ; irr_capq = IRR ; irr_capa = (1 + irr_capq)^(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 ; @ ------------------------------------ Procedure ------------------------------------------ @ 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 ; mask1a = 1~1~1~1~1~1~1~1~1 ; let fmt1a[9,3] = "-*.*lf" 4 0 " *.*lf" 3 0 "*.*lf" 7 0 " *.*lf" 12 0 " *.*lf" 15 4 " *.*lf" 16 2 " *.*lf" 16 2 " *.*lf" 14 2 " *.*lf" 16 2 ; mask1b = 1~1~1~1~1~1~1 ; let fmt1b[7,3] = "-*.*lf" 4 0 " *.*lf" 3 0 "*.*lf" 7 0 " *.*lf" 27 4 " *.*lf" 29 4 " *.*lf" 17 2 " *.*lf" 17 2 ; collar_table1 = DD[.,3]~DD[.,2]~DD[.,1]~days~r~Inter~Cap_pay~Floor_pay~Principal ; collar_table2 = DD[.,3]~DD[.,2]~DD[.,1]~r~NCF_collar~NCF_cap~NCF_n ; /* ** Producing a neater Table (by cutting off the rows of zeros ** (Matrix floor_tab (with 0) or floor_tab1 (without 0)) */ r_rows = counts(DD[.,3],0) ; r_rows = Size - r_rows ; v1 = zeros(r_rows,1) ; n = 1 ; do until n > r_rows ; v1[n,1] = n ; n = n+1 ; endo ; collar_tab1a = submat(collar_table1,v1,0) ; collar_tab1b = submat(collar_table2,v1,0) ; @@ ""; @@ " TABLE 15.05 : INTEREST RATE COLLAR " ; @@ " ================================== " ; @@ ""; @@ ftos(Dep,"Deposit (lending) : %*.*lf",22,2) ; @@ ftos(P_floor,"Premium Floor (short) : %*.*lf",18,2) ; @@ ftos(P_cap,"Premium Cap (long) : %*.*lf",21,2) ; @@ ""; @@ ftos(K_floor,"Strike rate (Floor) : %*.*lf",20,2) ; @@ ftos(K_cap,"Strike rate (Cap) : %*.*lf",22,2) ; @@ ""; @@ ftos(Day_y,"Days in the year (for options) : %*.*lf",6,0) ; @@ ftos(Reset_d,"Reset dates (days) : %*.*lf",18,0) ; @@ ""; @@ ""; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ " Date Days between LIBOR Interest Cap Floor Principal " ; @@ " Dates Received Payments Payments Repayment " ; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ call printfm(collar_tab1a, mask1a, fmt1a) ; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ ""; @@ " continue " ; @@ ""; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ " Date LIBOR Net Cash Flows " ; @@ " with Collar with Cap without Cap/Floor " ; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ call printfm(collar_tab1b, mask1b, fmt1b) ; @@ "------------------------------------------------------------------------------------------------------------ " ; @@ "" ; @@ "" ; @@ "The effective annual rate of return is : " @@ "" ; @@ " with collar (per period / per annuam) " irr_collarq~irr_collara ; @@ " with cap (per period / per annum) " irr_capq~irr_capa ; @@ " without cap or floor (per period / per annum) " irr_nq~irr_na ; @@ "" ; end ;