void ArrayPrint( const void& array[], // matriz mostrada uint digits=_Digits, // número de decimales tras la coma const string separator=NULL, // separador entre los valores de los campos de la estructura ulong start=0, // índice del primer elemento mostrado ulong count=WHOLE_ARRAY, // número de elementos mostrados ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN );ArrayPrint no muestra en el diario todos los campos de la matriz de estructuras, los campos-matrices y los campos-punteros de los objetos se omiten. Para mostrar todos los campos de esta estructura será necesaria una función propia de muestra masiva con el fotmato deseado.
//--- muestra los valores de las 10 últimas barras MqlRates rates[]; if(CopyRates(_Symbol,_Period,1,10,rates)) { ArrayPrint(rates); Print("Comprobando\n[time]\t[open]\t[high]\t[low]\t[close]\t[tick_volume]\t[spread]\t[real_volume]"); for(int i=0;i<10;i++) { PrintFormat("[%d]\t%s\t%G\t%G\t%G\t%G\t%G\t%G\t%I64d\t",i, TimeToString(rates[i].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS), rates[i].open,rates[i].high,rates[i].low,rates[i].close, rates[i].tick_volume,rates[i].spread,rates[i].real_volume); } } else PrintFormat("CopyRates failed, error code=%d",GetLastError()); //--- ejemplo de muestra /* [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.11930 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 Comprobando [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.1193 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 */
void OnStart() { int arr[]; //--- cuánta memoria se ha usado al inicio Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- cuánta memoria se ha usado para la matriz con el tamaño 1, pero con reserva ArrayResize(arr,1,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- tras aumentar la matriz, el tamaño utilizado de la memoria no ha aumentado a cuenta de la reserva ArrayResize(arr,1024*512,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- tras disminuir la matriz, el tamaño de la memoria tampoco cambiará ArrayResize(arr,1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- la memoria no utilizada por la matriz queda libre gracias a la eliminación de la reserva ArrayResize(arr,1,-1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); }
#include <Graphics/Graphic.mqh> double Func1(double x) { return MathPow(x,2); } double Func2(double x) { return MathPow(x,3); } double Func3(double x) { return MathPow(x,4); } void OnStart() { GraphPlot(Func1,Func2,Func3,-2,2,0.05,CURVE_LINES); }Resultado:
#include <Math/Stat/Binomial.mqh> #include <Graphics/Graphic.mqh> void OnStart(void) { double vars[101]; double results[101]; const int N=2000; //--- MathSequence(0,N,20,vars); MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results); ArrayPrint(results,4); GraphPlot(results); //--- }Resultado:
Documentación actualizada.
Añadidas descripciones emergentes para los botones Buy, Sell y Close en los cuadros de diálogo comerciales. Las descripciones aclararán qué activos precisamente se comprarán o venderán al realizar esta o aquella operación, ayudando así a los tráders principiantes a comprender la esencia del proceso comercial.
Asimismo, se ha incluido en la biblioteca una versión MQL5 de la biblioteca de análisis numérico ALGLIB.
Posibilidades de la biblioteca
Cómo usarlo
los archivos de la biblioteca ALGLIB se ubican en el catálogo \MQL5\Include\Math\Alglib. Para usar las funciones, incluya el archivo principal de la biblioteca en su programa:
En la biblioteca estándar se han incluido funciones para trabajar con estadística matemática. Ahora en MQL5 están disponibles las posibilidades del lenguaje R, uno de las mejores herramientas de procesamiento y análisis estadístico de datos.
Posibilidades de la biblioteca
La biblioteca estadística contiene funciones para el cálculo de las características estadísticas de los datos, así como funciones para trabajar con distribuciones estadísticas:
Cómo usarlo
los archivos de la biblioteca estadística se ubican en el catálogo \MQL5\Include\Math\Stat. Para usarla, incluya el archivo con las funciones necesarias en su programa, por ejemplo:
#include <Math\Stat\Binomal.mqh> #include <Math\Stat\Cauchy.mqh>
Puede leer una descripción detallada de las funciones de la biblioteca en el artículo Distribuciones Estadísticas en MQL5: tomando lo mejor de R.
Se ha incluido en la biblioteca estándar una versión MQL5 de la biblioteca Fuzzy, en la que se han implementado los sistemas de inferencia de lógica difusa Mamdani y Sugeno.
Posibilidades de la biblioteca
Cómo usarlo
Los archivos de la biblioteca Fuzzy se encuentran en el catálogo \MQL5\Include\Math\Fuzzy. Para usarla, incluya el archivo con las funciones necesarias en su programa, por ejemplo:
#include <Math\Fuzzy\mamdanifuzzysystem.mqh> #include <Math\Fuzzy\sugenofuzzysystem.mqh>
Podrá encontrar una descripción detallada de la biblioteca en Code Base: Fuzzy - biblioteca para trabajar con lógica difusa
long FileLoad( const string filename, // [in] nombre del archivo void &buffer[], // [out] matriz para la lectura uint common_flag=0 // [in] 0 - búsqueda de un archivo en la carpeta Files del terminal, FILE_COMMON - en la carpeta común de los terminales ); bool FileSave( const string filename, // [in] nombre del archivo const void &buffer[], // [in] matriz para el almacenamiento uint common_flag=0 // [in] 0 - creación de un archivo en la carpeta Files del terminal, FILE_COMMON - en la carpeta común de los terminales );Ejemplo de cómo grabar una matriz de ticks y leerla enseguida:
//--- parámetros de entrada input int ticks_to_save=1000; // número de ticks //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { string filename=_Symbol+"_ticks.bin"; MqlTick ticks[]; //--- int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save); if(copied!=-1) { PrintFormat(" CopyTicks(%s) copied %d ticks",_Symbol,copied); //--- si la historia de ticks está sicronizada, el código de error será igual a cero if(!GetLastError()==0) PrintFormat("%s: Ticks are not synchronized. Error=",_Symbol,copied,_LastError); //--- escribimos los ticks en el archivo if(!FileSave(filename,ticks,FILE_COMMON)) PrintFormat("FileSave() failed, error=%d",GetLastError()); } else PrintFormat("Failed CopyTicks(%s), Error=",_Symbol,GetLastError()); //--- ahora leemos estos ticks de vuelta desde el archivo ArrayFree(ticks); long count=FileLoad(filename,ticks,FILE_COMMON); if(count!=-1) { Print("Time\tBid\tAsk\tLast\tVolume\tms\tflags"); for(int i=0;i<count;i++) { PrintFormat("%s.%03I64u:\t%G\t%G\t%G\t%I64u\t0x%04x", TimeToString(ticks[i].time,TIME_DATE|TIME_SECONDS),ticks[i].time_msc%1000, ticks[i].bid,ticks[i].ask,ticks[i].last,ticks[i].volume,ticks[i].flags); } } }
//--- velas iguales, pintadas de un mismo color #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- solo se indica un color, por eso todas las velas serán solo de un color #property indicator_color1 clrGreenSi indicamos dos colores, los contornos se dibujarán con el primer color, y el cuerpo con el segundo.
//--- el color de las velas se diferencia del color de las sombras #property indicator_label1 "Two color candles" #property indicator_type1 DRAW_CANDLES //--- las sombras y el contorno de las velas en color verde, el cuerpo, en color blanco #property indicator_color1 clrGreen,clrWhiteSi se indican tres colores, el contorno de la vela se dibujará con el primer color, y el color de la vela alcista y bajista se establecerá con el segundo y el tercer color.
//--- el color de las velas se diferencia del color de las sombras #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- las sombras y el contorno de las velas en color verde, el cuerpo de la vela alcista, en color blanco, el cuerpo de la vela bajista, de color rojo #property indicator_color1 clrGreen,clrWhite,clrRedDe esta forma, con la ayuda del estilo DRAW_CANDLES se pueden crear variantes personalizadas propias del color de las velas. Asimismo, todos los colores pueden cambiarse de forma dinámica durante el proceso del trabajo con la ayuda de la función PlotIndexSetInteger(índice_de_la_construcción_DRAW_CANDLES, PLOT_LINE_COLOR, número_del_modificador, color) , donde el número_del_modificador puede tener los valores siguientes:
//--- establecemos el color del contorno y las sombras PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrBlue); //--- establecemos el color del cuerpo para la vela alcista PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrGreen); //--- establecemos el color del cuerpo para la vela bajista PlotIndexSetInteger(0,PLOT_LINE_COLOR,2,clrRed);
Se ha actualizado la documentación.
class CFoo final { //--- cuerpo de la clase }; class CBar : public CFoo { //--- cuerpo de la clase };Al intentar heredar de una clase con el modificador final, como se muestra en el ejemplo de más arriba, el compilador dará error:
class CFoo { void virtual func(int x) const { } };A continuación, el método se redefine en la clase heredada:
class CBar : public CFoo { void func(short x) { } };Pero por error, el tipo de argumento cambia de int a short. De hecho, en este caso ya tiene lugar no la redefinición, sino la sobrecarga del método. Actuando de acuerdo con el algoritmo de definición de la función sobrecargada, en ciertas situaciones el compilador puede elegir el método definido en la clase básica, en lugar del método redefinido.
class CBar : public CFoo { void func(short x) override { } };Si durante la redefinición se cambia la signatura del método, el compilador no podrá encontrar en la clase padre un método con la misma signatura y dará un error de compilación:
class CFoo { void virtual func(int x) final { } }; class CBar : public CFoo { void func(int) { } };Al intentar redefinir un método con el modificador final, como se muestra en el ejemplo de más arriba, el compilador dará error:
Se ha actualizado la documentación.
class CFoo { }; class CBar { }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { void *vptr[2]; vptr[0]=new CFoo(); vptr[1]=new CBar(); //--- for(int i=0;i<ArraySize(vptr);i++) { if(dynamic_cast<CFoo *>(vptr[i])!=NULL) Print("CFoo * object at index ",i); if(dynamic_cast<CBar *>(vptr[i])!=NULL) Print("CBar * object at index ",i); } CFoo *fptr=vptr[1]; // dará error de transformación de los punteros, vptr[1] no es un objeto de CFoo } //+------------------------------------------------------------------+
string text="Hello"; ushort symb=text[0]; // retornará el código del símbolo 'H'
Se ha actualizado la documentación.
Después de 2 meses de pruebas públicas, anunciamos el lanzamiento oficial de la versión web de la plataforma multimercado MetaTrader 5. Ella le permite negociar en los mercados financieros a través de cualquier navegador en cualquier sistema operativo. Y para ello, no es necesario instalar ningún software adicional, de hecho, basta con tener acceso a internet o cualquier navegador web.
La aplicación combina las ventajas clave de la plataforma de escritorio (velocidad, faceta multimercado y características comerciales mejoradas) con la comodidad y el carácter multiplataforma. La principal novedad de la versión actualizada es la profundidad de mercado, así como la colocación con un clic de ordenes de mercado y pendientes.
La plataforma web le permite realizar análisis técnico y realizar
negociaciones de la misma forma como en la versión de escritorio. En la
aplicación, usted tiene a su disposición:
Era |
Ahora es |
|
---|---|---|
Activación | Todos los tipos de órdenes y SL/TP según Bid/Ask |
Órdenes límite según Bid/Ask Órdenes stop, stop-limit y SL/TP según Last |
Ejecución | Todos los tipos de órdenes pendientes y SL/TP al precio indicado en la orden |
Todos los tipos de órdenes pendientes y SL/TP según los precios de mercado Bid/Ask en el momento de la activación |
Veamos un ejemplo con el instrumento Si-6.16. Con los precios
actuales Bid=72570, Ask=72572, Last=72552 se ha colocado una orden Buy
Stop con un precio de activación de 72580. En el flujo de precios hemos
obtenido los nuevos precios actuales:
En los instrumentos bursátiles, el precio Last es el que activa
las órdenes stop. Por eso, la llegada del precio Last=72580 en el flujo
ha provocado la activación de la orden Buy Stop. Antes, precisamente
este precio 72580 se utilizaba para la ejecución de esta orden. Este
comportamiento era incorrecto, puesto que el precio Ask=72580 para la
ejecución de una operación de compra en el mercado no existe.
En respuesta a las numerosas peticiones de los tráders, se ha desarrollado una versión web de la plataforma MetaTrader 5. El nuevo producto combina la comodidad y el carácter multiplataforma con las ventajas de la quinta versión para PC, es decir: velocidad, faceta multimercado y características comerciales mejoradas.
La plataforma web MetaTrader 5 ya está disponible en el sitio de la MQL5.community. Esta le permite negociar en los mercados financieros a través de cualquier navegador en cualquier sistema operativo (Windows, Mac, Linux). Y para ello, no es necesario instalar ningún software adicional, de hecho, basta con tener acceso a internet.
En la versión beta, los tráders tienen de inmediato a su disposición:
Sistema de compensación
Este sistema presupone que en un momento concreto, en la cuenta puede haber solo una posición abierta del mismo símbolo:
Más abajo mostramos un ejemplo de ejecución de dos operaciones de compra de EURUSD con un volumen de 0.5 cada una de ellas:s each:
Como resultado de la ejecución de estas operaciones, tenemos una posición general con un volumen de 1 lote.
Sistema de cobertura
Este sistema de registro de la posición permite tener multitud de
posiciones comerciales de un mismo instrumento, incluso en direcciones
diferentes.
Si hay una posición abierta de un instrumento
comercial y el tráder efectúa una nueva operación (o se activa una orden
pendiente), se abre una nueva posición. La posición existente no
cambia.
Más abajo mostramos un ejemplo de ejecución de dos operaciones de compra de EURUSD con un volumen de 0.5 cada una de ellas:
Como resultado de la ejecución de estas operaciones, tenemos la apertura de dos posiciones diferentes.
Nuevo tipo de operación comercial Close By
Para las cuentas con cobertura de registro de posiciones se ha añadido
un nuevo tipo de operaciones comerciales: el cierre de una posición con
una opuesta. Esta operación permite cerrar simultáneamente dos
posiciones en direcciones opuestas de un mismo instrumento. Si las
posiciones opuestas tienen una cantidad diferente de lotes, entonces
quedará abierta solo una orden de las dos. Su volumen será igual a la
diferencia de lotes de las dos posiciones cerradas, y la dirección de la
posición y el precio de apertura serán como en la mayor (en volumen) de
las posiciones cerradas.
En comparación con el cierre individual de dos posiciones, el cierre por orden opuesta permite al tráder ahorrarse un spread:
Al cerrar la posición con otra opuesta se establece una orden del tipo "close by". En el comentario a la misma se indican los tickets de las posiciones cerradas. El cierre de una pareja de posiciones opuestas tiene lugar mediante dos operaciones del tipo "out by". La magnitud del beneficio/pérdida total obtenido como resultado del cierre de ambas posiciones, se indica solo en una de las operaciones.
class CAnimal { public: CAnimal(); // constructor virtual void Sound() = 0; // función virtual pura private: double m_legs_count; // número de patas del animal };Aquí la función Sound() es virtual pura, por eso se la declara con el especificador de función virtual pura PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, debe ser redefinido en la clase derivada, la propia clase CAnimal se ha convertido en abstracta y no puede ser creada }; //--- derivada de la clase abstracta class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE es redefinido, la clase CCat no es abstracta y puede ser creada }; //--- ejemplos de uso incorrecto new CAnimal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" CAnimal some_animal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" //--- ejemplos de uso correcto new CCat; // no hay error, la clase CCat no es abstracta CCat cat; // no hay error, la clase CCat no es abstractaLimitaciones de uso de las clases abstractas
//+------------------------------------------------------------------+ //| Clase básica abstracta | //+------------------------------------------------------------------+ class CAnimal { public: //--- función virtual pura virtual void Sound(void)=NULL; //--- función void CallSound(void) { Sound(); } //--- constructor CAnimal() { //--- invocación directa del método virtual Sound(); //--- invocación indirecta (a través de una tercera función) CallSound(); //--- en el constructor y/o destructor siempre se invocan sus propias funciones, //--- a pesar del carácter virtual y de la redefinición de la función invocada en la derivada //--- si la función invocada es virtual pura, entonces //--- la invocación provocará el error de ejecución crítico: "pure virtual function call" } };Sin embargo, los constructores y destructores de las clases abstractas pueden invocar otras funciones miembro.
typedef int (*TFunc)(int,int);Ahora TFunc es un tipo y se puede declarar la variable-índice a una función:
TFunc func_ptr;En la variable func_ptr se puede guardar la dirección de una función para invocarla más tarde:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // error: neg no tiene el tipo int (int,int) Print(func_ptr(10)); // error: tiene que haber dos parámetrosLos índices a una función se pueden guardar y transmitir como parámetros. No es posible recibir un índice a un método de clase no estático.
ulong PositionGetTicket( int index // número en la lista de posiciones );
bool PositionSelectByTicket(
ulong ticket // ticket de la posición
);
Sistema de compensación
Este sistema presupone que en un momento concreto, en la cuenta puede haber
solo una posición abierta del mismo símbolo:
En este caso, no tiene importancia como resultado de qué acción se realiza
la operación en la dirección opuesta, si como fruto de la ejecución de
una orden de mercado o debido a la activación de una orden pendiente.
Más abajo mostramos un ejemplo de ejecución de dos operaciones de compra
de EURUSD con un volumen de 0.5 cada una de ellas:
Como resultado de la ejecución de estas operaciones, tenemos una posición
general con un volumen de 1 lote.
Sistema de cobertura
Este sistema de registro de la posición permite tener multitud de posiciones
comerciales de un mismo instrumento, incluso en direcciones diferentes.
Si hay una posición abierta de un instrumento comercial y el tráder efectúa
una nueva operación (o se activa una orden pendiente), se abre una nueva
posición. La posición existente no cambia.
Más abajo mostramos un ejemplo de ejecución de dos operaciones de compra
de EURUSD con un volumen de 0.5 cada una de ellas:
Como resultado de la ejecución de estas operaciones, tenemos la apertura
de dos posiciones diferentes.
Nuevo tipo de operación comercial Close By
Para las cuentas con cobertura de registro de posiciones se ha añadido
un nuevo tipo de operaciones comerciales: el cierre de una posición con
una opuesta. Esta operación permite cerrar simultáneamente dos posiciones
en direcciones opuestas de un mismo instrumento. Si las posiciones opuestas
tienen una cantidad diferente de lotes, entonces quedará abierta solo una
orden de las dos. Su volumen será igual a la diferencia de lotes de las
dos posiciones cerradas, y la dirección de la posición y el precio de apertura
serán como en la mayor (en volumen) de las posiciones cerradas.
En comparación con el cierre individual de dos posiciones, el cierre por
orden opuesta permite al tráder ahorrarse un spread:
Al cerrar la posición con otra opuesta se establece una orden del tipo "close by". En el comentario a la misma se indican los tickets de las posiciones cerradas. El cierre de una pareja de posiciones opuestas tiene lugar mediante dos operaciones del tipo "out by". La magnitud del beneficio/pérdida total obtenido como resultado del cierre de ambas posiciones, se indica solo en una de las operaciones.
class CAnimal { public: CAnimal(); // constructor virtual void Sound() = 0; // función virtual pura private: double m_legs_count; // número de patas del animal };Aquí la función Sound() es virtual pura, por eso se la declara con el especificador de función virtual pura PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, debe ser redefinido en la clase derivada, la propia clase CAnimal se ha convertido en abstracta y no puede ser creada }; //--- derivada de la clase abstracta class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE es redefinido, la clase CCat no es abstracta y puede ser creada }; //--- ejemplos de uso incorrecto new CAnimal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" CAnimal some_animal; // error 'CAnimal' - el compilador retorna el error "cannot instantiate abstract class" //--- ejemplos de uso correcto new CCat; // no hay error, la clase CCat no es abstracta CCat cat; // no hay error, la clase CCat no es abstractaLimitaciones de uso de las clases abstractas
//+------------------------------------------------------------------+ //| Clase básica abstracta | //+------------------------------------------------------------------+ class CAnimal { public: //--- función virtual pura virtual void Sound(void)=NULL; //--- función void CallSound(void) { Sound(); } //--- constructor CAnimal() { //--- invocación directa del método virtual Sound(); //--- invocación indirecta (a través de una tercera función) CallSound(); //--- en el constructor y/o destructor siempre se invocan sus propias funciones, //--- a pesar del carácter virtual y de la redefinición de la función invocada en la derivada //--- si la función invocada es virtual pura, entonces //--- la invocación provocará el error de ejecución crítico: "pure virtual function call" } };Sin embargo, los constructores y destructores de las clases abstractas pueden invocar otras funciones miembro.
typedef int (*TFunc)(int,int);Ahora TFunc es un tipo y se puede declarar la variable-índice a una función:
TFunc func_ptr;En la variable func_ptr se puede guardar la dirección de una función para invocarla más tarde:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // error: neg no tiene el tipo int (int,int) Print(func_ptr(10)); // error: tiene que haber dos parámetrosLos índices a una función se pueden guardar y transmitir como parámetros. No es posible recibir un índice a un método de clase no estático.
ulong PositionGetTicket( int index // número en la lista de posiciones );
bool PositionSelectByTicket(
ulong ticket // ticket de la posición
);
Se ha añadido al Asistente MQL5 el enlace al vídeo didáctico "Cómo montar un robot comercial en el Asistente MQL5". Vea este vídeo de 3 minutos y cree su propio robot comercial, sin escribir una sola línea de código.
2015.10.14 14:48:18.486 Data Folder: C:\Program Files\MetaTrader 5 2015.10.14 14:48:18.486 Windows 7 Professional (x64 based PC), IE 11.00, UAC, 8 x Intel Core i7 920 @ 2.67GHz, RAM: 8116 / 12277 Mb, HDD: 534262 / 753865 Mb, GMT+03:00 2015.10.14 14:48:18.486 MetaTrader 5 build 1190 started (MetaQuotes Software Corp.)
struct MqlTick { datetime time; // Hora de la última actualización de los precios double bid; // Precio Bid actual double ask; // Precio Ask actual double last; // Precio actual de la última transacción (Last) ulong volume; // Volumen para el precio Last actual long time_msc; // Hora de la última actualización de los precios en milisegundos uint flags; // Banderas de los tics };Todos los parámetros de cada tic siempre se llenan, independientemente de si han cambiado los datos en comparación con el tic anterior. Esto permite tener siempre el estado actual de los precios en cualquier momento, sin buscar los valores anteriores en la historia de tics. Por ejemplo, con el tic solo ha podido cambiar el precio bid, pero en la estructura, aparte del nuevo precio, se mostrarán también todos los demás parámetros: el precio anterior ask, el volumen, etcétera. Para saber qué datos precisamente han cambiado con el tic actual, analice sus banderas:
//+------------------------------------------------------------------+ //| TemplTest.mq5 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Anunciamos la plantilla de clase | //+------------------------------------------------------------------+ template<typename T> class TArray { protected: T m_data[]; public: bool Append(T item) { int new_size=ArraySize(m_data)+1; int reserve =(new_size/2+15)&~15; //--- if(ArrayResize(m_data,new_size,reserve)!=new_size) return(false); //--- m_data[new_size-1]=item; return(true); } T operator[](int index) { static T invalid_index; //--- if(index<0 || index>=ArraySize(m_data)) return(invalid_index); //--- return(m_data[index]); } }; //+------------------------------------------------------------------+ //| La plantilla de clase de la matriz de indicadores, | //| en el destructor elimina aquellos objetos a los que se referían | //| los indicadores guardados en la matriz. | //| Preste atención a la herencia de la clase de plantilla TArray | //+------------------------------------------------------------------+ template<typename T> class TArrayPtr : public TArray<T *> { public: void ~TArrayPtr() { for(int n=0,count=ArraySize(m_data);n<count;n++) if(CheckPointer(m_data[n])==POINTER_DYNAMIC) delete m_data[n]; } }; //+------------------------------------------------------------------+ //| Anunciamos la clase, los indicadores a sus objetos | //| los guardaremos en la matriz | //+------------------------------------------------------------------+ class CFoo { int m_x; public: CFoo(int x):m_x(x) { } int X(void) const { return(m_x); } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ TArray<int> ExtIntArray; // instanciamos la plantilla TArray (especializamos la plantilla TArray con el tipo int) TArray<double> ExtDblArray; // instanciamos la plantilla TArray (especializamos la plantilla TArray con el tipo double) TArrayPtr<CFoo> ExtPtrArray; // instanciamos la plantilla TArrayPtr (especializamos la plantilla TArrayPtr con el tipo CFoo) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- llenamos las matrices con datos for(int i=0;i<10;i++) { int integer=i+10; ExtIntArray.Append(integer); double dbl=i+20.0; ExtDblArray.Append(dbl); CFoo *ptr=new CFoo(i+30); ExtPtrArray.Append(ptr); } //--- generamos el contenido de las matrices string str="Int:"; for(int i=0;i<10;i++) str+=" "+(string)ExtIntArray[i]; Print(str); str="Dbl:"; for(int i=0;i<10;i++) str+=" "+DoubleToString(ExtDblArray[i],1); Print(str); str="Ptr:"; for(int i=0;i<10;i++) str+=" "+(string)ExtPtrArray[i].X(); Print(str); //--- no es necesario eliminar los objetos CFoo creados a través de new, se eliminan en el destructor del objeto TArrayPtr<CFoo> }Resultado de la ejecución:
int ObjectsDeleteAll( long chart_id, // indentificador del gráfico const string prefix, // prefijo del nombre del objeto int sub_window=-1, // índice de la ventana int object_type=-1 // tipo del objeto a eliminar );
Correciones de crash logs.
Se ha actualizado la documentación.Ahora es posible comprar cualquier aplicación en el Mercado en un solo paso, sin registrarse directamente en las plataformas MetaTrader 4/5. Para ello solo es necesario pulsar el botón "Comprar" y elegir el sistema de pago conveniente.
Después de esto, usted será redirigido a la página del sistema de pago, donde podrá realizar la compra. PayPal, WebMoney, Neteller o tarjeta bancaria, pague por sus compras en la tienda de robots e indicadores preparados usando el método que más le convenga.
Después de comprar, recomendamos de todas formas registrar una cuenta en MQL5.community, su compra quedará automáticamente ligada a ella. Así, usted tendrá la posibilidad de actualizar el producto e instalarlo en otros ordenadores. Además, la cuenta MQL5.community le abrirá acceso a usted a multitud de otros servicios para la plataforma MetaTrader, a las señales comerciales, para copiar transacciones de traders de éxito, al hosting virutal, para que sus aplicaciones puedan funcionar de manera ininterrumpida y al servicio freelance, con el que podrá encargar robots exclusivos a los desarrolladores.
Ahora seguro que ya sabe el modo más rápido y simple de obtener un robot comercial. ¡Más de 5 000 aplicaciones diferentes para MetaTrader ya le están esperando en el Mercado, elija y compre!
Los activos (Assets) se suman a fondos propios (Equity) y
aumentan el tamaño del margen libre (Free Margin), lo que permite
aumentar los volúmenes de las operaciones comerciales realizadas en la
cuenta.
De esta manera, ha surgido la posibilidad de crear las cuentas con diferentes tipos de cobertura.
ulong GetMicrosecondCount();
Se puede utilizar esta función para el perfilaje adicional de la ejecución del programa y detección de “cuellos de botella”.La actualización estará disponible a través del sistema LiveUpdate.
2. Ejecutada una serie de mejoras y correcciones en el funcionamiento del simulador de estrategias. Se han reducido significativamente las pérdidas de tiempo en las operaciones preparatorias intermedias, así como en los retrasos de la red. Aceleración de la simulación y de la optimización en todos los modos: al trabajar con los agentes locales, con la granja de agentes en la red local y al usar MQL5 Cloud Network.
Con ayuda de los comendos del menú de cliente se le puede permitir o
prohibir a un asesor concreto el comercio automático, se lo puede
eliminar del gráfico o ver sus propiedades.
3. Aumentada la precisión del algoritmo de determinación de
los puntos disponibles para la conexión al servidor comercial.
4. Corregido el error que provocaba en algunos casos que se limpiara la base de cuentas de cliente al reinstalar un terminal encima del ya disponible.
5. Se han continuado los trabajos de adaptación del interfaz al funcionamiento de las pantallas de alta defición (4K).
La actualización estará disponible a través del sistema LiveUpdate.
La actualización de la plataforma MetaTrader 5 build 1085 está publicada. Esta actualización contiene las siguientes modificaciones:
De esta manera, Usted puede cambiar en cualquier momento el número de los gráficos y la lista de los símbolos, el conjunto de programas iniciados y sus parámetros de entrada, los ajustes del terminal y la suscripción a las Señales.
Durante la ejecución de la migración, toda la información queda registrada en el log del terminal del cliente.
MetaTrader 5 Android build 1052
La nueva versión del terminal móvil MetaTrader 5 para Android ya está disponible en Google Play. Han sido corregidos algunos errores y ha sido mejorada la estabilidad de su funcionamiento. Planeamos añadir en la próximas versiones los objetos analíticos y el messanger.
Para descargar la aplicación, siga el enlace: https://download.mql5.com/cdn/mobile/mt5/android?hl=es&utm_source=www.metatrader5.com&hl=ru
La actualización estará disponible a través del sistema LiveUpdate.
Los agentes de simulación funcionan ahora solo en los sistemas de 64 bits. Esta decisión se basa en la necesidad de seguir las tendencias de desarrollo de la industria de IT. La renuncia a las antiguas tecnologías en favor de las nuevas permitirá aumentar la productividad de los cálculos y dará la posibilidad de desarrollar posteriormente la red de cálculos en la nube MQL5 Cloud Network.
Cambios en los compoenentes de la plataforma:
int WebRequest (string method, string url,string headers,int timeout, const char &data[], int data_size,char &result[], string &result_headers)
Esta función permite conformar explícitamente el contenido del encabezamiento de la solicitud HTTP, ofreciendo un mecanismo de interacción más flexible con los diferentes servicios web. Por ejemplo: Publicación automática con WebRequest()
Correciones de crash logs.
Actualización de la documentación.