Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 238

 

Ich hätte nie gedacht, dass ich einmal einen maschinell erzeugten Code im Quellcode verwenden würde. Vor allem an einer Stelle, die der Leistung wegen archiviert wird.


Unten ist der generierte Code zu sehen.

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

Für die Generierung wurde ein viel prägnanteres Skript geschrieben. Es kann zweckmäßig sein, Hypothesen schnell zu testen und menschliche Fehler zu vermeiden.

 
fxsaber #:

Ich hätte nie gedacht, dass ich einmal einen maschinell erzeugten Code im Quellcode verwenden würde. Vor allem an einer Stelle, die für die Archivierung der Leistung wichtig ist.


Unten ist der generierte Code zu sehen.

Für die Generierung wurde ein wesentlich prägnanteres Skript geschrieben. Dies kann nützlich sein, um Hypothesen schnell zu testen und menschliche Fehler zu vermeiden.

Seien Sie vorsichtig, das gleiche ChatGPT macht viele Fehler, sowohl in der Syntax als auch in der Logik, so dass Sie alles doppelt überprüfen müssen.

Aber es ist ein wirklich guter Spender, der Ihnen hilft, Ideen in Code auszudrücken.

 
fxsaber #:

Nachstehend finden Sie den generierten Code.

Für die Generierung wurde ein wesentlich prägnanteres Skript geschrieben. Dies kann nützlich sein, um Hypothesen schnell zu testen und menschliche Fehler zu vermeiden.

Es gibt nicht genügend Hintergrundinformationen: Wurde der neue Code schneller als der alte Code oder nicht?

Wenn nein, warum wurde der alte, verständliche Code durch den neuen, unverständlichen ersetzt?

Wenn ja, warum konnte der MQL-Compiler nicht gleich den leistungsoptimalen Code erzeugen, wo er doch viel mehr Möglichkeiten dazu hat als Chat

 
Aleksey Vyazmikin #:

Seien Sie vorsichtig, das gleiche ChatGPT macht viele Fehler, sowohl in der Syntax als auch in der Logik, so dass Sie alles doppelt überprüfen müssen.

Aber es ist ein wirklich guter Pitchman, es hilft, Ideen in Code auszudrücken.

Skript generieren.

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

Nicht genügend Hintergrundinformationen: Ist der neue Code schneller als der alte Code oder nicht?

Der neue Code ist schneller.

Wenn ja, warum konnte der MQL-Compiler nicht gleich den leistungsoptimalen Code erzeugen, obwohl er viel mehr Möglichkeiten dazu hat als Chat

Dies ist eine algorithmische Optimierung, keine Compiler-Optimierung.

 
fxsaber #:

Das neue System ist schneller.

Dies ist eine algorithmische Optimierung, keine Compiler-Optimierung.

Wie viel schneller? Um 1,5 % oder 1,5 Mal? Und als ob es schneller wäre? Oder basierend auf korrekten Messungen?

Sie haben ihm also keinen Code gegeben, sondern einen Algorithmus?

 
A100 #:

Wie viel schneller? Um 1,5 Prozent oder um das 1,5-fache? Und nach Gefühl oder durch spezifische Messungen?

Sie haben ihm also keinen Code gegeben, sondern einen Algorithmus?

Das ist es, was der virtuelle Quellcode verwendet. Sie müssen bei jedem Tick vier Überprüfungen durchführen.

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


Aber in manchen Situationen (Schalter 0-15) kann man mit weniger Prüfungen auskommen: 0-4. Das hängt von der TS ab.


Wenn der TS z. B. Positionen nur mit Marktaufträgen öffnet/schließt und keine SL/TP verwendet, brauchen Sie keine einzige Prüfung vorzunehmen.

Wenn jedoch alle Auftragsarten gleichzeitig verwendet werden, müssen Sie alle vier Prüfungen durchführen: Es gibt keine Beschleunigung.


Deshalb sollten Sie einen bestimmten TS nehmen und sich die Messergebnisse für diesen ansehen. Verschiedene TS haben unterschiedliche Beschleunigungsergebnisse.


Es war möglich, die Fälle (Anzahl der Fälle) in mehrere Varianten zu unterteilen. Ehrlich gesagt, konnte ich das nicht tun.

 

In MQL5 gibt es die Funktion StringReserve, mit der wir theoretisch die Anzahl der Neuzuweisungen von Speicher für unsere Zeichenkette reduzieren können: Wir haben einen ausreichend großen Puffer zugewiesen und arbeiten dann darin.

Aber wie die Praxis zeigt, ändert jede nachfolgende Zuweisung eines Wertes an diese Zeichenkette die Größe ihres Puffers (d. h., es kommt offensichtlich zu einer Neuzuweisung von Speicher).

Infolgedessen ist es sinnvoll, statt

string str;
str.Reserve(8192);
str="test";

ist es sinnvoll, statt

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

ist es sinnvoll, die

Exakt. Dieser Mechanismus funktioniert hervorragend bei der String-Vervollständigung. Zum Beispiel, wenn Sie große HTML-Berichte erstellen.

 

Wie kann ich herausfinden, ob ein Symbol Daten hat, so dass ich es nicht im [Market Watch]-Fenster belasse, wenn es keine hat?

Ich verwende eine solche Prüfung in einer Schleife:

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

Aber danach kann ich die Symbole nicht mehr manuell aus dem [Market Watch]-Fenster entfernen , weder eines nach dem anderen noch alle auf einmal, während sich der Expert Advisor im Chart befindet: