Mein Ansatz. Der Kern ist der Motor. - Seite 124

 
Andrey Barinov:

Denn anstelle von OrderOpenPrice setzen Sie OrderOpenTime()

Richtig. Ich habe es verwechselt. :)

 
Реter Konow:

Ich muss zugeben, dass ich von den Testergebnissen ein wenig überrascht war.

Deshalb wollte ich, dass Sie alles selbst machen und keine vorgefertigten Lösungen anbieten, die gegen die Wand fahren würden.
Weißt du, Peter, es gibt auch so etwas wie einen Zeiger auf eine Funktion, mit dem man Funktionsaufrufe organisieren kann, indem man einfach diese Zeiger aus einem Array von solchen Zeigern nimmt. Ich denke, dass dies für Ihre Aufgabe sehr nützlich sein wird. Das einzige Problem ist, dass man sich wieder mit Klassen herumschlagen muss.
 
Nikolai Semko:
Deshalb wollte ich, dass Sie alles selbst machen und keine vorgefertigten Lösungen anbieten, die wie Erbsen an der Wand sind.
Und weißt du, Peter, es gibt auch so etwas wie einen Zeiger auf eine Funktion, dank dem man Funktionsaufrufe organisieren kann, indem man einfach diese Zeiger aus einem Array solcher Zeiger nimmt. Ich denke, dass dies für Ihr Problem sehr nützlich sein könnte. Aber das Problem ist, dass man sich wieder mit Klassen beschäftigen muss.

Ich habe von Zeigern auf Funktionen gehört. Aber ich habe nur sehr wenige Funktionen. Das ist der Grund, warum ich keinen Platz habe und OOP verwenden muss.

Ich habe ein anderes Entwicklungskonzept. Ich glaube, dass der Betrieb von ganzheitlichen Multifunktionsblöcken effizienter ist als der von großen Komplexen aus kleinen Funktionen.

Vielversprechender unter dem Gesichtspunkt der Entwicklung von Mechanismen.

Das ist meine Meinung...

Ich habe mehrere große Blöcke. Um OOP anzuwenden, müssen sie in kleine Funktionen zerlegt, in Klassen organisiert und dann Zeiger und andere Dinge verwendet werden.

Aber das wird mir nicht gelingen. Einfach weil ich anders denke.

Das Konzept der OOP deckt sich nicht mit den Eigenheiten meiner Denkweise, und ich kann es nicht erweitern. Das ist der Grund dafür.

 
Nikolai Semko:

Beachten Sie, Nikolai, dass ich in Bezug auf die programmatische Entwicklung kein Problem habe. Alles entwickelt sich sehr schnell.

Zugleich funktionieren die Mechanismen gut.

Ich habe jetzt Unions gemeistert, und ich sehe ihre Anwendung in einer bestimmten Aufgabe, - Schreiben von Strings in eine Ressource.

Ich werde versuchen, die Geschwindigkeit und CPU-Last im Test-EA zu überprüfen und das Ergebnis zu posten.

Wenn es gut ist, werde ich die Kommunikation zwischen Motor und EA wiederherstellen, so dass es auf Ressourcen.

 

Um Ressourcen zur Übergabe von Zeichenketten undefinierter Länge zu verwenden, müssen diese Zeichenketten in ein char-Array geschrieben werden.

Es scheint jedoch, dass ihre Größe nur innerhalb der Vereinigung angegeben wird und sich danach nicht mehr ändert.

Ich habe versucht, die Größe des Char-Arrays aus der Union durch ArrayResize zu ändern, aber es gibt keinen Effekt.

Es scheint, dass die Größe des Char-Arrays vorher festgelegt werden muss. Und es sollte die maximale Größe sein.


Hier ist der Code:

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[4];
   uint    Uint[1];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(1000);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand();
   if(q > 10000)q = 10000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Меняем размер массива из Char[] юниона. 
   //-------------------------------------------------------
   ArrayResize(u.Char,StrSize);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   //StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //
   //-------------------------------------------------------
   Print("StrSize  ",StrSize," Размер u.Char  ",ArraySize(u.Char));
  }
//+------------------------------------------------------------------+
 

Es ist nun klar, dass die Größe deschar-Arrays in der Union vorher bekannt sein muss. DennArrayResize(u.Char,StrSize) ändert es nicht.

Wir müssen also die Größe des Arrays gleich der Länge der maximalen Zeichenkette setzen...

 

Eine gute Nachricht. Alles funktioniert gut.

Die Zeichenfolge wird in die Ressource geschrieben und von einem anderen EA auf einem anderen Diagramm gelesen.

Der Prozessor ist nicht belastet. Die Belastung wird nur durch den Aufruf des Alerts verursacht, der die Zeichenkette ausgibt.

Hier ist der Code der Expert Advisors:

1. Expert Advisor formt die Zeichenfolge und schreibt sie in eine Ressource.

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(16);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand(),width,height;
   if(q > 1000)q = 1000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //Cохраняем строку переведенную в байты в ресурсе.
   //-------------------------------------------------------
   if(!ResourceCreate("::Resource",u.Uint,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //-------------------------------------------------------
  }
//+------------------------------------------------------------------+
 

Ein Berater liest eine Zeile aus einer Ressource auf einer anderen Karte:

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(16); 
   
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"\\Experts\\TEST_2.ex4::Resource"))Print("Resource is not connected!");
   else Print("Resource connected!");
//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Char_Uint u;   
   uint width,height;
   //string Message; 
   //-----------------------------
   if(!ResourceReadImage("\\Experts\\TEST_2.ex4::Resource",u.Uint,width,height))Print("Failed to read resource!  ",GetLastError());
   //-----------------------------
   string String = CharArrayToString(u.Char);
   //-----------------------------
   Alert("  String  ",String);
   //-----------------------------
  }
//+------------------------------------------------------------------+


Wird Ressourcen für die Kommunikation nutzen. Der einzige Nachteil ist, dass Sie die maximale Größe des Char-Arrays in der Union festlegen müssen. Über die Größe der Zeichenkette und die Anzahl der MT-Objekte brauchen Sie sich jedoch keine Gedanken zu machen.

Diese Methode ist langsamer als die MT-Objekt-Verknüpfungsmethode, aber sie ist in Ordnung.

 
Реter Konow:

Sie haben eine interessante Theorie, auch wenn sie nicht ganz mit den Ergebnissen meiner Experimente übereinstimmt, die ich weiter unten veröffentlichen werde.

Wie der Test zeigt, ist es die Initialisierung des Pixelarrays, die die CPU am meisten belastet.

Sehen Sie sich den Test-EA unten an.

Lesen Sie sich die Aufgabe noch einmal durch:

Vasiliy Sokolov:

Peter, hier ist die Aufgabe. Erstellen Sie ein Panel, das die aktuellen Auftragseröffnungen im MT4 anzeigt. Erstellen Sie keine vollständige Kopie des Systempanels, sondern zeigen Sie eine einfache Tabelle mit den grundlegenden Eigenschaften der offenen Aufträge an: offener Preis, Richtung, Gewinn. Der Rest bleibt Ihnen überlassen. Das Wichtigste ist, dass mit dem Abschluss eines Auftrags auch dessen Anzeige in Ihrer Tabelle verschwindet. Umgekehrt würde sie in dieser Tabelle erscheinen, wenn ein neuer Auftrag eröffnet wird.

Hier sehen Sie die beiden notwendigen Operationen der Neuzeichnung, wenn sich die Tabelle auf dem Bildschirm ändert: 1. beim Schließen eines Geschäfts und 2. beim Eröffnen eines Geschäfts. Warum sollen die Pixel in der übrigen Zeit neu gezeichnet werden?

Lösen Sie ein anderes Problem?

 
Vladimir:

Lesen Sie das Problem noch einmal:

Vasiliy Sokolov:

Hier sehen wir zwei notwendige Umzeichnungsoperationen, wenn sich die Tabelle auf dem Bildschirm ändert: 1. beim Schließen eines Geschäfts und 2. beim Eröffnen eines Geschäfts. Warum werden die Pixel zu anderen Zeiten neu gezeichnet?

Lösen Sie ein anderes Problem?

Nun, sie werden genau wie von Ihnen beschrieben neu gezeichnet.

Die Belastung des Prozessors wird während der Animation angezeigt:

Es findet eine ständige Neuinitialisierung der Werte im Pixel-Array statt. Alle 16 Millisekunden. Dies belastet den Prozessor bis zu 40 %.

Ich habe versucht, herauszufinden, was genau die Belastung ist. Ich dachte, es ginge darum, eine Ressource zu speichern oder sie zu lesen. Es stellte sich heraus, dass es an der Reinitialisierung des Arrays in der Zeichenschleife lag.


Es stellte sich auch heraus, dass ein ständiger Aufruf von ObjectSetInteger(0, "MT object",OBJPROP_SELECTED,1); (alle 16 ms) ebenfalls den Prozessor belastet. Um etwa 10 %.

Ich verwende diesen Aufruf, um einen anderen EA anzuweisen, die Ressource mit den Animationsdaten zu lesen.

Insgesamt wird die CPU während der Animation zu etwa 50 % ausgelastet.