English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
preview
Verwendung von Ressourcen in MQL5

Verwendung von Ressourcen in MQL5

MetaTrader 5Beispiele | 15 Januar 2016, 14:48
1 248 0
MetaQuotes
MetaQuotes


Die Wichtigkeit eines Interfaces in modernen Programmen

Lange Zeit war das Hauptziel von Computerprogrammen die Durchführung von aufwendigen mathematischen Berechnungen und Verarbeitung riesiger Datenmengen. Doch mit der zunehmenden Leistung der Computer haben sich die Prioritäten geändert. Ein Benutzer kann jetzt zwischen zwei Programmen mit identischer Funktionalität dasjenige wählen, mit dem er leichter arbeiten kann.

Inzwischen reicht es nicht mehr, ein Programm nach dem notwendigen Berechnungsalgorithmus zu schreiben, sondern es muss auch ein benutzerfreundliches, graphisches Interface zur Verfügung gestellt werden. Selbst die technische Analyse ist eine Folge des Wunsches der Händler, ein virtuelles Abbild der aktuellen Marktsituation zu haben. Daher wurden Trendlinien, Support- und Beständigkeitsstufen, verschiedene Kanäle und technische Indikatoren entwickelt, um ein objektives Bild dessen anbieten zu können, was gerade geschieht.

Die neue MQL5 Sprache stellt noch leistungsfähigere Tools zur Erstellung vollfunktionaler Anwendungen zur Verfügung, die mit nichts anderem als nur dem MetaTrader 5 Client-Terminal gemacht werden können. In diesem Beitrag zeigen wir, wie man die Ressourcen zur Erzeugung einer ausführbaren EX5-Datei mit einem benutzerfreundlichen Interface verwendet. Diese Datei benötigt dann keine Routine-Operatoren mehr wie Installation oder Start.


Die Möglichkeiten von MQL5

Zunächst ist jedoch klar, dass die Möglichkeit mit Grafiken arbeiten zu können, extrem wichtig ist. Entsprechende Beispiele stehen in den jeweiligen Beiträgen, u.a. in:

Ein Programm wird nämlich durch die Verwendung von grafischen Elementen vom Standpunkt des Benutzers interessanter und ist zudem leichter zu verwalten. Zusätzlich zu den klassischen Tools wie Technische Analyse, bietet das MetaTrader 5 Terminal noch eine große Palette an graphischen Objekten, die als Bausteine zur Erzeugung des eigenen graphischen Interfaces genutzt werden können.


Verwendung von Imagedateien zur Erzeugung eines Interface

Zur Erzeugung eines speziellen Interfaces werden sehr oft Bilder von Grafikdateien verwendet. Dadurch erreicht man nämlich ein eindeutig erkennbares Design verschiedener Kontrollelemente. Die MQL5 Sprache bietet zwei graphische Objekte an, die Grafiken verwenden:

  • OBJ_BITMAP - das Bitmap Objekterlaubt den Download eines Bildes von einer BMP Datei und seine Darstellung auf einem Chart;
  • OBJ_BITMAP_LABEL - die Bezeichnung der Grafik ist eigentlich eine Taste, deren Bild sich je nach ihrem Status ändert (gedrückt/nicht gedrückt).

Mit diesen beiden Objekten kann man eine immense Vielfalt an Kontrollen erzeugen und sie mit den Ereignis-Anwendern "Mausklick" (CHARTEVENT_OBJECT_CLICK) vergleichen. Um das gewünschte Bild für OBJ_BITMAP oder OBJ_BITMAP_LABEL, einzurichten, muss in der OBJPROP_BMPFILE Eigenschaft die gewünschte BMP-Datei festgelegt werden. Dies kann manuell im "Parameter"-Tab des Grafik-Objekts gemacht werden.


Die zweite und hauptsächliche Möglichkeit für einen MQL5 Programmierer ist, für die OBJPROP_BMPFILE Eigenschaft einen Dateinamen mit Hilfe der ObjectSetString() Funktion festzulegen. Zum Beispiel:

   //--- Load an image for the "Pressed" button state
   bool set=ObjectSetString(0,object_name,OBJPROP_BMPFILE,0,bmp_file_name);

Ein Standardalgorithmus zur Verwendung von OBJ_BITMAP oder OBJ_BITMAP_LABEL:

  1. Mit Hilfe der ObjectCreate() Funktion erzeugt man ein Objekt.
  2. Und mit Hilfe der ObjectSetInteger() Funktion verankert man ggf. das Objekt an der gewünschten Ecke des Charts. Die X- und Y-Koordinaten der Ankerpunkte in Pixel werden dann in Bezug zu dieser Ecke gesetzt.
  3. Die Werte der X- und Y-Koordinaten (OBJPROP_XDISTANCE und OBJPROP_YDISTANCE) richtet man in ObjectSetInteger() ein.
  4. Das grafische Objekt des Wertes der OBJPROP_BMPFILE Eigenschaft (eine für BITMAP oder zwei für OBJ_BITMAP_LABEL) richtet man dann mit Hilfe von ObjectSetString() ein.
  5. Mit Hilfe von ObjectSetInteger() richtet man dann für das OBJ_BITMAP_LABEL Objekt den ursprünglichen Status der Taste ein - gedrückt oder nicht gedrückt (OBJPROP_STATE ergibt true oder false).

Nach der Erzeugung und Konfiguration des Objekts kann man, während das MQL5-Programm läuft, nicht nur die Position und Bedingung des Grafikobjekts dynamisch verändern, sondern auch den Wert der OBJ_BITMAP_LABEL Eigenschaft zur Anzeige von Bildern. Das Interface kann also extrem flexibel und re-konfigurierbar sein.


Wiedergabe von akustischen Signalen (Sounds)

Ein zusätzliches Komfortfeature, das in vielen Programm erwartet wird, ist die Möglichkeit, einen Benutzer in einer gewissen Situation zu fragen, ob er die Handlung ausführen möchte oder nicht. Zur Implementierung dieser umgekehrten Interaktion wird oft das Abspielen von Sounds genutzt - je nach Ereignis. Das erspart dem Händler nämlich, die Kurscharts dauernd im Blick haben zu müssen, da er einfach 'akustisch' darauf hingewiesen, wenn es nötig ist. Die PlaySound() Funktion dient in MQL5 zum Abspielen von Audiodateien.

PlaySound() ist sehr einfach zu verwenden und erfordert nur die Festlegung eines Pfads für eine Sounddatei:

//--- The path to a sound file  
string wav_file_name="Ok.wav";
...
//--- Play a sound from the file terminal_directory\Sounds\Ok.wav
bool played=PlaySound(wav_file_name);
if(!played)
  //--- Failed to play the sound, notify of this
  {
   PrintFormat("Failed to play file %s. Error code=%d", wav_file_name, GetLastError());
  }


Wo man Sound- und Imagedateien findet

Die Funktionen ObjectSetString() und PlaySound() erfordern die Festlegung eines Pfads für eine Datei. Aus Sicherheitsgründen befinden sich alle in MQL5-Programmen verwendeten Dateien innerhalb der Datei-Sandbox. Das heißt, dass diese Dateien nur in bestimmten Directories gespeichert werden können. Die Arbeit mit Dateien aus anderen Directories ist nicht erlaubt. Man muss daher als Erstes wissen, welche Directories für Dateivorgänge und Funktionen verfügbar sind und wie sie heißen.

Sie finden sich in drei unterschiedlichen Directories:

  • Terminal Directory - das Client-Terminal Installations-Directory. Von diesem Directory aus wird MetaTrader 5 gestartet. Zur Ansicht des Ordners im Terminal-Menü "File"-"Open terminal data" wählen.
  • Terminal Daten-Directory - der Ordner, der die Daten eines bestimmten Windows-Benutzer speichert. Die eingebauten Schutzmechanismen des Betriebssystems unterschieden sich je nach Benutzerzugriff, daher können die Daten jedes Benutzers separat von denen anderer Benutzer gespeichert werden. Alle Indikatoren, Expert Advisors und das im Navigator Fenster angezeigte Script, sind in diesem Directory, im MQL5 Unterordner, gespeichert.
  • Freigegebener Order aller Terminals (aller auf dem Computer installierten MetaTrader 5 Client-Terminals) - ein Order zur Ausführung der Dateivorgänge mit Hilfe der FILE_COMMON Flagge.

Um herauszufinden, wo sich diese Directories befinden, kann man das Script WhereMyFolders.mq5 verwenden:

//+------------------------------------------------------------------+
//|                                               WhereMyFolders.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- The folder from which the terminal is started - terminal_directory
   string terminal_path=TerminalInfoString(TERMINAL_PATH);
//--- The folder that stores the terminal data - terminal_data_directory
   string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
//--- The shared folder of all client terminals - common_terminal_folder
   string common_data_path=TerminalInfoString(TERMINAL_COMMONDATA_PATH);   
   //--- Show all the paths 
   Print("TERMINAL_PATH(terminal_directory) = ",TerminalInfoString(TERMINAL_PATH));
   Print("TERMINAL_DATA_PATH(terminal_data_directory) = ",TerminalInfoString(TERMINAL_DATA_PATH));
   Print("TERMINAL_COMMONDATA_PATH(comon_terminal_folder) = ",TerminalInfoString(TERMINAL_COMMONDATA_PATH));   
  }

Wichtig: Manchmal überschneiden sich die Standorte von terminal_directory und terminal_data_directory, doch ist es ratsam, sich nicht darauf zu verlassen und die beiden nicht zu verwechseln.

Image- und Sounddateien werden durch das Laufzeitsystem des Terminals in folgender Reihenfolge gesucht:

  • wenn der Backslash "\" Separator (geschrieben als "\\") am Anfang des Pfads platziert wird, sucht das System nach der Ressource in Bezug zum Directory terminal_data_directory\MQL5\;
  • wenn kein Backslash am Anfang des Pfads steht, wird nach der Datei in Bezug zum Standort der EX5-Datei gesucht, von der aus die Funktion ObjectSetString(... , OBJPROP_BMPFILE, ...) oder PlaySound() aufgerufen wird.
Für die PlaySound() Funktion gibt es eine Ergänzung: Wird die Datei nicht mit Hilfe der o.g. zwei Methoden gefunden, wird nach der Sounddatei in Bezug zum terminal_directory\Sounds\ gesucht.


Beispiel für Sounddateien:

  • Nach der Datei one.wav wird im terminal_data_directory\MQL5\ gesucht
    PlaySound("\\one.wav");
  • Nach der Datei two.wav wird im terminal_data_directory\MQL5\Files\ gesucht
    PlaySound("\\Files\\two.wav");
  • Nach der Datei three.wav wird im terminal_data_directory\MQL5\MySounds\ gesucht
    PlaySound("\\MySounds\\three.wav");
  • Nach der Datei four.wav wird in dem Ordner gesucht, von dem aus die ausführbare EX5-Datei abläuft. Wird diese Datei im Ordner nicht gefunden, wird versucht, sie im Ordner terminal_directory\Sounds\ zu finden.
    PlaySound("four.wav");


Beispiele für Imagedateien:

  • Die Datei bird.bmp wird im terminal_data_directory\MQL5\ gesucht
    //--- Setting an image for the OBJ_BITMAP_LABEL object
    bool res=ObjectSetString(0,object_name,OBJPROP_BMPFILE,0,"bird.bmp");// Modifier 0 is specified
  • swan.bmp wird im terminal_data_directory\MQL5\Files\ gesucht
    //--- Setting an image for the OBJ_BITMAP object
    bool set=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"\\Files\\swan.bmp");// No modifier
  • dog.bmp wird im terminal_data_directory\MQL5\MyPictures\ gesucht
    //--- Setting an image for OBJ_BITMAP
    bool done=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"\\MyPictures\\dog.bmp");// No modifier
  • cat.bmp wird in dem Ordner gesucht, von dem aus die ausführbare EX5-Datei abläuft
    //--- Setting an image for OBJ_BITMAP
    bool result=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"cat.bmp");// No modifier

Bitte beachten Sie, dass der Doppel-Backslash "\\" beim Schreiben des Pfads als Separator dient.

Wichtig: Bei der Festlegung des Pfads bitte immer einen Doppel-Backslash als Separator verwenden, da ein Einzel-Backslash ein Kontrollzeichen für den Compiler beim Parsing der konstanten Reihen und Zeichenkonstanten im Quellcode des Programms ist.


Neue Möglichkeiten - Ressourcen

Um Bilder und Audioelemente in Ihrem MQL5-Programm verwenden zu können, vergewissern Sie sich, dass alle vom Programm verwendeten Media-Dateien in den entsprechenden Ordnern sind. Ist dies nicht der Fall, erweist sich das als klarer Nachteil bei der Übertragung einer kompilierten EX5-Datei von einem Terminal zu einem anderen. Doch dieses Problem kann man bereits beim Schreiben des Codes lösen. In diesem Fall Ressourcen verwenden.

Um eine Ressource in einem Programm zu verwenden, sollte sie mit Hilfe der Compiler-Direktive #resource deklariert wird.

 #resource path_to_resource_file

Jetzt kann diese Ressource anstelle eines Dateipfads verwendet werden. Der Befehl #resource sagt dem Compiler, dass die Ressource im angegebenen Pfad path_to_Ressource_file in die ausführbare EX5-Datei aufgenommen werden soll. Somit können alle erforderlichen Bilder und Audioelemente direkt in der EX5-Datei abgelegt werden. Wenn man jetzt ein MQL5-Programm in einem anderen Terminal starten muss, müssen nicht mehr alle in dem Programm verwendeten Dateien übertragen werden.

Jede EX5-Datei kann Ressourcen enthalten, und jedes EX5-Programm kann die Ressourcen von einem anderen EX5-Programm verwenden. Also: ein Expert Advisor kann die Ressourcen, die sich in einem Indikator oder der EX5-Bibliothek befinden, nutzen. Ein weiterer Komfort bei der Verwendung von Ressourcen.

Der Einsatz von Ressourcen erlaubt einem, alles in einem zu bekommen - die ausführbare Datei an sich und alle Ressourcen, die sie verwendet. Sie alle werden während der Kompilierung eines Quellcodes in eine EX5-Datei gepackt.


Compiler-Suche nach Ressourcen

Eine Ressource wird mit Hilfe der Direktive #resource "<path to the Ressource file>" festgelegt.

 #resource "<path_to_resource_file>"
Die Länge des konstanten Strings ><path_to_Ressource_file> sollte max. 63 Zeichen betragen. Der Compiler sucht nun nach einer Ressource im angegebenen Pfad in folgender Abfolge:1
  • Wenn der Backslash "\" zu Anfang des Pfads gesetzt ist, wird nach der Ressource in Bezug zum Ordner terminal_data_directory\MQL5\ gesucht.
  • Ist kein Backslash angegeben, wird die Ressource in Bezug zur Position der Quell datei gesucht, in der die Ressource geschrieben wurde.

Wichtig: Substrings "..\\" und ":\\" dürfen in einem Ressourcen-Pfad nicht verwendet werden.

Beispiele für Ressourcen, einschließlich der vom Hilfe-Thema Ressourcen:

//--- Correct specification of a resource
#resource "\\Images\\euro.bmp" // euro.bmp is located in terminal_data_directory\MQL5\Images\
#resource "picture.bmp"        // picture.bmp is locate in the same directory with the source file
#resource "Resource\\map.bmp"  // The resource is located in the folder source_file_directory\Resource\map.bmp
 
//--- incorrect specification of resources
#resource ":picture_2.bmp"     // Use of ":" is not allowed
#resource "..\\picture_3.bmp"  // Use of ".." is not allowed
#resource "\\Files\\Images\\Folder_First\\My_panel\\Labels\\too_long_path.bmp" //More than 63 characters


Ressourcennamen

Nach der Deklarierung einer Ressource mit Hilfe der Direktive #resource, kann sie in jedem Teil des Programms verwendet werden. Für den Ressourcennamen wird ihr Pfad ohne einen Schrägstrich (Slash) zu Anfang des Strings, der den Pfad zur Ressource angibt, benutzt.

Beispiele:

//---Examples of specifying resources and their names in the comments
#resource "\\Images\\cat.bmp"           // Resource name - Images\cat.bmp
#resource "dog.bmp"                     // Resource name - dog.bmp
#resource "Resource\\map.bmp"           // Resource name - Resource\map.bmp
#resource "\\Files\\Pictures\\bird.bmp" // Resource name - Files\Pictures\bird.bmp
#resource "\\Files\\good.wav"           // Resource name - Files\good.wav"
#resource "\\Sounds\\thrill.wav"        // Resource name - Sounds\thrill.wav"

Ressourcenamen unterscheiden nicht zwischen Groß- und Kleinschreibung - für den Compiler bedeuten die Bezeichnungen dog.bmp und DOG.bmp dasselbe.


Verwendung von eigenen Ressourcen und Ressourcen Dritter

Um eine Ressource zu verwenden, sollte man ihr einen Namen geben. Der Ressourcenname ist sein Pfad ohne Backslash zu Anfang der Zeile. Wenn Sie Ihre eigene Ressource nutzen, sollte das spezielle Merkmal "::" vor dem Ressourcennamen hinzugefügt werden.

//--- Use of resources
ObjectSetString(0,bitmap_name,OBJPROP_BMPFILE,0,"::Images\\cat.bmp");
...
ObjectSetString(0,my_bitmap,OBJPROP_BMPFILE,0,"::dog.bmp");
...
set=ObjectSetString(0,bitmap_label,OBJPROP_BMPFILE,1,"::Files\\Pictures\\bird.bmp");
...
PlaySound("::Files\\good.wav");
...
PlaySound("::Sounds\\thrill.wav");

Sie können nicht nur Ihre eigenen Ressourcen (aus Ihrer EX5-Datei) verwenden, sondern auch alle aus jeder EX5-Bibliothek und allen Modulen. Somit können Sie also ein "Ressourcen-Depot" anlegen und sie in vielen anderen mql5-Programmen verwenden.

Um Ressourcen aus einer anderen EX5-Datei zu verwenden, muss der Ressourcenname in Form von <EX5_file_name_path>::<Ressource_name> angegeben sein. Angenommen das Draw_Triangles_Script.mq5 Script enthält eine Ressource zu einem Bild in der Datei triangle.bmp:

 #resource "\\Files\\triangle.bmp"

Dann sieht ihr Name, um das Script an sich nutzen zu können, so aus: "Files\triangle.bmp". Und um sie nutzen zu können, muss dem Ressourcennamen "::" hinzugefügt werden - "::Files\triangle.bmp". Um die gleiche Ressource von einem anderen Programm nutzen zu können, z.B. von einem Expert Advisor, müssen wir dem Ressourcennamen den Pfad zur EX5-Datei in Bezug zu terminal_data_directory\MQL5\ und den Namen der EX5-Datei des Scripts - Draw_Triangles_Script.ex5 hinzufügen. Angenommen das Scripot befindet sich im Standardordner terminal_data_directory\MQL5\Scripts\, sollte der Aufruf folgendermaßen geschrieben werden:

//--- Use of a script resource in an Expert Advisor
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"\\Scripts\\Draw_Triangles_Script.ex5::Files\\triangle_1.bmp");

Ist der Pfad zu der ausführbaren Datei nicht angegeben, wenn die Ressource von einer anderen EX5 aufgerufen wird, wird nach der ausführbaren Datei im gleichen Ordner gesucht, der das Programm enthält, das die Ressource aufruft. Das bedeutet folgendes: Wenn sich ein Expert Advisor in terminal_data_directory\MQL5\Experts\ befindet , und eine Ressource von der Datei Draw_Triangles_Script.ex5 wird in ihr ohne Spezifikation des Pfads verlangt, dann wird nach der Datei in terminal_data_directory\MQL5\Experts\ gesucht.

//--- Request for a resource from a script in an Expert Advisor without path specification
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"Draw_Triangles_Script.ex5::Files\\triangle_1.bmp");


Die Funktionsweise der Komprimierung von Ressourcen in EX5-Dateien

bmp.- und wav.-Dateien werden automatisch komprimiert, bevor sie in ausführbare EX5-Dateien mit aufgenommen werden. Das bedeutet, dass die Verwendung von Ressourcen einem jetzt, im Vergleich zur herkömmlichen Art MQL5-Programme zu schreiben, nicht nur erlaubt, vollfunktionale MQL5-Programme zu erzeugen, sondern zugleich auch die Gesamtgröße der vom Terminal zur Verwendung von Bildern und Audioelementen erforderlichen Dateien zu verringern.

Die Dateigröße der Ressource-Datei darf max. 16 MB betragen.

Wichtig: Ein zusätzlicher Vorteil bei der Verwendung von Ressourcen ist die automatische Komprimierung von wav.- und bmp.-Dateien, wenn sie in eine ausführbare EX5-Datei gepackt werden. Das verringert nicht nur ihre Menge, sondern auch die Größe der vom Programm benutzten Dateien.

Stellen Sie sich z.B. ein kleines Programm Animals_EA.mq5 vor. Ein kleiner Codeblock zur Verwendung von Ressourcen steht unten:

//+------------------------------------------------------------------+
//|                                                   Animals_EA.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- Declare image resources
#resource "\\Images\\cat.bmp"
#resource "\\Images\\dog.bmp"
#resource "\\Images\\cow.bmp"
#resource "\\Images\\bird.bmp"
//--- Declare sound resources
#resource "\\Files\\MySounds\\cat.wav"
#resource "\\Files\\MySounds\\dog.wav"
#resource "\\Files\\MySounds\\cow.wav"
#resource "\\Files\\MySounds\\bird.wav"
//--- Object names
string cat_dog="cat_dog";
string cow_bird="cow_bird";
string canvas="canvas";
string text="text";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Create a substrate
   CreateCanvas(canvas,50,50,500,500);
//--- Create buttons
   CreateObjectBITMAP_LABEL(cat_dog,110,120,"::Images\\cat.bmp","::Images\\dog.bmp");
   CreateObjectBITMAP_LABEL(cow_bird,110,330,"::Images\\cow.bmp","::Images\\bird.bmp");
   CreateText(text,"Click on any graphical object",200,90,clrTan);
//--- Give a command for an immediate refresh to see the object
   ChartRedraw();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|  Creating OBJ_BITMAP_LABEL with the specified images          |
//+------------------------------------------------------------------+
bool CreateObjectBITMAP_LABEL(string obj_name,int X,int Y,string res_name1,string res_name2)
  {
//--- If there is no such an object on the chart
   if(ObjectFind(0,obj_name)==-1)
     {
      //--- Create it
      bool res=ObjectCreate(0,obj_name,OBJ_BITMAP_LABEL,0,0,0);
      //--- Check the result
      if(!res)
        {
         PrintFormat("%s: Failed to create OBJ_BITMAP_LABEL with the name %s. Error code=%d",
                     __FUNCTION__,
                     GetLastError());
         return false;
        }
     }

//--- Set the coordinates
   ObjectSetInteger(0,obj_name,OBJPROP_XDISTANCE,X);
   ObjectSetInteger(0,obj_name,OBJPROP_YDISTANCE,Y);
//--- Disable display on the background
   ObjectSetInteger(0,obj_name,OBJPROP_BACK,false);
//--- Reset the error code
   ResetLastError();
//--- Set an image for the pressed condition
   bool res=ObjectSetString(0,obj_name,OBJPROP_BMPFILE,0,res_name1);
//--- Check the operation result
   if(!res)
     {
      PrintFormat("%s: Failed to upload an image from the resource %s. Error code=%d",
                  __FUNCTION__,
                  res_name1,
                  GetLastError());
      return false;
     }
//--- Set an image for the depressed state
   res=ObjectSetString(0,obj_name,OBJPROP_BMPFILE,1,res_name2);
//--- Check the operation result
   if(!res)
     {
      PrintFormat("%s: Failed to upload an image from the resource %s. Error code=%d",
                  __FUNCTION__,
                  res_name2,
                  GetLastError());
      return false;
     }
//--- Set the button pressed
   ObjectSetInteger(0,obj_name,OBJPROP_STATE,true);
   return true;
  }
//+------------------------------------------------------------------+

Das Programm hat die Aufgabe, zwei Grafikschaltflächen, die ihr Aussehen bei Mausklick verändern, vor einem blauen Hintergrund (Träger) zu zeichnen. Wenn man auf den Träger klickt, dann ändert sich die Farbe von Blau zu Beige und umgekehrt. Und bei jeder Farbveränderung ertönt ein Audiosignal, das 'Ereignis' der Maus wird in der Funktion OnChartEvent() gesteuert. Die unten stehende Abbildung zeigt ein Chart direkt nach dem Start von Adviser Animals_EA.mq5.



Sehen Sie sich die Eigenschaften des OBJ_BITMAP_LABEL Objekts an, z.B. cat_dog. Eine Änderung der Eigenschaften der Bitmap-Datei (On) und Bitmap-Datei (Off) ist nun mittels des Dialogfensters nicht mehr möglich, denn diese Felder stehen nicht mehr zur Verfügung und sich schwächer beleuchtet.


Wichtig: In grafischen Objekten können von Ressourcen geladene Bilder, nur per Programm verändert werden. Eine manuelle Veränderung dieser Eigenschaften via des Eigenschaften-Objektfensters steht nicht mehr zur Verfügung.

Die Gesamtmenge der von Expert Advisor Animals_EA.mq5 verwendeten Bilder ist 430 KB.


Doch die Größe der daraus folgenden, ausführbaren Animals_EA.ex5, die all diese Bilder enthält, ist 339 KB. Daher haben wir jetzt anstatt 9 Dateien (eine MQ5-Datei, vier bmp.- und vier wav.-Dateien), nur eine EX5-Datei, die alle notwendigen Ressourcen für das Programm enthält.

In Ressourcen kann nur 24- oder 32-Bit bmp. verwendet werden. 32-bit bmp. kann Alpha-Blending enthalten - in diesem Fall werden sie auf ein Chart in transparenter Form angewendet.

Die Datei der Expert Advisor Animals_EA.mq5, ihre Bilder und Audioelemente sind im Anhang dieses Beitrags zu finden:

  • Bilder aus ???? images.zip sollten in terminal_data_directory\MQL5\Images\ entpackt werden.
  • Audioelemente aus MySounds.zip sollten in terminal_data_directory\MQL5\Files\MySounds\ entpackt werden.

Wenn Sie dieses Programm in Ihrem Terminal testen wollen, laden Sie einfach die angehängte, kompilierte (erstellte) Expert Advisor Animals_EA.ex5 herunter, die alle notwendigen Ressourcen enthält. So müssen Sie nicht die Image- und Sound-Dateien herunterladen und installieren.


Arbeit mit benutzerdefinierten Indikatoren, die als Ressourcen mit eingeschlossen sind

Für den Betrieb der MQL5 Anwendungen kann einer oder mehrere benutzerdefinierte Indikatoren notwendig sein. Sie alle können im Code eines ausführbaren MQL5-Programms mit eingeschlossen werden. Die Aufnahme von Indikatoren als Ressourcen vereinfacht die Verteilung der Anwendungen.

Unten findet sich ein Beispiel, wie der benutzerdefinierte Indikator SampleIndicator.ex5, der sich im terminal_data_folder\MQL5\Indicators\ Directory befindet, mit eingeschlossen und verwendet werden kann:

//+------------------------------------------------------------------+
//|                                                     SampleEA.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#resource "\\Indicators\\SampleIndicator.ex5"
int handle_ind;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   handle_ind=iCustom(_Symbol,_Period,"::Indicators\\SampleIndicator.ex5");
   if(handle_ind==INVALID_HANDLE)
     {
      Print("Expert: iCustom call: Error code=",GetLastError());
      return(INIT_FAILED);
     }
//--- ...
   return(INIT_SUCCEEDED);
  }

Der Fall, in dem ein benutzerdefinierter Indikator in der OnInit() Funktion eine oder mehrere Kopien seiner selbst erzeugt, verdient extra Aufmerksamkeit. Bitte vergessen Sie nicht, dass die Ressource folgendermaßen spezifiziert werden sollte: <path_EX5_file_name>::<Ressource_name>.

Wenn also der SampleIndicator.ex5 Indikator in den SampleEA.ex5 Expert Advisor als eine Ressource mit aufgenommen werden soll, sieht der Pfad zu diesem Indikator selbst, der beim Aufruf iCustom() in der Initialisierungsfunktion des benutzerdefinierten Indikators angegeben wurde, folgendermaßen aus: "\\Experts\\SampleEA.ex5::Indicators\\SampleIndicator.ex5". Wenn dieser Pfad explizit festgelegt wird, ist der benutzerdefinierte Indikator SampleIndicator.ex5 unweigerlich mit der SampleEA.ex5 Expert Advisor verknüpft und kann ab sofort nicht mehr, unabhängig arbeiten.

Den 'auf sich selbst verweisenden' Pfad erhält man mit Hilfe der GetRelativeProgramPath() Funktion. Unten findet sich ein Beispiel ihrer Verwendung:

//+------------------------------------------------------------------+
//|                                              SampleIndicator.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_plots 0
int handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- the wrong way to provide a link to itself
//--- string path="\\Experts\\SampleEA.ex5::Indicators\\SampleIndicator.ex5";  
//--- the right way to receive a link to itself
  string path=GetRelativeProgramPath();
//--- indicator buffers mapping
   handle=iCustom(_Symbol,_Period,path,0,0);
   if(handle==INVALID_HANDLE)
     {
      Print("Indicator: iCustom call: Error code=",GetLastError());
      return(INIT_FAILED);
     }
   else Print("Indicator handle=",handle);
//---
   return(INIT_SUCCEEDED);
  }
///....
//+------------------------------------------------------------------+
//| GetRelativeProgramPath                                           |
//+------------------------------------------------------------------+
string GetRelativeProgramPath()
  {
   int pos2;
//--- get the absolute path to the application
   string path=MQLInfoString(MQL_PROGRAM_PATH);
//--- find the position of "\MQL5\" substring
   int    pos =StringFind(path,"\\MQL5\\");
//--- substring not found - error
   if(pos<0)
      return(NULL);
//--- skip "\MQL5" directory
   pos+=5;
//--- skip extra '\' symbols
   while(StringGetCharacter(path,pos+1)=='\\')
      pos++;
//--- if this is a resource, return the path relative to MQL5 directory
   if(StringFind(path,"::",pos)>=0)
      return(StringSubstr(path,pos));
//--- find a separator for the first MQL5 subdirectory (for example, MQL5\Indicators)
//--- if not found, return the path relative to MQL5 directory
   if((pos2=StringFind(path,"\\",pos+1))<0)
      return(StringSubstr(path,pos));
//--- return the path relative to the subdirectory (for example, MQL5\Indicators)
   return(StringSubstr(path,pos2+1));
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,        
                const double& price[])
  {
//--- return value of prev_calculated for next call
   return(rates_total);
  }


Speicherplatz im Terminal sparen

Jede Ressource wird nur einmal in den Terminal-Speicher geladen. Bei normaler Verwendung verursacht jeder Dateizugriff ein zusätzliches Laden der Datei in den Speicher. Wenn wir also z.B. 50 OBJ_BITMAP Objekte haben, von denen jedes einzelne das gleiche Bild von der Größe 100 KB hat, würden diese 50 Objekte, bei normaler Verwendung einen Speicherplatz von 50*100KB = 5MB benötigen.

Wenn wir für das hochgeladene Bild eine Ressource deklarieren, wird es nur einmal in den Speicher geladen, und zwar ungeachtet der Anzahl der Objekte in denen es verwendet wird.

Wichtig: Ressourcen werden nur einmal in den Speicher geladen und sparen daher, wenn sie mehrmals verwendet werden, Speicherplatz.


Fazit

Die Verwendung von Ressourcen erleichtert die Verwendung und Verteilung von MQL5-Programmen. Die Erzeugung komfortabler, moderner Tools für Handel erfordert die Verwendung von Multimedia-basierten Image- und Sounddateien. Das Ressourcenkonzept in MQL5 ist einfach und leicht zu verstehen, also bitte ausprobieren.

Bilder im 32-Bit bmp-Format können Alpha-Blending enthalten - in diesem Fall werden sie auf ein Chart in transparenter Form angewendet.

Die Ressourcen bieten folgenden Vorteile:

  • Kompaktheit - alle Dateien sind in eine einzige, ausführbare EX5-Datei gepackt, also ist das Programm leicht zu übertragen und zu starten;
  • Einsparung von Speicher - Der Terminal-Speicher enthält immer nur eine Instanz jeder Ressource, egal wie oft sie in einem Programm verwendet wird;
  • Bequemes Ablegen - eine EX5-Datei mit allen Ressourcen ist erheblich kleiner als die Summe der ursprünglichen Image- und Sounddateien.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/261

Beigefügte Dateien |
mysounds.zip (65.89 KB)
images.zip (214.29 KB)
wheremyfolders.mq5 (1.46 KB)
animals_ea.mq5 (18 KB)
animals_ea.ex5 (393.38 KB)
Wie die Testergebnisse des Experten selbstständig  bewerten Wie die Testergebnisse des Experten selbstständig bewerten
Im Artikel wurden Formel und die Berechnungsmethode der Daten angeboten, die im Testerbericht angezeigt werden.
Die Grundlagen für Tests in MetaTrader 5 Die Grundlagen für Tests in MetaTrader 5
Worin unterscheiden sich die drei Testmethoden in MetaTrader 5, und worauf sollte man ganz besonders achten? Wir laufen Tests eines Expert Advisors, der gleichzeitig auf verschiedenen Finanzinstrumenten handelt, ab? Wann und wie werden Indikatorwerte während der Tests berechnet und wie werden die Ereignisse behandelt? Wie synchronisiert man Bars aus unterschiedlichen Instrumenten während der Tests im Mosud "nur offene Kurse"? Der vorliegende Artikel versucht all diese und weitere Fragen zu beantworten.
Genetische Algorithmen - Mathematik Genetische Algorithmen - Mathematik
Genetische Algorithmen sind für die Lösung der Optimierungsaufgaben vorgesehen. Als Beispiel für eine solche Aufgabe, können wir das Lernen in Neuronet nehmen, das heißt, es werden solche Gewichtswerte ausgewählt, die den minimalen Fehler zulassen. Im Grunde des genetischen Algorithmus liegt ein Zufallssuchverfahren.
Handelsereignisse in MetaTrader 5 Handelsereignisse in MetaTrader 5
Eine Überwachung des aktuellen Status eines Handels-Account bedeutet offene Positions und Order kontrollieren zu können. Bevor ein Handelssignal zu einem Abschluss wird, sollte es vom Client-Terminal als Anfrage zum Handels-Server geschickt werden, wo es in eine Order-Warteschlange gestellt wird und auf seine Bearbeitung wartet. Eine Anfrage vom Handels-Server annehmen, sie löschen, wenn sie abläuft oder auf ihrer Grundlage einen Abschluss ausführen - alle diese Handlungen haben Handelsereignisse zur Folge, und der Handels-Server informiert das Terminal entsprechend darüber.