Chande Mommentum and the division mistery

 

I am trying to develop the Chande Momentum Indicator but something mysterious is happening.

If you can take a look in my code you will find at the last step of the calculation the following code:

cmo4 = scmo1[i]+cmo3;

If you comment this line you can see in the log file, in CSV format, that the previous steps are correct, so for some reason this division is generating some problem that I can´t trace.

First i thought it was the number of buffers than I start to use arrays and the problem still continues.

I would appreciate very much any help.


Thank you,

//+------------------------------------------------------------------+
//|                                           Chande Momentum        |
//+------------------------------------------------------------------+
 
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 20
#property  indicator_color1  Red
#property  indicator_width1  2
 
      
extern int CMO_Period = 15;
 
//---- buffers
 
 
double cmo1[];
double scmo1[];
double cmo2[];
double scmo2[];
double cmo[];
 
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  
//---- drawing settings
   
   SetIndexStyle(0,DRAW_LINE);
 
 
  // IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);
 
 
 
 
 
//cmo dif1    cmo1    scmo1    cmo2    scmo2    cmo3    cmo4
 
//---- 3 indicator buffers mapping
 
 
 
   SetIndexBuffer(0,cmo);
 
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("CMO("+CMO_Period+")");
   
   
   ArrayResize(cmo1,Bars);
   ArraySetAsSeries(cmo1,true);
 
   ArrayResize(scmo1,Bars);
   ArraySetAsSeries(scmo1,true);
 
   ArrayResize(cmo2,Bars);
   ArraySetAsSeries(cmo2,true);
 
   ArrayResize(scmo2,Bars);
   ArraySetAsSeries(scmo2,true);  
   
//---- initialization done
   return(0);
  }
 
int start()
{
   int i, j, k, limit;
   double dif1, cmo3, cmo4, Tcmo1, Tscmo1, Tcmo2, Tscmo2;
   int    counted_bars=IndicatorCounted();
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
  
 //dif1    cmo1    scmo1    cmo2    scmo2    cmo3    cmo4    cmo
 
 
 //=IF(dif1[i]>=0;dif[i];0)
 
 //=IF(dif1[i]>=0;0;-dif1[i])
 
   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0) Tcmo1 = dif1;
       else Tcmo1 = 0;
       cmo1[i] = Tcmo1;
       if(dif1>=0) Tcmo2 = 0;
       else Tcmo2 = -dif1;
       cmo2[i] = Tcmo2;
     }
 
 
   for(i = limit; i >= 0; i--)
     {
       Tscmo1 = 0;
       for(j = i + CMO_Period-1; j >= i; j--)Tscmo1 += cmo1[j];
       scmo1[i] = Tscmo1;
     }
 
 
   for(i = limit; i >= 0; i--)
     {
       Tscmo2 = 0;
       for(j = i + CMO_Period-1; j >= i; j--)Tscmo2 += cmo2[j];
       scmo2[i] = Tscmo2;
     }
 
//scmo1 - scmo2
 
int logCMO=FileOpen(Symbol()+"CMO.csv",FILE_CSV|FILE_WRITE, ';');
FileWrite(logCMO, "Time[i]", "Close[i]", "Close[i+1]", "Close[i]-Close[i+1]", "cmo1[i]", "scmo1[i]", "cmo2[i]", "scmo2[i]", "cmo3");       
   for(i = limit; i >= 0; i--)
     {
       cmo3 = scmo1[i]-scmo2[i];
       cmo4 = scmo1[i]+cmo3;
       cmo[i] = cmo3/cmo4; 
       FileWrite(logCMO, Time[i], Close[i], Close[i+1], Close[i]-Close[i+1], cmo1[i], scmo1[i], cmo2[i], scmo2[i], cmo3, cmo4, cmo[i]);       
     }
 
 FileClose(logCMO);
      
      return(0);
  }
//+------------------------------------------------------------------+
Files:
icmogt.mq4  3 kb
 
Well the answer is simple:

Division by zero occured.

You may add something like this.

if(cmo4!=0)
cmo[i] = cmo3/cmo4;


In that case the indicator line may be not continous in some places.
By the way could you write some more information about this indicator.
 
scalony:
Well the answer is simple:

Division by zero occured.

You may add something like this.

if(cmo4!=0)
cmo[i] = cmo3/cmo4;


In that case the indicator line may be not continous in some places.
By the way could you write some more information about this indicator.


Scalony,

Thank you very much for your response! It works!!
I changed the cmo4 for the following code:
if(cmo4 == 0)cmo4=0.0001;
cmo[i] = (cmo3/cmo4) *100 ;


Observe that I forgot the *100 in the last post.


For more information about Chande Momentum take a look at:
http://www.positiveterritory.com/do/tw/chanmo11.htm

 
I found another bug in your code.
You calculated the calculated cmo4 that way
cmo4 = scmo1[i]+cmo3;
and after I read the article about that indicator that you pointed I found that it should be
cmo4 = scmo1[i]+scmo2[i];
I attached the corrected version of this CMO indicator.
Files:
icmogt_1.mq4  3 kb
 
scalony:
I found another bug in your code.
You calculated the calculated cmo4 that way
cmo4 = scmo1[i]+cmo3;
and after I read the article about that indicator that you pointed I found that it should be
cmo4 = scmo1[i]+scmo2[i];
I attached the corrected version of this CMO indicator.






Well done!

You are totally right.

Thank you again.

 

Scalony,

I have another mystery for you.

As you can see in this attachment EA, I use a simple formula to obtain the Chande Momentum whit the iCustom function but the value of the CMO is different from another using the same indicator (The one we develop above).

To reproduce the test you must enable the visual mode and attach the indicator iCMO than you can see the same picture above.

Do you have any ideas?

Files:
cmoea.mq4  2 kb
 
SpaceTrader:


Scalony,

I have another mystery for you.

As you can see in this attachment EA, I use a simple formula to obtain the Chande Momentum whit the iCustom function but the value of the CMO is different from another using the same indicator (The one we develop above).

To reproduce the test you must enable the visual mode and attach the indicator iCMO than you can see the same picture above.

Do you have any ideas?


Scalony,


I found another error in the formula, here is the correction (as you can see in the attached file):

// If d >= 0, then cmo1i = d and cmo2i = 0 
// If d <   0, then cmo2i = -d and cmo1i = 0 
 
   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0)
         {
           Tcmo1 = dif1;
           Tcmo2 = 0;
         }
       else
         { 
           Tcmo1 = 0;
           Tcmo2 = -dif1;
         }
       cmo1[i] = Tcmo1;
       cmo2[i] = Tcmo2;
     }

But now I have 2 issues to solve:
First: The Expert Advisor still getting the wrong value from the same indicator that we can attach manually to the graphic:


Second: As you can see in the figure, now the final graphic that the tester plots by the Expert Advisor is quite equal to the one we attached manually to the graphic, but it create a zero line before some bars like you can see in these other picture, other thing is that after the zero line, the firsts points are different in the two graphics:

Do you have any ideias?
I think we are quite there…
Thank you!

Files:
icmo.mq4  3 kb
 
SpaceTrader:


Scalony,

I have another mystery for you.

As you can see in this attachment EA, I use a simple formula to obtain the Chande Momentum whit the iCustom function but the value of the CMO is different from another using the same indicator (The one we develop above).

To reproduce the test you must enable the visual mode and attach the indicator iCMO than you can see the same picture above.

Do you have any ideas?

I have an idea however I am not 100% sure it is right. Maybe indicator attached manually is not recalculated evry tick like the indicator in EA but only when candle is fully formed.
 
SpaceTrader:

Scalony,


I found another error in the formula, here is the correction (as you can see in the attached file):

// If d >= 0, then cmo1i = d and cmo2i = 0 
// If d <   0, then cmo2i = -d and cmo1i = 0 
 
   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0)
         {
           Tcmo1 = dif1;
           Tcmo2 = 0;
         }
       else
         { 
           Tcmo1 = 0;
           Tcmo2 = -dif1;
         }
       cmo1[i] = Tcmo1;
       cmo2[i] = Tcmo2;
     }
There was not any error in previous version of this formula but the code above looks more clear.
 
scalony:
SpaceTrader:

Scalony,


I found another error in the formula, here is the correction (as you can see in the attached file):

// If d >= 0, then cmo1i = d and cmo2i = 0 
// If d <   0, then cmo2i = -d and cmo1i = 0 
 
   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0)
         {
           Tcmo1 = dif1;
           Tcmo2 = 0;
         }
       else
         { 
           Tcmo1 = 0;
           Tcmo2 = -dif1;
         }
       cmo1[i] = Tcmo1;
       cmo2[i] = Tcmo2;
     }
There was not any error in previous version of this formula but the code above looks more clear.


Scalony,

The following code:


   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0) Tcmo1 = dif1;
       else Tcmo1 = 0;
       cmo1[i] = Tcmo1;
       if(dif1>=0) Tcmo2 = 0;
       else Tcmo2 = -dif1;
       cmo2[i] = Tcmo2;
     }

Have the same conditions for both arguments:
if(dif1>=0) Tcmo1 = dif1;
if(dif1 >= 0) Tcmo2 = 0;
Even if the second condition was <= it would still be a problem because there are 2 equals, so the correct is: if(dif1<0) Tcmo2 = 0;
But I agree that the second way is clearer…

I think you are correct about the calculation process being different when the indicator is used manually but it may have some way to solve this issue and I don’t have a clue…
I posted another question in the following topic: 'Indicator Calculation Direction'
Perhaps it is the direction of the calculation…
And don´t forget that there is another problem with the zero line before n numbers of bars.
Thanks a lot

 
SpaceTrader:
scalony:
SpaceTrader:

Scalony,


I found another error in the formula, here is the correction (as you can see in the attached file):

// If d >= 0, then cmo1i = d and cmo2i = 0 
// If d <   0, then cmo2i = -d and cmo1i = 0 
 
   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0)
         {
           Tcmo1 = dif1;
           Tcmo2 = 0;
         }
       else
         { 
           Tcmo1 = 0;
           Tcmo2 = -dif1;
         }
       cmo1[i] = Tcmo1;
       cmo2[i] = Tcmo2;
     }
There was not any error in previous version of this formula but the code above looks more clear.


Scalony,

The following code:


   for(i = limit; i >= 0; i--)
     {
       dif1 = Close[i]-Close[i+1];
       if(dif1>=0) Tcmo1 = dif1;
       else Tcmo1 = 0;
       cmo1[i] = Tcmo1;
       if(dif1>=0) Tcmo2 = 0;
       else Tcmo2 = -dif1;
       cmo2[i] = Tcmo2;
     }

Have the same conditions for both arguments:
if(dif1>=0) Tcmo1 = dif1;
if(dif1 >= 0) Tcmo2 = 0;
Even if the second condition was <= it would still be a problem because there are 2 equals, so the correct is: if(dif1<0) Tcmo2 = 0;
But I agree that the second way is clearer…

I think you are correct about the calculation process being different when the indicator is used manually but it may have some way to solve this issue and I don’t have a clue…
I posted another question in the following topic: 'Indicator Calculation Direction'
Perhaps it is the direction of the calculation…
And don´t forget that there is another problem with the zero line before n numbers of bars.
Thanks a lot

Reason: