MetaTrader 5 Build 3490: Die Version des Mobile Web Terminals und neue Matrix-Methoden in MQL5

Das neue Web-Terminal bietet eine umfassende Unterstützung für mobile Geräte. Die Oberfläche passt sich automatisch an die Bildschirmgröße an und ermöglicht so eine effiziente Bedienung von iOS- und Android-Handys und -Tablets:

4 November 2022

Mobile Version der Webplattform

Das neue Web-Terminal bietet eine umfassende Unterstützung für mobile Geräte. Die Oberfläche passt sich automatisch an die Bildschirmgröße an und ermöglicht so eine effiziente Bedienung von iOS- und Android-Handys und -Tablets:


Außerdem bietet das Web-Terminal eine Reihe von Korrekturen und Verbesserungen.

Das neue MetaTrader 5 Web-Terminal unterstützt den vollen Umfang der Handelsfunktionen. Es ermöglicht den Nutzern:

  • die Arbeit mit Demo- und Live-Konten,
  • den Erhalt von Preise für jede Art von Finanzsymbolen,
  • den Handel auf allen Märkten,
  • die Analyse der Preise der Symbole mit mehr als 30 Indikatoren und 20 grafischen Objekten,
  • die Nutzung der Wirtschaftskalenderdaten für die Fundamentalanalyse,


Terminal

  1. Erweiterte Funktionen des Task-Managers. Die neue Version ermöglicht eine genauere Überwachung der verwendeten Ressourcen.

    • Die Anzeige der Stackgröße für Threads wurde hinzugefügt.
    • Die Anzeige der Anzahl der Kontextwechsel wurde hinzugefügt.
    • Erkennung von System- und Drittanbieter-DLL-Threads hinzugefügt.
    • Anzeige der Betriebszeit im Kernel-Modus hinzugefügt. Ein Anstieg dieser Kennzahl im Vergleich zu der im Nutzermodus verbrachten Zeit kann auf Probleme auf Systemebene hinweisen: Treiberprobleme, Hardwarefehler oder langsame Hardware. Für weitere Details lesen Sie bitte die Microsoft Dokumentation.
    • Die Anzeige der Betriebszeit im Nutzermodus wurde hinzugefügt.




  2. Neue OpenCL-Registerkarte in den Terminaleinstellungen zur Verwaltung der verfügbaren Geräte. Der neue OpenCL-Manager ermöglicht die explizite Angabe von Geräten, die für Berechnungen verwendet werden sollen.




  3. Hinzugefügt wurde die Darstellung von Stop-Loss und Take-Profit in der Markttiefe für Konten, die im FIFO-Modus arbeiten (der Modus kann auf der Seite des Brokers aktiviert werden).

    Nach der FIFO-Regel können die Positionen für jedes Instrument nur in der gleichen Reihenfolge geschlossen werden, in der sie eröffnet wurden. Um durch die Stopp-Level die Positionen FIFO-konforme zu schließen, wurde auf der Seite des Client-Terminals folgende Logik implementiert:

    Wenn mehrere Positionen für dasselbe Instrument bestehen, führt das Setzen von Stopp-Levels für eine der Positionen dazu, dass die gleichen Levels auch für alle anderen Positionen gesetzt werden. Dementsprechend werden bei Auslösung eines Levels alle Positionen in einer FIFO-konformen Reihenfolge geschlossen.

    Wenn der Nutzer nun die Markttiefe für ein Instrument öffnet, für das bereits offene Positionen bestehen, werden die Niveaus der bestehenden Positionen (falls vorhanden) automatisch in den Feldern Stop-Loss und Take-Profit angegeben.

  4. Das Löschen von Stop-Loss- und Take-Profit-Levels mit Hilfe der X-Schaltflächen im Toolbox\Trade-Fenster wurde korrigiert. Der Fehler trat auf, wenn die Schnellhandelsfunktion deaktiviert war. Ein Klick auf die Schaltfläche öffnet einen Handelsdialog mit einem leeren Wert des entsprechenden Levels.

  5. Die Beschriftung der Grafiken und die Berechnung der Endprovisionen im Handelsbericht wurden korrigiert. Der Abschnitt konnte falsche Gewinne in den Berichtsstatistiken und falsche Werte in den Tooltips der Kapital- und Saldendiagramme anzeigen.

MQL5

  1. Die Vektor- und Matrixmethoden CopyTicks und CopyTicksRange wurden hinzugefügt. Sie ermöglichen das einfache Kopieren von Arrays mit Tickdaten in Vektoren und Matrizen.
    bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
    bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
    
    bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
    bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
    Der kopierte Datentyp wird im Parameter rates_mask unter Verwendung der Enumeration ENUM_COPY_RATES angegeben. Die folgenden Werte sind verfügbar:
    COPY_TICKS_INFO    = 1,       // Ticks aufgrund der Änderungen von Bid and/or Ask
    COPY_TICKS_TRADE   = 2,       // Ticks aufgrund der Änderungen von Last und Volumen
    COPY_TICKS_ALL     = 3,       // alle Ticks haben sich geändert
    COPY_TICKS_TIME_MS = 1<<8,    // Zeit in Millisekunden
    COPY_TICKS_BID     = 1<<9,    // Bid-Preis
    COPY_TICKS_ASK     = 1<<10,   // Ask-Preis
    COPY_TICKS_LAST    = 1<<11,   // Last-Preis
    COPY_TICKS_VOLUME  = 1<<12,   // Volume
    COPY_TICKS_FLAGS   = 1<<13,   // Tick-Flags
    Wenn mehrere Datentypen ausgewählt werden (nur bei Matrizen möglich), entspricht die Reihenfolge der Zeilen in der Matrix der Reihenfolge der Werte in der Enumeration.

  2. Erweiterte Funktionen der Methoden matrix::Assign und vector::Assign.

    Jetzt kann der Matrix ein eindimensionales Array oder ein Vektor zugewiesen werden:
    bool matrix::Assign(const vector &vec);
    Das Ergebnis wird eine einzeilige Matrix sein.

    Außerdem kann jetzt eine Matrix einem Vektor zugewiesen werden (es wird Matrixglättung durchgeführt):
    bool vector::Assign(const matrix &mat);
  3. Swap-Methoden für Vektoren und Matrizen hinzugefügt.
    bool vector::Swap(vector &vec);
    bool vector::Swap(matrix &vec);
    bool vector::Swap(double &arr[]);
    bool matrix::Swap(vector &vec);
    bool matrix::Swap(matrix &vec);
    bool matrix::Swap(double &arr[]);
    Jedes Array, jeder Vektor oder jede Matrix verweist auf einen Speicherpuffer, der die Elemente des betreffenden Objekts enthält. Die Swap-Methode tauscht tatsächlich die Zeiger auf diese Puffer aus, ohne die Elemente in den Speicher zu schreiben. Eine Matrix bleibt also eine Matrix, und ein Vektor bleibt ein Vektor. Das Vertauschen einer Matrix und eines Vektors führt zu einer einzeiligen Matrix mit Vektorelementen und einem Vektor mit Matrixelementen in einer flachen Darstellung (siehe die Methode Flat).
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
     {
    //---
      matrix a= {{1, 2, 3}, {4, 5, 6}};
      Print("a vor dem Tausch: \n", a);
      matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}};
      Print("b vor dem Tausch: \n", b);  
    //--- Tausch der Matrix-Pointer
      a.Swap(b);
      Print("a nach dem Tausch: \n", a);
      Print("b nach dem Tausch: \n", b);
      /*
      a vor dem Tausch:
      [[1,2,3]
      [4,5,6]]
      b vor dem Tausch:
      [[5,10,15,20]
      [25,30,35,40]
      [45,50,55,60]]
      
      a nach dem Tausch:
      [[5,10,15,20]
      [25,30,35,40]
      [45,50,55,60]]
      b nach dem Tausch:
      [[1,2,3]
      [4,5,6]]
      */
      vector v=vector::Full(10, 7);
      Print("v vor dem Tausch: \n", v);
      Print("b vor dem Tausch: \n", b);
      v.Swap(b);
      Print("v nach dem Tausch: \n", v);
      Print("b nach dem Tausch: \n", b);
      /*
      v vor dem Tausch:
      [7,7,7,7,7,7,7,7,7,7]
      b vor dem Tausch:
      [[1,2,3]
      [4,5,6]]
      
      v nach dem Tausch:
      [1,2,3,4,5,6]
      b nach dem Tausch:
      [[7,7,7,7,7,7,7,7,7,7]]
      */
     }
    Die Methode Swap() ermöglicht auch Operationen mit dynamischen Arrays (Arrays fester Größe können nicht als Parameter übergeben werden). Das Array kann eine beliebige Dimension haben, aber eine vereinbarte Größe, was bedeutet, dass die Gesamtgröße einer Matrix oder eines Vektors ein Vielfaches der Dimension Null des Arrays sein muss. Die Dimension Null des Arrays enthält die Anzahl der Elemente, die im ersten Index enthalten sind. Bei einem dynamischen dreidimensionalen Array ‚double array[][2][3]‘ beispielsweise ist die Dimension Null das Produkt aus der Größe der zweiten und dritten Dimension: 2x3=6. Daher kann ein solches Array bei der Swap-Methode nur mit Matrizen und Vektoren verwendet werden, deren Gesamtgröße ein Vielfaches von 6 ist: 6, 12, 18, 24, usw.

    Betrachten Sie das folgende Beispiel:
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
     {
    //--- Füllen einer 1x10 Matrix mit dem Wert 7.0
      matrix m= matrix::Full(1, 10, 7.0);
      Print("matrix vor dem Tausch:\n", m);
    //--- Tauschversuch von Matrix und Array
      double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
      Print("array_small vor dem Tausch:");
      ArrayPrint(array_small);
      if(m.Swap(array_small))
       {
        Print("array_small nach dem Tausch:");
        ArrayPrint(array_small);
        Print("matrix nach dem Tausch: \n", m);
       }
      else // Die Größe der Matrix ist kein Vielfaches der ersten Dimension
       {
        Print("m.Swap(array_small) failed. Error ", GetLastError());
       }
      /*
      matrix vor dem Tausch:
      [[7,7,7,7,7,7,7,7,7,7]]
      array_small vor dem Tausch:
               [,0]     [,1]     [,2]     [,3]     [,4]
      [0,]  1.00000  2.00000  3.00000  4.00000  5.00000
      [1,]  6.00000  7.00000  8.00000  9.00000 10.00000
      m.Swap(array_small) failed. Error 4006
      */
    //--- neuer Versuch des Tausches mit einer größeren Matrix
      double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
         {2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
         {3, 6, 9, 12, 15, 18, 21, 24, 27, 30}
       };
      Print("array_static vor dem Tausch:");
      ArrayPrint(array_static);
      if(m.Swap(array_static))
       {
        Print("array_static nach dem Tausch:");
        ArrayPrint(array_static);
        Print("matrix nach dem Tausch: \n", m);
       }
      else // ein statisches Array kann nicht für einen Matrix-Tausch verwendet werden
       {
        Print("m.Swap(array_static) failed. Error ", GetLastError());
       }
      /*
      array_static vor dem Tausch:
             [,0]     [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]     [,9]
      [0,]  1.00000  2.00000  3.00000  4.00000  5.00000  6.00000  7.00000  8.00000  9.00000 10.00000
      [1,]  2.00000  4.00000  6.00000  8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000
      [2,]  3.00000  6.00000  9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000
      m.Swap(array_static) failed. Error 4006
      */
    //--- ein weiterer Tauschversuch von Array und matrix
      double array_dynamic[][10];    // dynamischer Array
      ArrayResize(array_dynamic, 3); // setzen der Größe der ersten Dimension
      ArrayCopy(array_dynamic, array_static);
    //--- jetzt die Verwendung eines dynamischen Arrays für dejn Tausch
      if(m.Swap(array_dynamic))
       {
        Print("array_dynamic nach dem Tausch:");
        ArrayPrint(array_dynamic);
        Print("matrix nach dem Tausch: \n", m);
       }
      else //  no error
       {
        Print("m.Swap(array_dynamic) failed. Error ", GetLastError());
       }
      /*
      array_dynamic nach dem Tausch:
            [,0]    [,1]    [,2]    [,3]    [,4]    [,5]    [,6]    [,7]    [,8]    [,9]
      [0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000
      matrix nach dem Tausch:
      [[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]]
      */
     }
  4. Die Methode LossGradient für Vektoren und Matrizen wurde hinzugefügt. Diese Methode berechnet einen Vektor oder eine Matrix von partiellen Ableitungen der Verlustfunktion auf vorhergesagte Werte. In der linearen Algebra wird ein solcher Vektor als Gradient bezeichnet und beim maschinellen Lernen verwendet.
    vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const;
    matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
  5. Die Verwendung von FOREIGN KEYS in SQLite wurde ermöglicht, um Beziehungen zwischen Tabellen in SQL-Abfragen zu erzwingen.   Beispiel:
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );

  6. Korrigiert wurde die Auswahl der geeigneten Klassenmethode in Abhängigkeit von der Methoden- und Objektdeklaration.

MetaEditor

  1. Die zulässige Länge von Kommentaren bei der Übertragung in den MQL5-Storage wurde erhöht. Ausführliche Kommentare beim Übertragen von Änderungen in das Repository gelten als gute Praxis bei der Arbeit an großen Projekten, aber bisher war die Länge der Kommentare auf 128 Zeichen beschränkt. Die zulässige Länge beträgt jetzt bis zu 260 Zeichen.

MetaTester

  1. Erhöhte Empfindlichkeit des Prüfgeschwindigkeitsschalters im visuellen Modus.
Fehler in den Absturzprotokollen behoben.