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
