Fragen von Anfängern MQL4 MT4 MetaTrader 4 - Seite 137

 
Игорь Васильев:

Seltsam, dass der Compiler dies nicht meldet, wenn er Handelsbefehle im Code des Indikators sieht.

Nun müssen wir den Handelsteil aus dem Indikator in den EA ziehen, indem wir ihn über ICustom() mit ihm verbinden.

Es sieht aus wie "der Schwanz auf dem Kopf und der Bogen an der Seite".

Der Compiler prüft nur die Syntax. Seine Aufgabe ist es nicht, zu bestimmen, wie das resultierende Programm funktioniert (oder nicht funktioniert). Die Nichtfunktionalität von Handelsbefehlen kann erst in der Phase der Programmausführung festgestellt werden. Das heißt, es wird ein Laufzeitfehler empfangen.

 

Hallo zusammen, könnten Sie mir bitte sagen, ob es möglich ist, das Folgende zu tun?

Es gibt zum Beispiel eine Struktur:
// eine Struktur von einigen Ereignissen.
struct MyStruct
{
int-Nummer;
datetime DTm;
doppelter Wert;
Zeichenfolge Typ;
}

Ich deklariere ein dynamisches Array von Strukturen des Typs MyStruct:
MyStruct DataEvents[];

Ich bilde und fülle ein Array in einer Funktion aus, zum Beispiel
void GetDataEventsTest(MyStruct& DataEvents[], int countEvent=5)
{
MathSrand(GetTickCount());
ArrayResize(DatenEreignisse, countEvent);
int i = 0;
while( i<countEvent )
{
DataEvents.Number = i;
DataEvents.DTm = TimeCurrent();
DataEvents.Value = (double)MathRand();
if( MathMod(i, 2)>0 ) DataEvents.Type = "Up"; sonst DataEvents.Type = "Dn";
i = i + 1;
}
}

Irgendwo füllen wir das Array durch den Aufruf von GetDataEventsTest():
GetDataEventsTest(DatenEreignisse);

Wir müssen zum Beispiel ein neues Element vom Typ MyStruct in der Mitte des Intervalls der Arrayelemente einfügen, irgendwo bei Index 2.
Die Logik legt die folgenden Schritte nahe:
ArrayResize(DatenEreignisse, ArraySize(DatenEreignisse)+1);
und etwas in dieser Art:
int iNew = 2;
int i = ArraySize(DataEvents) - 2;
while( i>=iNeu )
{
// DataEvents[i+1] = DataEvents[i]; // das funktioniert natürlich nicht, weil wir mit den Adressen arbeiten müssen, auf die das Array-Element verweist, also
// DataEvents[i+1] in ein Array-Element schreiben, das auf das Array-Element DataEvents[i] zeigt;
i = i - 1;
}
... Dann fülle ich das Array-Element DataEvents[iNew] mit Daten.


Frage: Ist es möglich, dies mit mql4-Strukturen zu tun?

 
GitSM:

Frage: Ist es möglich, dies mit Strukturen in mql4 zu tun?

Ja, das ist möglich. Wenn die Struktur keinen komplexen Datentyp enthielte (in diesem Fall handelt es sich um String), würde alles auf Anhieb funktionieren. Und wenn die Struktur Datentypen enthält, deren Größe sich mit der Zeit ändern kann, müssen Sie den Zuweisungsoperator überladen:

struct MyStruct
{
    int Number;
    datetime DTm;
    double Value;
    string Type;

    void operator = (const MyStruct &stMyStruct)
    {
      Number = stMystruct.Number;
      DTm = stMyStruct.DTm;
      Value = stMyStruct.Value;
      Type = stMyStruct.Type;
    }
}
 
Ihor Herasko:

Ja, das ist möglich. Wäre die Struktur ohne einen komplexen Datentyp (in diesem Fall String), würde sie sofort funktionieren. Und wenn die Struktur Datentypen enthält, deren Datengröße sich im Laufe der Zeit ändern kann, müssen Sie den Zuweisungsoperator überladen:

Danke für den Tipp!
 

Auch hier stellte sich eine Frage in dieselbe Richtung wie im letzten Beispiel.
Wenn die Struktur komplex ist und Arrays mit anderen Strukturen enthalten kann. Ich mache zum Beispiel Erklärungen wie diese:

// Element mit Eigenschaften
struct ItemProperty
{
doppelt niedrig;
doppelt so hoch;
doppelte Mitte;
Doppelter Bereich;
Doppelter Bereich;
Zeichenfolge Typ;

void operator = (const ItemProperty &SourceItemProperty)
{
Niedrig = SourceItemProperty.Low;
Hoch = SourceItemProperty.High;
Middle = SourceItemProperty.Middle;
Bereich = SourceItemProperty.Range;
Area = SourceItemProperty.Area;
Type = SourceItemProperty.Type;
}
}

// Positionen mit statistischen Eigenschaften
struct ItemsProperty;
{
double MinLow;
double MaxHigh;
double AvgRange;
double AvgArea;
string Phase;

Item Items[];

void operator = (const ItemProperty &SourceItemsProperty)
{
MinLow = SourceItemsProperty.MinLow;
MaxHigh = SourceItemsProperty.MaxHigh;
AvgRange = SourceItemsProperty.AvgRange;
AvgArea = SourceItemsProperty.AvgArea;
Phase = SourceItemsProperty.Phase;

// Items = SourceItemProperty.Items; // Wie kann ich erreichen, dass mehrere Array-Variablen auf das gleiche physische Array im Speicher verweisen?
}
}

// Struktur einiger Ereignisse auf der Grundlage der Analyse von Elementen
struct EreignisEigenschaft
{
int-Nummer;
datetime DTm;
doppelter Wert;
Zeichenfolge Typ;

double Levels[];
int Weigths[];

ItemsProperty ItemsProp[];

void operator = (const ItemProperty &SourceEventProperty)
{
Zahl = SourceEventProperty.Number;
DTm = SourceEventProperty.DTm;
Wert = SourceEventProperty.Value;
Type = SourceEventProperty.Type;

// Levels = SourceEventProperty.Levels; // es gibt einen Haken
// Gewichte = SourceEventProperty.Weigths; // ehhh.

// ItemsProp = SourceEventProperty.ItemsProp; // auch hier gibt es ein Problem

}
}

Deklaration eines dynamischen Arrays von Ereignissen:
EreignisEigenschaft MyEvents[];

Ich fülle die Daten des Ereignis-Arrays in eine Funktion ein.
void GetEventsProperty(EventProperty& MyEvents)
{
// Befüllungscode
}

und irgendwo besteht die Notwendigkeit, die Elemente des Arrays MyEvents durch Hinzufügen oder Entfernen zu manipulieren.

int iNew = 2;
int i = ArraySize(MeineEreignisse) - 2;
while( i>=iNeu )
{
// MyEvents[i+1] = MyEvents[i]; // hier gibt es ein Problem
i = i - 1;
}

Ist es möglich, dies mit einem Array von Strukturen in mt4 zu tun? Es stellt sich heraus, dass wir in der Lage sein müssen, auf ein und dasselbe Element eines Arrays von Strukturen im Speicher aus verschiedenen Variablen-Referenz-Variablen zu verweisen, indem wir sie erstellen und löschen.
Ist es möglich, mit einem Array von Referenzen auf Strukturen zu arbeiten?

 
GitSM:

Ist es möglich, dies mit einem Array von Strukturen in mt4 zu tun? Es stellt sich heraus, dass man in der Lage sein muss, ein und dasselbe Element des Arrays von Strukturen im Speicher von verschiedenen Variablenreferenzen aus zu referenzieren, indem man sie erstellt und löscht.

Ist es möglich, mit einem Array von Referenzen auf Strukturen zu arbeiten?

Theoretisch sollte es so sein:

struct ItemsProperty;
{
    double MinLow;
    double MaxHigh;
    double AvgRange;
    double AvgArea;
    string Phase;
    
    Item Items[];
    
    void operator = (const ItemProperty &SourceItemsProperty)
    {
        MinLow = SourceItemsProperty.MinLow;
        MaxHigh = SourceItemsProperty.MaxHigh;
        AvgRange = SourceItemsProperty.AvgRange;
        AvgArea = SourceItemsProperty.AvgArea;
        Phase = SourceItemsProperty.Phase;
 
        int nTotal = ArraySize(SourceItemProperty.Items);
        ArrayResize(Items, nTotal);
        for (int i = 0; i < nTotal; ++i)
           Items[i] = SourceItemProperty.Items[i];
    }
}

Und bei allen anderen Arrays genau dasselbe. Frage:

Wie kann ich mehrere Array-Variablen auf das gleiche physische Array im Speicher verweisen lassen?

Das verstehe ich nicht.

P. S. Um Code einzufügen, verwenden Sie das Symbol "</>" oder Alt+S.

 

Как сделать так чтобы на один и тот же физический массив в памяти могло указывать несколько переменных массива?

Das verstehe ich nicht.

Entschuldigung, ich habe die Frage nicht ganz richtig formuliert. Wenn ich es richtig verstehe, besteht ein Array von Strukturen im Wesentlichen aus Verweisen - Adressen durch Array-Indizes, von denen jeder auf eine physische Adresse im Speicher verweist, die entsprechend der Datenstruktur auf eine bestimmte Weise verteilt ist. Mit "Wie kann man mehrere Array-Variablen auf dasselbe physische Array im Speicher zeigen lassen?" meinte ich die Möglichkeit, MyEvents[2] und MyEvents[5] auf dieselbe Struktur im Speicher zeigen zu lassen, d.h. MyEvents[2] und MyEvents[5] sollten nicht auf zwei identische Strukturen zeigen, sondern auf dieselbe Struktur.

Durch Überladen des Operators wird eine Kopie der Struktur erstellt. Die Datenstrukturen können sehr schwer sein oder es können viele von ihnen vorhanden sein, und es besteht keine Notwendigkeit, sie zu kopieren, man braucht nur ein Array, um von einem Index zu einem anderen zu springen, um die Datenstruktur zu adressieren. Etwa so *MeineEreignisse[2] = *MeineEreignisse[1]. Vielleicht habe ich die Zeiger hier falsch verwendet, deshalb werde ich es so erklären. Sie müssen die Adresse von MyEvents[2] nehmen und sie in die Adresse von MyEvents[1] ändern.

Unabhängig davon, wie komplex und schwer die Datenstrukturen sind, kann man sie im Array in jeder beliebigen Reihenfolge "mischen", ohne dass dabei Rechenressourcen verschwendet werden. Schließlich ist das Kopieren einer Speicheradresse von einem Ort zum anderen viel einfacher, um Größenordnungen schneller und erfordert keinen zusätzlichen Speicher, als das Kopieren von Strukturen, deren Komplexität stark variieren kann, um den Index zu ändern, auf den diese Struktur in einem Array verweist.

Распределенные вычисления в сети MQL5 Cloud Network
Распределенные вычисления в сети MQL5 Cloud Network
  • cloud.mql5.com
Большую часть времени современные компьютеры простаивают и не используют всех возможностей процессора. Мы предлагаем задействовать их с пользой. Вы можете сдавать мощности вашего компьютера другим участникам нашей сети для выполнения разнообразных...
 
So wie ich es verstehe, müssen diese Strukturen durch Klassen implementiert werden, um einen solchen Mechanismus der "mischenden" Referenzen auf Strukturen in einem Array zu implementieren.
Ich habe ein solches Beispiel ausprobiert, und es scheint zu funktionieren. Ich verstehe, dass ich auch das Entfernen von Klassenobjekten, die mit new erstellt wurden, überwachen muss.
Ich habe in der Variablendeklaration eine Testklasse und ein dynamisches Array von Zeigern (so wie ich es verstehe, sind es im Wesentlichen die gleichen Links) auf Klassen beschrieben:
class MyClassTest
{
        public:
        int a;
        double b;
        string c;
};

MyClassTest* arrayRefsMyClassTest[];
Ich habe auch diese Kontrollen durchgeführt:
Print("Тест операций над массивом ссылок на классы: начало");

// создаём объекты классов и сохраняем ссылки на них в массиве ссылок.
i = 0;
while( i<5 )
{
        ArrayResize(arrayRefsMyClassTest, i+1);
        arrayRefsMyClassTest[i] = new MyClassTest();
        arrayRefsMyClassTest[i].a = i;
        arrayRefsMyClassTest[i].b = 3.14+i;
        arrayRefsMyClassTest[i].c = "testclass" + i;
        i = i + 1;
}

i = 0;
while( i<ArraySize(arrayRefsMyClassTest) ) { if( CheckPointer(arrayRefsMyClassTest[i])!=POINTER_INVALID ) Print("arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1; }

Print("Изменяем размер массива ссылок на классы");
ArrayResize(arrayRefsMyClassTest, ArraySize(arrayRefsMyClassTest)+2);

i = 0;
while( i<ArraySize(arrayRefsMyClassTest) ) { if( CheckPointer(arrayRefsMyClassTest[i])!=POINTER_INVALID ) Print("arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1; }

Print("Присваиваю последнему элементу ссылку во втором элементе");
i =  ArraySize(arrayRefsMyClassTest) - 1;
arrayRefsMyClassTest[i] = arrayRefsMyClassTest[2];

i = 0;
while( i<ArraySize(arrayRefsMyClassTest) ) { if( CheckPointer(arrayRefsMyClassTest[i])!=POINTER_INVALID ) Print("arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1; }

Print("Присваиваю 2 элементу ссылку в 5 элементе");
arrayRefsMyClassTest[1] = arrayRefsMyClassTest[5];

i = 0;
while( i<ArraySize(arrayRefsMyClassTest) ) { if( CheckPointer(arrayRefsMyClassTest[i])!=POINTER_INVALID ) Print("arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1; }

Print("\nТест операций над массивом ссылок на классы: конец");
Ich habe diese Ergebnisse im Protokoll:
Тест операций над массивом ссылок на классы: начало
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[0]: a = 0, b = 3.14, c = testclass0
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[1]: a = 1, b = 4.14, c = testclass1
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[2]: a = 2, b = 5.14, c = testclass2
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[3]: a = 3, b = 6.14, c = testclass3
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[4]: a = 4, b = 7.14, c = testclass4
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: Изменяем размер массива ссылок на классы
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[0]: a = 0, b = 3.14, c = testclass0
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[1]: a = 1, b = 4.14, c = testclass1
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[2]: a = 2, b = 5.14, c = testclass2
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[3]: a = 3, b = 6.14, c = testclass3
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[4]: a = 4, b = 7.14, c = testclass4
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: Присваиваю последнему элементу ссылку во втором элементе
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[0]: a = 0, b = 3.14, c = testclass0
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[1]: a = 1, b = 4.14, c = testclass1
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[2]: a = 2, b = 5.14, c = testclass2
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[3]: a = 3, b = 6.14, c = testclass3
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[4]: a = 4, b = 7.14, c = testclass4
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[6]: a = 2, b = 5.14, c = testclass2
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: Присваиваю 2 элементу ссылку в 5 элементе
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[0]: a = 0, b = 3.14, c = testclass0
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[1]: a = 4, b = 7.14, c = testclass4
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[2]: a = 2, b = 5.14, c = testclass2
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[3]: a = 3, b = 6.14, c = testclass3
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[4]: a = 4, b = 7.14, c = testclass4
0       21:59:14.658    2018.02.01 00:00:00  Tester3 EURUSD,M5: arrayRefsMyClassTest[6]: a = 2, b = 5.14, c = testclass2
Тест операций над массивом ссылок на классы: конец
Es scheint wie vorgesehen zu funktionieren. Überflüssige Kopien von Daten werden in diesem Fall, so wie ich es verstehe, nicht erstellt. Wenn ich mich irre, korrigieren Sie mich bitte. Vielleicht gibt es Kommentare oder Klarstellungen?
 
Wie kann MQL5 (oder WinAPI) das Diagramm auf Vollbild erweitern???
 
GitSM:
Soweit ich es verstanden habe, müssen diese Strukturen durch Klassen implementiert werden, um einen solchen Mechanismus des "Mischen" von Referenzen auf Strukturen in einem Array zu implementieren.

Ja, leider können Sie in MQL keine Zeiger auf Strukturen erstellen. Es ist nicht klar, warum eine solche Einschränkung gemacht wird, wenn man es mit Klassen machen kann. Schließlich unterscheiden sich die Strukturen nicht wirklich von den Klassen.