Problem with pricing option : negative premium as results...

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

aptech

1,773


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

aptech

1,773


0



Thanks a lot for your answer and your help.

Arthur

Your Answer

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


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.

Try GAUSS for 14 days for FREE

See what GAUSS can do for your data

© Aptech Systems, Inc. All rights reserved.

Privacy Policy