Dear All,
I have a program here below in order to price knock out options but for some values it gives me some negative value and it is theoretically impossible... Do you some ideas why ?
Thanks in advance.
------
// PARAMETRES
fer = {879, 874, 876, 873, 871, 858, 854, 857, 861, 862, 856, 849, 832, 835, 854, 858, 850, 847, 849, 851, 844, 838, 838, 836, 841, 847, 857, 860, 854, 849, 843, 825, 816, 813, 816, 812, 799, 796, 798, 795, 774, 734, 731, 726, 737, 735, 734, 730, 733, 744, 735, 730, 751, 755, 761, 769, 789};
K6 = {879, 874, 876, 873, 871, 858, 854, 857, 861, 862, 856, 849, 832, 835, 854, 858, 850, 847, 849, 851, 844, 838, 838, 836, 841, 847, 857, 860, 854, 849, 843, 825, 816, 813, 816, 812, 799, 796, 798, 795, 774, 734, 731, 726, 737, 735, 734, 730, 733, 744, 735, 730, 751, 755, 761, 769, 789};
K6A = K6 - 0.05*K6 ; K6B = K6 + 0.05*K6 ;
K6C = K6 + 0.05*K6 ; K6D = K6 - 0.05*K6 ;
sigma6 = {0.12051, 0.11976, 0.11894, 0.11795, 0.11693, 0.11936, 0.11891, 0.11534, 0.11547, 0.11407, 0.11477, 0.11459, 0.12139, 0.12122, 0.13112, 0.12325, 0.12297, 0.12304, 0.12327, 0.12353, 0.12436, 0.12486, 0.12448, 0.12405, 0.12467, 0.1257, 0.12867, 0.12885, 0.12807, 0.12796, 0.12852, 0.1353, 0.13478, 0.1348, 0.13518, 0.13501, 0.13812, 0.13794, 0.13631, 0.13621, 0.14481, 0.17862, 0.1783, 0.17838, 0.18273, 0.17855, 0.17802, 0.17805, 0.17839, 0.18241, 0.18328, 0.17927, 0.18968, 0.19035, 0.19149, 0.19121, 0.1981};
r = 0.00146 ; b = 0 ; k = 0 ;
sigma = sigma6 ; S = fer ; X = K6C ; H = 1.05*fer ;
T3 = {0.224657534246575, 0.216438356164384, 0.213698630136986, 0.210958904109589, 0.208219178082192, 0.205479452054795, 0.197260273972603, 0.194520547945205, 0.191780821917808, 0.189041095890411, 0.186301369863014, 0.175342465753425, 0.172602739726027, 0.16986301369863, 0.167123287671233, 0.158904109589041, 0.156164383561644, 0.153424657534247, 0.150684931506849, 0.147945205479452, 0.13972602739726, 0.136986301369863, 0.134246575342466, 0.131506849315068, 0.128767123287671, 0.120547945205479, 0.117808219178082, 0.115068493150685, 0.112328767123288, 0.10958904109589, 0.0986301369863014, 0.0958904109589041, 0.0931506849315069, 0.0904109589041096, 0.0821917808219178, 0.0794520547945206, 0.0767123287671233, 0.073972602739726, 0.0712328767123288, 0.063013698630137, 0.0602739726027397, 0.0575342465753425, 0.0547945205479452, 0.0520547945205479, 0.0438356164383562, 0.0410958904109589, 0.0383561643835616, 0.0356164383561644, 0.0328767123287671, 0.0246575342465753, 0.0219178082191781, 0.0191780821917808, 0.0164383561643836, 0.0136986301369863, 0.00547945205479452, 0.00273972602739726, 0.00};
T = T3 ;
// Facteurs utilisés pour le formules //
u = (b-((1/2).*sigma.*sigma))./(sigma.*sigma);
l = sqrt(u^2 + (2*r)./(sigma.*sigma));
x1 = ln(S/X)./(sigma.*sqrt(T))+((1+u).*sigma.*sqrt(T));
x2 = ln(S/H)./(sigma.*sqrt(T))+((1+u).*sigma.*sqrt(T));
y1 = ln((H^2)./(S.*X))./(sigma.*sqrt(T))+(1+u).*sigma.*sqrt(T);
y2 = ln(H./S)./(sigma.*sqrt(T))+(1+u).*sigma.*sqrt(T);
z = ln(H./S)./(sigma.*sqrt(T))+(l.*sigma.*sqrt(T));
// A = O.*S.*exp((b-r).*T).*cdfn(O.*x1)-O.*X.*exp(-r.*T).*cdfn(O.*x1-O.*sigma.*sqrt(T));
A1 = S.*exp((b-r).*T).*cdfn(x1)-X.*exp(-r.*T).*cdfn(x1-(sigma.*sqrt(T))); _A1 = A1 ;
A2 = S.*exp((b-r).*T).*cdfn(x1)-X.*exp(-r.*T).*cdfn(x1-(sigma.*sqrt(T))); _A2 = A2 ;
A3 = -S.*exp((b-r).*T).*cdfn(-x1)-(-X.*exp(-r.*T).*cdfn(-x1-(-sigma.*sqrt(T)))); _A3 = A3 ;
A4 = -S.*exp((b-r).*T).*cdfn(-x1)-(-X.*exp(-r.*T).*cdfn(-x1-(-sigma.*sqrt(T)))); _A4 = A4 ;
// Bi = O.*S.*exp((b-r).*T).*cdfn(O.*x2)-O.*X.*exp(-r.*T).*cdfn(O.*x2-O.*sigma.*sqrt(T));
B1 = S.*exp((b-r).*T).*cdfn(x2)-X.*exp(-r.*T).*cdfn(x2-sigma.*sqrt(T)); _B1 = B1 ;
B2 = S.*exp((b-r).*T).*cdfn(x2)-X.*exp(-r.*T).*cdfn(x2-sigma.*sqrt(T)); _B2 = B2 ;
B3 = -S.*exp((b-r).*T).*cdfn(-x2)-(-X.*exp(-r.*T).*cdfn(-x2+sigma.*sqrt(T))); _B3 = B3 ;
B4 = -S.*exp((b-r).*T).*cdfn(-x2)-(-X.*exp(-r.*T).*cdfn(-x2+sigma.*sqrt(T))); _B4 = B4 ;
// C = O.*S.*exp((b-r).*T).*(H./S)^(2.*(u+1)).*cdfn(n.*y1)-O.*X.*exp(-r.*T).*(H./S)^(2.*u).*cdfn(n.*y1-n.*sigma.*sqrt(T));
C1 = S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(y1) - X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(y1-sigma.*sqrt(T)); _C1 = C1 ;
C2 = S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(-y1) - X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(-y1+sigma.*sqrt(T)); _C2 = C2 ;
C3 = -S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(y1)-(-X).*exp(-r.*T).*(H./S)^(2*u).*cdfn(y1-sigma.*sqrt(T)); _C3 = C3 ;
C4 = -S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(-y1)-(-X).*exp(-r.*T).*(H./S)^(2*u).*cdfn(-y1+sigma.*sqrt(T)); _C4 = C4 ;
// D = O.*S.*exp((b-r).*T).*(H./S)^(2.*(u+1)).*cdfn(n.*y2)-O.*X.*exp(-r.*T).*(H./S)^(2.*u).*cdfn(n.*y2-n.*sigma.*sqrt(T));
D1 = S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(y2) - X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(y2-sigma.*sqrt(T)); _D1 = D1 ;
D2 = S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(-y2) - X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(-y2+sigma.*sqrt(T)); _D2 = D2 ;
D3 = -S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(y2) + X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(y2-sigma.*sqrt(T)); _D3 = D3 ;
D4 = -S.*exp((b-r).*T).*(H./S)^(2*(u+1)).*cdfn(-y2) + X.*exp(-r.*T).*(H./S)^(2*u).*cdfn(-y2+sigma.*sqrt(T)); _D4 = D4 ;
// E = K.*exp(-r.*T).*(cdfn(n.*x2-n.*sigma.*sqrt(T))-(H./S)^(2.*u).*cdfn(n.*y2-n.*sigma.*sqrt(T)));
E1 = K.*exp(-r.*T).*(cdfn(x2-sigma.*sqrt(T))-(H./S)^(2*u).*cdfn(y2-sigma.*sqrt(T))); _E1 = E1 ;
E2 = K.*exp(-r.*T).*(cdfn(-x2+sigma.*sqrt(T))-(H./S)^(2*u).*cdfn(-y2+sigma.*sqrt(T))); _E2 = E2 ;
E3 = K.*exp(-r.*T).*(cdfn(x2-sigma.*sqrt(T))-(H./S)^(2*u).*cdfn(y2-sigma.*sqrt(T))); _E3 = E3 ;
E4 = K.*exp(-r.*T).*(cdfn(-x2+sigma.*sqrt(T))-(H./S)^(2*u).*cdfn(-y2+sigma.*sqrt(T))); _E4 = E4 ;
// F = K.*(((H./S)^(u+l)).*cdfn(n.*z)+((H./S)^(u-l)).*cdfn(n.*z-2.*n.*l.*sigma.*sqrt(T)));
F1 = K.*(((H./S)^(u+l)).*cdfn(z)+((H./S)^(u-l)).*cdfn(z-2*l.*sigma.*sqrt(T))); _F1 = F1 ;
F2 = K.*(((H./S)^(u+l)).*cdfn(-z)+((H./S)^(u-l)).*cdfn(-z+2*l.*sigma.*sqrt(T))); _F2 = F2 ;
F3 = K.*(((H./S)^(u+l)).*cdfn(z)+((H./S)^(u-l)).*cdfn(z-2*l.*sigma.*sqrt(T))); _F3 = F3 ;
F4 = K.*(((H./S)^(u+l)).*cdfn(-z)+((H./S)^(u-l)).*cdfn(-z+2*l.*sigma.*sqrt(T))); _F4 = F4 ;
cls;
print "Call Barrière Out";
BarrierOutCall(S,X,H);
print "Put Barrière Out";
BarrierOutPut(S,X,H);
// OUT BARRIER OPTIONS - STANDARD BARRIER OPIONS //
proc(1) = BarrierOutCall(S,X,H);
local cal;
if S > H ;
if X > H ;
cal = _A1-_C1+_F1 ;
else;
cal = _B1-_D1+_F1 ;
endif;
else;
if X > H ;
cal = _F2 ;
else;
cal = _A2-_B2+_C2-_D2+_F2 ;
endif;
endif;
retp(cal);
endp;
// OUT BARRIER OPTIONS - STANDARD BARRIER OPIONS //
proc(1) = BarrierOutPut(S,X,H);
local put, Ai4, Bi4, Ci4, Di4, Fi4 ;
if S > H ;
if X > H ;
put = _A3-_B3+_C3-_D3+_F3 ;
else;
put = _F3 ;
endif;
else;
if X > H ;
Fi4 = _F4 ; Bi4 = _B4 ; Di4 = _D4 ; put = Fi4+Bi4-Di4 ;
else;
Ai4 = _A4 ; Ci4 = _C4 ; Fi4 = _F4 ; put = Ai4+Fi4-Ci4 ;
endif;
endif;
retp(put);
endp;
4 Answers
0
Is this the output that you are seeing?
Call Barrière Out 0.0000000 -2.8421709e-14 -2.8421709e-14 0.0000000 2.8421709e-14 -2.8421709e-14 0.0000000 5.6843419e-14 2.8421709e-14 0.0000000 -5.6843419e-14 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 2.8421709e-14 -5.6843419e-14 0.0000000 0.0000000 0.0000000 -1.4210855e-14 -1.4210855e-14 2.8421709e-14 4.2632564e-14 -1.4210855e-14 -1.4210855e-14 1.4210855e-14 0.0000000 1.4210855e-14 0.0000000 1.4210855e-14 0.0000000 0.0000000 -1.4210855e-14 0.0000000 1.4210855e-14 2.8421709e-14 1.4210855e-14 0.0000000 0.0000000 1.4210855e-14 0.0000000 0.0000000 1.4210855e-14 1.4210855e-14 0.0000000 0.0000000 -7.1054274e-15 0.0000000 -3.5527137e-15 0.0000000 0.0000000 0.0000000 -2.7755576e-17 0.0000000 0.0000000 Put Barrière Out 43.935587 43.686193 43.786337 43.636558 43.536763 42.887132 42.687704 42.837832 43.037948 43.088106 42.788360 42.439134 41.589518 41.739647 42.689582 42.890048 42.490311 42.340515 42.440662 42.540810 42.191392 41.891621 41.891788 41.791975 42.042095 42.342547 42.842630 42.992777 42.692998 42.443209 42.143931 41.244225 40.794452 40.644635 40.795104 40.595291 39.945526 39.795702 39.895851 39.746343 38.696595 36.696917 36.547076 36.297241 36.847642 36.747795 36.697945 36.498102 36.648241 37.198661 36.748824 36.498978 37.549099 37.749245 38.049696 38.449846 39.450000
0
It is !
As you see, negative prices are not possible ... And I don't understand where is the mistake...
0
The problem is that your calculations are not going to give more than 14 digits of accuracy. For example, the second element of _A2 and the second element of _C2 are:
5.2356085631733436 -5.2356085631733720
The addition of these two numbers inside of BarrierOutCall is causing one of your negative outputs. We can see that these numbers do not differ until the 15 place. Computers only have 15.5 digits of precision. Computer calculations involve some round-off error, so the data in the 15th place will be noise. Therefore, to the accuracy of the calculations the option values are all 0.
NOTE that this does not mean that you cannot get precision for numbers smaller than 1e-14. What matters is the number of digits. So if we perform this calculation:
5.2356085631733436 - 5.2356085631733720
we get:
2.8421709430404007e-14
And if we change the scale to this calculation:
5.2356085631733436e-121 - 5.2356085631733720e-121
We will get an answer with a similar number of accurate digits:
-2.9236196820131970e-135
0
Thanks a lot for your answer and your help.
Arthur
Your Answer
4 Answers
Is this the output that you are seeing?
Call Barrière Out 0.0000000 -2.8421709e-14 -2.8421709e-14 0.0000000 2.8421709e-14 -2.8421709e-14 0.0000000 5.6843419e-14 2.8421709e-14 0.0000000 -5.6843419e-14 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 2.8421709e-14 -5.6843419e-14 0.0000000 0.0000000 0.0000000 -1.4210855e-14 -1.4210855e-14 2.8421709e-14 4.2632564e-14 -1.4210855e-14 -1.4210855e-14 1.4210855e-14 0.0000000 1.4210855e-14 0.0000000 1.4210855e-14 0.0000000 0.0000000 -1.4210855e-14 0.0000000 1.4210855e-14 2.8421709e-14 1.4210855e-14 0.0000000 0.0000000 1.4210855e-14 0.0000000 0.0000000 1.4210855e-14 1.4210855e-14 0.0000000 0.0000000 -7.1054274e-15 0.0000000 -3.5527137e-15 0.0000000 0.0000000 0.0000000 -2.7755576e-17 0.0000000 0.0000000 Put Barrière Out 43.935587 43.686193 43.786337 43.636558 43.536763 42.887132 42.687704 42.837832 43.037948 43.088106 42.788360 42.439134 41.589518 41.739647 42.689582 42.890048 42.490311 42.340515 42.440662 42.540810 42.191392 41.891621 41.891788 41.791975 42.042095 42.342547 42.842630 42.992777 42.692998 42.443209 42.143931 41.244225 40.794452 40.644635 40.795104 40.595291 39.945526 39.795702 39.895851 39.746343 38.696595 36.696917 36.547076 36.297241 36.847642 36.747795 36.697945 36.498102 36.648241 37.198661 36.748824 36.498978 37.549099 37.749245 38.049696 38.449846 39.450000
It is !
As you see, negative prices are not possible ... And I don't understand where is the mistake...
The problem is that your calculations are not going to give more than 14 digits of accuracy. For example, the second element of _A2 and the second element of _C2 are:
5.2356085631733436 -5.2356085631733720
The addition of these two numbers inside of BarrierOutCall is causing one of your negative outputs. We can see that these numbers do not differ until the 15 place. Computers only have 15.5 digits of precision. Computer calculations involve some round-off error, so the data in the 15th place will be noise. Therefore, to the accuracy of the calculations the option values are all 0.
NOTE that this does not mean that you cannot get precision for numbers smaller than 1e-14. What matters is the number of digits. So if we perform this calculation:
5.2356085631733436 - 5.2356085631733720
we get:
2.8421709430404007e-14
And if we change the scale to this calculation:
5.2356085631733436e-121 - 5.2356085631733720e-121
We will get an answer with a similar number of accurate digits:
-2.9236196820131970e-135
Thanks a lot for your answer and your help.
Arthur