Mi enfoque. El núcleo es el motor. - página 92

 
Maxim Kuznetsov:

Las únicas variables globales y los archivos para el intercambio de datos entre EAs, indicadores y scripts son

Los 4 puntos anteriores son "hacks" locales por falta de pescado. Los 4 puntos anteriores utilizan mecanismos no diseñados para intercambiar datos arbitrarios, y mucho menos matrices de datos.

Se podría pensar que GlobalVariables fue diseñado específicamente para la mensajería. Eso es una tontería. De hecho, es el mismo hack que cualquier otro artículo.

 
fxsaber:


...A grandes rasgos,un ciclo completo de escritura/lectura de un recurso se ejecuta a una velocidad de 4 millones de ticks por segundo.

La lectura/escritura en el recurso es muy rápida. Pero, ¿hasta qué punto es adecuado para esta transmisión?

1. Línea A. Evento del temporizador. Recoge todos los valores de los parámetros que fueron cambiados en el evento y los traduce en una cadena. Traducir cadena a Char, escribir en el recurso. Envía un mensaje al lado B.

2. Parte B. Evento OnChartEvent(), recibe una señal de mensaje, abre el recurso, lo lee, rellena el núcleo de parámetros con nuevos valores, redibuja los elementos necesarios.

¿Y si este evento se ejecuta continuamente, con la frecuencia del temporizador?

La cuestión es cómo utilizar mejor los recursos para ello, si hay otras opciones.

//---------------------------------------------------------------------------------------------------------------------

  • La opción EventChartCustom() tiene dos inconvenientes.

  1. El paquete pasa a estar en la cola de eventos.
  2. El paquete no puede tener más de 127 caracteres. Por lo tanto, un mensaje de 1000 caracteres tiene que ser dividido y luego reensamblado. Y cada parte del mensaje estará en la cola de eventos.
  • La variante con el paso por los objetos del grafo, requiere dividir el mensaje en paquetes de 64 caracteres, escribirlos en descripciones de objetos y luego volver a ensamblarlos. Es interesante que esta variante sea la más rápida, pero a medida que aumenta la longitud de la cadena, su velocidad disminuye. Es decir, cada llamada a ObjectSetString() tarda 3 microsegundos. Pero si una cadena tiene 1000 caracteres, tenemos que dividirla en 64 caracteres, lo que significa que tenemos que llamar a ObjectSetString() unas 8 veces. 8*3 = 24 ms. Luego se tarda el mismo tiempo en montar la cuerda. Por eso, si la cadena tuviera 10 000 caracteres, este método se acercaría definitivamente a la velocidad del método que trabaja a través de los recursos. (Me refiero al tiempo de guardar y leer el recurso + transferir las cadenas a uint y viceversa).
La variante del recurso sigue sin probarse hasta el final. Hoy lo probaré en el probador y se verá finalmente si puede ser universal.
 
Реter Konow:

¿Y si este evento se ejecuta continuamente, con la frecuencia del temporizador?

La cuestión es cómo utilizar mejor los recursos para ello, si hay otras opciones.

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

Intercambio de datos entre programas

fxsaber, 2018.11.21 13:12

Probablemente tenga mucho tiempo para describir con tanto detalle las distintas opciones de interacción. Desgraciadamente, no poseo ese recurso.

Aquí hay un artículo sobre el tema en el que se produce una interacción completa. Cada edificio se construye con ladrillos y para tareas específicas. Todos los ladrillos posibles se muestran al principio del hilo. El resto depende del constructor.

 
fxsaber:

El artículo no prueba la comunicación de dos programas a través de recursos, uno de los cuales está en el probador.

 

¿Cuál es el problema con el sindicato? Por favor, un ejemplo:

union UZ{
   double d;
   int i[2];
};

void OnStart(){

   UZ u1;
   UZ u2;
   
   u1.d=12345.678;
   
   ArrayCopy(u2.i,u1.i);
   
   Alert(u2.d);

}
 
Реter Konow:

El artículo no prueba la comunicación de dos programas a través de recursos, uno de los cuales está en el probador.

Lee la frase sobre los ladrillos.

 
fxsaber:

...

Este artículo está disparando un cañón a los gorriones. Como muchos artículos. Prefiero resolver el problema yo mismo que entender el artículo.

Todo se puede hacer 10 veces más fácil y claro. Pero el artículo es mucho más fácil...


¿Y de qué sirve el artículo si dice que no ha comprobado el funcionamiento de los recursos en el probador?

 
Реter Konow:

¿Y de qué sirve este artículo si dice que no ha comprobado el funcionamiento de los recursos en el probador?

Salí de la discusión.

 

Hay algo que no funciona en esta solución. Quizá esté haciendo algo mal.

Para abreviar:

La función StringToCharArray() toma SOLO un array de char.

La función ResourceCreate() sólo acepta una matriz uint.

Por lo tanto, es necesario reescribir de forma intermedia el contenido de la matriz char (rellenada con la cadena convertida), en la matriz uint.

 
//+------------------------------------------------------------------+
//|                                                    Tester EA.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //----------------------------------------------
   ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   uchar Arr[];
   uint  Data[];
   //---------------------------
   string price = (string)Bid;
   //---------------------------
   int width = StringToCharArray(price,Arr);
   //---------------------------
   ArrayResize(Data,width);
   //---------------------------
   ArrayCopy(Arr,Data);
   //---------------------------
   if(!ResourceCreate("::Resource",Data,width,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //---------------------------
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+

Indicador en un gráfico normal:

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(25); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   uint Data[50],width,height;
   //-----------------------------
   if(!ResourceReadImage("::Resource",Data,width,height))Print("Failed to read resource!");
   else Print("Resource is readable!");
   //-----------------------------
   
  }
//+------------------------------------------------------------------+