Questions from Beginners MQL5 MT5 MetaTrader 5 - page 1332

 
Mikhail Tkachev:

Digging through documentation and forum ...
How to make variables of pointer type global [in the example var], if they are created in OnInit() by string:

and the number of objects and constructor parameters are unknown in advance and are calculated in OnInit() ?

That's easy.

CObj* var1 = NULL;
CObj* var2 = NULL;
CObj* var3 = NULL;

int OnInit()
{
   var1 = new CObj( p1, p2, p3 );
   var2 = new CObj( p1, p2, p3 );
   var3 = new CObj( p1, p2, p3 );
}
 

Hello

mt5 has a crosshair button

When you press it on the chart, it shows how many bars, how many pips and percent

Help me how to correctly calculate this value so that i can bind it to my robot

Thank you

 
Artyom Trishkin:

Is the new bar class already in place?

And what exactly do the input parameters look like?

The class is borrowed from:https://www.mql5.com/ru/code/768, minor changes made

//+------------------------------------------------------------------+
//|                                                     IsNewBar.mqh |
//|                               Copyright © 2011, Nikolay Kositsin |
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "2011,   Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
#property version   "1.00"
//+------------------------------------------------------------------+
//|  Алгоритм определения момента появления нового бара              |
//| Для каждого таймфрейма каждого символа нужно создавать объект    |
//+------------------------------------------------------------------+  
#include <Object.mqh>

class CIsNewBar : public CObject // Сделан наследником класса для возможности работы с классом CArrayObj (из библиотеки)
// class CIsNewBar   // Первоначальная редакция
  {
   //----
public:

      //---- функция определения момента появления нового бара
   bool IsNewBar()
     {
      //---- получим время появления текущего бара
      datetime TNew=datetime(SeriesInfoInteger(m_Symbol,m_TimeFrame,SERIES_LASTBAR_DATE));

      if(TNew!=m_TOld && TNew) // проверка на появление нового бара
        {
         m_TOld=TNew;
         return(true); // появился новый бар!
        }
      //----
      return(false); // новых баров пока нет!
     };

   //---- конструктор класса    
                     CIsNewBar(const string &pSymbol, const ENUM_TIMEFRAMES pTimeFrame){
                        m_Symbol=pSymbol; m_TimeFrame=pTimeFrame;
                        m_TOld=-1;};

protected:
   datetime          m_TOld;        // Время хранится 
   ENUM_TIMEFRAMES   m_TimeFrame;   //    для каждого таймфрейма
   string            m_Symbol;      //    каждого символа

   //---- 
  };
//+------------------------------------------------------------------+

It is intended to be applied as follows:

int OnInit()
{
    // Переменная NB_M1 - объект для контроля нового бара по символу currSymbol для таймфрейма M1

    CIsNewBar* NB_M1=new CIsNewBar(currSymbol,PERIOD_M1);
}

void OnTick()
{
    if (NB_M1.IsNewBar())  // (1) Если появился новый бар M1
        {....}
    ......
}
 
Koldun Zloy:

Easy.

Thanks for the reply)
At first I did so.
So the object is created twice, first empty, then as it should be by a constructor with parameters.
But ... In this case the compiler prints a warning on the line in OnInit():

declaration of 'var1' hides global variable -> on the line in OnInit()
see previous declaration of 'var1'.

So a local variable hides a global variable ... So what happens?
What variable will then be seen by another function, OnTick(), for instance? The global variable is =NULL, the local one is initialized correctly but cannot be seen by another function ...

 
Mikhail Tkachev:

The class is borrowed from:https://www.mql5.com/ru/code/768, with minor modifications

It is supposed to be applied as follows:

Extract all substrings from the input parameters and use them to create names of symbols and corresponding timeframes.

Then create new bar objects from these lists and place pointer to each object to be created - "New Bar" - in CArrayObj that is declared globally.

Next, it receives a pointer to the next object in the list in the OnTimer() loop and checks for a new bar. If there is no new object, you must go to the next one, if there is, you must do what you must do when a new bar opens.

The timer should be set according to your needs - millisecond, second, minute - in general, with whatever frequency you consider sufficient to react to a new bar on a non-current symbol.

 
Mikhail Tkachev:

Thanks for the reply)
At first I did so.
So the object is created twice, first empty, then as it should be by a constructor with parameters.
But ... In this case the compiler prints a warning on the line in OnInit():

declaration of 'var1' hides global variable -> on the line in OnInit()
see previous declaration of 'var1'.

So a local variable hides a global variable ... So what happens?
What variable will then be seen by another function, OnTick(), for instance? The global variable is =NULL and the local one is initialized correctly, but cannot be seen by another function.

Look closely. That is not what you did.

 
Artyom Trishkin:

From the input parameters all substrings must be extracted, from which the names of symbols and their corresponding timeframes must be compiled.

Then create new bar objects from these lists and put a pointer to each new object into CArrayObj that is declared on global level.

Next, it receives a pointer to the next object in the list in the OnTimer() loop and checks for a new bar. If there is no new object, you must go to the next one, if there is, you must do what you must do when a new bar opens.

Make a timer according to your needs - millisecond, second, minute - in general, with whatever frequency you think is enough to respond to a new bar on a non-current symbol.

This is what I was doing, but ArrObj.At(0) doesn't call theclass member functions...

 
Koldun Zloy:

Take a closer look. That's not what you were doing.

Already noticed)
So the solution is to declare globally empty objects....
And if you don't know beforehand how many of them there will be ? Just declare "with reserve" ? :)
P.S. I didn't find this way of declaring objects in the built-in help

CObj* var1 = NULL;
 
Mikhail Tkachev:

Already noticed)
So the solution is to declare globally empty objects....
And if you don't know beforehand how many of them there will be ? Just declare them "with reserve" ? :)

Put inCArrayObj.

TheArrObj.At(0) functionreturns a pointer to a base class that knows nothing about the members of the derived class.

In order to refer to them, just do a type conversion.

CIsNewBar* newBar = (CIsNewBar*)ArrayObj.At(0);
newBar.method( parameter );
 
Koldun Zloy:

Put inCArrayObj.

FunctionArrObj.At(0) returns pointer to base class, which knows nothing about derived class members.

Just do a type conversion to refer to them.

Thanks for the reply, you're not evil at all)
Now everything is clear)
UPD
This is the construction that works too

CIsNewBar* newBar = ArrayObj.At(0);
newBar.method( parameter )
Reason: