Pon "Me gusta" y sigue las noticias
Deje un enlace a él, ¡qué los demás también lo valoren!
Evalúe su trabajo en el terminal MetaTrader 5
- Visualizaciones:
- 67
- Ranking:
- Publicado:
-
¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa
Alternativa para la librería EAToMath https://www.mql5.com/es/code/61283
Registra los ticks en modo ticks reales y los lee en modo matemático llamando a su estrategia con cada tick registrado.
Motivo de creación: MQ tester, escribe ficheros de datos de ticks en cada agente cada vez que se ejecuta el optimizador. Tengo 36 agentes escribiendo 10GB cada uno para una de las herramientas y el periodo de prueba - un total de 360GB en un disco de 480GB. Este proceso dura aproximadamente 1 hora antes de cada optimización. Las unidades SSD típicas tienen una vida útil de 500-1000 ciclos de escritura. Al reescribir 360GB cada vez, el recurso se agotará muy rápidamente. Esta librería sólo escribe 1 archivo y luego los 36 agentes leerán los datos de este único archivo. Todo esto fue la razon para escribir la libreria: usamos solo 1 fichero + ahorro de 1 hora para escribir datos a cada agente + aceleracion en comparacion con MQ tester e incluso con Virtual en modo ticks reales.
El problema fue investigado simultaneamente con fxsaber (el autor de EAToMath), cada uno con su propia version. Mi código me resulta más claro, por eso lo utilizo.
Para las operaciones de trading se utiliza la librería MT4Orders https://www.mql5.com/es/code/16006
Para el trading virtual es necesario utilizar la librería Virtual https://www.mql5.com/es/code/22577
Para ver los resultados del trading se puede utilizar MT4Orders QuickReport https://www.mql5.com/es/code/47816 o Report
Para comprimir los ticks TickCompressorhttps://www.mql5.com/es/code/66201
Para eliminar los ticks posiblemente innecesarios se conecta la librería Control_Trade_Sessions https://www.mql5.com/es/code/48059, por ejemplo, si una sesión de cotización es mayor que una sesión de trading. También se puede eliminar si se utilizan todos los ticks, es decir, si las sesiones coinciden.
Diferencias con EAToMath:
Pros:
- El código es más corto y sencillo, sólo 5 librerías plug-in. Si necesitas modificarlo, será más fácil de entender.
- Los datos se comprimen mejor debido a un algoritmo diferente https://www.mql5.com/es/code/66201. Al guardar sólo time_msc, ask y bid - hasta el 86% de los ticks se guardan como números de 3 char, es decir, 3 bytes. Tamaño medio por tick = 3.266 Bytes al guardar los datos de tick de BTCUSDT para 2023.
Al guardar con volúmenes media = 4.835 Bytes. Y al guardar el tick completo = 8.439 Bytes. A continuación se muestra la tabla con los resultados de la prueba.
Además, puede utilizar el archivo ZIP incorporado. El tamaño del archivo se reduce 2 veces. Un archivo de este tipo ocupa 245 Mb, mientras que la suma de los tamaños de archivo en .tcs para 2023 ocupa 364 Mb, es decir, la compresión es 1,5 veces mejor que en MQ. Y la velocidad de generación de ticks en el modo matemático es ~2 veces más rápida. Véase la tabla siguiente. - Hay más opciones de guardado:

- El archivo se puede guardar en un disco SSD o RAM haciendo un enlace en el sistema. Los archivos pueden ocupar mucho espacio y el disco RAM puede no ser suficiente, por lo que puedes elegir guardar en el disco principal. Las velocidades de lectura de SSD y RAM son más o menos las mismas, he leído que el SSD almacena en caché hasta un 5% de la capacidad total de los datos solicitados con más frecuencia.
Hay un poco de desgaste en el SSD cuando se lee, ya que hay que sobrescribir las celdas de memoria más a menudo que cuando se almacena sin leer. No conozco las cifras exactas, pero por ejemplo 1 sobreescritura cada 10 lecturas o cada 1000 lecturas.... Pero esto tiene poca importancia comparado con el desgaste del disco por el probador MQ.
Contras:
- Conectar Virtual tiene que hacerlo usted mismo (instrucciones aquí https://www.mql5.com/es/code/22577), EAToMath pasará su estrategia a Virtual por sí mismo.
La velocidad de la variante BidAsk es comparable a la de EAToMath. Otras variantes son más lentas porque contienen más datos o tienen compresión ZIP adicional.
Características de uso:
No puede utilizar las funciones estándar Symbol(), Digits( ) (=4), Point() (=0.0001) en la estrategia, ya que producirán valores por defecto, no relacionados con el símbolo bajo prueba. En su lugar, utilice _Symbol, _Digits, _Point que se anulan en los valores leídos desde el archivo. Además, se han añadido las nuevas constantes _TickSize y _TickValue con valores del símbolo registrado - son necesarias para el cálculo correcto del beneficio, comisión y swaps en la divisa de depósito.
El orden de trabajo con el período de prueba seleccionado al guardar los ticks:
- Seleccione el modo de prueba por ticks reales, el instrumento requerido y las fechas de prueba. Establezca la variable Tarea en Guardar y seleccione la opción de guardar ticks. Inicie el comprobador. Después se creará un fichero con los ticks en la carpeta especificada.
- Establezca la variable Tarea en Ejecutar_estrategia. Puede dejar el modo por ticks reales para comparar más tarde. Inicie el comprobador. Los cálculos se hacen por ticks reales, no desde el fichero. Obtenga el resultado.

- Ajuste el modo de prueba a cálculos matemáticos. Inicie el comprobador. Los cálculos se realizan por ticks a partir del fichero. Compare con el resultado del paso 2. Debería ser el mismo, pero varias veces más rápido.
El orden de trabajo con el archivo:
- Crear un archivo con todos los ticks del historial: Seleccionar el modo de testeo por ticks reales, el instrumento requerido. Establezca las fechas de las pruebas desde <= primer tick hasta >= último tick en el historial disponible. Configure la variable Tarea como Guardar...En_Archivo y seleccione la opción de guardar los ticks. Inicie el comprobador. Después se creará una carpeta con el nombre de la herramienta en la carpeta especificada donde se guardarán los archivos con los ticks de cada año. El último año puede sobrescribirse si es necesario, para ello seleccione sólo el año actual en las fechas para evitar sobrescribir los años anteriores.
- Establezca el modo de prueba en Matemáticas. Establezca la variable Tarea a Ejecutar_Estrategia_Fron_Archivo.
- En el MathTicker: utilizando el grupo de archivo completo, establezca:
Instrumento - a Nombre del instrumento (debe coincidir con el nombre de la carpeta donde se almacenan sus ticks), fecha de inicio y fin de la prueba.

- Inicie el comprobador. Los cálculos se realizan por ticks de los archivos anuales requeridos. Debido a que el trabajo no se realiza con un fichero, sino con varios, es un poco más lento, porque se tarda en abrir y cerrar ficheros. Por ejemplo, en lugar de 1,7 segundos se tardarán 2,7 segundos en generar los ticks de 3 años.
- La suma de ticks obtenida por el Asesor Experto a continuación puede diferir por un pequeño valor de un primer tick. Al probar en caracteres personalizados en modo de ticks reales, el primer tick produce sólo Ask o Bid (si no guardó ambos). Cuando se prueba desde archivo, ambos son restaurados desde ticks anteriores.
Un ejemplo del Asesor Experto más simple para estimar la velocidad de trabajo:
#property tester_no_cache #include <Forester\MathTicker.mqh> // conectar el comercio en modo matemático input int rep=0;//Repetir para optimizar sinput bool AddVolumes=true; void OnInit(){} void OnTick(){ static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//si guardamos los ticks, entonces salimos y no operamos. #endif Strategy(Tick); } } double Sum = 0;int tk=0; void Strategy(MqlTick& Tick){ // la estrategia más simple - utilizada para comparar la velocidad de lectura con EAToMath Sum += Tick.bid+Tick.ask+(AddVolumes?Tick.volume_real:0.0); tk++; //if(tk<100){Print(Tick.time," " ",Tick.ask," ",Tick.bid," ",Tick.last," ",Tick.volume_real," ",Tick.flags);} } ulong StartTime = GetMicrosecondCount(); double OnTester(){ #ifdef _MathTick_ // ejecutar con MathTick - cuenta los parámetros de símbolos del archivo con ticks. Para pruebas en modo mat if(MathTick.SaveTicksEnd()){return 0;}// cerrar el archivo después de grabar los ticks y salir if(MathTick.ReadSymbolVars()){ MathTick.Ticker();// en modo mat alimentará todos los ticks a Strategy(MqlTick &Tick). } #endif Print("ticks: ",tk); long work_time = (long)(GetMicrosecondCount() - StartTime)/1000; //return(NormalizeDouble(tiempo_trabajo, 1)); // para obtener la velocidad de trabajo y return Sum;// para comparar los resultados de los cálculos }
Puede alternar 1 ajuste:
//#define RestoreFlags // восстановить флаги тика из изменения ask, bid, volume - добавит 7% к времени генерации тиков 931 вместо 869 мс
Al generar ticks, se mostrarán estadísticas sobre la compresión de ticks.
A continuación se muestran impresiones de estadísticas, volúmenes y tiempo de generación de ticks.
-----------
MQtester sin volúmenes
pass 1 resultado devuelto 4345830621850.311523 en 0:00:08.232
| Compresión C ZIP | |
|---|---|
| AskBid. Tamaño del fichero: 225 mb -------------------- Estadísticas: -------------------- 3 bytes: 86.6%, 62644158 ticks 4 bytes: 0.6%, 412167 ticks 5 bytes: 12.7%, 9185484 ticks 6 bytes: 0.0%, 15274 ticks 11 bytes: 0.1%, 46214 ticks 12 bytes: 0.0%, 1 ticks 24 bytes: 0.0%, 1 ticks Total: 72303299 ticks, 236108596 bytes. Promedio: 3.266 bytes por tick saldo final 0.00 USD pass 10 resultado devuelto 4345830621850.311523 en 0: 00:01.485 sin normalización pass 1 resultado devuelto 4345830621850.311523 en 0:00:00.892 | AskBid_Zipped. Tamaño del archivo: 106 mb -------------------- Estadísticas: -------------------- 3 bytes: 86,6%, 62644158 ticks 4 bytes: 0,6%, 412167 ticks 5 bytes: 12,7%, 9185484 ticks 6 bytes: 0.0%, 15274 ticks 11 bytes: 0,1%, 46214 ticks 12 bytes: 0,0%, 1 ticks 24 bytes: 0,0%, 1 ticks Total: 72303299 ticks, 236108596 bytes. Media: 3,266 bytes por tick Tamaño sin comprimir:236108596. Tamaño comprimido:111720863. Compresión ZIP: 47,3% paso 10 resultado devuelto 4345830621850.311523 en 0:00:02.548 sin normalización paso 2 resultado devuelto 4345830621850.311523 en 0:00:01.890 |
MQ tester con volúmenes
pass 1 devuelve el resultado 4345879117123.356445 en 0:00:07.962
| Compresión C ZIP | |
|---|---|
| AskBidVolume. Tamaño del archivo: 333 mb -------------------- Estadísticas: -------------------- 4 bytes: 60,4%, 43684907 ticks 5 bytes: 1,1%, 809676 ticks 6 bytes: 33.5%, 24194111 ticks 7 bytes: 4.9%, 3548666 ticks 8 bytes: 0.0%, 7909 ticks 12 bytes: 0.1%, 40022 ticks 13 bytes: 0.0%, 17964 ticks 14 bytes: 0.0%, 2 ticks 19 bytes: 0.0%, 41 ticks 32 bytes: 0.0%, 1 ticks Total: 72303299 ticks, 349571243 bytes. Media: 4.835 bytes por tick pass 1 resultado devuelto 4345879117123.356445 en 0:00:02.803 sin normalización pass 4 resultado devuelto 4345879117123.356445 en 0:00:01.659 | AskBidVolume_Zipped. Tamaño del archivo: 204 mb -------------------- Estadísticas: -------------------- 4 bytes: 60,4%, 43684907 ticks 5 bytes: 1,1%, 809676 ticks 6 bytes: 33,5%, 24194111 ticks 7 bytes: 4,9%, 3548666 ticks 8 bytes: 0.0%, 7909 ticks 12 bytes: 0,1%, 40022 ticks 13 bytes: 0,0%, 17964 ticks 14 bytes: 0,0%, 2 ticks 19 bytes: 0,0%, 41 ticks 32 bytes: 0,0%, 1 ticks Total: 72303299 ticks, 349571243 bytes. Media: 4,835 bytes por tick Tamaño sin comprimir:349571243. Tamaño comprimido:214897079. Compresión ZIP: 61,5% pase 2 resultado devuelto 4345879117123.356445 en 0:00:04.260 sin normalización pase 2 resultado devuelto 4345879117123.356445 en 0:00:03.096 |
| Todo. Tamaño del archivo: 582 mb -------------------- Estadísticas: -------------------- 8 bytes: 61,5%, 44494583 ticks 9 bytes: 33,5%, 24194111 ticks 10 bytes: 4,9%, 3548666 ticks 11 bytes: 0,0%, 7909 ticks 15 bytes: 0,1%, 40022 ticks 16 bytes: 0,0%, 17964 ticks 17 bytes: 0.0%, 2 ticks 22 bytes: 0.0%, 41 ticks 44 bytes: 0.0%, 1 ticks Total: 72303299 ticks, 610166056 bytes. Promedio: 8.439 bytes por tick pase 2 resultado devuelto 4345879117123.356445 en 0:00:03.768 sin normalización pase 1 resultado devuelto 4345879117123.356445 en 0:00:02.256 | Todo_comprimido. Tamaño del archivo: 245 mb -------------------- Estadísticas: -------------------- 8 bytes: 61,5%, 44494583 ticks 9 bytes: 33,5%, 24194111 ticks 10 bytes: 4,9%, 3548666 ticks 11 bytes: 0,0%, 7909 ticks 15 bytes: 0.1%, 40022 ticks 16 bytes: 0,0%, 17964 ticks 17 bytes: 0,0%, 2 ticks 22 bytes: 0,0%, 41 ticks 44 bytes: 0,0%, 1 ticks Total: 72303299 ticks, 610166056 bytes. Media: 8,439 bytes por tick Tamaño sin comprimir:610166056. Tamaño comprimido:257105213. Compresión ZIP: 42,1 % pass 1 resultado devuelto 4345879117123.356445 en 0:00:05.388 sin normalización pass 10 resultado devuelto 4345879117123.356445 en 0:00:03.936 |
El tamaño de los archivos .tcs para el mismo año 2023:

Todas las variantes con ZIP, incluso el guardado de tick completo son más compactas (de 3,5 a 1,5 veces).
Expert Advisor ejemplo para el comercio virtual y la salida de informes:
#property tester_no_cache #include <MT4Orders.mqh> // https://www.mql5.com/es/code/16006 #include <Forester\MathTicker.mqh> // conectar el comercio en modo matemático #define ORDER_CURRENCY_DIGITS 2 // Ajuste de dígitos para calcular el beneficio/comisión/intercambio cuando se coloca en el historial de operaciones. #define VIRTUAL_LIMITS_TP_SLIPPAGE // Los limitadores y los TP se ejecutan al primer precio de aceptación - deslizamientos positivos #define ORDER_COMMISSION -0 // Asignación de comisión = Lotes * ORDER_COMMISSION. #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/es/code/22577 #define REPORT_TESTER // El comprobador registrará automáticamente los informes #define REPORT_BROWSER // Crear un informe con el inicio del navegador - requiere permiso DLL. #define USE_highcharts //- Puede descargar y probar gratuitamente todos los productos Highcharts. Una vez que su proyecto/producto esté listo para su lanzamiento, adquiera una licencia comercial. https://shop.highcharts.com/ #include <MT4Orders_QuickReport.mqh>// enum VirtTyp {MQ_Tester=0,Virtual1=1,Virtual2=2}; sinput VirtTyp tester1=1;//Prueba 1 sinput VirtTyp tester2=2;//Prueba 2 input int rep=0;//Repetir para optimizar bool isOptimization = false, isTester=false; double balInit=0; VIRTUAL_POINTER Virtual[10]; void OnInit(){ Virtual[0] = 0; // 0 - entorno comercial real Virtual[1] = VIRTUAL::Create(AccountBalance()); // Virtualización creada 1. Virtual[2] = VIRTUAL::Create(AccountBalance()); // Virtualización creada 2. //Virtual[tester1].Select(); isOptimization = MQLInfoInteger(MQL_OPTIMIZATION) ; isTester = MQLInfoInteger(MQL_TESTER); balInit=AccountBalance(); } void OnTick(){ //Virtual[0].Select(); VIRTUAL::NewTick();// enviar el tick a la máquina virtual actual static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//cuando la escritura de ticks salga de la función, no se llamará a Strategy() #endif Strategy(Tick);//comercio } } void Strategy(MqlTick& Tick){ // la estrategia más simple - utilizada para comparar la velocidad de lectura con EAToMath if(Tick.ask==0 || Tick.bid==0){return;}//MQ tester opera en un tick fallido, Virtual no. Prohibición también para MQ if(tester1>0){Virtual[tester1].Select(); VIRTUAL::NewTick(Tick);}//seleccionar virtualización 1 y enviar un tick if(tester2>0){Virtual[tester2].Select(); VIRTUAL::NewTick(Tick);}//seleccionar virtualización 2 y enviar un tick if(isNewHour(Tick.time)){//el primer tick de cada hora if(GetHour0(Tick.time) % 2==0){// comprar a horas pares en probador 1 Virtual[tester1].Select();//seleccionar virtualización 1 OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, Tick.ask - 100 * _Point, Tick.ask + 100 * _Point); }else{//vender a horas impares en probador 2 Virtual[tester2].Select();//seleccionar virtualización 2 OrderSend(_Symbol, OP_SELL, 1, Tick.bid, 0, Tick.bid + 100 * _Point, Tick.bid - 100 * _Point); } } } double OnTester(){ #ifdef _MathTick_ // ejecutar con MathTick - leerá los parámetros del símbolo desde el archivo tick. Para pruebas en modo mat if(MathTick.SaveTicksEnd()){return 0;}//volver después de guardar los ticks if(MathTick.isMath && MathTick.ReadSymbolVars()){ if(tester1==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} if(tester2==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickSize=_TickSize; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_; //como en SetSymbol() en \fxsaber\Virtual\Symbol_Base.mqh Virtual[1].Select(); VIRTUAL::SetSymbolBase(sb); Virtual[2].Select(); VIRTUAL::SetSymbolBase(sb); //minFreezeLevel = _minFreezeLevel*_Point; minStopLevel = _minStopLevel*_Point; Virtual[tester1].Select(); MathTick.Ticker();// en modo mat alimentará todos los ticks a Strategy(MqlTick &Tick). } #endif double ret_val=0; for (int v = 0 ; v <= VIRTUAL::Total(); v++){ if(Virtual[v].Select()){ if(v > 0){ VIRTUAL::Stop(); #ifdef _MathTick_ // ejecutar con MathTick - leerá los parámetros del símbolo desde el archivo tick. Para pruebas en modo mat if(MathTick.isMath){ VIRTUAL::CalcSwaps( MathTick.swapShort, MathTick.swapLong, 0, MathTick.swap3days ); }//intercambios desde el archivo tick else{VIRTUAL::CalcSwaps( _Symbol, 0 );} #else VIRTUAL::CalcSwaps( _Symbol, 0 );//calcular swaps - todas las operaciones tienen un swap, es decir, si hay más de 2 instrumentos diferentes, ambos tendrán el swap del símbolo principal. #endif }// cerrar las operaciones incompletas al precio del último tick, como en el probador if( !isOptimization){QuickReport("report_"+(string)v, true, v,false,true);} Print((string)v+" AccountBalance = ",AccountBalance(), " AccountEquity = ",AccountEquity()); double prib=AccountBalance()-balInit; ret_val += prib; // }} return ret_val;// para comparar los resultados de los cálculos } bool isNewHour (datetime &t){ static int next_h=-1; if(t < next_h){ return false; } else { next_h = (GetHour0(t)+1)*3600;return true;}} int GetHour0 (datetime &t){return((int)( t / 3600));}//hora actual a partir del 1 de enero de 1971
Este ejemplo crea 2 máquinas virtuales con diferentes operaciones. En las horas pares un probador está comprando, el otro está vendiendo en las horas impares.
Es un ejemplo complejo con 2 probadores, se puede simplificar si necesita trabajar con un probador.
También puede seleccionar el probador MQ y compararlo con los resultados de los probadores virtuales para controlar la corrección de los cálculos. Sólo la comisión puede no coincidir, porque hay muchas comisiones diferentes, y sólo una variante está programada en el probador virtual.
Traducción del ruso realizada por MetaQuotes Ltd
Artículo original: https://www.mql5.com/ru/code/65821
Función para calcular el tamaño del lote a partir del riesgo por depósito
La función calcula el tamaño de lote de una posición abierta. Se pasan como parámetros el precio de apertura de una operación, el precio del nivel de stop loss y el riesgo por operación en porcentaje del depósito
ATR Cycles
Un filtro de volatilidad basado en 3 ATR: un ATR rápido, un ATR medio y un ATR lento.
SAR ADX Signal
Señal SAR ADX con notificación móvil, reescrito de la versión MT4 (fuente ya no se encuentra). Este es un indicador repintable, por favor tenga cuidado al usarlo.
Velas de color del Momento Estocástico
Idea de Andrey F. Zelinsky, basada en un indicador de William Blau