/* ** Version 01 ** Date : 20/07/2001 ** -------------------------------------------------------------------------- ** Copyright K.Cuthbertson and D. Nitzsche ** "Financial Engineering:Derivatives and Risk Manangement" - J. Wiley 2001 ** ** COMPLEX DERIVATIVES (PRICING AN ASIAN CALL) ** ** Pricing an Asian call option - BOPM ** (for T max of 7) ** */ new ; cls ; /* ofile = "c:\\kcdn\\output.out" ; output file = ^ofile reset ; */ format /m1/rdn 16,8 ; output on ; screen on ; " ------------------------------------------------------------------------ " ; " " ; " FILE : Chp16 Asian Option.txt " ; " ============================= " ; " " ; " Version 20/07/2001 " ; " " ; " Copyright K.Cuthbertson and D. Nitzsche " ; " 'Financial Engineering:Derivatives and Risk Manangement' - J. Wiley 2001 " ; " " ; " COMPLEX DERIVATIVES (PRICING AN ASIAN CALL) " ; " Pricing an Asian call option - BOPM " ; " " ; " Note : max T = 7 " ; " " ; " ------------------------------------------------------------------------ " ; output off ; screen off ; " ------------------------------------------------------------------ " ; " Definitions of Variables Used " ; " ------------------------------------------------------------------ " ; " T = Time horizon in latttice (integer between 1 to 7) " ; " K = Strike price " ; " S0 = Stock price at t=0 " ; " " ; " U = Probabuility of an UP move (default = 0.15) " ; " D = Probability of a DOWN move (default = -0.20) " ; " r = short term interest rates " ; " ------------------------------------------------------------------ " ; @ ------------------------------------- START USER DATA INPUT ------------------------------ @ T = 3 ; @ Time horizon in lattice from 0 to T @ K = 100 ; S0 = 100 ; U = 0.15 ; D = -0.20 ; r = 0.1 ; @ ------------------------------------- END USER DATA INPUT -------------------------------- @ @ ---------------------------------- STARTING THE CALCULATION ------------------------------ @ RR = 1+r ; UU = 1+U ; DD = 1+D ; q = (RR-DD)/(UU-DD) ; qq = 1-q ; @ ---------------------------- Number of pathS - depends on n --------------------------------@ S = zeros(T+1,T+1) ; @ T+1 nodes on time axis of tree @ i = T+1 ; j = 1 ; S[i,j] = S0 ; j = 2 ; do until i < 1 ; do until j > T+1 ; if i .== T+1 ; S[i,j] = S[i,j-1]*DD ; else ; S[i,j] = S[i+1,j-1]*UU ; endif ; j = j+1 ; endo ; i = i-1 ; j = T+1-i+1 ; endo ; comb = zeros(T+1,1) ; ups = seqa(1,1,T) ; ups = 0|ups ; comb = T!/((T-ups)!.*ups!) ; no_path = sumc(comb) ; Prob = zeros(no_path,1) ; path_mat= ones(no_path,T) ; S_mat = zeros(no_path,T+1) ; qv = ones(no_path,1) ; qv = qv*q ; qqv = ones(no_path,1) ; qqv = qqv*qq ; @ ------------------------------- start: obtaining the possible paths ------------------------ @ @ --- This is for T = 2 only --- @ if T == 2 ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,2) ; PP_1 = PP2 ; path_mat = PP_0|PP_1|rev(abs(PP_0-1)) ; @ --- This is for T = 3 only --- @ elseif T == 3 ; PP3 = rev(eye(3)) ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,3) ; PP_1 = PP3 ; path_mat = PP_0|PP_1 ; @--- This is only half of it !!!--- @ path_mat = path_mat|rev(abs(path_mat-1)) ; @ --- This is for T = 4 only --- @ elseif T == 4 ; PP4 = rev(eye(4)) ; PP3 = rev(eye(3)) ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,4) ; PP_1 = PP4 ; PP_2 = PP3~ones(3,1)|PP2~ones(2,1)~zeros(2,1)|PP1~ones(1,1)~zeros(1,2) ; path_mat = PP_0|PP_1|PP_2|abs(PP_1-1)|abs(PP_0-1) ; @ --- This is for T = 5 only --- @ elseif T == 5 ; PP5 = rev(eye(5)) ; PP4 = rev(eye(4)) ; PP3 = rev(eye(3)) ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,5) ; PP_1 = PP5 ; PP_2 = PP4~ones(4,1)|PP3~ones(3,1)~zeros(3,1)|PP2~ones(2,1)~zeros(2,2)|PP1~ones(1,1)~zeros(1,3) ; path_mat = PP_0|PP_1|PP_2 ; @ This is only halve of it !!! @ path_mat = path_mat|rev(abs(path_mat-1)) ; @ --- This is for T = 6 only --- @ elseif T == 6 ; PP6 = rev(eye(6)) ; PP5 = rev(eye(5)) ; PP4 = rev(eye(4)) ; PP3 = rev(eye(3)) ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,6) ; PP_1 = PP6 ; PP_2 = PP5~ones(5,1)|PP4~ones(4,1)~zeros(4,1)|PP3~ones(3,1)~zeros(3,2)|PP2~ones(2,1)~zeros(2,3)|PP1~ones(1,1)~zeros(1,4) ; PP_3 = PP4~ones(4,2)|PP3~ones(3,1)~zeros(3,1)~ones(3,1)|PP2~ones(2,1)~zeros(2,2)~ones(2,1)|PP1~ones(1,1)~zeros(1,3)~ones(1,1) ; path_mat = PP_0|PP_1|PP_2|PP_3 ; @ This is only halve of it !!! @ path_mat = path_mat|rev(abs(path_mat-1)) ; @ --- This is for T = 7 only --- @ elseif T == 7 ; PP7 = rev(eye(7)) ; PP6 = rev(eye(6)) ; PP5 = rev(eye(5)) ; PP4 = rev(eye(4)) ; PP3 = rev(eye(3)) ; PP2 = rev(eye(2)) ; PP1 = rev(eye(1)) ; PP_0 = zeros(1,7) ; PP_1 = PP7 ; PP_2 = PP6~ones(6,1)|PP5~ones(5,1)~zeros(5,1)|PP4~ones(4,1)~zeros(4,2)|PP3~ones(3,1)~zeros(3,3)|PP2~ones(2,1)~zeros(2,4)| PP1~ones(1,1)~zeros(1,5) ; PP_3 = PP5~ones(5,2)|PP4~ones(4,2)~zeros(4,1)|PP3~ones(3,2)~zeros(3,2)|PP2~ones(2,2)~zeros(2,3)|PP1~ones(1,2)~zeros(1,4)| PP4~ones(4,1)~zeros(4,1)~ones(4,1)|PP3~ones(3,1)~zeros(3,2)~ones(3,1)|PP2~ones(2,1)~zeros(2,3)~ones(2,1)| PP1~ones(1,1)~zeros(1,4)~ones(1,1)| PP3~ones(3,1)~zeros(3,1)~ones(3,1)~zeros(3,1)|PP2~ones(2,1)~zeros(2,2)~ones(2,1)~zeros(2,1)| PP1~ones(1,1)~zeros(1,3)~ones(1,1)~zeros(1,1)| PP2~ones(2,1)~zeros(2,1)~ones(2,1)~zeros(2,2)|PP1~ones(1,1)~zeros(1,1)~ones(1,1)~zeros(1,3)| PP1~ones(1,1)~zeros(1,2)~ones(1,1)~zeros(1,2) ; path_mat = PP_0|PP_1|PP_2|PP_3 ; @ This is only halve of it !!! @ path_mat = path_mat|rev(abs(path_mat-1)) ; else ; errorlog "ERROR : THE TIME PERIOD CHOOSEN IS TOO LONG - T NOT MORE THAN 7" ; end; endif ; @ --------------------- End of obtaining possible paths for T = 1 to 7 -------------------- @ no_down = sumc(path_mat') ; no_up = rev(no_down) ; Prob = (qv.^no_up).*(qqv.^(no_down)) ; S0 = ones(no_path,1) ; S0 = S0*S[T+1,1] ; S_mat[1:no_path,1] = S0 ; path_mat = rev(path_mat) ; @ --- Turn path_mat 'upside down'--- @ print path_mat ; RS = rev(S) ; print RS ; cumpath_mat = path_mat ; j = 2 ; do until j > T ; cumpath_mat[.,j] = path_mat[.,j] + cumpath_mat[.,j-1] ; j = j+1 ; endo ; @ ----------------------------------- Building the Big S matrix ---------------------------- @ i = 1 ; do until i > no_path ; j = 2 ; m = 1 ; do until j > T+1 ; cp = cumpath_mat[i,j-1] ; S_mat[i,m+1] = RS[cp+1,j] ; j = j+1 ; m = m+1 ; endo ; i = i+1 ; endo ; print S_mat ; av_S = sumc(S_mat')/cols(S_mat) ; max_S = maxc(S_mat') ; min_S = minc(S_mat') ; @ -------------------- Calculating the payoffs of European and Asian Options ----------------- @ @ ------------------------------------- European Call option --------------------------------- @ ECall_PO = zeros(no_path,1) ; ECall_PO[.,1] = S_mat[.,T+1] - K ; @ Next 3 lines : Max(0 or ST-K) @ ECall_PO = zeros(no_path,1)~ECall_PO ; ECall_PO = maxc(ECall_PO') ; @ ------------------------------------- European Put option ---------------------------------- @ EPut_PO = zeros(no_path,1) ; EPut_PO = K - S_mat[.,T+1] ; @ Next 3 lines : Max(0 or K-ST) @ EPut_PO = zeros(no_path,1)~EPut_PO ; EPut_PO = maxc(EPut_PO') ; ECall_Val = Prob'*ECall_PO/(1+r)^T ; EPut_Val = Prob'*EPut_PO/(1+r)^T ; @ ----------------------------------- Asian Option: Call Payoff ------------------------------- @ ACall_PO = av_S - K ; @ --- Next 3 lines : Max(0 or S(av)-K) --- @ ACall_PO = zeros(no_path,1)~ACall_PO ; ACall_PO = maxc(ACall_PO') ; @ ----------------------------------- Asian Option: Put Payoff -------------------------------- @ APut_PO = K - av_S ; @ --- Next 3 lines : Max(0 or K - S(av)) --- @ APut_PO = zeros(no_path,1)~APut_PO ; APut_PO = maxc(APut_PO') ; @ --------------------------- Asian Option: Average Strike: Call Payoff ------------------------ @ AKCall_PO = S_mat[.,T+1] - av_S ; @ --- Next 3 lines : Max(0 or ST-S(av)) --- @ AKCall_PO = zeros(no_path,1)~AKCall_PO ; AKCall_PO = maxc(AKCall_PO') ; @ --------------------------- Asian Option: Average Strike: Put Payoff ------------------------- @ AKPut_PO = av_S - S_mat[.,T+1] ; @ --- Next 3 lines : Max(0 or S(av)-ST) --- @ AKPut_PO = zeros(no_path,1)~AKPut_PO ; AKPut_PO = maxc(AKPut_PO') ; ACall_Val = Prob'*ACall_PO/(1+r)^T ; APut_Val = Prob'*APut_PO/(1+r)^T ; AKCall_Val = Prob'*AKCall_PO/(1+r)^T ; AKPut_Val = Prob'*AKPut_PO/(1+r)^T ; @ ---------------------------------- Printing Output and the Graph ----------------------------- @ output on ; screen on ; maska = 1~1~1~1~1~1~1~1~1~1 ; let fmta[10,3] = " *.*lf" 6 0 " *.*lf" 13 0 " *.*lf" 15 4 " *.*lf" 10 0 " *.*lf" 12 4 " *.*lf" 13 2 " *.*lf" 15 2 " *.*lf" 9 2 " *.*lf" 11 2 " *.*lf" 11 2 ; Tab1603a = seqa(1,1,rows(S_mat))~no_up~Prob~S_mat[.,1]~S_mat[.,T+1]~av_S~max_S~min_S~ECall_PO~EPut_PO ; maskb = 1~1~1~1~1~1~1~1~1 ; let fmtb[9,3] = " *.*lf" 6 0 " *.*lf" 13 0 " *.*lf" 15 4 " *.*lf" 14 4 " *.*lf" 12 4 " *.*lf" 16 2 " *.*lf" 11 2 " *.*lf" 11 2 " *.*lf" 11 2 ; Tab1603b = seqa(1,1,rows(S_mat))~no_up~Prob~S_mat[.,T+1]~av_S~ACall_PO~APut_PO~AKCall_PO~AKPut_PO ; ?; " ----------------------------------------------------------------------------------------- " ; " TABLE 16.03 : PRICING AN ASIAN CALL OPTION " ; " ----------------------------------------------------------------------------------------- " ; ftos(S_mat[1,1], "Stock price at t = 0 : %*.*lf",10,2) ; ftos(K, "Strike price : %*.*lf",18,2) ; ftos(T, "Time horizon : %*.*lf",15,0) ; ftos(U, "Probability of an UP : %*.*lf",10,2) ; ftos(D, "Probability of a DOWN : %*.*lf",9,2) ; ftos(r, "Interest rates : %*.*lf",16,2) ; {S,TT} = print_fmt(S) ; @ --- This procedure fills in dots at the upper triangle --- @ ?; " ----------------------------------------------------------------------------------------- " ; " TABLE 16.03 : Share price lattice " ; " ----------------------------------------------------------------------------------------- " ; print S ; ?; print TT ; ?; ?; "--------------------------------------------------------------------------------------------------------------------- " ; " Path Number of Probability S0 S(T) S(average) S(Max) S(min) European Options " ; " number ups Call Put " ; "--------------------------------------------------------------------------------------------------------------------- " ; ?; call printfm(Tab1603a, maska, fmta) ; "--------------------------------------------------------------------------------------------------------------------- " ; ?; ?; "--------------------------------------------------------------------------------------------------------------------- " ; " Path Number of Probability S(T) S(average) Asian Option Payoff " ; " number ups ------------------------------------------- " ; " Call Put Strike Call Strike Put " ; "--------------------------------------------------------------------------------------------------------------------- " ; ?; call printfm(Tab1603b, maskb, fmtb) ; "--------------------------------------------------------------------------------------------------------------------- " ; ?; " ----------------------------------------------------------------------------------------- " ; " TABLE 16.03 : Value of Options " ; " ----------------------------------------------------------------------------------------- " ; ftos(ECall_Val, " Value of European CALL option %*.*lf",22,2) ; ftos(EPut_Val, " Value of European PUT option %*.*lf",23,2) ; ftos(ACall_Val, " Value of Asian (average price) CALL option %*.*lf",9,2) ; ftos(APut_Val, " Value of Asian (average price) PUT option %*.*lf",10,2) ; ftos(AKCall_Val, " Value of Asian STRIKE CALL option %*.*lf",18,2) ; ftos(AKPut_Val, " Value of Asian STRIKE PUT option %*.*lf",19,2) ; /* ** --------------------------------------------------------------- ** Procedure Procedure Procedure ** --------------------------------------------------------------- ** Printing Format - general ** (To print dots in off diagonal elements of lattice). ** --------------------------------------------------------------- */ proc(2) = Print_fmt(mat) ; local ro, co, i, j, TT ; ro = rows(mat) ; co = cols(mat) ; TT = seqa(0,1,co) ; TT = TT' ; i = 1 ; do until i > co - 1 ; j = 1 ; do until j > ro - i ; mat[j,i] = miss(0,0) ; j = j + 1 ; endo ; i = i + 1 ; endo ; retp(mat,TT) ; endp ; end ;