---
title: "MetaTrader 5 build 3490: versión móvil del terminal web y nuevos métodos de matrices en MQL5 - Últimas actualizaciones"
description: "En la nueva versión del terminal web se ha añadido el soporte completo para dispositivos móviles. Ahora la interfaz se adapta... - Últimas actualizaciones"
image: "https://www.metatrader5.com/c/17/0/opencl_manager.png"
url: "https://www.metatrader5.com/es/releasenotes/terminal/2257"
---

# MetaTrader 5 build 3490: versión móvil del terminal web y nuevos métodos de matrices en MQL5

## 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

4 noviembre 2022

### **Versión móvil del terminal web**

En la nueva versión del [terminal web](https://www.metatrader5.com/es/news/2253) 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:

![El nuevo terminal web añade compatibilidad con los dispositivos móviles](https://www.metatrader5.com/c/17/0/mobile.png)

Además, hemos introducido en el terminal web numerosas correcciones y mejoras.

[El nuevo terminal web MetaTrader 5](https://www.metatrader5.com/es/news/2253) ofrece todas las funciones que necesita un tráder moderno. La aplicación le permitirá:

- Trabajar con cuentas demo y reales
- Recibir cotizaciones de cualquier instrumento financiero
- Comerciar en cualquier mercado
- Realizar el análisis técnico de las cotizaciones con más de 30 indicadores y 20 objetos gráficos
- Analizar los datos del Calendario Económico

### Terminal

1. Ampliadas las funciones del [gestor de tareas](https://www.metatrader5.com/es/terminal/help/start_advanced/task_manager). Ahora permite monitorear de forma más precisa el consumo de recursos.

     - Añadida la visualización del tamaño de la [pila](https://es.wikipedia.org/wiki/Pila_(informática)) para los hilos
     - Añadida la visualización del número de [cambios de contexto](https://es.wikipedia.org/wiki/Cambio_de_contexto)
     - Añadido el reconocimiento de los hilos del sistema y los hilos de las DLL de terceros
     - Añadida la visualización del tiempo de ejecución en el modo kernel. Un aumento de este indicador comparado con el tiempo de ejecución en el modo usuario puede indicar problemas a nivel de sistema: problemas de drivers, errores de hardware, hardware lento. Encontrará más información en [la documentación de Microsoft](https://www.mql5.com/go?link=https://learn.microsoft.com/es-es/windows-hardware/drivers/gettingstarted/user-mode-and-kernel-mode).
     - Añadida la visualización del tiempo de funcionamiento en el modo usuario.

   ![Ampliadas las funciones del gestor de tareas](https://www.metatrader5.com/c/17/0/terminal_task_manager.png)
2. Añadida una pestaña OpenCL a [la configuración del terminal](https://www.metatrader5.com/es/terminal/help/startworking/settings) para administrar los dispositivos disponibles. El nuevo administrador de OpenCL nos permitirá indicar explícitamente los dispositivos que se utilizarán para los cálculos.

   ![Administrador de OpenCL para gestionar los dispositivos disponibles](https://www.metatrader5.com/c/17/0/opencl_manager.png)
3. Agregada la adición de niveles de Stop Loss y Take Profit en la Profundidad de Mercado para las cuentas que operan en el modo FIFO (se puede activar en el lado del bróker). El modo FIFO implica que las posiciones de cada instrumento deberán cerrarse en el orden en que se han abierto. Para garantizar que el cierre de posiciones según los niveles stop siempre se corresponda con la regla FIFO, en el lado del terminal del cliente se implementa siguiente lógica :  Si hay varias posiciones para el mismo instrumento, la colocación de niveles stop para cualquiera de ellas dará lugar a la colocación de niveles stop similares para todas las demás. En consecuencia, al activarse un nivel, todas las posiciones se cerrarán según el orden de la regla FIFO. Al abrir la Profundidad de Mercado para un instrumento del que ya existen posiciones, los campos Stop Loss y Take Profit se rellenarán ahora automáticamente con los niveles de las posiciones existentes (si han sido establecido).
4. Corregida [la eliminación de los niveles](https://www.metatrader5.com/es/terminal/help/trading/one_click_trading#sl_tp_delete) de Stop Loss y Take Profit con los botones "X" en el apartado «Herramientas/Trading». El error se producía cuando la función de comercio rápido estaba desactivada. Al pulsar el botón, se abrirá una ventana de diálogo comercial con un valor en blanco para el nivel correspondiente.
5. Se han realizado cambios en el [informe comercial](https://www.metatrader5.com/es/releasenotes/terminal/2251), hemos corregido los rótulos fijos en los gráficos y el cálculo de la comisión final. Salvo en algunos casos, se mostraba un beneficio incorrecto en las estadísticas del informe, además de valores incorrectos en la información sobre las herramientas al pasar el cursor del ratón sobre los gráficos de equidad y balance.

### MQL5

1. Añadidos los métodos vectoriales y matriciales CopyTicks y CopyTicksRange. Estos permiten copiar fácilmente los arrays de datos de precio en vectores y matrices.

   ```
   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.
2. Ampliados los métodos [matrix::Assign](https://www.mql5.com/es/docs/matrix/matrix_initialization/matrix_assign) y [vector::Assign](https://www.mql5.com/es/docs/matrix/matrix_initialization/matrix_assign). Ahora se puede asignar a la matriz un array o vector unidimensional:

   ```
   bool matrix::Assign(const vector &vec);
   ```

   Obtendremos como resultado una matriz de una línea. Ahora también se puede asignar una matriz a un vector (se realizará el suavizado de la matriz):

   ```
   bool vector::Assign(const matrix &mat);
   ```
3. Añadidos los métodos Swap para vectores y matrices.

   ```
   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](https://www.mql5.com/es/docs/matrix/matrix_manipulations/matrix_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.Vamos a mostrar esto con un ejemplo:

   ```
   //+------------------------------------------------------------------+ //| 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]]   */ }
   ```
4. Añadidos los métodos LossGradient para vectores y matrices. Este método calcula un vector o matriz de derivadas parciales de la función de pérdida con respecto a los valores predichos. En álgebra lineal, dicho vector se denomina gradiente y se usa en el aprendizaje automático.```
   vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const; matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
   ```
5. Habilitado el uso de FOREIGN KEYS en [SQLite](https://www.mql5.com/es/docs/database), lo cual nos permitirá crear relaciones entre tablas en solicitudes SQL. Ejemplo:

   ```
   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. Corregida la selección del método de clase requerido dependiendo de la consistencia del método y el objeto.

### MetaEditor

1. Aumentada la longitud de comentario admitida para [las confirmaciones en el repositorio MQL5 Storage](https://www.metatrader5.com/es/metaeditor/help/mql5storage/mql5storage_working#commit). Los comentarios detallados al enviar cambios al repositorio se consideran de buenos modales al trabajar en grandes proyectos, pero la longitud de tales mensajes antes estaba limitada a 128 caracteres. El límite ahora se ha establecido en 260 caracteres.

### MetaTester

1. Aumentada la sensibilidad en el interruptor de velocidad de simulación en el [modo visual](https://www.metatrader5.com/es/terminal/help/algotrading/visualization).

Correcciones de crash logs.

**Lea las noticias anteriores:**

- [MetaTrader 5 build 3440: Nuevo informe sobre la cuenta comercial](https://www.metatrader5.com/es/releasenotes/terminal/2251)
- [MetaTrader 5 build 3390: Float en OpenCL y funciones matemáticas, métodos de activación y pérdida para el aprendizaje automático](https://www.metatrader5.com/es/releasenotes/terminal/2247)
- [MetaTrader 5 build 3320: Mejoras y correcciones](https://www.metatrader5.com/es/releasenotes/terminal/2243)
- [MetaTrader 5 build 3300: Compilación rápida y mejor navegación por el código de MetaEditor](https://www.metatrader5.com/es/releasenotes/terminal/2241)
- [MetaTrader 5 build 3280: Mejoras y correcciones según los comentarios de los tráders](https://www.metatrader5.com/es/releasenotes/terminal/2239)
