[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Dmi flaw: final explanation and fixed version



PureBytes Links

Trading Reference Links


WAS  RE: How to see the DMI bug without any testprintouts at all

> -----Message d'origine-----
> De : Bengtsson, Mats [mailto:mats.bengtsson@xxxxxxxx]
> Envoyé : samedi 4 août 2001 16:10
> À : pierre.orphelin@xxxxxxxxxxxxxx; omega-list@xxxxxxxxxx
> Objet : RE: How to see the DMI bug without any testprintouts at all
>
>
> Well Pierre, we all know you will never admit a bug in an Omega
> product and> that will have to be ok, but could you not stop confusing
others with your
> theories?
>

If you had sent the price data as you did after 150 post, things could have
been easier.
I do not want to confuse anyone, I only want to understand.
And your previous assumptions telling this problem was a TS lack of
precision, a need to use doubles instead of float, althought this is not
needed, was not sufficient to make us understand where was the problem and
why it occured.

Because you are right on this point: There is a problem with the Dmi EL
code, but not with the TS software.

The problem occurs only under special circumstances that are:
High[0] > High[1]
and Low [1] < Low [0]
and absvalue(High[0] - High[1]) = absvalue(Low [1] - Low [0])

This rare pattern occurs when the last bar overlaps the hi lo values of the
previous bar by the same amount to the high and to the low.

Because the above difference are the values reported from a variable
difference into the final PlusDM and Minus DM values after comparizon, the
problem only occurs WHEN the above condition are met AND if an epsilon (e)
error ( from the float precision) apperars to be of a different sign  for
PlusDM and Minus DM.

This do not occur very often, but when it occurs ( like it is the case at
bar date 990416) plusdm is not set to  0 because there is a  2*e difference
instead of  0 as expected.
This also depends on the price values to be substracted themselves, the
+e -e error is tied to this too, so the +e -e  sign value in difficult to
predict.

So, the Dmi error exists, this is a fact, and the solution has nothing to do
with TS itself,but rather with the Easy language code that has a flaw: It's
clearly an EL programming error that misused the common programming general
rule that says: do not write condition that compares strictly equal numbers
without knowing the sequels.

This has nothing to do with the internal TS compiler, and you should have
the same if you compare floats or doubles in any language, because the e
difference exists with every computer language that store real numbers
 decimal).

The comment below show where the error may occur in the code, and the fix
comes after ( no need to write a special function to compare the numbers
that are of epsilon value different).The minimum difference should be less
than the tick move, what is easily obtained from the pricescale.

Now, why ro you observe a  30% difference from the modified code?
The reason is simple and only occurs for indicators that reset a value from
a strictly equal comparizon.
Plus dm and Minus dm are accumulated to produce te final results, so a
missing reset to zero will of course take effect on the sum where a number
different of zero is added.

Do you have the right to say that TS Float lack of precision is guilty of
that? Certainly not.
TS precision is what it is and it perfectly works in respect of price data
precision, and ha no error.
The only culprit is the writer of the DmiPlus function that forgot an
elementary test warning that is not recommended to use in any computer
language.
You may call this a bug, but not a general TS bug.
It's a progamming flaw in a function ( Dmiminus is also affected, so is ADX
and ADXR).

Fortunately, you can rewrite this function if you estimate that the cost is
heavy to you, because TS allows this.
This is not a sufficient reason to throw awy TS and go to Matlab,
mAthematica or C++, where its also easy to do the same kind of error.

The advantage of these software is obvious: As they are not provided with
technical analysis libraries, fully disclosed in TS, you cannot claim that a
Dmi bug will exist in the software, because you have to write your own.
So please, do not confuse a flaw in a function and a general bug in the
software, what you previously indented to do.

Obviously, TRAD has to implement the fix below in their Dmi EL code,
including the new TS Pro Dmi code that still has the same flaw.
Also, they could rewrite the linearregression function using, for example,
Bob Fulks' version.
As they monitor this list, they should know what they have to do.

Again, I like to understand what I do and what people do.
If you had been less verbose, more precise and less agressive with the
software problem, we could have found an explanation earlier. You also could
have determined the exact conditions of the flaw as I did, rather than
posting 100 lines where a few only were useful.

But this poor TS, still the only game in town for technical analysis
programmer, is too much the target of unfair attacks. You still forgot that
most of you have learnt comes from TS ( do not say the contrary) and now
that you areless dependent of it, you do not show any form of thanking, only
rancor at its worst.


This is probably what I do not like here.
I do not like people that do not recognize the hand that fed them when they
were younger.


Here is the explanation in the code
===================================


> So here comes a way of seeing the bug without test printouts. Try it for
> yourselves, create a new indicator, which does
> "plot1(dmiplus(5));", that is
> all that is needed.
>
>   Then look at the plot value of 990416, you
> can see that it is higher than for the day before. This is since the
PlusDM calculation
> decided that the low difference (minusDM) of 0.05 is not higher
> or equal to the high difference (plusDM) of 0.05, due to the precision
error. Thus the
> DMI is given a higher value than yesterday though adding a number
> to the old value, when instead it should be given a lower value by just
removing part
> of the old value.


if CurrentBar > 1 Then Begin
		If High[0] - High[1] < 0 Then
			PlusDM = 0
		Else
			PlusDM = High[0] - High[1];     =====> PlusDm is set to 0.05 ( here
6.80-6.75), but in fact 0.05 +e
		If Low [1] - Low [0] < 0 Then
			MinusDM = 0
		Else
			MinusDM = Low[1] - Low[0];      ====>set to 0.05 (here 6.60-6.55), but in
fact 0.05 -e
		If MinusDM >= PlusDM Then
			PlusDM = 0;                      ===> will not be set to 0 because of the
2*e difference that forbids the " = " test
		{MinusDM not set to 0 because it is not used}
		If MyRange > 0 Then Begin
			TRange = TRange[1] - (TRange[1] / MyRange) + TrueRange;
			PlusDM14 = PlusDM14[1] - (PlusDM14[1] / MyRange) + PlusDM;
		End;
		If TRange <> 0 Then
			DMIPlus2 = 100 * PlusDM14 / TRange
		Else
			DMIPlus2 = 0 ;
	End ;



> date high low close volume
> 04/01/1999	7.0000	6.7000	6.7000	26100
> 04/06/1999	6.9500	6.5000	6.6500	23700
> 04/07/1999	6.8500	6.5000	6.6000	20300
> 04/08/1999	6.7500	6.6000	6.6000	25320
> 04/09/1999	6.8500	6.6500	6.7000	15500
> 04/12/1999	6.7500	6.6000	6.7500	31800
> 04/13/1999	6.8500	6.6000	6.6000	20250
> 04/14/1999	6.7500	6.6000	6.6000	21700
> 04/15/1999	6.7500	6.6000	6.6000	34000 <===compare H L values with the next
values
> 04/16/1999	6.8000	6.5500	6.7500	36800 <=== Day in error



And here is the fixed version of Dmiplus
========================================

{*******************************************************************
Dmiplus2 function. Description: Directional Movement Index Plus modified by
Pierre Orphelin
Originally provided By: Omega Research, Inc. (c) Copyright 1999
********************************************************************}


Inputs: Length(10) ;
Variables:Dmiplus2(0),Counter(0), TRange(0), MyRange(Length), PlusDM14(0),
PlusDM(0), MinusDM(0);

If CurrentBar = 1 Then Begin
	MyRange = Length;
	DMIPlus2 = 0;
	PlusDM14 = 0;
	TRange = 0;
	For Counter = 0 To MyRange - 1 Begin
		If High[Counter] - High[Counter+1] < 0 Then
			PlusDM = 0
		Else
			PlusDM = High[Counter] - High[Counter+1];
		If Low[Counter+1] - Low[Counter] < 0 Then
			MinusDM = 0
		Else
			MinusDM = Low[Counter+1] - Low[Counter];
			If MinusDM > PlusDM -.5/pricescale Then
			PlusDM = 0;
		{MinusDM not set to 0 because it is not used}
		TRange = TRange + TrueRange[Counter];
		PlusDM14 = PlusDM14 + PlusDM;
	End;
	If TRange <> 0 Then
		DMIPlus2 = 100 * PlusDM14 / TRange
	Else
		DMIPlus2 = 0 ;
End
Else
	If CurrentBar > 1 Then Begin
If High[0] - High[1] < 0 Then
			PlusDM = 0
		Else
			PlusDM = High[0] - High[1];
		If Low [1] - Low [0] < 0 Then
			MinusDM = 0
		Else
			MinusDM = Low[1] - Low[0];
		If MinusDM > PlusDM -.5/pricescale Then
			PlusDM = 0;
		{MinusDM not set to 0 because it is not used}
		If MyRange > 0 Then Begin
			TRange = TRange[1] - (TRange[1] / MyRange) + TrueRange;
			PlusDM14 = PlusDM14[1] - (PlusDM14[1] / MyRange) + PlusDM;
		End;
		If TRange <> 0 Then
			DMIPlus2 = 100 * PlusDM14 / TRange
		Else
			DMIPlus2 = 0 ;
	End ;



Sincerely,

Pierre Orphelin
www.sirtrade.com
TradeStation Technologies representative in France