MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal

Source code library - Expert Advisors, Indicators and Scripts

MetaTrader Market: we have 650 Expert Advisors for algorithmic trading!
To post a new code, please log in or register

Interesting script?
So post a link to it -
let others appraise it

You liked the script? Try it in the MetaTrader 5 terminal

2011.08.18 12:51
Center of Gravity J. F. Ehlers

Center of Gravity J. F. Ehlers - indicator for MetaTrader 5

| English Russian Chinese Spanish Portuguese

Published by:
Nikolay Kositsin
Views:
4947
Rating:
votes: 13
\MQL5\Include\

Real author:

Rosh

Description:

Center of Gravity actually has a zero lag and allows to define turning points precisely. This indicator is the result of Ehler's study of adaptive filters.

The indicator Center of Gravity allows to identify main pivot points almost without any lag.

The idea of calculating a center of gravity appeared from the investigation of lags of different filters with the finite impulse response (FIR) in accordance with the relative amplitude of filter coefficients. SMA (Simple Moving Average) is a FIR-filter, in which all coefficients have one and the same value. As a result the center of gravity of SMA is an exact center of the filter. WMA (Weighted Moving Average) is a FIR-filter, in which the last price change is weighted through the filter length, and so on.

The values of weighting are coefficients of filters. Coefficients of WMA filters can be presented as contours of a triangle. The center of gravity is on the 1/3 of the triangle base length. Thus WMA gravity center is shifted to the right with respect to the center of gravitation of SMA of the same length, which gives us a smaller lag. For all examples with FIR filters the sum of productions of coefficients and the price must be divided by the sum of coefficients for preservation of original prices.

The most famous of such FIR filters is Ehlers filter that can be presented the following way:

Center of Gravity

The quote from the article:

"The coefficients of the Ehlers Filter can be almost any measure of variability. I have looked at momentum, signal to noise ratio, volatility, and even Stochastics and RSI values as filter coefficients. One of the most adaptive set of coefficients arose from video edge detection filters, and was the sum of the square of the differences of each price to each previous price. In any event, the result of using different filter coefficients is to make the filter adaptive by moving the CG of the coefficients.

While I was debugging the code of an adaptive FIR filter I noticed that the CG, itself, moved in exact opposition to the price swings. The CG moves to the right when prices go up and moves to the left when prices go down. Measured as the distance from the most recent price, the CG decreased when prices rose and increased when they fell. All I had to do was to invert the sign of the CG to get a smoothed oscillator that was both in phase with the price swings and had essentially zero lag."

The Center of Gravity is calculated as Ehlers filter using the formula:

Center of Gravity

In this indicator Period_ parameter sets the period for the indicator calculation, AppliedPrice parameter sets the price type, based on which the indicator is calculated - thus we get the main line of the indicator (with changing color).

For the signal line (blue dot-dash line) the SmoothPeriod parameter sets the period of smoothing the main indicator line, the SmoothType parameter denotes the type of smoothing. The interpretation of the values of parameters is given in the form of comments in the indicator code.

Indicator uses the СMoving_Average class of the SmoothAlgorithms.mqh library. Working with that class was described in details in the article "Averaging Price Series for Intermediate Calculations Without Using Additional Buffers".

This indicator was first implemented in MQL4 and published in CodeBase at mql4.com 20.02.2007.

Image:

Fig.1 Center Of Gravity indicator


Translated from Russian by MetaQuotes Software Corp.
Original code: http://www.mql5.com/ru/code/442

Last comments | Go to discussion (6)
FForex
FForex | 15 Sep 2011 at 06:05
In his opinion this indicator which works with mehor and symbol and timeframe.
What the best values ​​for the parameters of this indicator?


gideons
gideons | 23 Jul 2012 at 13:30

Many many thanks for this great indicator.

I found the previous version as interesting and useful as the new one, or in fact even more so..

Could you please port the old one to mq5 as well ? I'd highly appreciate if it can be done.


Cheers, and thanks in advance !!

Adam W
adamuu | 28 Jul 2012 at 21:20
This indicator is non-deterministic. Ask for the same datapoints twice, at different times, and you'll get different answers. The drift is larger closer to the current time. The inconsistency can be as large as 3.7 x 10^-04.
Bruno Pio
BrunoPio | 10 Aug 2012 at 03:35
InfiniteDesign:

Hello,

This oscillator is a great one, but I have problems with it.

The signal line's end, wich is calculated by the last candle is not shown, so it always shows red at the present time. When I reset the oscillator it shows good values for a moment with the end of the signal line, but then switches back to red, (even if it has to show green).

What should i do to eliminate this problem?

I've tried to re-debug it but it didn't help.

Greets,

InfiniteDesign 

I have the same problem...
Bruno Pio
BrunoPio | 10 Aug 2012 at 03:38

I tried to create a Signal from this indicator, but I was unable...

Any help?


//+------------------------------------------------------------------+
//|                                                          COG.mqh |
//|                                                        Bruno Pio |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Bruno Pio"
#property link      "http://www.mql5.com"
#property version   "1.00"
#include "..\ExpertSignal.mqh"   // CExpertSignal is in the file ExpertSignal
#property tester_indicator "CenterOfGravity.ex5"
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of Center of Gravity                               |
//| Type=SignalAdvanced                                              |
//| Name=My_COG                                                      |
//| ShortName=CG                                                     |
//| Class=COG                                                        |
//| Page=Not needed                                                  |
//| Parameter=Period_,int,10,Indicator averaging period              |
//| Parameter=SmoothPeriod,int,3,Signal line smoothing period        |
//| Parameter=MA_Method_,ENUM_MA_METHOD,MODE_EMA,Signal Method       |
//| Parameter=AppliedPrice,int,1,Price constant                      |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class COG : public CExpertSignal
  {
private:
CiCustom             m_COG;               // The indicator as an object
//--- Configurable module parameters
   int               m_Period_;           // Indicator averaging period
   int               m_SmoothPeriod;      // Signal line smoothing period 
   ENUM_MA_METHOD    m_MA_Method_;        // Signal line averaging method
   int               m_AppliedPrice;      // Price constant
public:
                     COG(void);
                    ~COG(void);
//--- Checking correctness of input data
   bool              ValidationSettings();
//--- Creating indicators and timeseries for the module of signals
   bool              InitIndicators(CIndicators *indicators);
//--- Access to indicator data
   double            CG(const int index)                 const { return(m_COG.GetData(0,index)); }
   double            Signal(const int index)             const { return(m_COG.GetData(1,index)); }   
//--- Checking buy and sell conditions
   virtual int       LongCondition();
   virtual int       ShortCondition();
//--- Methods for setting
   void              Period_(int value)               { m_Period_=value;        }
   void              SmoothPeriod(int value)          { m_SmoothPeriod=value;   }
   void              MA_Method_(ENUM_MA_METHOD value) { m_MA_Method_=value;     }
   void              AppliedPrice(int value)          { m_AppliedPrice=value;   }
protected:
   //--- Creating indicator
   bool              CreateCOG(CIndicators *indicators);



  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
COG::COG(void) :           m_Period_(10),                // Indicator averaging period
                           m_SmoothPeriod(3),            // Signal line smoothing period 
                           m_MA_Method_(MODE_EMA),       // Signal line averaging method
                           m_AppliedPrice(1)             // Price constant
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COG::~COG()
  {
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Checks input parameters and returns true if everything is OK     |
//+------------------------------------------------------------------+
bool COG:: ValidationSettings()
  {
   //--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
   //--- Check periods, number of bars for the calculation of the MA >=1
   if(m_Period_<1)
     {
      PrintFormat("Incorrect value set for one of the period! Period_=%d",
                  m_Period_);
      return false;
     }
//--- Check periods, number of bars for the calculation of the MA >=1
   if(m_SmoothPeriod<1)
     {
      PrintFormat("Incorrect value set for one of the period! m_SmoothPeriod=%d",
                  m_SmoothPeriod);
      return false;
     }
//--- Fast MA smoothing type must be one of the four values of the enumeration
   if(m_MA_Method_!=MODE_SMA && m_MA_Method_!=MODE_EMA && m_MA_Method_!=MODE_SMMA && m_MA_Method_!=MODE_LWMA)
     {
      PrintFormat("Invalid type of smoothing of the fast MA!");
      return false;
     }
//--- m_AppliedPrice must be validy
   if(m_AppliedPrice<1 || m_AppliedPrice>11) 
     {
      PrintFormat("Invalid type of Price!");
      return false;
     }
//--- All checks are completed, everything is ok
   return true;
  }
//+------------------------------------------------------------------+
//| Creates indicators                                               |
//| Input:  a pointer to a collection of indicators                  |
//| Output: true if successful, otherwise false                      |
//+------------------------------------------------------------------+
bool COG::InitIndicators(CIndicators *indicators)
  {
//--- Standard check of the collection of indicators for NULL
   if(indicators==NULL) return(false);
//--- Initializing indicators and timeseries in additional filters
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
//--- Creating our indicators
   if(!CreateCOG(indicators))                  return(false);   
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Creates the "COG" indicator                                      |
//+------------------------------------------------------------------+
bool COG::CreateCOG(CIndicators *indicators)
  {
//--- Checking the pointer
   if(indicators==NULL) return(false);
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_COG)))
     {
      printf(__FUNCTION__+": Error adding an object of the COG");
      return(false);
     }
//--- Setting parameters of the COG
   MqlParam parameters[5];
//---
   parameters[0].type=TYPE_STRING;
   parameters[0].string_value="CenterOfGravity.ex5";
   parameters[1].type=TYPE_INT;
   parameters[1].integer_value=m_Period_;                 // Period
   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=m_SmoothPeriod;            // Signal line smoothing period
   parameters[3].type=TYPE_INT;
   parameters[3].integer_value=m_MA_Method_;              // Signal line averaging method
   parameters[4].type=TYPE_INT;
   parameters[4].integer_value=m_AppliedPrice;            // Price constant
//--- Object initialization  
   if(!m_COG.Create(m_symbol.Name(),0,IND_CUSTOM,5,parameters))
     {
      printf(__FUNCTION__+": Error initializing the object of the COG");
      return(false);
     }
//--- Number of buffers
   if(!m_COG.NumBuffers(2)) return(false);
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Returns the strength of the buy signal                           |
//+------------------------------------------------------------------+
int COG::LongCondition()
  {
   int signal=0;
//--- For operation with ticks idx=0, for operation with formed bars idx=1
   int idx=StartIndex();
//--- Values of COGs at the last formed bar
   double last_fast_value=CG(idx);
   double last_slow_value=Signal(idx);
//--- Values of COGs at the last but one formed bar
   double prev_fast_value=CG(idx+1);
   double prev_slow_value=Signal(idx+1);   
//---If CG > Signal && CG-1 < Signal-1
   if((last_fast_value>last_slow_value) && (prev_fast_value<prev_slow_value))
     {
      signal=100; // There is a signal to buy
     }
//--- Return the signal value
   return(signal);
  }
//+------------------------------------------------------------------+
//| Returns the strength of the sell signal                          |
//+------------------------------------------------------------------+
int COG::ShortCondition()
  {
   int signal=0;
//--- For operation with ticks idx=0, for operation with formed bars idx=1
   int idx=StartIndex();
//--- Values of COGs at the last formed bar
   double last_fast_value=CG(idx);
   double last_slow_value=Signal(idx);
//--- Values of COGs at the last but one formed bar
   double prev_fast_value=CG(idx+1);
   double prev_slow_value=Signal(idx+1);   
//---If CG < Signal && CG-1 > Signal-1
   if((last_fast_value<last_slow_value) && (prev_fast_value>prev_slow_value))
     {
      signal=100; // There is a signal to sell
     }
//--- Return the signal value
   return(signal);
  }