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

 
Andrey Barinov:

Porque en lugar de OrderOpenPrice poner OrderOpenTime()

Sí. Me confundí. :)

 
Реter Konow:

Tengo que admitir que me sorprendieron un poco los resultados de la prueba.

Por eso quería que lo hicieras todo tú, no dar soluciones prefabricadas que se estrellaran contra la pared.
Sabes, Peter, también existe la función de puntero a función, gracias a la cual puedes organizar las llamadas a función simplemente tomando estos punteros de un array de dichos punteros. Creo que esto sería muy útil en su tarea. El único problema es que tienes que volver a meterte con las clases.
 
Nikolai Semko:
Por eso quería que lo hicieras todo tú, no dar soluciones prefabricadas, que son como guisantes contra la pared.
Y ya sabes, Peter, que también existe el puntero a una función, gracias al cual puedes organizar las llamadas a funciones simplemente tomando estos punteros de un array de dichos punteros. Creo que esto sería muy útil en su problema. Pero aquí está el problema: tienes que volver a lidiar con las clases.

He oído hablar de los punteros a las funciones. Pero tengo muy pocas funciones. Es por esto que no tengo espacio y necesito usar OOP.

Tengo un concepto de desarrollo diferente. Creo que el funcionamiento de los bloques multifuncionales holísticos es más eficiente que el de los grandes complejos de pequeñas funciones.

Más prometedor, desde el punto de vista del desarrollo de mecanismos.

Esa es mi opinión...

Tengo varios bloques grandes. Para aplicar la POO, hay que descomponerlas en pequeñas funciones, organizarlas en clases, y luego, utilizar punteros y otras cosas.

Pero no podré hacerlo. Simplemente porque pienso de forma diferente.

El concepto de OOP no coincide con las peculiaridades de mi forma de pensar, y no puedo expandirme en él. Esa es la razón.

 
Nikolai Semko:

Ten en cuenta, Nikolai, que en el tema del desarrollo programático no tengo ningún problema. Todo se desarrolla muy rápidamente.

Al mismo tiempo, los mecanismos funcionan bien.

Ahora domino las uniones, y veo su aplicación en una tarea particular, - escribir cadenas en un recurso.

Intentaré comprobar la velocidad y la carga de la CPU en el EA de prueba y publicaré el resultado.

Si es bueno, reconstruiré la comunicación entre el motor y el EA, haciéndolo sobre los recursos.

 

Para utilizar los recursos para pasar cadenas de longitud indefinida, estas cadenas deben escribirse en una matriz de caracteres.

Sin embargo, parece que su tamaño sólo se declara dentro de la unión y no cambia después.

He probado a redimensionar el array de char desde la unión, a través de ArrayResize, pero no tiene efecto.

Parece que el tamaño de la matriz char debe ser establecido de antemano. Y debe ser de tamaño máximo.


Aquí está el código:

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[4];
   uint    Uint[1];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(1000);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand();
   if(q > 10000)q = 10000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Меняем размер массива из Char[] юниона. 
   //-------------------------------------------------------
   ArrayResize(u.Char,StrSize);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   //StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //
   //-------------------------------------------------------
   Print("StrSize  ",StrSize," Размер u.Char  ",ArraySize(u.Char));
  }
//+------------------------------------------------------------------+
 

Ahora está claro que hay que conocer de antemano el tamaño de la matrizchar en la unión. PorqueArrayResize(u.Char,StrSize) no lo cambia.

Así que tenemos que establecer el tamaño del array igual a la longitud de la cadena máxima...

 

Buenas noticias. Todo funciona bien.

La cadena se escribe en el recurso y es leída por otro EA en un gráfico diferente.

El procesador no está sometido a ninguna carga. La carga sólo se produce al llamar a la Alerta que imprime la cadena.

Aquí está el código de los Asesores Expertos:

1. Expert Advisor formando la cadena y escribiéndola en un recurso.

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(16);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand(),width,height;
   if(q > 1000)q = 1000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //Cохраняем строку переведенную в байты в ресурсе.
   //-------------------------------------------------------
   if(!ResourceCreate("::Resource",u.Uint,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //-------------------------------------------------------
  }
//+------------------------------------------------------------------+
 

Un asesor leyendo una línea de un recurso en otro gráfico:

//+------------------------------------------------------------------+
//|                                              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

//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(16); 
   
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"\\Experts\\TEST_2.ex4::Resource"))Print("Resource is not connected!");
   else Print("Resource connected!");
//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Char_Uint u;   
   uint width,height;
   //string Message; 
   //-----------------------------
   if(!ResourceReadImage("\\Experts\\TEST_2.ex4::Resource",u.Uint,width,height))Print("Failed to read resource!  ",GetLastError());
   //-----------------------------
   string String = CharArrayToString(u.Char);
   //-----------------------------
   Alert("  String  ",String);
   //-----------------------------
  }
//+------------------------------------------------------------------+


Utilizará recursos para la comunicación. El único inconveniente es que hay que establecer el tamaño máximo de la matriz de caracteres en la unión. Pero, no es necesario pensar en el tamaño de la cadena y el número de objetos MT.

Este método es más lento que el método de enlace de objetos MT, pero está bien.

 
Реter Konow:

Tienes una teoría interesante, aunque no coincide del todo con los resultados de mis experimentos, que publicaré a continuación.

Como muestra la prueba, es la inicialización de la matriz de píxeles lo que más carga la CPU.

Comprueba el EA de prueba a continuación.

Vuelve a leer la tarea:

Vasiliy Sokolov:

Peter, esta es la tarea. Hacer un panel que muestre las aperturas de órdenes actuales en MT4. No es necesario hacer una copia completa del panel del sistema, basta con hacer una simple tabla con las propiedades básicas de las órdenes abiertas: precio abierto, dirección, beneficio. El resto depende de ti. Lo principal es que cuando una orden se cierra, su indicación en la tabla también desaparece. Y viceversa, aparecería en esta tabla cuando se abra un nuevo pedido.

Aquí puede ver las dos operaciones necesarias de redibujado cuando la tabla cambia en la pantalla: 1. al cerrar una operación y 2. al abrir una operación. ¿Por qué redibujar los píxeles en el resto del tiempo?

¿Está resolviendo algún otro problema?

 
Vladimir:

Vuelve a leer el problema:

Vasiliy Sokolov:

Aquí vemos dos operaciones de redibujado necesarias cuando la tabla cambia en la pantalla: 1. al cerrar una operación y 2. al abrir una operación. ¿Por qué redibujar los píxeles en otros momentos?

¿Está resolviendo algún otro problema?

Bueno, están redibujados exactamente como tú dices.

La carga del procesador aparece durante la animación:

Hay una reinicialización constante de los valores de la matriz de píxeles. Cada 16 milisegundos. Esto carga el procesador hasta un 40%.

Estaba tratando de averiguar cuál es exactamente la carga. Pensé que era guardar un recurso o leerlo. Resultó que era la reinicialización del array en el bucle de dibujo.


También resultó que una llamada constante de ObjectSetInteger(0, "MT object",OBJPROP_SELECTED,1); (cada 16 ms) también carga el procesador. En un 10% aproximadamente.

Utilizo esta llamada para decirle a otro EA que lea el recurso con los datos de la animación.

En total, obtiene +~50% de carga de la CPU durante la animación.