Estimados desarrolladores, ¿podrían informarme de cómo se calcula MQL_MEMORY_USED?
He hecho un cálculo de la memoria que ocupan todas las variables de EA.
Es menos del 10%. Si he entendido bien, MQL_MEMORY_USED incluye la caché del historial y la caché de CopyTicks. Pero sigue siendo mucho menos.
Al mismo tiempo, el Asesor Experto paralelo consume varias veces menos. Pero el principio es el mismo.
En general, ¿qué se incluye a este valor?
He guardado una plantilla con Expert Advisor y la he aplicado al mismo gráfico provocando la recarga. Lo he visto así.
El uso de la memoria ha cambiado en casi un orden de magnitud. Hasta ahora, es difícil explicar lo que significa.
Muchos programas tienen un efecto acumulativo de uso de memoria. Esto es un pecado de los navegadores y a veces incluso de Word. La Terminal también puede ser culpable de ello. Además, todos los registros se escriben por defecto y es fácil pasar una semana si tienes demasiadas acciones en un giga. Es un mal que hay que gestionar. Pero no está claro cómo.
4gb (precio de 20 euros) no es bueno en 2020 cuando se trata de análisis e investigación.
Para los productos de mercado, este enfoque no es bueno en ninguna parte. Tenemos que evitar la retención de 10 segundos de datos innecesarios a través de dicha muleta.
Hacer un producto de mercado trivial en forma de un Market Screener no es realmente una tarea alcanzable para MT5 debido al excesivo consumo de memoria.
Hacer un producto de mercado trivial en forma de Market Screener no es realmente una tarea alcanzable para la MT5 debido al excesivo consumo de memoria.
El terminal come mucha memoria después del lanzamiento.
Después de la ejecución del screener empezó a comer 2 gigas (TERMINAL_MEMORY_USED y no disminuyó con el tiempo). Esto es con un solo gráfico abierto para 5000 barras M1.
No se ha guardado una captura de pantalla. Pero decidió lanzar un ejemplo, que muestra la memoria comer Terminal no en sí mismo, donde es simplemente estúpido.
// Создание копий оригинальных символов из Обзора рынка в виде пользовательских.#property script_show_inputsinputdatetime inStartTime = D'2020.06.01'; // С какого времени закачивать тикиvoidOnStart()
{
for (int i = SymbolsTotal(true) - 1; !IsStopped() && (i >= 0); i--)
{
conststring Symb = SymbolName(i, true);
if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM)) // Если символ не кастомный.
{
Alert(Symb + " - Start.");
MqlTick Ticks[];
if (CopyTicksRange(Symb, Ticks, COPY_TICKS_ALL, (long)inStartTime * 1000) > 0) // Взяли с него тики.
{
conststring CustomSymb = "CUSTOM_" + Symb;
if (SymbolInfoInteger(CustomSymb, SYMBOL_EXIST) || CustomSymbolCreate(CustomSymb, AccountInfoString(ACCOUNT_SERVER), Symb)) // Содали кастомный.
{
Alert((string)i + ": " + Symb + " - " + (string)CustomTicksReplace(CustomSymb, 0, LONG_MAX, Ticks)); // Поместили в него тики.SymbolSelect(CustomSymb, true);
}
}
}
}
}
El script sólo hace copias de los símbolos originales del Market Watch. Se supone que debo añadir todos los símbolos en MQ-Demo y ejecutar este script primero en frío y luego en caliente.
Y después de la ejecución en caliente (cuando los ticks ya están en SSD en forma de archivos tkc) observaré un enorme agotamiento de la memoria donde no es necesario en una implementación adecuada.
Sin embargo, al ejecutar el script, me he encontrado con que se cuelga en MQ-Demo. Sólo puede descargarse a través de la terminación anormal, tras la cual el Terminal no libera más de 1 GB de memoria.
Es fácil comparar esta captura de pantalla con la del principio.
Lo siento, no estoy seguro de si esto es un error o una característica. No he encontrado una respuesta por mi cuenta. Pero la pregunta está relacionada con el rendimiento y supongo que es mejor hacerla aquí.
Si añadimos, por ejemplo, 22 búferes de tipo DRAW_SECTION a un indicador vacío, entonces al inicio de dicho indicador para un gráfico que contenga 1000000 barras o más, el terminal se retrasa significativamente (provoca una carga importante de la CPU) y consume cantidades significativas de memoria, incluso si el indicador no calcula nada.
Mi interés se ha despertado por el hecho de que si se utilizan buffers con otros tipos, todo funciona sin problemas y no se observa esa ralentización.
Por ejemplo, he ejecutado el siguiente código en un solo gráfico con 1000000 barras y ha consumido unos 500 MBytes y se retrasa, sobre todo el propio gráfico.
Pero si cambio el tipo de búfer a, por ejemplo, DRAW_LINE, la carga del procesador se reduce drásticamente, no se observan retrasos y la memoria consume 5 veces menos (unos 100 MBytes consumidos).
Un ciudadano particular sacó de sus amplios pantalonesun duplicado de una carga inestimable de código MQL, que demostró que en las mismas condiciones la muleta funcionaba más rápido que la función normal.
Una prueba muy sencilla:
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnTick()
{
TestSymbolInfoTick();
TestPositionSelectByTicket();
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void TestSymbolInfoTick()
{
MqlTick Tick;
//---ulong start,end,max_time=0,avr_time=0,counter=0;
int count=100000;
for(int i=0; i<count; i++)
{
start=GetMicrosecondCount();
SymbolInfoTick(_Symbol, Tick);
end=GetMicrosecondCount()-start;
//---if(end>max_time)
max_time=end;
if(end>100)
{
avr_time+=end;
counter++;
}
}
Print("SymbolInfoTick max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void TestPositionSelectByTicket()
{
//---ulong start,end,max_time=0,avr_time=0,counter=0;
int count=100000;
for(int i=0; i<count; i++)
{
start=GetMicrosecondCount();
GetBid();
end=GetMicrosecondCount()-start;
//---if(end>max_time)
max_time=end;
if(end>100)
{
avr_time+=end;
counter++;
}
}
Print("GetBid max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
}
20 Asesores Expertos en EURUSD, es decir, todos los procesos OnTick simultáneamente. La construcción de la terminal es 2664. La prueba se ejecuta sin optimización, compilación y otra carga adicional al 100% de la CPU - no vas a ejecutar un comercio real "hft" en este fondo, ¿verdad?
Típico registro de pruebas:
2020.10.2911:10:49.133SymbolInfoTick (EURUSD,M15) GetBid max bad time: 28.004 ms; avr bad time: 0.393 ms; bad iterations: 1569 total iterations: 1000002020.10.2911:10:49.136SymbolInfoTick (EURUSD,H1) GetBid max bad time: 4.795 ms; avr bad time: 0.361 ms; bad iterations: 1783 total iterations: 1000002020.10.2911:10:49.137SymbolInfoTick (EURUSD,M15) GetBid max bad time: 25.367 ms; avr bad time: 0.425 ms; bad iterations: 1496 total iterations: 1000002020.10.2911:10:49.138SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.681 ms; avr bad time: 0.352 ms; bad iterations: 1804 total iterations: 1000002020.10.2911:10:49.139SymbolInfoTick (EURUSD,M15) GetBid max bad time: 4.264 ms; avr bad time: 0.370 ms; bad iterations: 1734 total iterations: 1000002020.10.2911:10:49.142SymbolInfoTick (EURUSD,H1) GetBid max bad time: 7.049 ms; avr bad time: 0.362 ms; bad iterations: 1803 total iterations: 1000002020.10.2911:10:49.142SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.376 ms; avr bad time: 0.365 ms; bad iterations: 1754 total iterations: 1000002020.10.2911:10:49.144SymbolInfoTick (EURUSD,H1) GetBid max bad time: 18.048 ms; avr bad time: 0.417 ms; bad iterations: 1516 total iterations: 1000002020.10.2911:10:49.144SymbolInfoTick (EURUSD,M15) GetBid max bad time: 21.280 ms; avr bad time: 0.372 ms; bad iterations: 1769 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.631 ms; avr bad time: 0.143 ms; bad iterations: 205 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.517 ms; avr bad time: 0.134 ms; bad iterations: 170 total iterations: 1000002020.10.2911:10:53.837SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.483 ms; avr bad time: 0.144 ms; bad iterations: 178 total iterations: 1000002020.10.2911:10:53.838SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.517 ms; avr bad time: 0.147 ms; bad iterations: 182 total iterations: 1000002020.10.2911:10:53.844SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.582 ms; avr bad time: 0.134 ms; bad iterations: 165 total iterations: 1000002020.10.2911:10:53.845SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.518 ms; avr bad time: 0.137 ms; bad iterations: 195 total iterations: 1000002020.10.2911:10:53.845SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.530 ms; avr bad time: 0.139 ms; bad iterations: 160 total iterations: 1000002020.10.2911:10:53.846SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.575 ms; avr bad time: 0.138 ms; bad iterations: 143 total iterations: 1000002020.10.2911:10:53.848SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.593 ms; avr bad time: 0.143 ms; bad iterations: 206 total iterations: 1000002020.10.2911:10:53.849SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.446 ms; avr bad time: 0.138 ms; bad iterations: 147 total iterations: 1000002020.10.2911:10:53.850SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.661 ms; avr bad time: 0.146 ms; bad iterations: 191 total iterations: 1000002020.10.2911:10:53.850SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.471 ms; avr bad time: 0.141 ms; bad iterations: 219 total iterations: 1000002020.10.2911:10:53.851SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.442 ms; avr bad time: 0.137 ms; bad iterations: 198 total iterations: 1000002020.10.2911:10:53.851SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.574 ms; avr bad time: 0.140 ms; bad iterations: 215 total iterations: 1000002020.10.2911:10:53.853SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.507 ms; avr bad time: 0.140 ms; bad iterations: 222 total iterations: 1000002020.10.2911:10:53.857SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 0.776 ms; avr bad time: 0.165 ms; bad iterations: 341 total iterations: 1000002020.10.2911:10:53.858SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.568 ms; avr bad time: 0.156 ms; bad iterations: 381 total iterations: 1000002020.10.2911:10:53.860SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.896 ms; avr bad time: 0.164 ms; bad iterations: 293 total iterations: 1000002020.10.2911:10:53.861SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 6.124 ms; avr bad time: 0.178 ms; bad iterations: 219 total iterations: 1000002020.10.2911:10:53.862SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 0.794 ms; avr bad time: 0.164 ms; bad iterations: 356 total iterations: 1000002020.10.2911:10:54.686SymbolInfoTick (EURUSD,M15) GetBid max bad time: 4.870 ms; avr bad time: 0.339 ms; bad iterations: 1575 total iterations: 1000002020.10.2911:10:54.728SymbolInfoTick (EURUSD,M15) GetBid max bad time: 6.442 ms; avr bad time: 0.343 ms; bad iterations: 1691 total iterations: 1000002020.10.2911:10:54.732SymbolInfoTick (EURUSD,M15) GetBid max bad time: 7.568 ms; avr bad time: 0.349 ms; bad iterations: 1671 total iterations: 1000002020.10.2911:10:54.755SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.354 ms; avr bad time: 0.365 ms; bad iterations: 1634 total iterations: 1000002020.10.2911:10:54.773SymbolInfoTick (EURUSD,M15) GetBid max bad time: 9.385 ms; avr bad time: 0.352 ms; bad iterations: 1734 total iterations: 1000002020.10.2911:10:54.778SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.526 ms; avr bad time: 0.342 ms; bad iterations: 1748 total iterations: 1000002020.10.2911:10:54.785SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.195 ms; avr bad time: 0.356 ms; bad iterations: 1708 total iterations: 1000002020.10.2911:10:54.790SymbolInfoTick (EURUSD,H1) GetBid max bad time: 5.180 ms; avr bad time: 0.347 ms; bad iterations: 1796 total iterations: 100000
20 EAs en EURUSD, es decir, todos los procesos OnTick al mismo tiempo. Terminal build 2664. La prueba se ejecuta sin optimización, compilación y otra carga de trabajo adicional en el 100% de la CPU - no vas a ejecutar un comercio real "hft" en este fondo, ¿verdad?
Típico registro de pruebas:
Se crean condiciones de invernadero haciendo 100K iteraciones durante 1,5 segundos en el mismo tick. Yo, en cambio, esperé a propósito los ticks que no generaron un OnTick.
Mirando mis registros de operaciones, me doy cuenta de la ejecución de SymbolInfoTick en unos pocos milisegundos. Y sé al 100% que la CPU estaba a pleno rendimiento en ese momento.
Es muy sencillo. Hay condicionalmente 1 millón de garrapatas al día. Incluso un 0,01% de ralentización de los ticks son 100 ticks al día con retrasos. Dirás que eso es una tontería. Diré que es malo. Si me encuentro con un retraso cuando tengo que hacer un pedido, es una pérdida monetaria potencial.
Se agradece mucho que esta rama no pase desapercibida, y en esta característica en particular, se ha trabajado mucho para agilizar las cosas. Sin embargo, me sorprendió un poco que la horrible muleta pudiera superar a la función normal en ciertas situaciones. Y tal vez si se ordenara y eliminara ese desfase, 100 desfases potenciales al día se convertirían en 10.
Yo digo que está mucho mejor que al principio del hilo. Pero el hecho es que hay veces que no es bueno. Y veo que no quieres investigarlo. Respeto su elección.
Arriba se citó la opción de la instantánea para obtener los precios actuales. Me convendría completamente si no cogiera lapsos de milisegundos en la máquina Idle-CPU.
También me preocupa no sólo la velocidad de SymbolInfoTick, sino también la relevancia de los precios que devuelve. Veo que no se plantea esta cuestión. Al parecer, decidiste mirarlo más tarde.
Se crean condiciones de invernadero haciendo 100K iteraciones en 1,5 segundos en el mismo tick. Yo, en cambio, esperé específicamente a los ticks que no generaban OnTick.
Al revisar mis registros de operaciones, observo que SymbolInfoTick se ejecuta durante unos pocos milisegundos. Sé al 100% que la CPU estaba en reposo en ese momento.
Es muy sencillo. En un día hay condicionalmente 1 millón de garrapatas. Incluso un desfase del 0,01% son 100 ticks al día con desfases. Dirás que eso es una tontería. Diré que es malo. Si me encuentro con un retraso cuando tengo que hacer un pedido, es una pérdida monetaria potencial.
Se agradece mucho que esta rama no pase desapercibida, y en esta característica en particular, se ha trabajado mucho para agilizar las cosas. Sin embargo, me sorprendió un poco que la horrible muleta pudiera superar a la función normal en ciertas situaciones. Y tal vez si se ordenara y eliminara ese desfase, 100 desfases potenciales al día se convertirían en 10.
Yo digo que está mucho mejor que al principio del hilo. Pero el hecho es que hay veces que no es bueno. Y veo que no quieres investigarlo. Respeto su elección.
Arriba se citó la opción de la instantánea para obtener los precios actuales. Me convendría completamente si no cogiera lapsos de milisegundos en la máquina Idle-CPU.
También me preocupa no sólo la velocidad de SymbolInfoTick, sino también la relevancia de los precios que devuelve. Veo que no se plantea esta cuestión. Al parecer, decidiste mirarlo más tarde.
Estas no son condiciones cálidas en absoluto. Un bucle para 100000 peticiones de precio sin Sleep() y similares y en 20 hilos simultáneamente es una prueba de estrés evidente. Nada de eso debería estar siquiera cerca en condiciones reales.
Si crees que no hay más ticks en 1,5 segundos - vale, haz 10 millones de consultas, no cambiará nada, tu "muleta" funciona peor:
NG 010:26:22.903SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 2.223 ms; avr bad time: 0.146 ms; bad iterations: 22369 total iterations: 10000000
OK 010:26:22.934SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 1.759 ms; avr bad time: 0.144 ms; bad iterations: 22462 total iterations: 10000000
KO 010:26:22.944SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 4.587 ms; avr bad time: 0.145 ms; bad iterations: 22620 total iterations: 10000000
RS 010:26:23.443SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 8.433 ms; avr bad time: 0.162 ms; bad iterations: 36242 total iterations: 10000000
LG 010:26:23.487SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 9.660 ms; avr bad time: 0.163 ms; bad iterations: 36378 total iterations: 10000000
KH 010:26:23.492SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 8.433 ms; avr bad time: 0.163 ms; bad iterations: 36208 total iterations: 10000000
HK 010:26:23.505SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 14.355 ms; avr bad time: 0.164 ms; bad iterations: 36292 total iterations: 10000000
QN 010:27:26.728SymbolInfoTick (EURUSD,M15) GetBid max bad time: 18.589 ms; avr bad time: 0.373 ms; bad iterations: 122026 total iterations: 10000000
HQ 010:27:27.042SymbolInfoTick (EURUSD,H1) GetBid max bad time: 15.544 ms; avr bad time: 0.371 ms; bad iterations: 123026 total iterations: 10000000
RD 010:27:29.190SymbolInfoTick (EURUSD,H1) GetBid max bad time: 16.207 ms; avr bad time: 0.370 ms; bad iterations: 127228 total iterations: 10000000
QJ 010:27:32.661SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 7.465 ms; avr bad time: 0.495 ms; bad iterations: 994 total iterations: 10000000
CL 010:27:32.799SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 16.999 ms; avr bad time: 0.585 ms; bad iterations: 1081 total iterations: 10000000
EP 010:27:33.056SymbolInfoTick (EURUSD,H1) SymbolInfoTick max bad time: 11.774 ms; avr bad time: 0.515 ms; bad iterations: 1122 total iterations: 10000000
EE 010:27:33.555SymbolInfoTick (EURUSD,M15) GetBid max bad time: 17.385 ms; avr bad time: 0.368 ms; bad iterations: 134761 total iterations: 10000000
FG 010:27:35.581SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 10.428 ms; avr bad time: 0.502 ms; bad iterations: 373 total iterations: 10000000
CJ 010:27:46.372SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.278 ms; avr bad time: 0.360 ms; bad iterations: 153668 total iterations: 10000000
QO 010:27:46.819SymbolInfoTick (EURUSD,M15) GetBid max bad time: 12.494 ms; avr bad time: 0.361 ms; bad iterations: 154170 total iterations: 10000000
KP 010:27:46.897SymbolInfoTick (EURUSD,M15) GetBid max bad time: 17.176 ms; avr bad time: 0.362 ms; bad iterations: 154258 total iterations: 10000000
PE 010:27:47.560SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.090 ms; avr bad time: 0.362 ms; bad iterations: 156325 total iterations: 10000000
LF 010:27:47.946SymbolInfoTick (EURUSD,M15) GetBid max bad time: 16.794 ms; avr bad time: 0.367 ms; bad iterations: 160557 total iterations: 10000000
IH 010:27:47.970SymbolInfoTick (EURUSD,H1) GetBid max bad time: 11.241 ms; avr bad time: 0.366 ms; bad iterations: 160307 total iterations: 10000000
KN 010:27:51.026SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 4.961 ms; avr bad time: 0.333 ms; bad iterations: 687 total iterations: 10000000
FP 010:27:51.517SymbolInfoTick (EURUSD,M15) GetBid max bad time: 19.844 ms; avr bad time: 0.372 ms; bad iterations: 165266 total iterations: 10000000
LE 010:27:51.574SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.435 ms; avr bad time: 0.371 ms; bad iterations: 165785 total iterations: 10000000
QE 010:27:51.686SymbolInfoTick (EURUSD,H1) GetBid max bad time: 13.601 ms; avr bad time: 0.371 ms; bad iterations: 166278 total iterations: 10000000
CK 010:27:52.204SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.480 ms; avr bad time: 0.374 ms; bad iterations: 161441 total iterations: 10000000
FL 010:27:52.262SymbolInfoTick (EURUSD,M15) GetBid max bad time: 19.503 ms; avr bad time: 0.374 ms; bad iterations: 161363 total iterations: 10000000
FQ 010:27:52.504SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.440 ms; avr bad time: 0.375 ms; bad iterations: 161927 total iterations: 10000000
KQ 010:27:52.507SymbolInfoTick (EURUSD,H1) GetBid max bad time: 20.155 ms; avr bad time: 0.375 ms; bad iterations: 161670 total iterations: 10000000
EG 010:27:52.558SymbolInfoTick (EURUSD,M15) GetBid max bad time: 15.634 ms; avr bad time: 0.371 ms; bad iterations: 167511 total iterations: 10000000
OK 010:27:52.751SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.698 ms; avr bad time: 0.368 ms; bad iterations: 168482 total iterations: 10000000
LL 010:27:53.941SymbolInfoTick (EURUSD,M15) GetBid max bad time: 16.659 ms; avr bad time: 0.364 ms; bad iterations: 171194 total iterations: 10000000
JP 010:27:58.244SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 12.019 ms; avr bad time: 0.308 ms; bad iterations: 970 total iterations: 10000000
OD 010:27:58.879SymbolInfoTick (EURUSD,M15) SymbolInfoTick max bad time: 7.972 ms; avr bad time: 0.299 ms; bad iterations: 1094 total iterations: 10000000
CE 010:28:06.402SymbolInfoTick (EURUSD,M15) GetBid max bad time: 14.140 ms; avr bad time: 0.342 ms; bad iterations: 56289 total iterations: 10000000
EK 010:28:06.860SymbolInfoTick (EURUSD,H1) GetBid max bad time: 14.013 ms; avr bad time: 0.344 ms; bad iterations: 56008 total iterations: 10000000
QL 010:28:06.922SymbolInfoTick (EURUSD,H1) GetBid max bad time: 11.626 ms; avr bad time: 0.343 ms; bad iterations: 56676 total iterations: 10000000
ER 010:28:07.010SymbolInfoTick (EURUSD,M15) GetBid max bad time: 13.021 ms; avr bad time: 0.340 ms; bad iterations: 51610 total iterations: 10000000
ER 010:28:08.708SymbolInfoTick (EURUSD,M15) GetBid max bad time: 2.970 ms; avr bad time: 0.317 ms; bad iterations: 24083 total iterations: 10000000
Esta su afirmación es 100% falsa:
Просматривая логи своей торговли, замечаю исполнение SymbolInfoTick в течение нескольких миллисекунд. При этом на 100% знаю, что в этот момент был полный Idle CPU.
Al igual que esta declaración anterior suya:
Уверен, что могу доказать, что получение текущих цен у Вас реализовано очень медленно. И CPU-нагрузка создает такие тормоза только из-за неправильной реализации Вами самой главной функции в MQL5.
El acceso a los precios a través de SymbolInfoTick es ahora muy rápido y está completamente desacoplado del procesamiento del flujo de ticks. Se trabaja con un caché de precios ya hecho, que se actualiza muy poco y rápidamente.
Todas las "ralentizaciones del 0,01% de la tasa de tick" sólo aparecen en condiciones de prueba de estrés, y eso es un gran resultado. En condiciones normales, se garantiza que el acceso sea muy rápido.
Si admite que "se ha trabajado mucho para agilizar" SymbolInfoTick, entonces debería creerme que la "muleta" de obtener los precios mediante PositionSelectByTicket no puede ser una solución mejor.
Por una simple razón - la implementación de PositionSelectByTicket es completamente idéntica a la implementación original "lenta" de SymbolInfoTick.
Como escribí anteriormente, esta implementación no es lenta en el sentido literal de la palabra, pero bajo una fuerte carga de la CPU, tiene una mayor probabilidad de que se produzcan valores atípicos en tiempo de ejecución (lo que es claramente visible en mi última prueba).
Los tiempos aquí dependen en gran medida del programador de tareas del sistema que se ejecuta bajo carga, es decir, puede haber diferencias de un sistema operativo a otro e incluso de una versión a otra.
Y cuanto más pesada sea la carga, más se probará el rendimiento del programador de tareas, no del terminal.
Este es el final del tema del rendimiento de SymbolInfoTick.
Si sus expertos crean una carga al nivel de las pruebas de estrés sintéticas, entonces hay una solución: "el hierro debe coincidir con las tareas".
Estimados desarrolladores, ¿podrían informarme de cómo se calcula MQL_MEMORY_USED?
He hecho un cálculo de la memoria que ocupan todas las variables de EA.
Es menos del 10%. Si he entendido bien, MQL_MEMORY_USED incluye la caché del historial y la caché de CopyTicks. Pero sigue siendo mucho menos.
Al mismo tiempo, el Asesor Experto paralelo consume varias veces menos. Pero el principio es el mismo.
En general, ¿qué se incluye a este valor?
He guardado una plantilla con Expert Advisor y la he aplicado al mismo gráfico provocando la recarga. Lo he visto así.
El uso de la memoria ha cambiado en casi un orden de magnitud. Hasta ahora, es difícil explicar lo que significa.
Muchos programas tienen un efecto acumulativo de uso de memoria. Esto es un pecado de los navegadores y a veces incluso de Word. La Terminal también puede ser culpable de ello. Además, todos los registros se escriben por defecto y es fácil pasar una semana si tienes demasiadas acciones en un giga. Es un mal que hay que gestionar. Pero no está claro cómo.
¿Tal vez sepa cómo seleccionar mediante programación un instrumento financiero y no quedarse colgado durante mucho tiempo?
A través de un indicador
Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading
MT5 y Speed en acción
Renat Fatkhullin, 2020.10.14 04:15
Para el ticking masivo pon más memoria.
4gb (precio de 20 euros) no es bueno en 2020 cuando se trata de análisis e investigación.
Para los productos de mercado, este enfoque no es bueno en ninguna parte. Tenemos que evitar la retención de 10 segundos de datos innecesarios a través de dicha muleta.
Hacer un producto de mercado trivial en forma de un Market Screener no es realmente una tarea alcanzable para MT5 debido al excesivo consumo de memoria.
Hacer un producto de mercado trivial en forma de Market Screener no es realmente una tarea alcanzable para la MT5 debido al excesivo consumo de memoria.
El terminal come mucha memoria después del lanzamiento.
Después de la ejecución del screener empezó a comer 2 gigas (TERMINAL_MEMORY_USED y no disminuyó con el tiempo). Esto es con un solo gráfico abierto para 5000 barras M1.
No se ha guardado una captura de pantalla. Pero decidió lanzar un ejemplo, que muestra la memoria comer Terminal no en sí mismo, donde es simplemente estúpido.
El script sólo hace copias de los símbolos originales del Market Watch. Se supone que debo añadir todos los símbolos en MQ-Demo y ejecutar este script primero en frío y luego en caliente.
Y después de la ejecución en caliente (cuando los ticks ya están en SSD en forma de archivos tkc) observaré un enorme agotamiento de la memoria donde no es necesario en una implementación adecuada.
Sin embargo, al ejecutar el script, me he encontrado con que se cuelga en MQ-Demo. Sólo puede descargarse a través de la terminación anormal, tras la cual el Terminal no libera más de 1 GB de memoria.
Es fácil comparar esta captura de pantalla con la del principio.
Lo siento, no estoy seguro de si esto es un error o una característica. No he encontrado una respuesta por mi cuenta. Pero la pregunta está relacionada con el rendimiento y supongo que es mejor hacerla aquí.
Si añadimos, por ejemplo, 22 búferes de tipo DRAW_SECTION a un indicador vacío, entonces al inicio de dicho indicador para un gráfico que contenga 1000000 barras o más, el terminal se retrasa significativamente (provoca una carga importante de la CPU) y consume cantidades significativas de memoria, incluso si el indicador no calcula nada.
Mi interés se ha despertado por el hecho de que si se utilizan buffers con otros tipos, todo funciona sin problemas y no se observa esa ralentización.
Por ejemplo, he ejecutado el siguiente código en un solo gráfico con 1000000 barras y ha consumido unos 500 MBytes y se retrasa, sobre todo el propio gráfico.
Pero si cambio el tipo de búfer a, por ejemplo, DRAW_LINE, la carga del procesador se reduce drásticamente, no se observan retrasos y la memoria consume 5 veces menos (unos 100 MBytes consumidos).
Se hicieron pruebas similares en diferentes builds, hasta la de 2019 y la situación es la misma.
Un ciudadano particular sacó de sus amplios pantalonesun duplicado de una carga inestimable de código MQL, que demostró que en las mismas condiciones la muleta funcionaba más rápido que la función normal.
Una prueba muy sencilla:
20 Asesores Expertos en EURUSD, es decir, todos los procesos OnTick simultáneamente. La construcción de la terminal es 2664. La prueba se ejecuta sin optimización, compilación y otra carga adicional al 100% de la CPU - no vas a ejecutar un comercio real "hft" en este fondo, ¿verdad?
Típico registro de pruebas:
Una prueba muy sencilla:
20 EAs en EURUSD, es decir, todos los procesos OnTick al mismo tiempo. Terminal build 2664. La prueba se ejecuta sin optimización, compilación y otra carga de trabajo adicional en el 100% de la CPU - no vas a ejecutar un comercio real "hft" en este fondo, ¿verdad?
Típico registro de pruebas:
Se crean condiciones de invernadero haciendo 100K iteraciones durante 1,5 segundos en el mismo tick. Yo, en cambio, esperé a propósito los ticks que no generaron un OnTick.
Mirando mis registros de operaciones, me doy cuenta de la ejecución de SymbolInfoTick en unos pocos milisegundos. Y sé al 100% que la CPU estaba a pleno rendimiento en ese momento.
Es muy sencillo. Hay condicionalmente 1 millón de garrapatas al día. Incluso un 0,01% de ralentización de los ticks son 100 ticks al día con retrasos. Dirás que eso es una tontería. Diré que es malo. Si me encuentro con un retraso cuando tengo que hacer un pedido, es una pérdida monetaria potencial.
Se agradece mucho que esta rama no pase desapercibida, y en esta característica en particular, se ha trabajado mucho para agilizar las cosas. Sin embargo, me sorprendió un poco que la horrible muleta pudiera superar a la función normal en ciertas situaciones. Y tal vez si se ordenara y eliminara ese desfase, 100 desfases potenciales al día se convertirían en 10.
Yo digo que está mucho mejor que al principio del hilo. Pero el hecho es que hay veces que no es bueno. Y veo que no quieres investigarlo. Respeto su elección.
Arriba se citó la opción de la instantánea para obtener los precios actuales. Me convendría completamente si no cogiera lapsos de milisegundos en la máquina Idle-CPU.
También me preocupa no sólo la velocidad de SymbolInfoTick, sino también la relevancia de los precios que devuelve. Veo que no se plantea esta cuestión. Al parecer, decidiste mirarlo más tarde.
Se crean condiciones de invernadero haciendo 100K iteraciones en 1,5 segundos en el mismo tick. Yo, en cambio, esperé específicamente a los ticks que no generaban OnTick.
Al revisar mis registros de operaciones, observo que SymbolInfoTick se ejecuta durante unos pocos milisegundos. Sé al 100% que la CPU estaba en reposo en ese momento.Es muy sencillo. En un día hay condicionalmente 1 millón de garrapatas. Incluso un desfase del 0,01% son 100 ticks al día con desfases. Dirás que eso es una tontería. Diré que es malo. Si me encuentro con un retraso cuando tengo que hacer un pedido, es una pérdida monetaria potencial.
Se agradece mucho que esta rama no pase desapercibida, y en esta característica en particular, se ha trabajado mucho para agilizar las cosas. Sin embargo, me sorprendió un poco que la horrible muleta pudiera superar a la función normal en ciertas situaciones. Y tal vez si se ordenara y eliminara ese desfase, 100 desfases potenciales al día se convertirían en 10.
Yo digo que está mucho mejor que al principio del hilo. Pero el hecho es que hay veces que no es bueno. Y veo que no quieres investigarlo. Respeto su elección.
Arriba se citó la opción de la instantánea para obtener los precios actuales. Me convendría completamente si no cogiera lapsos de milisegundos en la máquina Idle-CPU.
También me preocupa no sólo la velocidad de SymbolInfoTick, sino también la relevancia de los precios que devuelve. Veo que no se plantea esta cuestión. Al parecer, decidiste mirarlo más tarde.
Estas no son condiciones cálidas en absoluto. Un bucle para 100000 peticiones de precio sin Sleep() y similares y en 20 hilos simultáneamente es una prueba de estrés evidente. Nada de eso debería estar siquiera cerca en condiciones reales.
Si crees que no hay más ticks en 1,5 segundos - vale, haz 10 millones de consultas, no cambiará nada, tu "muleta" funciona peor:Esta su afirmación es 100% falsa:
Al igual que esta declaración anterior suya:
El acceso a los precios a través de SymbolInfoTick es ahora muy rápido y está completamente desacoplado del procesamiento del flujo de ticks. Se trabaja con un caché de precios ya hecho, que se actualiza muy poco y rápidamente.
Todas las "ralentizaciones del 0,01% de la tasa de tick" sólo aparecen en condiciones de prueba de estrés, y eso es un gran resultado. En condiciones normales, se garantiza que el acceso sea muy rápido.
Si admite que "se ha trabajado mucho para agilizar" SymbolInfoTick, entonces debería creerme que la "muleta" de obtener los precios mediante PositionSelectByTicket no puede ser una solución mejor.
Por una simple razón - la implementación de PositionSelectByTicket es completamente idéntica a la implementación original "lenta" de SymbolInfoTick.
Como escribí anteriormente, esta implementación no es lenta en el sentido literal de la palabra, pero bajo una fuerte carga de la CPU, tiene una mayor probabilidad de que se produzcan valores atípicos en tiempo de ejecución (lo que es claramente visible en mi última prueba).
Los tiempos aquí dependen en gran medida del programador de tareas del sistema que se ejecuta bajo carga, es decir, puede haber diferencias de un sistema operativo a otro e incluso de una versión a otra.
Y cuanto más pesada sea la carga, más se probará el rendimiento del programador de tareas, no del terminal.
Este es el final del tema del rendimiento de SymbolInfoTick.
Si sus expertos crean una carga al nivel de las pruebas de estrés sintéticas, entonces hay una solución: "el hierro debe coincidir con las tareas".
Tengo una pregunta sobre la relevancia de los ticks dados por SymbolInfoTick.
Situación:
1. Hacemos TimeCurretn(); obtenemos la hora 18:00:00
2. Hacer SymbolInfoTick en un símbolo no etiquetado. Obtenemos una marca con la hora 17:58:00.
3. Dormir(1)
4. Añade un SymbolInfoTick para el símbolo no izquierdo. Obtenemos una marca con la hora 17:59:00.
Es decir, en el cuarto elemento tenemos un nuevo tick, que es un minuto diferente al de TimeCurretn().
¿Ves algún problema en esta situación?
¿Cómo llegar a esta situación con menos frecuencia?
Tengo una pregunta sobre la relevancia de los ticks dados por SymbolInfoTick.
Situación:
1. Hacemos TimeCurretn(); obtenemos la hora 18:00:00
2. Hacer SymbolInfoTick en un símbolo no etiquetado. Obtenemos una marca con la hora 17:58:00.
3. Dormir(1)
4. Añade un SymbolInfoTick para el símbolo no izquierdo. Obtenemos una marca con la hora 17:59:00.
Es decir, en el cuarto elemento tenemos un nuevo tick, que es un minuto diferente al de TimeCurretn().
¿Ves algún problema en esta situación?
¿Cómo llegar a esta situación con menos frecuencia?
SymbolInfoTick envía los datos recibidos del servidor del corredor. Lo que el servidor envió es lo que se obtiene.
Si tiene alguna duda sobre el flujo de ticks que emite su corredor, debe ponerse en contacto con él.