Terminal
MQL5
//--- the first handle parameter is ignored when obtaining the last error code
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
//--- get the code of the last OpenCL error
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
string desc; // to get the text description of the error
//--- use the error code to get the text description of the error
if(!CLGetInfoString(code,CL_ERROR_DESCRIPTION,desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
//--- to get the description of the last OpenCL error without receiving the code, pass CL_LAST_ERROR
if(!CLGetInfoString(CL_LAST_ERROR,CL_ERROR_DESCRIPTION, desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
Der interne Name der Enumeration wird als Fehlerbeschreibung übergeben. Die Erklärung dazu finden Sie unter https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_SUCCESS.
Der Wert CL_INVALID_KERNEL_ARGS bedeutet beispielsweise "Wird
zurückgegeben, wenn der Kernel in die Prozess-Enqueue gestellt wird und
einige Kernel-Argumente nicht gesetzt oder ungültig sind." MetaTrader 5 WebTerminal
Terminal
MQL5
Klasse A { }; void OnStart(void) { const A *const arr[][2][3]={}; Print(typename(arr)); }Ergebnis:
"class A const * const [][2][3]"
Terminal
MQL5
Fehler in den Absturzprotokollen wurden behoben.
MetaTrader 5 WebTerminal Version 3500
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:
Terminal
MQL5
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.bool matrix::Assign(const vector &vec);
Das Ergebnis wird eine einzeilige Matrix sein.bool vector::Assign(const matrix &mat);
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.//+------------------------------------------------------------------+
//| 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]]
*/
}
vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const;
matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
MetaEditor
MetaTester
Terminal
MQL5
bool vector<TDst>::Assign(const vector<TSrc> &assign); bool matrix<TDst>::Assign(const matrix<TSrc> &assign);Beispiel:
//--- copying matrices matrix b={}; matrix a=b; a.Assign(b); //--- copying an array to a matrix double arr[5][5]={{1,2},{3,4},{5,6}}; Print("array arr"); ArrayPrint(arr); b.Assign(arr); Print("matrix b \n",b); /* array arr [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 0.00000 0.00000 0.00000 [1,] 3.00000 4.00000 0.00000 0.00000 0.00000 [2,] 5.00000 6.00000 0.00000 0.00000 0.00000 [3,] 0.00000 0.00000 0.00000 0.00000 0.00000 [4,] 0.00000 0.00000 0.00000 0.00000 0.00000 matrix b [[1,2,0,0,0] [3,4,0,0,0] [5,6,0,0,0] [0,0,0,0,0] [0,0,0,0,0]] */
bool matrix::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count); bool vector::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count);Der kopierte Datentyp wird im Parameter rates_mask unter Verwendung der Enumeration ENUM_COPY_RATES angegeben. Die folgenden Werte sind verfügbar:
Fehler beim Ändern eines konstanten Parameters, der als Objektzeigerreferenz an eine Funktion übergeben wurde, behoben.
Der Spezifizierer const deklariert eine Variable als Konstante, um zu verhindern, dass sie während der Programmausführung geändert wird. Es erlaubt nur die einmalige Initialisierung von Variablen während der Deklaration. Ein Beispiel für konstante Variablen in der Funktion OnCalculate:
int OnCalculate (const int rates_total, // price[] array size const int prev_calculated, // bars processed on previous call const int begin, // meaningful data starts at const double& price[] // array for calculation );
Das folgende Beispiel enthält einen Compilerfehler, der ein implizites Zeiger-Casting für Referenzparameter zuließ:
class A {}; const A *a = new A; void foo( const A*& b ) { b = a; } void OnStart() { A *b; foo(b); // not allowed Print( a,":",b ); }Der Compiler erkennt solche illegalen Operationen und gibt den entsprechenden Fehler zurück.
MetaEditor
Neues MetaTrader 5 Web-Terminal
Wir
haben ein überarbeitetes MetaTrader 5 Web-Terminal veröffentlicht, das
eine aktualisierte Oberfläche und einen neu gestalteten Kern aufweist.
Die neue Oberfläche ähnelt der Terminalversion für das iPad:
Außerdem bietet es eine Fülle neuer Funktionen:
Versuchen Sie das neue Webterminal unter www.mql5.com gleich jetzt. Es wird in Kürze für Ihre Makler verfügbar sein.
Terminal
MQL5
//--- matrix a= {{1, 4}, {9, 16}}; Print("matrix a=\n",a); a=MathSqrt(a); Print("MatrSqrt(a)=\n",a); /* matrix a= [[1,4] [9,16]] MatrSqrt(a)= [[1,2] [3,4]] */Bei MathMod und MathPow kann das zweite Element entweder ein Skalar oder eine Matrix/ein Vektor mit der entsprechenden Größe sein.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Use the initializing function to populate the vector vector r(10, ArrayRandom); // Array of random numbers from 0 to 1 //--- Calculate the average value double avr=r.Mean(); // Array mean value vector d=r-avr; // Calculate an array of deviations from the mean Print("avr(r)=", avr); Print("r=", r); Print("d=", d); vector s2=MathPow(d, 2); // Array of squared deviations double sum=s2.Sum(); // Sum of squared deviations //--- Calculate standard deviation in two ways double std=MathSqrt(sum/r.Size()); Print(" std(r)=", std); Print("r.Std()=", r.Std()); } /* avr(r)=0.5300302133243813 r=[0.8346201971495713,0.8031556138798182,0.6696676534318063,0.05386516922513505,0.5491195410016175,0.8224433118686484,... d=[0.30458998382519,0.2731254005554369,0.1396374401074251,-0.4761650440992462,0.01908932767723626,0.2924130985442671, ... std(r)=0.2838269732183663 r.Std()=0.2838269732183663 */ //+------------------------------------------------------------------+ //| Fills the vector with random values | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Verbesserte mathematische Funktionen für Operationen mit dem Typ float.
Die neu implementierte Möglichkeit, mathematische Funktionen auf
'float'-Matrizen und -Vektoren anzuwenden, hat eine Verbesserung der auf
'float'-Skalare angewandten mathematischen Funktionen ermöglicht. Zuvor
wurden diese Funktionsparameter bedingungslos in den Typ "double"
umgewandelt, dann wurde die entsprechende Implementierung der
mathematischen Funktion aufgerufen, und das Ergebnis wurde in den Typ
"float" zurückgewandelt. Jetzt werden die Operationen ohne zusätzliches
Typenumwandlung (Casting) implementiert.
Das folgende Beispiel zeigt den Unterschied in den mathematischen Sinusberechnungen:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Array of random numbers from 0 to 1 vector d(10, ArrayRandom); for(ulong i=0; i<d.Size(); i++) { double delta=MathSin(d[i])-MathSin((float)d[i]); Print(i,". delta=",delta); } } /* 0. delta=5.198186103783087e-09 1. delta=8.927621308885136e-09 2. delta=2.131878673594656e-09 3. delta=1.0228555918923021e-09 4. delta=2.0585739779477308e-09 5. delta=-4.199390279957527e-09 6. delta=-1.3221741035351897e-08 7. delta=-1.742922250969059e-09 8. delta=-8.770715820283215e-10 9. delta=-1.2543186267421902e-08 */ //+------------------------------------------------------------------+ //| Fills the vector with random values | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
AF_ELU | Exponential-Linear-Einheit |
AF_EXP | Exponential |
AF_GELU | Gaußscher Fehler Lineare Einheit |
AF_HARD_SIGMOID | Hartes Sigmoid |
AF_LINEAR | Linear |
AF_LRELU | Undichte rektifizierte Lineareinheit |
AF_RELU | Rektifizierte Lineareinheit |
AF_SELU | Skalierte Exponential-Linear-Einheit |
AF_SIGMOID | Sigmoid |
AF_SOFTMAX | Softmax |
AF_SOFTPLUS | Softplus |
AF_SOFTSIGN | Softsign |
AF_SWISH | Swish |
AF_TANH | Hyperbolischer Tangens |
AF_TRELU | Schwellenwerteinheit (Rectified Linear Unit) |
LOSS_MSE | Mittlerer quadratischer Fehler |
LOSS_MAE | Mittlerer absoluter Fehler |
LOSS_CCE | Kategoriale Kreuzentropie |
LOSS_BCE | Binäre Kreuzentropie |
LOSS_MAPE | Mittlerer absoluter prozentualer Fehler |
LOSS_MSLE | Mittlerer quadratischer logarithmischer Fehler |
LOSS_KLD | Kullback-Leibler Divergenz |
LOSS_COSINE | Kosinus-Ähnlichkeit/-Nähe |
LOSS_POISSON | Poisson |
LOSS_HINGE | Hinge-Verlustfunktion |
LOSS_SQ_HINGE | Quadratische Hinge-Verlustfunktion |
LOSS_CAT_HINGE | Kategoriale Hinge-Verlustfunktion |
LOSS_LOG_COSH | Logarithmus des Hyperbolischen Kosinus |
LOSS_HUBER | Huber-Verlustfunktion |
int cl_ctx; //--- Initializing the OpenCL context if((cl_ctx=CLContextCreate(CL_USE_GPU_DOUBLE_ONLY))==INVALID_HANDLE) { Print("OpenCL not found"); return; }
CalendarValueLast(change, result, "", "EUR")
MetaEditor
'levels.bmp' as 'uint levels[18990]'
Terminal
MQL5
MetaTester
MetaEditor
Fehler in den Absturz-Logs behoben.
Terminal
MQL5
double vector.RegressionError(const enum lr_error); double matrix.RegressionError(const enum lr_error); vector matrix.RegressionError(const enum lr_error,const int axis);Die folgenden Variablen können als Metriken verwendet werden:
enum REGRESSION_ERROR { REGRESSION_MAE, // Mittlerer absoluter Fehler REGRESSION_MSE, // Mittlerer quadratischer Fehler REGRESSION_RMSE, // Wurzel des mittleren quadratischen Fehlers REGRESSION_R2, // R-Quadrat REGRESSION_MAPE, // Mittlerer absoluter Fehler in Prozent REGRESSION_MSPE, // Mittlerer quadratischer Fehler in Prozent REGRESSION_RMSLE // Logarithmus der Wurzel des mittleren quadratischen Fehlers };
MetaEditor
Tester
Terminal
Terminal
Terminal
MQL5
void OnStart() { int arr[4][5]= { {22, 34, 11, 20, 1}, {10, 36, 2, 12, 5}, {33, 37, 25, 13, 4}, {14, 9, 26, 21, 59} }; ulong indexes[4][5]; //--- Sort the array arr.ArgSort(indexes,-1,0); Print("indexes"); ArrayPrint(indexes); } // Result log: // indexes // [,0][,1][,2][,3][,4] // [0,] 4 2 3 0 1 // [1,] 2 4 0 3 1 // [2,] 4 3 2 0 1 // [3,] 1 0 3 2 4
void OnStart() { string test="some string"; PrintFormat("String length is %d",test.Length()); } // Result log: // String length is 11
MQL5
double matrix::Flat(ulong index) const; // getter void matrix::Flat(ulong index,double value); // setter
Pseudocode zur Berechnung der Adresse eines Matrixelements:
ulong row=index / mat.Cols(); ulong col=index % mat.Cols(); mat[row,col]
Für die "Matrix mat(3,3)" zum Beispiel kann der Zugriff auf die Elemente wie folgt geschrieben werden:
Tester
Terminal
Terminal
MQL5
VPS
MetaEditor
Tester
>
Die Dokumentation wurde aktualisiert.
struct POINT { int x,y; }; int GetYFunc(y) { return(y * y); } void SomeFunction(int x1,int x2,int y) { POINT pt={ x1+x2, GetYFunc(y) }; ProcessPoint(pt); };
struct complex { double real; // reeler Teile double imag; // imaginärer Teil };Der Typ "complex" kann als Parameter für MQL5-Funktionen per Wert übergeben werden (im Gegensatz zu normalen Strukturen, die nur per Referenz übergeben werden). Bei Funktionen, die aus DLLs importiert werden, muss der Typ "complex" ausschließlich als Referenz übergeben werden.
complex square(complex c) { return(c*c); } void OnStart() { Print(square(1+2i)); // Die Übergaben einer Konstanten als Parameter } // ausgegeben wird "(-3,4)", die komplexe Zahl in TextformFür komplexe Zahlen sind derzeit nur einfache Operationen verfügbar: =, +, -, *, /, +=, -=, *=, /=, ==,!=.
select count(*) as book_count, cast(avg(parent) as integer) as mean, cast(median(parent) as integer) as median, mode(parent) as mode, percentile_90(parent) as p90, percentile_95(parent) as p95, percentile_99(parent) as p99 from moz_bookmarks;