Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1332

 
Mikhail Tkachev:

Перекопал документацию и  форум ...
Как сделать глобальными переменные типа указатель на объект [в примере var], если они создаются в OnInit() строкой:

 причем количество объектов и параметры конструкторов заранее неизвестны и вычисляются в OnInit() ?

Легко.

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

Здравствуйте

в мт5 есть кнопка перекрестие

когда нажимаеш на графике то показывается информация сколько баров сколько пунктов и процент

помогите как правильно высчитать это значение чтоб можно было привязать его к роботу

спасибо

 
Artyom Trishkin:

Класс нового бара уже есть?

И как именно выглядят входные параметры?

Класс позаимствован на сайте: https://www.mql5.com/ru/code/768, сделаны незначительные изменения

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

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

Предполагается применять следующим образом:

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

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

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

Легко.

Спасибо за ответ)
Сначала я так и сделал.
Таким образом, объект создается два раза, сначала пустой, потом, как положено, конструктором с параметрами.
Но ... Компилятор при этом на строку в OnInit() выводит предупреждение:

declaration of 'var1' hides global variable -> на строку в OnInit()
see previous declaration of 'var1'

Таким образом, локальная переменная скрывает глобальную ... и что при этом происходит ?
Какую переменную видит тогда другая функция, OnTick(), например? Глобальная у нас =NULL, локальная проинициализирована правильно, но её не может видеть другая функция ...

 
Mikhail Tkachev:

Класс позаимствован на сайте: https://www.mql5.com/ru/code/768, сделаны незначительные изменения

Предполагается применять следующим образом:

Из входных параметров нужно извлечь все подстроки, из них составить наименования символов и соответствующих им таймфреймов.

Далее из этих списков создать объекты-новые бары и указатель на каждый создаваемый объект "Новый бар" поместить в CArrayObj, который объявлен на глобальном уровне.

Далее - в OnTimer() в цикле по этому списку получать указатель на очередной объект в нём и проверять наличие нового бара. Если нету - переходим к следующему, если есть - делаем то, что нужно делать при открытии нового этого бара.

Таймер сделать по своим потребностям - миллисекундный, секундный, минутный - в общем, с той частотой, которую считаете достаточной для реакции на новый бар на нетекущем символе.

 
Mikhail Tkachev:

Спасибо за ответ)
Сначала я так и сделал.
Таким образом, объект создается два раза, сначала пустой, потом, как положено, конструктором с параметрами.
Но ... Компилятор при этом на строку в OnInit() выводит предупреждение:

declaration of 'var1' hides global variable -> на строку в OnInit()
see previous declaration of 'var1'

Таким образом, локальная переменная скрывает глобальную ... и что при этом происходит ?
Какую переменную видит тогда другая функция, OnTick(), например? Глобальная у нас =NULL, локальная проинициализирована правильно, но её не может видеть другая функция ...

Смотрите внимательнее. Вы делали не так.

 
Artyom Trishkin:

Из входных параметров нужно извлечь все подстроки, из них составить наименования символов и соответствующих им таймфреймов.

Далее из этих списков создать объекты-новые бары и указатель на каждый создаваемый объект "Новый бар" поместить в CArrayObj, который объявлен на глобальном уровне.

Далее - в OnTimer() в цикле по этому списку получать указатель на очередной объект в нём и проверять наличие нового бара. Если нету - переходим к следующему, если есть - делаем то, что нужно делать при открытии нового этого бара.

Таймер сделать по своим потребностям - миллисекундный, секундный, минутный - в общем, стой частотой, которую считаете достаточной для реакции на новый бар на нетекущем символе.

Примерно так и делал, но по ArrObj.At(0) не вызываются функции-члены класса...

 
Koldun Zloy:

Смотрите внимательнее. Вы делали не так.

Уже заметил)
Значит, выход - объявлять глобально пустые объекты....
А если заранее неизвестно, сколько их будет ? Просто объявить "с запасом"  ?  :)
P.S. Во встроенной справке не нашел такой способ объявления объектов 

CObj* var1 = NULL;
 
Mikhail Tkachev:

Уже заметил)
Значит, выход - объявлять глобально пустые объекты....
А если заранее неизвестно, сколько их будет ? Просто объявить "с запасом"  ?  :)

Положите в CArrayObj.

Функция ArrObj.At(0) возвращает указатель на базовый класс, который ничего не знает о членах производного класса.

Для того чтобы к ним обращаться просто сделайте преобразование типа.

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

Положите в CArrayObj.

Функция ArrObj.At(0) возвращает указатель на базовый класс, который ничего не знает о членах производного класса.

Для того чтобы к ним обращаться просто сделайте преобразование типа.

Спасибо за ответ, вовсе вы не злой)
Теперь все стало ясно)
UPD
Вот такая конструкция тоже работает

CIsNewBar* newBar = ArrayObj.At(0);
newBar.method( parameter )
Причина обращения: