Problem with weighting factor on Pattern (Signal Module)

 

I have follow this article on custom signal module and weighting algorithms and I've discovered a great way to assemble custom EA. However I passed the all day trying to sort an issue I cannot understand and start having big headache.

My EA have threshold for opening a position set to 80, one Signal Module with a weight = 1.0 and one pattern (m_pattern_1) in the Signal Module with a weight = 70.

What it is not clear for me is why a sell position is open when pattern_1's condition is fullfilled ? because in my understanding it supposes to be 1*70 = 70 which is less than ThresholdOpen (80). M'I missing something ?

Sell position is also open when  m_pattern_1 = 10 but it is not when m_pattern_1 = 9.  If somebody can see the logic in this I would really appreciate.

I'm not sure about these 3 lines because it seems here that filter0 is related to one specific indicator, but in my module I use differents indicator in the conditions of pattern_1. Also, filter0 on Weight looks ok for me but and I don't fully understand the concept of filter0 on Period and Applied :/

//--- Set filter parameters

   filter0.PeriodMFI(Signal_MFI_PeriodMFI);
   filter0.AppliedMFI(Signal_MFI_AppliedMFI);
   filter0.Weight(Signal_MFI_Weight);

I would really appreciate if someone could have a look at the code bellow or give me clue on investigate this problem.

Thank you,

Vivaldie


rob.mq5 :

//--- inputs for main signal
input int                 Signal_ThresholdOpen =80;          // Signal threshold value to open [0...100]
input int                 Signal_ThresholdClose=80;          // Signal threshold value to close [0...100]
input double              Signal_PriceLevel    =0.0;         // Price level to execute a deal
input double              Signal_StopLevel     =50.0;        // Stop Loss level (in points)
input double              Signal_TakeLevel     =50.0;        // Take Profit level (in points)
input int                 Signal_Expiration    =4;           // Expiration of pending orders (in bars)
input int                 Signal_MFI_PeriodMFI =14;          // Money Flow Index(14,...) Period of calculation
input ENUM_APPLIED_VOLUME Signal_MFI_AppliedMFI   =VOLUME_REAL; // Money Flow Index(14,...) Volumes
input double              Signal_MFI_Weight    =1.0;         // Money Flow Index(14,...) Weight [0...1.0]
//--- inputs for money
input double              Money_FixLot_Percent =10.0;        // Percent
input double              Money_FixLot_Lots    =0.1;         // Fixed volume

//+------------------------------------------------------------------+
//| Global expert object                                             |
//+------------------------------------------------------------------+

CExpert ExtExpert;

//+------------------------------------------------------------------+
//| Initialization function of the expert                            |
//+------------------------------------------------------------------+

int OnInit()
  {
//--- Initializing expert
   if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
     {
      //--- failed
      printf(__FUNCTION__+": error initializing expert");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }

//--- Creating signal
   CExpertSignal *signal=new CExpertSignal;
   if(signal==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating signal");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }

//---
   ExtExpert.InitSignal(signal);
   signal.ThresholdOpen(Signal_ThresholdOpen);
   signal.ThresholdClose(Signal_ThresholdClose);
   signal.PriceLevel(Signal_PriceLevel);
   signal.StopLevel(Signal_StopLevel);
   signal.TakeLevel(Signal_TakeLevel);
   signal.Expiration(Signal_Expiration);

//--- Creating filter CSampleSignal

   CSampleSignal *filter0=new CSampleSignal;
   if(filter0==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter0");
      ExtExpert.Deinit();
      return(INIT_FAILED); 
     }
   signal.AddFilter(filter0);

//--- Set filter parameters

   filter0.PeriodMFI(Signal_MFI_PeriodMFI);
   filter0.AppliedMFI(Signal_MFI_AppliedMFI);
   filter0.Weight(Signal_MFI_Weight);


SignalCustom.mqh :


//+------------------------------------------------------------------+
//|                                                    SignalMFI.mqh |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of oscilator 'MFI, Chaikin, Force Index'           |
//| Type=SignalAdvanced                                              |
//| Name=Signal for Robotus EA                                       |
//| ShortName=MFI                                                |
//| Class=CSampleSignal                                              |
//| Page=signal_mfi                                              |
//| Parameter=PeriodMFI,int,14,Period of calculation                 |
//| Parameter=AppliedMFI,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes     |
//| Parameter=PeriodFastCHO,int,8,Period of fast calculation         |
//| Parameter=PeriodSlowCHO,int,14,Period of slow calculation        |
//| Parameter=AppliedCHO,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes     |
//| Parameter=PeriodFORCE,int,13,Period of calculation               |
//| Parameter=AppliedFORCE,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes   |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSampleSignal.                                                |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Commodity Channel Index' oscillator.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSampleSignal : public CExpertSignal
  {
protected:

   CiMFI               m_mfi;               
   CiChaikin           m_CHO;               
   CiForce             m_FORCE;             
   
   //--- adjusted parameters
   int                 m_periodMFI;
   ENUM_APPLIED_VOLUME m_appliedMFI; 
   
   int                 m_fast_period_cho;
   int                 m_slow_period_cho;
   ENUM_APPLIED_VOLUME m_applied_cho; 
   ENUM_MA_METHOD      m_method_cho;
   
   int                 m_period_force; 
   ENUM_APPLIED_VOLUME m_applied_force;
   ENUM_MA_METHOD      m_method_force;
   
   //--- "weights" of market models (0-100)
   int               m_pattern_1;     
   int               m_pattern_2;     
   
   //--- variables
   double            m_extr_osc[10];   // array of values of extremums of the oscillator
   double            m_extr_pr[10];    // array of values of the corresponding extremums of price
   int               m_extr_pos[10];   // array of shifts of extremums (in bars)
   uint              m_extr_map;       // resulting bit-map of ratio of extremums of the oscillator and the price


public:
                    CSampleSignal(void);
                    ~CSampleSignal(void);
                    
   //--- methods of setting adjustable parameters
   void              PeriodMFI(int value)                     { m_periodMFI=value;         }
   void              AppliedMFI(ENUM_APPLIED_VOLUME value)    { m_appliedMFI=value;        }
   
   void               PeriodFastCHO(int value)                { m_fast_period_cho=value;   }
   void               PeriodSlowCHO(int value)                { m_slow_period_cho=value;   }
   void               MethodCHO(ENUM_MA_METHOD value)         { m_method_cho=value;        }
   void               AppliedCHO(ENUM_APPLIED_VOLUME value)   { m_applied_cho=value;       }
   
   void               PeriodFORCE(int value)                  { m_period_force=value;      }
   void               MethodFORCE(ENUM_MA_METHOD value)       { m_method_force=value;      }
   void               AppliedFORCE(ENUM_APPLIED_VOLUME value) { m_applied_force=value;     }
   
   //--- methods of adjusting "weights" of market models
   void              Pattern_1(int value)              { m_pattern_1=value;           }
   void              Pattern_2(int value)              { m_pattern_2=value;           }
   
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   
   //--- method of creating the indicator and timeseries
   virtual bool      InitIndicators(CIndicators *indicators);
   
   //--- methods of checking if the market models are formed
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

protected:

   //--- method of initialization of the oscillator
   bool              InitStoch(CIndicators *indicators);
   
   //--- methods of getting data
   double            MFI(int ind)                       { return(m_mfi.Main(ind));     }
   double            CHO(int ind)                       { return(m_CHO.Main(ind));     }
   double            FORCE(int ind)                     { return(m_FORCE.Main(ind));   }
   double            MFIDiff(int ind)                   { return(MFI(ind)-MFI(ind+1)); }
   int               State(int ind);
   bool              ExtState(int ind);
   bool              CompareMaps(int map,int count,bool minimax=false,int start=0);
   
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSampleSignal::CSampleSignal(void) : m_periodMFI(14),
                                       m_appliedMFI(VOLUME_REAL),
                                       m_fast_period_cho(8),
                                       m_slow_period_cho(14),
                                       m_method_cho(MODE_EMA),
                                       m_applied_cho(VOLUME_REAL),
                                       m_period_force(13),
                                       m_method_force(MODE_SMA),
                                       m_applied_force(VOLUME_REAL),
                                       m_pattern_1(70)
...
 
Vivaldi:

I have follow this article on custom signal module and weighting algorithms and I've discovered a great way to assemble custom EA. However I passed the all day trying to sort an issue I cannot understand and start having big headache.

My EA have threshold for opening a position set to 80, one Signal Module with a weight = 1.0 and one pattern (m_pattern_1) in the Signal Module with a weight = 70.

What it is not clear for me is why a sell position is open when pattern_1's condition is fullfilled ? because in my understanding it supposes to be 1*70 = 70 which is less than ThresholdOpen (80). M'I missing something ?

Sell position is also open when  m_pattern_1 = 10 but it is not when m_pattern_1 = 9.  If somebody can see the logic in this I would really appreciate.

I'm not sure about these 3 lines because it seems here that filter0 is related to one specific indicator, but in my module I use differents indicator in the conditions of pattern_1. Also, filter0 on Weight looks ok for me but and I don't fully understand the concept of filter0 on Period and Applied :/

I would really appreciate if someone could have a look at the code bellow or give me clue on investigate this problem.

Thank you,

Vivaldie


rob.mq5 :


SignalCustom.mqh :


Your code is incomplete. If you need help please provide code that compiles. Otherwise no way to help you.
 
Vivaldi:

I have follow this article on custom signal module and weighting algorithms and I've discovered a great way to assemble custom EA. However I passed the all day trying to sort an issue I cannot understand and start having big headache.

My EA have threshold for opening a position set to 80, one Signal Module with a weight = 1.0 and one pattern (m_pattern_1) in the Signal Module with a weight = 70.

What it is not clear for me is why a sell position is open when pattern_1's condition is fullfilled ? because in my understanding it supposes to be 1*70 = 70 which is less than ThresholdOpen (80). M'I missing something ?

Sell position is also open when  m_pattern_1 = 10 but it is not when m_pattern_1 = 9.  If somebody can see the logic in this I would really appreciate.

...

Your code is incomplete. If you need help please provide code that compiles. Otherwise no way to help you.
 
angevoyageur:
Your code is incomplete. If you need help please provide code that compiles. Otherwise no way to help you.


Hi Ange, please find bellow the complete files. Problem is still there but not sure what happened because now the order is passed when m_pattern_1 = 80, and it is not when m_pattern_1 = 79.

Threshold is 100 and wheighting 1.0 so it should returns 1*80 = 80 which is less than 100.

Thank you,


robotus.mq5

//+------------------------------------------------------------------+
//|                                                      Robotus.mq5 |
//|                                                         Vivaldie |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Vivaldie"
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+

#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\MySignals\SRobotus.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+

//--- inputs for expert
input string              Expert_Title         ="Robotus";   // Document name
ulong                     Expert_MagicNumber   =19823;       // 
bool                      Expert_EveryTick     =false;       // 

//--- inputs for main signal
input int                 Signal_ThresholdOpen =100;          // Signal threshold value to open [0...100]
input int                 Signal_ThresholdClose=100;          // Signal threshold value to close [0...100]
input double              Signal_PriceLevel    =0.0;         // Price level to execute a deal
input double              Signal_StopLevel     =50.0;        // Stop Loss level (in points)
input double              Signal_TakeLevel     =50.0;        // Take Profit level (in points)
input int                 Signal_Expiration    =4;           // Expiration of pending orders (in bars)
input int                 Signal_SRobotus_PeriodMFI =14;          // Money Flow Index(14,...) Period of calculation
input ENUM_APPLIED_VOLUME Signal_SRobotus_AppliedMFI =VOLUME_REAL; // Money Flow Index(14,...) Volumes
input double              Signal_SRobotus_Weight    =1.0;         // Money Flow Index(14,...) Weight [0...1.0]

//--- inputs for money
input double              Money_FixLot_Percent =10.0;        // Percent
input double              Money_FixLot_Lots    =0.1;         // Fixed volume

//+------------------------------------------------------------------+
//| Global expert object                                             |
//+------------------------------------------------------------------+

CExpert ExtExpert;

//+------------------------------------------------------------------+
//| Initialization function of the expert                            |
//+------------------------------------------------------------------+

int OnInit()
  {
//--- Initializing expert
   if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
     {
      //--- failed
      printf(__FUNCTION__+": error initializing expert");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
     
  
//--- Creating signal
   CExpertSignal *signal=new CExpertSignal;
   if(signal==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating signal");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//---
   ExtExpert.InitSignal(signal);
   signal.ThresholdOpen(Signal_ThresholdOpen);
   signal.ThresholdClose(Signal_ThresholdClose);
   signal.PriceLevel(Signal_PriceLevel);
   signal.StopLevel(Signal_StopLevel);
   signal.TakeLevel(Signal_TakeLevel);
   signal.Expiration(Signal_Expiration);

//--- Creating filter CRobotusSignal
   CRobotusSignal *filter0=new CRobotusSignal;
   if(filter0==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter0");
      ExtExpert.Deinit();
      return(INIT_FAILED); 
     }
   signal.AddFilter(filter0);

//--- Set filter parameters
   filter0.PeriodMFI(Signal_SRobotus_PeriodMFI);
   filter0.AppliedMFI(Signal_SRobotus_AppliedMFI);
   filter0.Weight(Signal_SRobotus_Weight);
   
//--- Creation of trailing object
   CTrailingNone *trailing=new CTrailingNone;
   if(trailing==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating trailing");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- Add trailing to expert (will be deleted automatically))
   if(!ExtExpert.InitTrailing(trailing))
     {
      //--- failed
      printf(__FUNCTION__+": error initializing trailing");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- Set trailing parameters
//--- Creation of money object

   CMoneyFixedLot *money=new CMoneyFixedLot;
   if(money==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating money");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- Add money to expert (will be deleted automatically))
   if(!ExtExpert.InitMoney(money))
     {
      //--- failed
      printf(__FUNCTION__+": error initializing money");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- Set money parameters
   money.Percent(Money_FixLot_Percent);
   money.Lots(Money_FixLot_Lots);
//--- Check all trading objects parameters
   if(!ExtExpert.ValidationSettings())
     {
      //--- failed
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- Tuning of all necessary indicators
   if(!ExtExpert.InitIndicators())
     {
      //--- failed
      printf(__FUNCTION__+": error initializing indicators");
      ExtExpert.Deinit();
      return(INIT_FAILED);
     }
//--- ok
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Deinitialization function of the expert                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ExtExpert.Deinit();
  }
//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   ExtExpert.OnTick();   
   
  }
//+------------------------------------------------------------------+
//| "Trade" event handler function                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
   ExtExpert.OnTrade();
  }
//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ExtExpert.OnTimer();
  }
//+------------------------------------------------------------------+
 

File for the signal SRobotus.mqh :


//+------------------------------------------------------------------+
//|                                                    SRobotus.mqh |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of oscilator 'MFI, Chaikin, Force Index'           |
//| Type=SignalAdvanced                                              |
//| Name=Signal for Robotus EA                                       |
//| ShortName=Robotus EA                                             |
//| Class=CRobotusSignal                                              |
//| Page=signal_robotus                                                  |
//| Parameter=PeriodMFI,int,14,Period of calculation                 |
//| Parameter=AppliedMFI,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes     |
//| Parameter=PeriodFastCHO,int,8,Period of fast calculation         |
//| Parameter=PeriodSlowCHO,int,14,Period of slow calculation        |
//| Parameter=AppliedCHO,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes     |
//| Parameter=PeriodFORCE,int,13,Period of calculation               |
//| Parameter=AppliedFORCE,ENUM_APPLIED_VOLUME,VOLUME_REAL,Volumes   |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CRobotusSignal.                                                |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Commodity Channel Index' oscillator.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CRobotusSignal : public CExpertSignal
  {

protected:

   //--- method of initialization of the oscillator
   bool              InitStoch(CIndicators *indicators);
   
   //--- methods of getting data
   double            MFI(int ind)                       { return(m_mfi.Main(ind));     }
   double            CHO(int ind)                       { return(m_CHO.Main(ind));     }
   double            FORCE(int ind)                     { return(m_FORCE.Main(ind));   }
   double            MFIDiff(int ind)                   { return(MFI(ind)-MFI(ind+1)); }
   int               State(int ind);
   bool              ExtState(int ind);
   bool              CompareMaps(int map,int count,bool minimax=false,int start=0);

   CiMFI               m_mfi;               // object-oscillator
   CiChaikin           m_CHO;               // object to access the data
   CiForce             m_FORCE;             // object to access the data
   
   //--- adjusted parameters
   int                 m_periodMFI;        // the "period of calculation" parameter of the oscillator
   ENUM_APPLIED_VOLUME  m_appliedMFI;       // the "prices seriddes" parameter of the oscillator
   
   int                 m_fast_period_cho;   // averaging period of the Chaikin
   int                 m_slow_period_cho;   // averaging period of the Chaikin
   ENUM_APPLIED_VOLUME  m_applied_cho;       // averaging object of the Chaikin
   ENUM_MA_METHOD      m_method_cho;        // averaging method of the Chaikin
   
   int                 m_period_force;      // averaging period of the Force Index
   ENUM_APPLIED_VOLUME  m_applied_force;     // averaging object of the Force Index
   ENUM_MA_METHOD      m_method_force;      // averaging method of the Force Index
   
   //--- "weights" of market models (0-100)
   int               m_pattern_1;      // model 1 "reverse of Money Flow Index (MFI) behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "reverse of Chaikin (CHO) behind the level of overbuying/overselling"
   
   //--- variables
   double            m_extr_osc[10];   // array of values of extremums of the oscillator
   double            m_extr_pr[10];    // array of values of the corresponding extremums of price
   int               m_extr_pos[10];   // array of shifts of extremums (in bars)
   uint              m_extr_map;       // resulting bit-map of ratio of extremums of the oscillator and the price

public:
                    CRobotusSignal(void);
                    ~CRobotusSignal(void);
                    
   //--- methods of setting adjustable parameters
   void               PeriodMFI(int value)                    { m_periodMFI=value;         }
   void               AppliedMFI(ENUM_APPLIED_VOLUME value)   { m_appliedMFI=value;        }
   
   void               PeriodFastCHO(int value)                { m_fast_period_cho=value;   }
   void               PeriodSlowCHO(int value)                { m_slow_period_cho=value;   }
   void               MethodCHO(ENUM_MA_METHOD value)         { m_method_cho=value;        }
   void               AppliedCHO(ENUM_APPLIED_VOLUME value)   { m_applied_cho=value;       }
   
   void               PeriodFORCE(int value)                  { m_period_force=value;      }
   void               MethodFORCE(ENUM_MA_METHOD value)       { m_method_force=value;      }
   void               AppliedFORCE(ENUM_APPLIED_VOLUME value) { m_applied_force=value;     }
   
   //--- methods of adjusting "weights" of market models
   void              Pattern_1(int value)                     { m_pattern_1=value;           }
   void              Pattern_2(int value)                     { m_pattern_2=value;           }
   
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   
   //--- method of creating the indicator and timeseries
   virtual bool      InitIndicators(CIndicators *indicators);
   
   //--- methods of checking if the market models are formed
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

   
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+

CRobotusSignal::CRobotusSignal(void) : m_periodMFI(14),
                                       m_appliedMFI(VOLUME_REAL),
                                       m_fast_period_cho(8),
                                       m_slow_period_cho(14),
                                       m_method_cho(MODE_EMA),
                                       m_applied_cho(VOLUME_REAL),
                                       m_period_force(13),
                                       m_method_force(MODE_SMA),
                                       m_applied_force(VOLUME_REAL),
                                       m_pattern_1(80) //80 signal is detected. 79 it is not.
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+

CRobotusSignal::~CRobotusSignal(void)
  {
  }
  
//+------------------------------------------------------------------+
//| Validation settings protected data.                              |
//+------------------------------------------------------------------+

bool CRobotusSignal::ValidationSettings(void)
  {
//--- validation settings of additional filters
   if(!CExpertSignal::ValidationSettings())
      return(false);
      
//--- initial data checks
   if(m_periodMFI<=0        ||
      m_fast_period_cho<=0  ||
      m_slow_period_cho<=0  ||
      m_period_force<=0)
     {
      printf(__FUNCTION__+": period must be greater than 0");
      return(false);
     }
//--- ok
   return(true);
  }
  
//+------------------------------------------------------------------+
//| Create indicators.                                               |
//+------------------------------------------------------------------+

bool CRobotusSignal::InitIndicators(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- initialization of indicators and timeseries of additional filters
   if(!CExpertSignal::InitIndicators(indicators))
      return(false);
//--- create and initialize MFI oscillator
   if(!InitStoch(indicators))
      return(false);
//--- ok
   return(true);
  }
  
//+------------------------------------------------------------------+
//| Initialize oscillators.                                          |
//+------------------------------------------------------------------+

bool CRobotusSignal::InitStoch(CIndicators *indicators)
  {
//--- check pointer
   if(indicators==NULL)
      return(false);
//--- add object to collection
   if(!indicators.Add(GetPointer(m_mfi)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
   if(!indicators.Add(GetPointer(m_CHO)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
   if(!indicators.Add(GetPointer(m_FORCE)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
          
//--- initialize object
   if(!m_mfi.Create(m_symbol.Name(),m_period,m_periodMFI,m_appliedMFI))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
   if(!m_CHO.Create(m_symbol.Name(),m_period,m_fast_period_cho,m_slow_period_cho,m_method_cho,m_applied_cho))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
   if(!m_FORCE.Create(m_symbol.Name(),m_period,m_period_force,m_method_force,m_applied_force))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Check of the oscillator MFI state.                                   |
//+------------------------------------------------------------------+
int CRobotusSignal::State(int ind)
  {
   int    res=0;
   double var;
//---
   for(int i=ind;;i++)
     {
      if(MFI(i+1)==EMPTY_VALUE)
         break;
      var=MFIDiff(i);
      if(res>0)
        {
         if(var<0)
            break;
         res++;
         continue;
        }
      if(res<0)
        {
         if(var>0)
            break;
         res--;
         continue;
        }
      if(var>0)
         res++;
      if(var<0)
         res--;
     }
//--- return the result
   return(res);
  }
//+------------------------------------------------------------------+
//| Extended check of the oscillator state consists                  |
//| in forming a bit-map according to certain rules,                 |
//| which shows ratios of extremums of the oscillator and price.     |
//+------------------------------------------------------------------+
bool CRobotusSignal::ExtState(int ind)
  {
//--- operation of this method results in a bit-map of extremums
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
//--- each "element of the array" definitely describes the ratio
//--- of current extremums of the oscillator and the price with previous ones
//--- purpose of bits of an element of the analyzed bit-map
//--- bit 3 - not used (always 0)
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
//---         (a higher peak or a deeper valley), otherwise - 0
//--- bit 1 - not used (always 0)
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
//---         (a higher peak or a deeper valley), otherwise - 0
//--- in addition to them, the following is formed:
//--- array of values of extremums of the oscillator,
//--- array of values of price extremums and
//--- array of "distances" between extremums of the oscillator (in bars)
//--- it should be noted that when using the results of the extended check of state,
//--- you should consider, which extremum of the oscillator (peak or valley)
//--- is the "reference point" (i.e. was detected first during the analysis)
//--- if a peak is detected first then even elements of all arrays
//--- will contain information about peaks, and odd elements will contain information about valleys
//--- if a valley is detected first, then respectively in reverse
   int    pos=ind,off,index;
   uint   map;                 // intermediate bit-map for one extremum
//---
   m_extr_map=0;
   for(int i=0;i<10;i++)
     {
      off=State(pos);
      if(off>0)
        {
         //--- minimum of the oscillator is detected
         pos+=off;
         m_extr_pos[i]=pos;
         m_extr_osc[i]=MFI(pos);
         if(i>1)
           {
            m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
            //--- form the intermediate bit-map
            map=0;
            if(m_extr_pr[i-2]<m_extr_pr[i])
               map+=1;  // set bit 0
            if(m_extr_osc[i-2]<m_extr_osc[i])
               map+=4;  // set bit 2
            //--- add the result
            m_extr_map+=map<<(4*(i-2));
           }
         else
            m_extr_pr[i]=m_low.MinValue(pos-1,3,index);
        }
      else
        {
         //--- maximum of the oscillator is detected
         pos-=off;
         m_extr_pos[i]=pos;
         m_extr_osc[i]=MFI(pos);
         if(i>1)
           {
            m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
            //--- form the intermediate bit-map
            map=0;
            if(m_extr_pr[i-2]>m_extr_pr[i])
               map+=1;  // set bit 0
            if(m_extr_osc[i-2]>m_extr_osc[i])
               map+=4;  // set bit 2
            //--- add the result
            m_extr_map+=map<<(4*(i-2));
           }
         else
            m_extr_pr[i]=m_high.MaxValue(pos-1,3,index);
        }
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Comparing the bit-map of extremums with pattern.                 |
//+------------------------------------------------------------------+
bool CRobotusSignal::CompareMaps(int map,int count,bool minimax,int start)
  {
   int step =(minimax)?4:8;
   int total=step*(start+count);
//--- check input parameters for a possible going out of range of the bit-map
   if(total>32)
      return(false);
//--- bit-map of the patter is an "array" of 4-bit fields
//--- each "element of the array" definitely describes the desired ratio
//--- of current extremums of the oscillator and the price with previous ones
//--- purpose of bits of an elements of the pattern of the bit-map pattern
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
//---         is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
//---         (current peak is higher or current valley is deeper)
//---         is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
//---         (current peak is lower or current valley is less deep)
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
//---         it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
//---         (current peak is higher or current valley is deeper)
//---         it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
//---         (current peak is lower or current valley is less deep)
   uint inp_map,check_map;
   int  i,j;
//--- loop by extremums (4 minimums and 4 maximums)
//--- price and the oscillator are checked separately (thus, there are 16 checks)
   for(i=step*start,j=0;i<total;i+=step,j+=4)
     {
      //--- "take" two bits - patter of the corresponding extremum of the price
      inp_map=(map>>j)&3;
      //--- if the higher-order bit=1, then any ratio is suitable for us
      if(inp_map<2)
        {
         //--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
         check_map=(m_extr_map>>i)&3;
         if(inp_map!=check_map)
            return(false);
        }
      //--- "take" two bits - pattern of the corresponding oscillator extremum
      inp_map=(map>>(j+2))&3;
      //--- if the higher-order bit=1, then any ratio is suitable for us
      if(inp_map>=2)
         continue;
      //--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
      check_map=(m_extr_map>>(i+2))&3;
      if(inp_map!=check_map)
         return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CRobotusSignal::LongCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(MFIDiff(idx)>0.0)
     {
      //--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
      if (IS_PATTERN_USAGE(1) && MFI(idx+2)<20 && MFI(idx+1)>20.0)
         result=m_pattern_1;      // signal number 1
         Alert("sig1 bull");
     }
//--- return the result
   return(result);
  }
//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CRobotusSignal::ShortCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(MFIDiff(idx)<0.0)
     {
      //--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
         if (IS_PATTERN_USAGE(1) && MFI(idx+2)>80 && MFI(idx+1)<80.0)
         result=m_pattern_1;      // signal number 1 
         Alert("sig1 bear");
    }
   if(IS_PATTERN_USAGE(2))
     {
      //--- if the model 2 is used, search for high value of Force Index in the last 10 bars
         if(
            FORCE(idx+2)<200000 && FORCE(idx+1)>200000        
         )
         result=m_pattern_2;      // signal number 2
    }
//--- return the result
   return(result);
  }
//+------------------------------------------------------------------+

/*

            FORCE(idx+9)>0.36 ||
            FORCE(idx+8)>0.36 ||
            FORCE(idx+7)>0.36 ||
            FORCE(idx+6)>0.36 ||
            FORCE(idx+5)>0.36 ||
            FORCE(idx+4)>0.36 ||
            FORCE(idx+3)>0.36 ||
            FORCE(idx+2)>0.36 ||
            FORCE(idx+1)>0.36 ||
            */