Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 1332

 
Mikhail Tkachev:

Ich habe mich durch die Dokumentation und das Forum gewühlt ...
Wie macht man Variablen vom Zeigertyp global [im Beispiel var], wenn sie in OnInit() von string erstellt werden:

und die Anzahl der Objekte und Konstruktorparameter sind im Voraus unbekannt und werden in OnInit() berechnet ?

Das ist ganz einfach.

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

Hallo

mt5 hat eine Fadenkreuztaste

Wenn Sie die Taste auf dem Diagramm drücken, wird angezeigt, wie viele Balken, wie viele Pips und Prozent

Helfen Sie mir, diesen Wert korrekt zu berechnen, damit ich ihn an meinen Roboter binden kann.

Dankeschön

 
Artyom Trishkin:

Gibt es die neue Anwaltsklasse bereits?

Und wie genau sehen die Eingabeparameter aus?

Die Klasse ist entlehnt aus:https://www.mql5.com/ru/code/768, kleinere Änderungen vorgenommen

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

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

Sie soll wie folgt angewendet werden:

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

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

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

Einfach.

Danke für die Antwort)
Zuerst habe ich das getan.
Das Objekt wird also zweimal erstellt, zuerst leer und dann, wie es sein sollte, durch einen Konstruktor mit Parametern.
Aber ... In diesem Fall gibt der Compiler eine Warnung in der Zeile in OnInit() aus:

Deklaration von 'var1' blendet globale Variable aus -> in der Zeile in OnInit()
siehe vorherige Deklaration von 'var1'.

Eine lokale Variable verbirgt also eine globale Variable ... Was passiert also?
Welche Variable wird dann von einer anderen Funktion, z.B. OnTick(), gesehen? Die globale Variable ist =NULL, die lokale Variable ist korrekt initialisiert, kann aber von einer anderen Funktion nicht gesehen werden ...

 
Mikhail Tkachev:

Die Klasse ist entlehnt aus:https://www.mql5.com/ru/code/768, mit kleinen Änderungen

Es soll wie folgt angewendet werden:

Extrahieren Sie alle Teilstrings aus den Eingabeparametern und verwenden Sie diese, um die Namen der Symbole und die entsprechenden Zeitrahmen zu erstellen.

Erstellen Sie dann neue Balkenobjekte aus diesen Listen und platzieren Sie den Zeiger auf jedes zu erstellende Objekt - "New Bar" - in CArrayObj, das global deklariert ist.

Als Nächstes erhält er in der OnTimer()-Schleife einen Zeiger auf das nächste Objekt in der Liste und sucht nach einem neuen Balken. Wenn es kein neues Objekt gibt, müssen Sie zum nächsten gehen, wenn es eines gibt, müssen Sie tun, was Sie tun müssen, wenn sich ein neuer Balken öffnet.

Der Timer sollte nach Ihren Bedürfnissen eingestellt werden - Millisekunde, Sekunde, Minute - im Allgemeinen mit der Frequenz, die Sie für ausreichend halten, um auf einen neuen Balken auf einem nicht aktuellen Symbol zu reagieren.

 
Mikhail Tkachev:

Danke für die Antwort)
Zuerst habe ich das getan.
Das Objekt wird also zweimal erstellt, zuerst leer und dann, wie es sein sollte, durch einen Konstruktor mit Parametern.
Aber ... In diesem Fall gibt der Compiler eine Warnung in der Zeile in OnInit() aus:

Deklaration von 'var1' blendet globale Variable aus -> in der Zeile in OnInit()
siehe vorherige Deklaration von 'var1'.

Eine lokale Variable verbirgt also eine globale Variable ... Was passiert also?
Welche Variable wird dann von einer anderen Funktion, z.B. OnTick(), gesehen? Die globale Variable ist =NULL und die lokale Variable ist korrekt initialisiert, kann aber von einer anderen Funktion nicht gesehen werden.

Sehen Sie genau hin. Das ist nicht das, was Sie getan haben.

 
Artyom Trishkin:

Aus den Eingabeparametern müssen alle Teilstrings extrahiert werden, aus denen die Namen der Symbole und die entsprechenden Zeitrahmen zusammengestellt werden müssen.

Erstellen Sie dann neue Balkenobjekte aus diesen Listen und setzen Sie einen Zeiger auf jedes neue Objekt in CArrayObj, das auf globaler Ebene deklariert ist.

Als Nächstes erhält er in der OnTimer()-Schleife einen Zeiger auf das nächste Objekt in der Liste und sucht nach einem neuen Balken. Wenn es kein neues Objekt gibt, müssen Sie zum nächsten gehen, wenn es eines gibt, müssen Sie tun, was Sie tun müssen, wenn sich ein neuer Balken öffnet.

Erstellen Sie einen Timer nach Ihren Bedürfnissen - Millisekunde, Sekunde, Minute - im Allgemeinen mit der Frequenz, die Sie für ausreichend halten, um auf einen neuen Balken auf einem nicht aktuellen Symbol zu reagieren.

Dies ist, was ich tat, aber ArrObj.At(0) ruft nicht dieKlasse Mitglied Funktionen...

 
Koldun Zloy:

Schauen Sie genauer hin. Das ist nicht das, was Sie getan haben.

Bereits bemerkt)
Die Lösung besteht also darin, global leere Objekte zu deklarieren....
Und wenn man vorher nicht weiß, wie viele es sein werden? Einfach "mit Reserve" deklarieren ? :)
P.S. Ich habe diese Art der Deklaration von Objekten nicht in der integrierten Hilfe gefunden

CObj* var1 = NULL;
 
Mikhail Tkachev:

Bereits bemerkt)
Die Lösung besteht also darin, global leere Objekte zu deklarieren....
Und wenn man vorher nicht weiß, wie viele es sein werden? Erklären Sie sie einfach als "unter Vorbehalt" :)

InCArrayObj einfügen.

Die FunktionArrObj.At(0) gibt einen Zeiger auf eine Basisklasse zurück, die nichts über die Mitglieder der abgeleiteten Klasse weiß.

Um auf sie zu verweisen, müssen Sie lediglich eine Typumwandlung vornehmen.

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

InCArrayObj einfügen.

Die FunktionArrObj.At(0) gibt einen Zeiger auf die Basisklasse zurück, die nichts über die Mitglieder der abgeleiteten Klasse weiß.

Führen Sie einfach eine Typumwandlung durch, um auf sie zu verweisen.

Danke für die Antwort, du bist gar nicht böse)
Jetzt ist alles klar)
UPD
So funktioniert die Konstruktion auch

CIsNewBar* newBar = ArrayObj.At(0);
newBar.method( parameter )
Grund der Beschwerde: