Diskussion zum Artikel "LifeHack für Händler: Fast-Food aus Indikatoren" - Seite 3

 
Renat Fatkhullin:

...fängt an, Aufrufe mit verschiedenen Parametern zu machen, multipliziert Indikatoren, verliert alle Handles und wundert sich dann über Bremsen und Speicherverbrauch.

Um ehrlich zu sein, habe ich nicht verstanden, wie man ein Handle verlieren kann, wenn es hinter den Kulissen von MetaTrader gespeichert ist.

p.s. Generell sollte sich der Autor des Artikels an der Diskussion beteiligen und ein paar Punkte zu seiner Sicht der Arbeit mit Indikator-Handles im MT5 erläutern.

 
Vasiliy Sokolov:
Um ehrlich zu sein, habe ich nie verstanden, wie man einen Griff verlieren kann, wenn er hinter den Kulissen von MetaTrader gespeichert ist.

Mit diesem Ansatz zur Codequalität habe ich keine Fragen mehr.

 
Vasiliy Sokolov:

Es ist nicht klar, was Sie mit Ihrer Aussage meinen. Soweit ich verstanden habe, werden Hendles nirgendwo geschlossen( es gibt keineAufrufe von IndicatorRelease ). Es gibt einen ständigen Aufruf von Standardfunktionen zur Erstellung von Hendles, wie z. B. iMACD:

Offensichtlich basiert das ganze Spiel hier auf der Tatsache, dass iMACD und ähnliche Funktionen das zuvor zurückgegebene Handle in sich selbst zwischenspeichern, so dass es keine Wiederherstellung des Indikators geben sollte.


Ja, ich hatte eine ursprüngliche Idee, um zu zeigen, dass man in MQL5 mit Indikatoren auf eine schicke Art und Weise arbeiten sollte: ein Handle sollte in OnInit() erstellt werden, und der Zugriff auf die Indikatordaten sollte durch CopyXXXX-Funktionen erfolgen, und wenn man die Neuerstellung von Handles im Stil von MQL4 verwendet, ist das sehr falsch und wird eine Katastrophe sein: es wird Speicher fressen. Dabei stellte sich jedoch heraus, dass der MQL5-Kernel so clever ist (offensichtlich gibt es eine interne Zwischenspeicherung von identischen Handles), dass er die Neuerstellung von Handles nicht zulässt.

Der Nebeneffekt ist, dass der MQL5-Kernel so gut konzipiert ist, dass er es MQL5 erlaubt, auf eine nicht zeitgemäße Weise zu arbeiten.

 
Vasiliy Sokolov:

Ich habe keine Gemeinsamkeiten festgestellt.

Beide Artikel bieten das Gleiche - das Schreiben der einfachsten Variante im MQL4-Stil in MQL5. Vergleichen Sie dies

Forum über Trading, automatisierte Handelssysteme und das Testen von Handelsstrategien

Diskussion über den Artikel "LifeHack für Trader: Fast Food aus Indikatoren kochen"

Vasiliy Sokolov, 2018.01.25 16:05

//+------------------------------------------------------------------+
//| iMACD-Funktion in MQL4-Notation|
Die Puffernummern sind die folgenden: //|
//| MQL4 0 - MODUS_HAUPT, 1 - MODUS_SIGNAL|
//| MQL5 0 - MAIN_LINE, 1 - SIGNAL_LINE|
//+------------------------------------------------------------------+
double   iMACD(
               string                     symbol,              // Symbolname 
               ENUM_TIMEFRAMES            timeframe,           // Zeitrahmen 
               int                        fast_ema_period,     // Zeitraum für die Berechnung des Fast-Durchschnitts 
               int                        slow_ema_period,     // Zeitraum für die Berechnung des langsamen Durchschnitts 
               int                        signal_period,       // Zeitraum für die Mittelwertbildung ihrer Differenz 
               ENUM_APPLIED_PRICE         applied_price,       // Art des Preises oder des Griffs 
               int                        buffer,              // Puffer 
               int                        shift                // Verschiebung
               )
  {
   
   double result=NaN;
//---
   int handle=iMACD(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price);
   if(handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": INVALID_HANDLE error=",GetLastError());
      return(result);
     }
   double val[1];
   int copied=CopyBuffer(handle,buffer,shift,1,val);
   if(copied>0)
      result=val[0];
   else
      Print(__FUNCTION__,": CopyBuffer error=",GetLastError());
   return(result);
  }

und dies

double iMACDMQL4(string symbol,
                 int tf,
                 int fast_ema_period,
                 int slow_ema_period,
                 int signal_period,
                 int price,
                 int mode,
                 int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iMACD(symbol,timeframe,
                    fast_ema_period,slow_ema_period,
                    signal_period,applied_price);
   if(handle<0)
     {
      Print("Объект iMACD не создан: Ошибка ",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,mode,shift));
  }

In der Tat ist es das Gleiche.

Sollten sie vorhanden sein? Ich denke, der Titel des Artikels (oder eher seine Beschreibung) sagt eindeutig nur über Indikatoren?

Nach dem Titel zu urteilen, sollten sie das nicht. Aber der Artikel berührt die Arbeit mit Zeitreihen im Stil von MQL4. Und ohne sie erhalten wir eine unvollständige Lösung. Fast jeder verwendet "High[i]" in MQL4. Außerdem ist die Implementierung dieser Funktion leicht zu finden.

Leider unterstützt MQL keine Funktionen mit einer beliebigen Anzahl von Parametern, so dass es nicht möglich ist, iCustom "wie in MT4" zu implementieren.

Ich glaube nicht, dass es möglich ist, in einem Artikel eine vollwertige Engine zu schreiben, die den MT4-Stil vollständig emuliert. Das Thema war klar formuliert: Arbeiten mit Indikatoren im MQL4-Stil (schade, dass der Titel des Artikels das Thema nicht widerspiegelt, was verwirrend ist).

MQL4-Stil ist immer noch ein Konzept, aber nicht eine klare Einhaltung der Syntax.

 
Vladimir Karputov:

Wenn Sie die Neuerstellung von Handles im Stil von MQL4 verwenden, ist das sehr falsch und verursacht Probleme: Es wird Speicher verbraucht.

Deshalb stellt sich die Frage, warum sie die falsche Arbeit implementiert haben, wenn es richtig und im Stil von MQL4 gemacht werden könnte?

MQL5 ist nicht schlau, es hat nur einen narrensicheren Schutz. Andernfalls würde jeder versehentliche Fehler unangenehme Konsequenzen nach sich ziehen. Aber der narrensichere Schutz ist, wie Leistungsmessungen zeigen, so konzipiert, dass es zu Leistungseinbußen kommt. Deshalb ist es notwendig, die "Neuerstellung des Handles" in den MQL5-Wrapper zu verlagern und sie (einen kleinen Teil der OOP-Fähigkeiten) vor den Augen des Benutzers zu verstecken.

 
fxsaber:

... Aber auch die Absicherung ist, wie Leistungsmessungen zeigen, so angelegt, dass es einen Leistungsabfall gibt ...

Ja, das ist interessant. Ich werde die Geschwindigkeit messen und meine Ergebnisse hier posten.

 
Vasiliy Sokolov:

Gemessen an den einfachsten Rohlingen.

Name des ExpertenBeschreibungLeistung
iMACDklassische MT5-Stil-Hendle-ArbeitEURUSD,M5: 26189141 Ticks, 74266 generierte Bars. Umgebung synchronisiert um 0:00:01.045. Test bestanden in 0:00:12.121 (einschließlich Ticks Vorverarbeitung 0:00:01.966).
MACD MQL4-Stil EA kurzArbeit im MQL4-StilEURUSD,M5: 26189141 Ticks, 74266 Balken erzeugt. Umgebung synchronisiert um 0:00:00.047. Test bestanden in 0:00:34.960 (einschließlich Ticks Vorverarbeitung 0:00:01.872).

Der Overhead beträgt etwa das Dreifache. Also ja, MetaTrader 5 braucht viel Zeit, um ein zwischengespeichertes Handle zu finden.


Ich hatte eine Idee, um dies zu testen: ein EA ähnlich dem"MACD MQL4 style EA short", nur dass man darin nicht zwei, sondern drei, vier, fünf Indikatoren ansprechen kann .... In diesem Zusammenhang bedeutet "Indikator" (am Beispiel des MACD) ein Indikator mit verschiedenen Parametern, aber jeweils einem Symbol.

 

Ich habe meinen vorherigen Beitrag gelöscht, weil ich festgestellt habe, dass der MACD MQL4 Style EA zusätzlich auf das Grafiksubsystem zugreift:

//+------------------------------------------------------------------+
//| Experten-Tick-Funktion|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double macd_main_1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MAIN_LINE,1);
   Comment("MACD, main buffer, index 1: ",DoubleToString(macd_main_1,Digits()+1));
  }

D.h. die durchgeführten Tests wurden nicht korrekt durchgeführt. Nachdem ich die Comment-Funktion kommentiert habe, ist die Leistung fast gleich:

EURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronized in 0:00:00.047. Test passed in 0:00:15.444 (including ticks preprocessing 0:00:01.872).

Schlussfolgerungen: MetaTrader 5 findet den zuvor angelegten Cache immer noch effektiv und es ist möglich, den vorgeschlagenen Codestyle zu verwenden.

fxsaber:

Aber der narrensichere Schutz ist, wie die Performancemessungen zeigen, so angelegt, dass es zu einem Leistungsabfall kommt. Deshalb ist es notwendig, die "Neuerstellung des Handles" in den MQL5-Wrapper zu verlagern, um sie (einen kleinen Teil der OOP-Funktionen) vor den Augen des Benutzers zu verstecken.

Wenn der letzte Test korrekt durchgeführt wird, stellt sich heraus, dass die Verlagerung auf den OOP-Wrapper nichts bewirkt. Die Geschwindigkeiten sind fast gleich.
 
Vasiliy Sokolov:

MetaTrader 5 benötigt recht viel Zeit, um ein zwischengespeichertes Handle zu finden.

Es gibt keine Gewissheit, dass ein Benutzer diesen Prozess generell beschleunigen kann. Offensichtlich wird der Overhead für die Berechnung der Hash-Funktion verwendet.

Eine Variante einer solchen Indikator-Hash-Funktion in allgemeiner Form wurde hier veröffentlicht

  static string GetMyUniqueName( void )
  {
    const int handle = GetMyHandle();

    MqlParam Params[];
    ENUM_INDICATOR Type;

    const int Total = ::IndicatorParameters(handle, Type, Params);
    ::IndicatorRelease(handle);

    uchar Bytes[];

    for (int i = 1; i < Total; i++)
    {
      ::ArrayCopy(Bytes, _R(Params[i].double_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].integer_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].string_value).Bytes, ::ArraySize(Bytes));
    }

    return("::" + (string)::ChartID() + (string)INIT_SYNC::crc64(Bytes) + ::MQLInfoString(MQL_PROGRAM_NAME));
  }

Ich habe mich dort nicht um die Leistung gekümmert, aber es war klar, dass jede Hash-Funktion ein Array von MqlParam-Werten sein muss. Und das kann nicht schnell funktionieren, wenn man bedenkt, dass es ein langsames String-Feld gibt.

Daher ist das Schreiben eines universellen Indikators schnelle Hash-Funktion viel schneller als das, was in MT5 gebaut ist eine offene Aufgabe. Aber ich bin kategorisch gegen den Aufruf von Indikatoren von irgendwo. Deshalb will ich das Thema nicht einmal verstehen.


Es gibt noch einen weiteren Gedanken zu smart MQL5. Es gibt eine Menge Expert Advisors, bei denen derselbe Indikator auf jedem Balken aufgerufen wird, aber mit unterschiedlichen Eingabeparametern. MQL5 "schießt" im Laufe der Zeit unnötige Griffe ab. Aber das ist eine universelle Lösung. Und in einem Expert Advisor kann der Autor diese Verantwortung auf sich nehmen, indem er selbst Handles tötet. Es liegt auf der Hand, dass es eine enorme Verschwendung von Rechenressourcen und Speicherplatz ist, wenn man hundert Handles durch hundert Bars schleppt. Aber ich habe noch keine EAs gesehen, die einen Handle auf diese Weise festnageln würden. Alles wird der "Cleverness von MQL5" überlassen, was die Autoren dazu zwingt, überhaupt nicht clever zu sein.


Aber wieder, Indikatoren und Bars sind böse.

 
fxsaber:

Es gibt keine Gewissheit, dass ein Benutzer diesen Prozess generell beschleunigen kann. Offensichtlich wird der Overhead für die Berechnung der Hash-Funktion verwendet.

Eine Variante einer solchen Indikator-Hash-Funktion in allgemeiner Form wurde hier veröffentlicht


Nun, Sie wollten den Leser mit einer Menge Informationen in einem Artikel überhäufen. Aber was Ihre Methode betrifft - sie ist eine Frontal-Lösung, haben Sie andere ausprobiert? Und die Leistung verglichen?