Errores, fallos, preguntas - página 2963

 
fxsaber:

El Indicador1 y el Indicador2 deben sincronizarse de alguna manera para que ambos números puedan escribirse en la misma línea común.

Se trata de una solución muy compleja.

¿Por qué tendrían que estar sincronizados? user32.dll lo hará por ellos.
Lo principal es numerarlos correctamente, de manera que cada número tenga un número único y este número sea un índice de la matriz de datos.
Esto puede, como último recurso, hacerse manualmente. O puede hacerlo automáticamente. Por cierto, hace poco publiqué algo parecido en KB(Casos de Indicadores).
¿Qué es lo que no le gusta de los recursos? Creo que es óptimo dentro de los límites de un terminal. La variante que sugiero, usando user32.dll (implementé esta variante hace unos 10 años, cuando era joven y hacía sus pinitos en el arbitraje), el tiempo de acceso y de análisis de datos es de unos 50 microsegundos (creo que se puede acelerar en 1,5-2 veces). ¿Es más lento con los recursos?

 
Nikolai Semko:

¿Por qué tendrían que sincronizarse? user32.dll lo hará por ellos.

Intenta escribirlo. Tal vez no entienda del todo la tarea.

¿Por qué no te gustan los recursos? Creo que es óptimo dentro de los límites de un solo terminal. La variante que sugerí usando user32.dll (implementé esta variante hace unos 10 años, cuando hacía mis pinitos en el arbitraje cuando era joven) tiene un tiempo de acceso y análisis de unos 50 microsegundos (creo que se puede acelerar 1,5-2 veces). ¿Es más lento con los recursos?

Tarda 100 microsegundos en leerse en una máquina doméstica en condiciones ideales. Un Asesor Experto en un solo tick puede provocar la lectura de cien veces. Es lento.

En condiciones ideales, GlobalVariableGet se ejecutará en 10 microsegundos. Pero eso no es un indicador, ya que en condiciones de combate nuevas para mí es un freno horrible.

 
fxsaber:

Esto es HistoryTicks - capturando todos los ticks para los EAs. Por lo tanto, EventChartCustom no es adecuado, tiene su propia cola. Lo mismo ocurre con el buffer.

Lo tengo funcionando en EventChartCustom. El 99,8% de los ticks se reciben en 0,15 ms.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

EventChartCustom => el indicador es demasiado lento

Andrey Khatimlianskii, 2019.12.12 09:27

Aquí están las estadísticas de 9 horas de trabajo con 5 símbolos:

Windows 8.1 (build 9600) x64, IE 11, UAC, Intel Core i5-3570  @ 3.40 GHz, Memory: 6979 / 16346 Mb, Disk: 341 / 499 Gb, GMT+2
[USDCHF]: 22784 of 22833 (99.8 %) ticks were processed (0.14 ms delay in average), 49 (0.2 %) ticks were skipped (103.4 ms delay in average)
[EURUSD]: 22944 of 22974 (99.9 %) ticks were processed (0.16 ms delay in average), 30 (0.1 %) ticks were skipped (115.6 ms delay in average)
[USDCAD]: 15331 of 15347 (99.9 %) ticks were processed (0.13 ms delay in average), 16 (0.1 %) ticks were skipped (104.6 ms delay in average)
[EURCHF]: 22516 of 22571 (99.8 %) ticks were processed (0.13 ms delay in average), 55 (0.2 %) ticks were skipped (127.8 ms delay in average)
[EURAUD]: 66842 of 66924 (99.9 %) ticks were processed (0.13 ms delay in average), 82 (0.1 %) ticks were skipped (117.8 ms delay in average)
[GBPUSD]: 41393 of 41393 (100.0 %) ticks were processed (0.00 ms delay in average)
Total trade requests time: 4.280 sec

El Asesor Experto estaba en GBPUSD, así que el OnTick nativo funcionó para él.

No hubo errores de "el indicador es demasiado lento".


En cambio, el porcentaje de ticks perdidos y la latencia media es mucho mayor en el VPS de MQ (publicaré las estadísticas más adelante).
Y hay muchos errores de "el indicador es demasiado lento".

No entiendo la naturaleza del desbordamiento de la cola, ya que el Asesor Experto procesa los eventos acumulados inmediatamente (sólo regresa).
¿Alguien más lo procesa?


 
Andrey Khatimlianskii:

Lo tengo funcionando enEventChartCustom. El 99,8% de los ticks se reciben en 0,15 ms.

Envío los ticks del indicador a través de esto: sparam contiene MqlTick, lparam - número de tick.

El Asesor Experto en OnChartEvent capta estos ticks. ¿Y necesita entender si el tick actual es el más actual o no? Es decir, ¿hay una cola de ticks o está vacía?

Para ello, lee el número (la tarea es leer este número) del último tick enviado por el indicador. Si el tick tiene el mismo número - la cola está vacía, y es posible empezar a trabajar con los ticks.


Y durante la operación de OnTick, después de OrderSend es necesario comprobar si el indicador ha enviado más ticks. Para ello, tenemos que volver a leer el número del indicador. Y puede haber más de un centenar de estas comprobaciones durante un OnTick. Por eso hay que leer rápido.

 

Dentro de 1 terminal, lo más rápido de winapi será la asignación de memoria (global dentro de un proceso) y las funciones entrelazadas como https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.

Estos son no bloqueantes, atómicos y esencialmente ejecutados en unas pocas instrucciones asm.

InterlockedExchange function (winnt.h) - Win32 apps
InterlockedExchange function (winnt.h) - Win32 apps
  • 2018.12.05
  • lastnameholiu
  • docs.microsoft.com
Sets a 32-bit variable to the specified value as an atomic operation.
 
traveller00:

Dentro de 1 terminal, lo más rápido de winapi será la asignación de memoria (global dentro de un proceso) y las funciones entrelazadas como https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.

Estos son no bloqueantes, atómicos y esencialmente ejecutados en unas pocas instrucciones asm.

No sin un ejemplo.

 
fxsaber:

Para ello, lee el número (la tarea es leer este número) del último tick enviado por el indicador. Si el tick recibido tiene el mismo número - la cola está vacía, y se puede empezar a trabajar con un paquete de ticks.

Y durante la operación de OnTick, después de OrderSend es necesario comprobar si el indicador ha enviado más ticks. Para ello, tenemos que volver a leer el número del indicador. Y puede haber más de un centenar de estas comprobaciones durante un OnTick. Por lo tanto, tenemos que leerlo rápidamente.

Inicialización.

1. En el primer hilo (muy probablemente, el hilo de escritura), asignar la memoria de cualquier manera para la variable del tamaño requerido.

2. En los hilos requeridos (hilos de lectura), envía la dirección de esta memoria.

Trabajo básico.

3. El hilo de escritura inicia InterlockedExchange o InterlockedExchange64 dependiendo del tamaño de la variable para escribir en ella.

4. El hilo de lectura tira, por ejemplo, de InterlockedCompareExchange para leer.

Completar.

5. Liberar la memoria asignada, preferiblemente en el mismo hilo que la asignó.


Si es necesario, se puede repetir para crear varios contadores. Por el contrario, necesitará la conexión WinAPI. De las características de la dirección de memoria asignada debe ser alineado, pero por defecto por lo general es.


El trabajo será dentro de 1 proceso, la memoria se comparte para los hilos de 1 proceso. Si es necesario, hay otras funciones enclavadas como InterlockedDecrement, InterlockedAdd, etc.

Las funciones son no bloqueantes, no esperan nada, autómatas, se ejecutan en unas pocas instrucciones asm.


P.D. Hasta donde recuerdo, las operaciones regulares de lectura y escritura a través de mov en ensamblador son atómicas de todos modos. Y si el compilador no se hace un lío (en teoría no debería), podemos intentar leer y escribir en la variable en la memoria asignada y será atómico.

Si se adapta a la tarea, es poco probable que sea más rápido dentro de 1 proceso. Para el interproceso lo más rápido será similar, pero con memoria compartida, en este caso no se puede prescindir de WinAPI.

 
fxsaber:

Este esquema no parece funcionar. Muestra un ejemplo elemental, por favor.

¿Por qué no es factible? Tal y como yo lo veo. El principio getter setter.
Obtener el valor de una variable oculta a través de una función.
Si pasas la estructura M qlTick, define tu estructura con los campos establecidos como MqlTick, y añade tu campo contador a la estructura.
Y devolver esta estructura desde la función de exportación.
Un ejemplo elemental para el indicador. No preste atención al ejemplo del guión.

struct myMqlTick 
{ 
   datetime     time;          // Время последнего обновления цен 
   double       bid;           // Текущая цена Bid 
   double       ask;           // Текущая цена Ask 
   double       last;          // Текущая цена последней сделки (Last) 
   ulong        volume;        // Объем для текущей цены Last 
   ulong        count;  //Свой счётчик
   
}myStruct;

//--------------------------------------------------
myMqlTick GetTickStruct() export
{
   
   return(myStruct);
}

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   myStruct.time   = 0.0;
   myStruct.bid    = 0.0;
   myStruct.ask    = 0.0;
   myStruct.last   = 0.0;
   myStruct.volume = 0;
   myStruct.count  = 1;  //свой счётчик  
  
}
//+------------------------------------------------------------------+

En el Asesor Experto, llame a GetTickStruct y obtenga la estructura completa con su contador.

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура для получения текущих цен
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура для получения текущих цен
  • www.mql5.com
Структура для получения текущих цен - Структуры данных - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Roman:

En el Asesor Experto se llama a GetTickStruct, se obtiene la estructura completa, con su contador.

Por favor, escriba una transferencia numérica elemental de indicador a EA.

 
fxsaber:

Una transferencia numérica elemental de indicador a EA, por favor escriba.

Sustituir la estructura por una variable ))

Razón de la queja: