Terminal
MQL5
Web Terminal
Web Terminal
MQL5
MQL5: Añadidas las banderas COPY_TICKS_VERTICAL y COPY_RATES_VERTICAL para los métodos CopyTicks, CopyTicksRange y CopyRates, respectivamente.
Por
defecto, el copiado de ticks y series en la matriz se realiza a lo
largo del eje horizontal, es decir, los datos se añadirán a la izquierda
al final de la fila. En las tareas de inicio de un modelo ONNX entrenado, dicha matriz deberá transponerse para suministrar los datos de entrada:
const long ExtOutputShape[] = {1,1}; // model output shape const long ExtInputShape [] = {1,10,4}; // model input form #resource "Python/model.onnx" as uchar ExtModel[] // model as resource //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- get 10 bars if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10)) return(-1); //--- input a set of OHLC vectors matrix x_norm=rates.Transpose(); vector m=x_norm.Mean(0); vector s=x_norm.Std(0); matrix mm(10,4); matrix ms(10,4);
Ahora, bastará con indicar la bandera adicional COPY_RATES_VERTICAL (COPY_TICKS_VERTICAL para los ticks) al llamar al método para evitar operaciones innecesarias de transformación de datos:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- get 10 bars if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC|COPY_RATES_VERTICAL,2,10)) return(-1); //--- input a set of OHLC vectors
MetaEditor
Terminal
Terminal
MQL5
Compile el proyecto y ejecútelo en EURUSD H1 para ver el resultado.
Además
del modelo ya preparado y del código MQL5 para ejecutarlo, en el
proyecto también estará disponible el script Python
PricePredictionTraining.py. Este muestra cómo crear un modelo ONNX por
uno mismo. Para ejecutar el script, instale Python en su ordenador,
además de los módulos necesarios desde la línea de comandos:
#import "mmlib.dll"
bool sgemm(uint flags,matrix<float> &C,const matrix<float> &A,const matrix<float> &B,ulong M,ulong N,ulong K,float alpha,float beta);
#import
C++extern "C" __declspec(dllexport) bool sgemm(UINT flags,float *C,const float *A,const float *B,UINT64 M,UINT64 N,UINT64 K,float alpha,float beta)
Para procesar correctamente las matrices y vectores, además de sus búferes, deberemos transmitir sus dimensiones.Añadida la nueva función CopySeries para copiar series temporales sincronizadas desde MqlRates a arrays aparte.
La función CopySeries permite obtener de una sola vez solo las series temporales deseadas en los distintos arrays especificados, además, todas ellas estarán sincronizadas entre sí. Esto significa que todos los valores de los arrays resultantes para un determinado índice N pertenecerán a la misma barra en el par Símbolo/Marco temporal indicado. En este caso, no será necesario preocuparse de que todas las series temporales obtenidas estén sincronizadas con la hora de apertura de la barra.
A diferencia de CopyRates, que retorna un conjunto completo de series temporales como un array MQLRates, la función CopySeries permite al programador obtener solo las series temporales deseadas usando como base una combinación de banderas que indican el tipo de serie temporal solicitada. El orden de los arrays transmitidos a la función deberá coincidir con el orden de los campos de la estructura MqlRates:
struct MqlRates
{
datetime time; // hora de inicio del periodo
double open; // precio de apertura
double high; // precio máximo en el periodo
double low; // precio mínimo en el periodo
double close; // precio de cierre
long tick_volume; // volumen de ticks
int spread; // spread
long real_volume; // volumen bursátil
}
Así, si desea obtener los valores de las series temporales time, close y real_volume de las últimas 100 barras del símbolo/marco temporal actual, la llamada debería ser la siguiente:
datetime time[];
double close[];
long volume[];
CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
El orden de los arrays "time, close, volume" es importante: deberá coincidir con el orden de los campos de la estructura MqlRates. En cambio, el orden de los valores en la máscara rates_mask no importará, la máscara podría ser así:
COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE
Ejemplo
//--- input parameters
input datetime InpDateFrom=D'2022.01.01 00:00:00';
input datetime InpDateTo =D'2023.01.01 00:00:00';
input uint InpCount =20;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(void)
{
//--- matrices para obtener las series temporales de la estructura de precio Rates
double open[];
double close[];
float closef[];
datetime time1[], time2[];
//---solicitamos los precios de cierre a un array del tipo double
ResetLastError();
int res1=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
COPY_RATES_TIME|COPY_RATES_CLOSE, time1, close);
PrintFormat("1. CopySeries returns %d values. Error code=%d", res1, GetLastError());
ArrayPrint(close);
//--- ahora solicitaremos más precios apertura, mientras que los precios de cierre los solicitaremos a un array de tipo float
ResetLastError();
int res2=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_OPEN, time2, open, closef);
PrintFormat("2. CopySeries returns %d values. Error code=%d", res2, GetLastError());
ArrayPrint(closef);
//--- comparamos los datos obtenidos
if((res1==res2) && (time1[0]==time2[0]))
{
Print(" | Time | Open | Close double | Close float |");
for(int i=0; i<10; i++)
{
PrintFormat("%d | %s | %.5f | %.5f | %.5f |",
i, TimeToString(time1[i]), open[i], close[i], closef[i]);
}
}
/* Resultado
1. CopySeries returns 0 values. Error code=0
[ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
[10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
2. CopySeries returns 0 values. Error code=0
[ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
[10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
| Time | Open | Close double | Close float |
0 | 2023.03.01 17:00 | 1.06660 | 1.06722 | 1.06722 |
1 | 2023.03.01 18:00 | 1.06722 | 1.06733 | 1.06733 |
2 | 2023.03.01 19:00 | 1.06734 | 1.06653 | 1.06653 |
3 | 2023.03.01 20:00 | 1.06654 | 1.06520 | 1.06520 |
4 | 2023.03.01 21:00 | 1.06520 | 1.06573 | 1.06573 |
5 | 2023.03.01 22:00 | 1.06572 | 1.06649 | 1.06649 |
6 | 2023.03.01 23:00 | 1.06649 | 1.06694 | 1.06694 |
7 | 2023.03.02 00:00 | 1.06683 | 1.06675 | 1.06675 |
8 | 2023.03.02 01:00 | 1.06675 | 1.06684 | 1.06684 |
9 | 2023.03.02 02:00 | 1.06687 | 1.06604 | 1.06604 |
*/
}
MetaEditor
Simulador
MetaTrader 5 Web Terminal build 3620
Terminal
Web Terminal
WebTerminal
Terminal
MQL5
long preferred_workgroup_size_multiple=OpenCL.GetDeviceInfo(0x1067);
void OnStart() { string cpu,os; //--- cpu=TerminalInfoString(TERMINAL_CPU_NAME); os=TerminalInfoString(TERMINAL_OS_VERSION); PrintFormat("CPU: %s, OS: %s",cpu,os); }Resultado:
Terminal
MQL5
//--- el primer parámetro handle se ignora al obtener el código del últimoo error
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
//--- obtener código del último error de OpenCL
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
string desc; // para obtener la descripción de texto del error
//--- utilizamos el código de error para obtener la descripción de texto del error
if(!CLGetInfoString(code,CL_ERROR_DESCRIPTION,desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
//--- para obtener la descripción del último error de OpenCL sin obtención previa del código, deberemos transmitir CL_LAST_ERROR
if(!CLGetInfoString(CL_LAST_ERROR,CL_ERROR_DESCRIPTION, desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
Por
ahora, como descripción del error, se ofrece el nombre de la
enumeración interna cuyo desciframiento puede verse en la página https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_SUCCESS.
Por ejemplo, si obtenemos CL_INVALID_KERNEL_ARGS, la descripción para
ello será "Returned when enqueuing a kernel when some kernel arguments
have not been set or are invalid". MetaTrader 5 WebTerminal
Terminal
MQL5
class A { }; void OnStart(void) { const A *const arr[][2][3]={}; Print(typename(arr)); }Resultado:
"clase A const * const [][2][3]"
Terminal
MQL5
Correcciones de crash logs.
MetaTrader 5 WebTerminal build 3500
Versión móvil del terminal web
En la nueva versión del terminal web se ha añadido el soporte completo para dispositivos móviles. Ahora la interfaz se adapta automáticamente al tamaño de la pantalla, lo cual permite a los usuarios trabajar cómodamente en la plataforma tanto en teléfonos como tabletas con iOS y Android:
Además, hemos introducido en el terminal web numerosas correcciones y mejoras.
El nuevo terminal web MetaTrader 5 ofrece todas las funciones que necesita un tráder moderno. La aplicación le permitirá:
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);
El
tipo de datos a copiar se indica en el parámetro rates_mask con la
ayuda de la enumeración ENUM_COPY_RATES. Están disponibles los valores
siguientes:COPY_TICKS_INFO = 1, // ticks llamados por los cambios de Bid y/o Ask
COPY_TICKS_TRADE = 2, // ticks llamados por los cambios de Last y Volume
COPY_TICKS_ALL = 3, // todos los ticks en en los que hay cambios
COPY_TICKS_TIME_MS = 1<<8, // tiempo en milisegundos
COPY_TICKS_BID = 1<<9, // precio Bid
COPY_TICKS_ASK = 1<<10, // precio Ask
COPY_TICKS_LAST = 1<<11, // precio Last
COPY_TICKS_VOLUME = 1<<12, // volumen
COPY_TICKS_FLAGS = 1<<13, // banderas de tick
Al
seleccionar varios tipos de datos (solo disponible para matrices), el
orden de las filas de la matriz se corresponderá con el orden de los
valores de la enumeración.bool matrix::Assign(const vector &vec);
Obtendremos como resultado una matriz de una línea.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[]);
Cada
array, vector o matriz se refiere a un búfer de memoria que contiene
elementos de ese objeto. El método Swap realmente intercambia los
punteros a estos búferes sin escribir los elementos en la memoria. Así
que una matriz sigue siendo una matriz, y un vector un vector. Al
intercambiar una matriz y un vector se obtiene una matriz de una línea
con elementos vectoriales y un vector con elementos matriciales en
representación plana (puede consultar el método Flat).//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
matrix a= {{1, 2, 3}, {4, 5, 6}};
Print("a before Swap: \n", a);
matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}};
Print("b before Swap: \n", b);
//--- intercambiamos de sitio los punteros por las matrices
a.Swap(b);
Print("a after Swap: \n", a);
Print("b after Swap: \n", b);
/*
a before Swap:
[[1,2,3]
[4,5,6]]
b before Swap:
[[5,10,15,20]
[25,30,35,40]
[45,50,55,60]]
a after Swap:
[[5,10,15,20]
[25,30,35,40]
[45,50,55,60]]
b after Swap:
[[1,2,3]
[4,5,6]]
*/
vector v=vector::Full(10, 7);
Print("v before Swap: \n", v);
Print("b before Swap: \n", b);
v.Swap(b);
Print("v after Swap: \n", v);
Print("b after Swap: \n", b);
/*
v before Swap:
[7,7,7,7,7,7,7,7,7,7]
b before Swap:
[[1,2,3]
[4,5,6]]
v after Swap:
[1,2,3,4,5,6]
b after Swap:
[[7,7,7,7,7,7,7,7,7,7]]
*/
}
El
método Swap también permite trabajar con arrays dinámicos (no se puede
transmitir un array de tamaño fijo como parámetro). En este caso, el
array puede ser de cualquier dimensión, pero de un tamaño consistente.
Esto significa que el tamaño total de la matriz o del vector deberá ser
un múltiplo de la dimensionalidad cero de un array. La dimensionalidad
cero de un array es el número de elementos que contiene el primer índice
del array. Por ejemplo, para un array dinámico tridimensional double
array[][2][3], la dimensionalidad cero será el producto de los tamaños
de la segunda y tercera dimensión, es decir, 2x3=6. Por lo tanto, un
array de este tipo solo podrá utilizarse en un método Swap con matrices y
vectores cuyo tamaño total sea un múltiplo de 6: 6, 12, 18, 24, etc.//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- rellenamos la matriz 1x10 con el valor 7.0
matrix m= matrix::Full(1, 10, 7.0);
Print("matrix before Swap:\n", m);
//--- intentamos realizar el intercambio entre la matriz y el array
double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
Print("array_small before Swap:");
ArrayPrint(array_small);
if(m.Swap(array_small))
{
Print("array_small after Swap:");
ArrayPrint(array_small);
Print("matrix after Swap: \n", m);
}
else // el tamaño de la matriz no es múltiplo del tamaño de la primera dimensión del array
{
Print("m.Swap(array_small) failed. Error ", GetLastError());
}
/*
matrix before Swap:
[[7,7,7,7,7,7,7,7,7,7]]
array_small before Swap:
[,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
*/
//--- tomamos una matriz mayor e intentamos realizar el intercambio de nuevo
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 before Swap:");
ArrayPrint(array_static);
if(m.Swap(array_static))
{
Print("array_static after Swap:");
ArrayPrint(array_static);
Print("matrix after Swap: \n", m);
}
else // no se puede utilizar un array dinámico para el intercambio con una matriz
{
Print("m.Swap(array_static) failed. Error ", GetLastError());
}
/*
array_static before Swap:
[,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
*/
//--- un nuevo intento de de intercambiar el array y la matriz
double array_dynamic[][10]; // array dinámico
ArrayResize(array_dynamic, 3); // indicamos el tamaño de la primera dimensión
ArrayCopy(array_dynamic, array_static);
//--- ahora utilizaremos un array dinámico para el intercambio
if(m.Swap(array_dynamic))
{
Print("array_dynamic after Swap:");
ArrayPrint(array_dynamic);
Print("matrix after Swap: \n", m);
}
else // no hay error
{
Print("m.Swap(array_dynamic) failed. Error ", GetLastError());
}
/*
array_dynamic after Swap:
[,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 after Swap:
[[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);Ejemplo:
//--- 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);El tipo de datos a copiar se indica en el parámetro rates_mask usando la enumeración ENUM_COPY_RATES. Están disponibles los siguientes valores:
Corregido el error de cambio de un parámetro constante transmitido a una función como referencia a un puntero de objeto.
Recordemos que el especificador const declara una variable como constante y no permite cambiar el valor de esa variable en la ejecución del programa. Solo permite la inicialización única de la variable al realizarse su declaración. Ejemplo de constantes en la función 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 );
Sin embargo, en el ejemplo siguiente, se encontró un error del
compilador que permitía la conversión implícita de punteros para los
parámetros de referencia:
class A {}; const A *a = new A; void foo( const A*& b ) { b = a; } void OnStart() { A *b; foo(b); // no permitido Print( a,":",b ); }Esta operación no válida será ahora detectada por el compilador y generará un error.
MetaEditor
Nuevo terminal web de MetaTrader 5
Le
presentamos el nuevo terminal web para MetaTrader 5. Lo hemos hecho más
moderno y rápido, no solo actualizando su aspecto, sino también
reescribiendo completamente el núcleo. En cuanto a su interfaz, el
terminal web ahora se parece a la ya conocida versión de la plataforma
para iPad:
En comparación con la versión anterior, tiene multitud de características nuevas:
Pruebe ahora el nuevo terminal web en www.mql5.com. Sus brókeres lo tendrán pronto a su disposición.
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]] */En el caso de MathMod y MathPow, el segundo parámetro podrá ser un escalar, o una matriz o vector del tamaño correspondiente.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- используем инициализирующую функцию для заполнения вектора vector r(10, ArrayRandom); // массив случайных чисел от 0 до 1 //--- вычислим среднее значение double avr=r.Mean(); // среднее значение массива vector d=r-avr; // вычислим массив отклонений от среднего значения Print("avr(r)=", avr); Print("r=", r); Print("d=", d); vector s2=MathPow(d, 2); // массив квадратов отклонений double sum=s2.Sum(); // сумма квадратов отклонений //--- вычислим стандартное отклонение 2-мя способами 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 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Mejoradas las funciones matemáticas para trabajar con el tipo float.
Debido a la nueva posibilidad de aplicar funciones matemáticas a
matrices y vectores de tipo float, también se han mejorado las funciones
correspondientes aplicadas a escalares del tipo float. Antes, los
parámetros de estas funciones se convertían incondicionalmente al tipo
double, se llamaba a la implementación correspondiente de la función
matemática y luego el resultado se convertía en float. Ahora, en el caso
del tipo float, los parámetros y los resultados no se convierten, ya
que se llaman las implementaciones de las funciones matemáticas
correspondientes al tipo float.
Diferencia en los cálculos usando como ejemplo el seno matemático:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- массив случайных чисел от 0 до 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 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
La función de activación en una red neuronal determina cómo la suma ponderada de la señal de entrada se transforma en la señal de salida de un nodo o varios nodos a nivel de red. La elección de la función de activación ejerce una gran influencia en las capacidades y el rendimiento de la red neuronal. Las diferentes partes del modelo pueden usar funciones de activación distintas. En MQL5 no solo se implementan todas las funciones de activación conocidas, sino también las derivadas de la función de activación. Las funciones derivadas son necesarias a la hora de calcular rápidamente una corrección basada en el error resultante durante el entrenamiento de una red neuronal.
AF_ELU Exponential Linear Unit AF_EXP Exponential AF_GELU Gaussian Error Linear Unit AF_HARD_SIGMOID Hard Sigmoid AF_LINEAR Linear AF_LRELU Leaky REctified Linear Unit AF_RELU REctified Linear Unit AF_SELU Scaled Exponential Linear Unit AF_SIGMOID Sigmoid AF_SOFTMAX Softmax AF_SOFTPLUS Softplus AF_SOFTSIGN Softsign AF_SWISH Swish AF_TANH Hyperbolic Tangent AF_TRELU Thresholded REctified Linear Unit
LOSS_MSE Mean Squared Error LOSS_MAE Mean Absolute Error LOSS_CCE Categorical Crossentropy LOSS_BCE Binary Crossentropy LOSS_MAPE Absolute Percentage Error LOSS_MSLE Mean Squared Logarithmic Error LOSS_KLD Kullback-Leibler Divergence LOSS_COSINE Cosine similarity/proximity LOSS_POISSON Poisson LOSS_HINGE Hinge LOSS_SQ_HINGE Squared Hinge LOSS_CAT_HINGE Categorical Hinge LOSS_LOG_COSH Logarithm of the Hyperbolic Cosine LOSS_HUBER Huber
int cl_ctx; //--- инициализация OpenCL контекста 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
Correcciones de crash logs.
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);Los cálculos que se pueden utilizar son:
enum REGRESSION_ERROR { REGRESSION_MAE, // Error medio absoluto REGRESSION_MSE, // Error medio cuadrático REGRESSION_RMSE, // Raíz del error medio cuadrático REGRESSION_R2, // R al cuadrado REGRESSION_MAPE, // Error medio absoluto en porcentaje REGRESSION_MSPE, // Error medio cuadrático en porcentaje REGRESSION_RMSLE // Error medio logarítmico cuadrático };
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
Pseudocódigo para calcular la dirección de un elemento de la matriz:
ulong row=index / mat.Cols(); ulong col=index % mat.Cols(); mat[row,col]
Por ejemplo, para una matriz mat(3,3), el acceso a los elementos puede escribirse como sigue
Tester
Terminal
Terminal
MQL5
VPS
MetaEditor
Tester