Center of Gravity

 
Can anyone help write the Center of Gravity indicator by John Ehler in MT4?


Blessings,

Jerry

Is there anyone that can point me in the right direction or to the right person for help??
 
Here's my attempt at the Ehlers COG. Someone needs to verify this code and correct my hacks.

//+------------------------------------------------------------------+
//|                                                   Ehlers COG.mq4 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  Red
#property indicator_color2  Blue

extern int COGPeriod = 10;

double COG[], COG1[], wrkArray[];
//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(3);
   IndicatorDigits( MarketInfo( Symbol(), MODE_DIGITS ));
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);

   if( !SetIndexBuffer( 0, COG ) &&
       !SetIndexBuffer( 1, COG1 ) &&
       !SetIndexBuffer( 2, wrkArray ))
      Print( "cannot set indicator buffers!" );

   SetIndexDrawBegin( 0, COGPeriod );
   SetIndexDrawBegin( 1, COGPeriod );

   IndicatorShortName( "Ehlers COG" );

   return(0);
}
//+------------------------------------------------------------------+
int start()
{
   int i, j, limit, iWrk00;
   int countedBars = IndicatorCounted();
   double dWrk00, num, denom;

   limit = Bars - countedBars;
   for( i = 0; i < limit; i++ )
   {
      wrkArray[i] = iMA(NULL, 0, COGPeriod, 0, MODE_SMA, PRICE_MEDIAN, i);
      if((i >= COGPeriod) || (limit < 10))
      {
         num = 0;
         denom = 0;
         for( j = 0; j < COGPeriod; j++)
         {
            if(limit < 10)
               iWrk00 = i + j;
            else
               iWrk00 = i - COGPeriod + j;
            num = num + (1 + j) * wrkArray[iWrk00];
            denom = denom + wrkArray[iWrk00];
         }
         if(limit < 10)
            iWrk00 = i;
         else
            iWrk00 = i - COGPeriod;
         COG[iWrk00] = -num / denom;
         if(iWrk00 > 0)
            COG1[iWrk00 - 1] = COG[iWrk00];
      }
   }

   return(0);
}
//+------------------------------------------------------------------+



Hope it helps!

 
Oops! Sorry about the following line:

wrkArray[i] = iMA(NULL, 0, COGPeriod, 0, MODE_SMA, PRICE_MEDIAN, i);

This line is incorrect...I am fixing it now. I was trying to use MT4's ability to use different averaging methods to make the oscillator more responsive. I'll post as soon as I have corrected the problem.

Again, my apologies.
 
Here is the updated code. Again though if anyone can optimize it further or make it better have at it!

//+------------------------------------------------------------------+
//|                                                   Ehlers COG.mq4 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  Red
#property indicator_color2  Blue

extern int COGPeriod = 10;

double COG[], COG1[], wrkArray[];
//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(2);
   IndicatorDigits( MarketInfo( Symbol(), MODE_DIGITS ));
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);

   if( !SetIndexBuffer( 0, COG ) &&
       !SetIndexBuffer( 1, COG1 ))
      Print( "cannot set indicator buffers!" );

   SetIndexDrawBegin( 0, COGPeriod );
   SetIndexDrawBegin( 1, COGPeriod );

   IndicatorShortName( "Ehlers COG" );

   return(0);
}
//+------------------------------------------------------------------+
// Calculating Ehlers Center of Gravity
//+------------------------------------------------------------------+
// COG = -1 * (NUM / DENOM)
// NUM = the sum of [PRICE[i] * (i + 1)] from 0 to N
// DENOM = the sum of PRICE[i] from 0 to N
//   where N equals the number of periods (COGPeriod)
//         PRICE[0] equals the current bar
//         PRICE[1] equals the previous bar
//         PRICE[n] equals the price from n bars previous
//+------------------------------------------------------------------+
int start()
{
   int i, j, limit, iWrk00;
   int countedBars = IndicatorCounted();
   double dWrk00, num, denom;

   limit = Bars - countedBars;
   for( i = 0; i < limit; i++ )
   {
      if((i >= COGPeriod) || (limit < 10))
      {
         num = 0;
         denom = 0;
         for( j = 0; j < COGPeriod; j++)
         {
            if(limit < 10)
               iWrk00 = i + j;
            else
               iWrk00 = i - COGPeriod + j;
            dWrk00 = (High[iWrk00] + Low[iWrk00]) / 2;
            num = num + (1 + j) * dWrk00;
            denom = denom + dWrk00;
         }
         if(limit < 10)
            iWrk00 = i;
         else
            iWrk00 = i - COGPeriod;
         COG[iWrk00] = -num / denom;
         if(iWrk00 > 0)
            COG1[iWrk00 - 1] = COG[iWrk00];
      }
   }

   return(0);
}
//+------------------------------------------------------------------+



One final suggestion. As Ehlers site states regarding the CG oscillator setting the period window to half the dominant cycle will give an ideal CG oscillator under the given market condition. Integrating the Zig-Zag indicator into the system to determine this half dominant cycle number and using it as the window period can be coded. We use the tools at hand and the Zig-Zag is readily available in MT4.

 
Blessings on you for your work! Thank you so much for this and all your information regarding the Zig-Zag indicator. I appreciate this!

Jerry


Here is the updated code. Again though if anyone can optimize it further or make it better have at it!

//+------------------------------------------------------------------+
//|                                                   Ehlers COG.mq4 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  Red
#property indicator_color2  Blue

extern int COGPeriod = 10;

double COG[], COG1[], wrkArray[];
//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(2);
   IndicatorDigits( MarketInfo( Symbol(), MODE_DIGITS ));
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);

   if( !SetIndexBuffer( 0, COG ) &&
       !SetIndexBuffer( 1, COG1 ))
      Print( "cannot set indicator buffers!" );

   SetIndexDrawBegin( 0, COGPeriod );
   SetIndexDrawBegin( 1, COGPeriod );

   IndicatorShortName( "Ehlers COG" );

   return(0);
}
//+------------------------------------------------------------------+
// Calculating Ehlers Center of Gravity
//+------------------------------------------------------------------+
// COG = -1 * (NUM / DENOM)
// NUM = the sum of [PRICE[i] * (i + 1)] from 0 to N
// DENOM = the sum of PRICE[i] from 0 to N
//   where N equals the number of periods (COGPeriod)
//         PRICE[0] equals the current bar
//         PRICE[1] equals the previous bar
//         PRICE[n] equals the price from n bars previous
//+------------------------------------------------------------------+
int start()
{
   int i, j, limit, iWrk00;
   int countedBars = IndicatorCounted();
   double dWrk00, num, denom;

   limit = Bars - countedBars;
   for( i = 0; i < limit; i++ )
   {
      if((i >= COGPeriod) || (limit < 10))
      {
         num = 0;
         denom = 0;
         for( j = 0; j < COGPeriod; j++)
         {
            if(limit < 10)
               iWrk00 = i + j;
            else
               iWrk00 = i - COGPeriod + j;
            dWrk00 = (High[iWrk00] + Low[iWrk00]) / 2;
            num = num + (1 + j) * dWrk00;
            denom = denom + dWrk00;
         }
         if(limit < 10)
            iWrk00 = i;
         else
            iWrk00 = i - COGPeriod;
         COG[iWrk00] = -num / denom;
         if(iWrk00 > 0)
            COG1[iWrk00 - 1] = COG[iWrk00];
      }
   }

   return(0);
}
//+------------------------------------------------------------------+



One final suggestion. As Ehlers site states regarding the CG oscillator setting the period window to half the dominant cycle will give an ideal CG oscillator under the given market condition. Integrating the Zig-Zag indicator into the system to determine this half dominant cycle number and using it as the window period can be coded. We use the tools at hand and the Zig-Zag is readily available in MT4.

Reason: