Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 1332

 
Mikhail Tkachev:

Escarbando en la documentación y en el foro...
Cómo hacer globales las variables de tipo puntero [en el ejemplo var], si se crean en OnInit() por cadena:

y el número de objetos y parámetros del constructor son desconocidos de antemano y se calculan en OnInit() ?

Eso es fácil.

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 );
}
 

Hola

mt5 tiene un botón de retícula

Cuando se pulsa en el gráfico, se muestra cuántas barras, cuántos pips y el porcentaje

Ayúdame a calcular correctamente este valor para poder vincularlo a mi robot

Gracias

 
Artyom Trishkin:

¿Ya existe la nueva clase de bar?

¿Y cómo son exactamente los parámetros de entrada?

La clase se ha tomado prestada de:https://www.mql5.com/ru/code/768, con pequeños cambios

//+------------------------------------------------------------------+
//|                                                     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;      //    каждого символа

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

Está previsto que se aplique de la siguiente manera:

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

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

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

Fácil.

Gracias por la respuesta)
Al principio lo hice.
Así que el objeto se crea dos veces, primero vacío, y luego como debe ser por un constructor con parámetros.
Pero... En este caso el compilador imprime una advertencia en la línea de OnInit():

la declaración de 'var1' oculta la variable global -> en la línea de OnInit()
ver la declaración anterior de 'var1'.

Así que una variable local oculta una variable global ... ¿Y qué pasa?
¿Qué variable será vista entonces por otra función, OnTick(), por ejemplo? La variable global es =NULL, la local se inicializa correctamente pero no puede ser vista por otra función...

 
Mikhail Tkachev:

La clase está tomada de:https://www.mql5.com/ru/code/768, con pequeñas modificaciones

Se supone que se aplica de la siguiente manera:

Extrae todas las subcadenas de los parámetros de entrada y las utiliza para crear los nombres de los símbolos y los plazos correspondientes.

A continuación, cree nuevos objetos de barra a partir de estas listas y coloque el puntero a cada objeto que se va a crear - "Nueva barra"- en el CArrayObj que se declara globalmente.

A continuación, recibe un puntero al siguiente objeto de la lista en el bucle OnTimer() y comprueba si hay una nueva barra. Si no hay ningún objeto nuevo, debe pasar al siguiente, si lo hay, debe hacer lo que debe hacer cuando se abre una nueva barra.

El temporizador debe ajustarse según sus necesidades -milisegundos, segundos, minutos- en general, con la frecuencia que considere suficiente para reaccionar ante una nueva barra en un símbolo no actual.

 
Mikhail Tkachev:

Gracias por la respuesta)
Al principio lo hice.
Así que el objeto se crea dos veces, primero vacío, y luego como debe ser por un constructor con parámetros.
Pero... En este caso el compilador imprime una advertencia en la línea de OnInit():

la declaración de 'var1' oculta la variable global -> en la línea de OnInit()
ver la declaración anterior de 'var1'.

Así que una variable local oculta una variable global ... ¿Y qué pasa?
¿Qué variable será vista entonces por otra función, OnTick(), por ejemplo? La variable global es =NULL y la local se inicializa correctamente, pero no puede ser vista por otra función.

Mira con atención. Eso no es lo que hiciste.

 
Artyom Trishkin:

De los parámetros de entrada hay que extraer todas las subcadenas, a partir de las cuales hay que compilar los nombres de los símbolos y sus correspondientes plazos.

A continuación, crear nuevos objetos de barra de estas listas y poner un puntero a cada nuevo objeto en CArrayObj que se declara en el nivel global.

A continuación, recibe un puntero al siguiente objeto de la lista en el bucle OnTimer() y comprueba si hay una nueva barra. Si no hay ningún objeto nuevo, debe pasar al siguiente, si lo hay, debe hacer lo que debe hacer cuando se abre una nueva barra.

Haga un temporizador según sus necesidades - milisegundo, segundo, minuto - en general, con la frecuencia que considere suficiente para responder a una nueva barra en un símbolo no actual.

Esto es lo que estaba haciendo, pero ArrObj.At(0) no llama a las funciones miembro dela clase...

 
Koldun Zloy:

Mira más de cerca. Eso no es lo que estabas haciendo.

Ya lo he notado)
Así que la solución es declarar objetos globalmente vacíos....
¿Y si no se sabe de antemano cuántos serán? ¿Sólo declarar "con reserva"? :)
P.D. No encontré esta forma de declarar objetos en la ayuda incorporada

CObj* var1 = NULL;
 
Mikhail Tkachev:

Ya lo he notado)
Así que la solución es declarar objetos globalmente vacíos....
¿Y si no se sabe de antemano cuántos serán? ¿Sólo declararlos "con reserva"? :)

Poner enCArrayObj.

La funciónArrObj.At(0) devuelve un puntero a una clase base que no sabe nada de los miembros de la clase derivada.

Para referirse a ellos, basta con hacer una conversión de tipo.

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

Poner enCArrayObj.

La funciónArrObj.At(0) devuelve un puntero a la clase base, que no sabe nada de los miembros de la clase derivada.

Sólo hay que hacer una conversión de tipo para referirse a ellos.

Gracias por la respuesta, no eres malo en absoluto)
Ahora todo está claro)
UPD
Esta es la construcción que funciona también

CIsNewBar* newBar = ArrayObj.At(0);
newBar.method( parameter )
Razón de la queja: