Discussion of article "Extending MQL5 Standard Library and reusing code"

 

New article Extending MQL5 Standard Library and reusing code has been published:

MQL5 Standard Library makes your life as a developer easier. Nevertheless, it does not implement all the needs of all developers in the world, so if you feel that you need some more custom stuff you can take a step further and extend. This article walks you through integrating MetaQuotes' Zig-Zag technical indicator into the Standard Library. We get inspired by MetaQuotes' design philosophy to achieve our goal.

In a nutshell, MQL5 API is intended for you to benefit from code reuse, reliability, flexibility and easy maintenance. This is what the theory says, but beyond all this, if you plan to continue to advance in MQL5 to develop more sophisticated things, such as multi-currency Experts Advisors, you should first be able to code in the Standard Library way so that your apps are guaranteed a successful life. As your EAs and indicators become more and more complex, it is more necessary to master the concepts involved in a framework development. As a real life example, it is my personal need to develop a complex multi-currency EA which dictates the need of strengthening the base of my project from scratch.

Figure 2. We start downloading MetaQuotes' ZigZag from our MT5 Terminal

Author: Jordi Bassaganas

[Deleted]  

Thank you. Very informative.

 

I try to understand what this code means in this article why we have an * near the CINDICATOBUFFER and then use at.  

 

((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");

 

I would appreciate a detail explanation

 

thanks  

 
rodlivar:

I try to understand what this code means in this article why we have an * near the CINDICATOBUFFER and then use at.  

 

((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");

 

I would appreciate a detail explanation

 

thanks  

* indicates a pointer. Detailed explanation in this article Using the Object Pointers in MQL5
 

string

m_handle=iCustom(symbol,period,zigzag,depth,deviation_create,backstep);

I can't find the path to the indicator.

What is the correct way to specify the path here, the indicators I am trying to call are in the standard folder

 
Tango_X:

string

m_handle=iCustom(symbol,period,zigzag,depth,deviation_create,backstep);

I can't find the path to the indicator.

What is the correct way to specify here, the indicators I am trying to call lie in the standard folder.

Standard Zigzag lies in the folder Examples - you need to add the name of the folder to the path


 
Rashid Umarov:

The standard Zigzag is in the Examples folder - you need to add the folder name in the path



2017.07.12 10:38:05.703 Proba2(EURUSD.m,M1) cannot load custom indicator 'Examples\ZigZag' [4302]

What's wrong?? everything is just like in your picture.
 
Tango_X:

2017.07.12 10:38:05.703 Proba2 (EURUSD.m,M1) cannot load custom indicator 'Examples\ZigZag'[4302]

What's wrong?? Everything is just like in your picture.

Who will look at the error code?

ERR_MARKET_NOT_SELECTED

4302

Symbol not selected in MarketWatch

 
Rashid Umarov:

Who is going to look at the error code?

ERR_MARKET_NOT_SELECTED

4302

Symbol not selected in MarketWatch


I put NULL - works, I put "EURUSD" - doesn't work!!!!

bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- check history
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- create
   //m_handle=iCustom(symbol,period, "Examples\\\ZigZag",depth,deviation_create,backstep);
     //m_handle=iCustom("EURUSD",period, "Examples\\\ZigZag",depth,deviation_create,backstep); - does NOT work
     m_handle=iCustom(NULL,period,"Examples\\ZigZag",depth,deviation_create,backstep);       - работает
//--- check the result
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- indicator successfully created
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- initialisation error
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- ok
   return(true);
  }
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- ok
   return(true);
  }
 
Got it! The question is solved! I have a symbol name with a prefix) - "EURUSD.m".
 
//+------------------------------------------------------------------+
//|| Create the "Zig Zag" indicator|
//+------------------------------------------------------------------+
bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- check history
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- create
   m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep);
//--- check the result
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- indicator successfully created
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- initialisation error
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- ok
   return(true);
  }
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- rendering status line
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- save settings
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- create buffers
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- ok
      return(true);
     }
//--- error
   return(false);
  }


Help me understand how the indexing direction of the indicator buffer array is set here, i.e. the same as ArraySetAsSeries. The default direction is from present to past, but I need to make it from past to present. Since yesterday I have been struggling with this question! Help!