初学者的问题 MQL5 MT5 MetaTrader 5 - 页 1332

 
Mikhail Tkachev:

通过文档和论坛挖掘...
如果在OnInit()中由字符串创建指针类型的变量,如何使其成为全局变量[在例子中为var]。

而对象的数量和构造函数的参数事先是未知的,在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 );
}
 

你好

mt5有一个十字准线按钮

当你在图表上按下它时,它会显示多少个柱子,多少个点和百分比。

帮助我如何正确计算这个值,以便我能够将其与我的机器人绑定。

谢谢你

 
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()这一行打印了一个警告。

对'var1'的声明隐藏了全局变量->在OnInit()中的一行
,看到之前对'var1'的声明。

因此,一个局部变量 隐藏着一个全局变量......。那么会发生什么?
例如,什么变量会被另一个函数OnTick()看到?全局变量是=NULL,局部变量被正确初始化,但不能被另一个函数看到......。

 
Mikhail Tkachev:

该类借自:https://www.mql5.com/ru/code/768,并 做了少量修改

它应该按以下方式应用。

从输入参数中提取所有子字符串,并使用它们来创建符号的名称和相应的时间框架。

然后从这些列表中创建新的酒吧对象,并将每个要创建的对象的指针--"新酒吧"--放在全局声明的CArrayObj中。

接下来,它在OnTimer()循环中接收一个指向列表中下一个对象的指针,并检查是否有新条。如果没有新的对象,你必须去找下一个,如果有,你必须做新栏打开时必须做的事。

计时器应该根据你的需要来设置--毫秒、秒、分钟--一般来说,你认为有什么频率就有什么频率,以对非当前符号的新条形作出反应。

 
Mikhail Tkachev:

谢谢你的答复)
起初我是这样做的。
因此,该对象被创建了两次,第一次是空的,然后是由一个带参数的构造函数创建的。
但是......。在这种情况下,编译器在OnInit()这一行打印了一个警告。

对'var1'的声明隐藏了全局变量->在OnInit()中的一行
,看到之前对'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 )