Errores, fallos, preguntas - página 2377

 
Slava:
Sí, cualquier impresión de OnInit

Gracias. Interesante, si no me di cuenta por casualidad, cómo sería posible descubrirlo...


ZS Yo lo dejaría sólo para los Agentes locales. En la Nube, se puede enviar fácilmente el registro de spam de esta manera.

 
fxsaber:

Gracias. Interesante, si no me di cuenta por casualidad, cómo sería posible descubrirlo...


ZS Yo lo dejaría sólo para los Agentes locales. En la Nube, se puede enviar fácilmente el registro de spam de esta manera.

En la nube, no aparecerá. Porque no hay razón para ello.
 
Slava:

Cuando ejecuta la genética, ¿optimiza según su criterio personalizado?

Según los registros presentados, OnTester devolvió 0 en todos los casos

Suelo optimizar según mi criterio, pero aquí he probado también el criterio personalizado. El resultado es el mismo.

OnTester devuelve 0, por eso devuelve ceros en los resultados, es comprensible. La pregunta es ¿por qué devuelve "0" en la ejecución general (optimización) pero en la ejecución única de "resultados cero" (con los mismos parámetros) devuelve el resultado normal, el gráfico, etc.? Es decir, algo no funciona en "Superación total" y sin embargo la genética funciona bien. ¿Alguna otra idea?

 
Kuzmich:

¿Alguna otra idea?

Extraer toda la información de la optimización pasar de esta manera

Foro sobre trading, sistemas de trading automatizados y comprobación de estrategias

MT5. PROBADOR DE ESTRATEGIAS. Divergencia de los resultados de las pruebas y de la optimización.

fxsaber, 2017.08.22 11:06

Inserte estas líneas en el EA

#define  REPORT_TESTER // В тестере будут автоматически записываться отчеты
#include <Report.mqh>

Y corre la optimización. A continuación, ejecute una carrera individual no coincidente.

A continuación, compare los dos informes guardados de la ejecución correspondiente de Optimización y de la ejecución única.

El resultado de la comparación de los dos informes revelará rápidamente las causas.

 
En el marco de la familiarización con la funcionalidad de Socket* surgieron una serie de preguntas a la implementación actual.
El objetivo es mejorar en lo posible lo que se hace, pido a los desarrolladores que no se ofendan por las posibles críticas.



1. No entiendo las razones de las diferencias tan fuertes en las "interfaces" para las funciones de lectura de sockets
: a) Para la conexión encriptada hay dos funciones para la lectura, y para la no encriptada - una.
b) EnSocketRead es necesario especificartimeout_ms explícitamente, y enSocketTlsRead ySocketTlsReadAvailable
no hay
tal parámetro en absoluto (establecido por la función separada SocketTimeouts)
.
int  SocketTlsRead(int socket, uchar& buffer[], int buffer_maxlen);
int  SocketTlsReadAvailable(int socket, uchar& buffer[], int buffer_maxlen);

int  SocketRead(int socket, uchar& buffer[], int buffer_maxlen, uint timeout_ms);


2. El nombre de la función SocketIsReadable no tiene nada que ver con lo que realmente realiza:

bool  SocketIsWritable(const int  socket); // Return true if writing is possible, otherwise false.
uint  SocketIsReadable(const int  socket); // Number of bytes that can be calculated. In case of an error, 0 is returned.
bool  SocketIsConnected(const int socket); // New function without description. May be, it returns true if connection is not closed.

De hecho, SocketIsReadable es análoga a la función ioctlsocket() con la bandera FIONREAD en Ws2_32.dll


3. ¿Cómo puede un usuario que utiliza la funcionalidad Socket* a través de una conexión no encriptada obtener una respuesta de un servidor con un retraso mínimo, si el servidor no rompe la conexión después de la transferencia de datos?

- La función SocketIsReadable sin utilizar explícitamente un retardo de tiempo (por ejemplo, sin Sleep) devuelve 0.
- la función SocketRead no sabe cuánto leer, se especificabuffer_maxlen con una reserva - tendrá que esperartimeout_ms

Sí, así es como se hace:

- esperar 1 byte de datos en SocketRead;
- luego averiguar el tamaño de toda la respuesta usando SocketIsReadable;
- leer la longitud restante en SocketRead;
- fusionar los resultados copiando las matrices:

#define  PRINT(x) Print(#x, ": ", string(x))
                
void OnStart() {
   string domain = "www.mql5.com";
   int port = 80;
 
   string request = "GET / HTTP/1.1\r\nHost: " + domain + "\r\n\r\n";
   char req[];
   
   int socket = SocketCreate();
   PRINT(SocketConnect(socket, domain, port, 5000));
   int len=StringToCharArray(request,req)-1;
   PRINT(SocketSend(socket,req,len));
   
   
   
   uchar resp[];
   uchar result[];
   
   int resp_result;
   uint resp_len;
   int start_write;
   
   
   resp_len = 1;
   resp_result = SocketRead(socket, resp, resp_len, 5000);
   if (resp_result <= 0){
      PRINT(GetLastError());
      return;
   }
   start_write = ArraySize(result);
   ArrayResize(result, start_write + resp_result);
   ArrayCopy(result, resp, start_write);
   
   
   resp_len = SocketIsReadable(socket);
   resp_result = SocketRead(socket, resp, resp_len, 5000);
   if (resp_result <= 0){
      PRINT(GetLastError());
      return;
   }
   start_write = ArraySize(result);
   ArrayResize(result, start_write + resp_result);
   ArrayCopy(result, resp, start_write);
   
   
   PRINT(CharArrayToString(result));
};

¿No es demasiado código?


4. SocketIsReadable devuelve información falsa.
Apague el internet y ejecute el código anterior.
Como resultado, SocketIsReadable devuelve un valor sano de 1. Maravillas.


Conseguí describir aproximadamente un tercio de todas las preguntas y problemas relacionados con Socket*.
Por desgracia, he necesitado mucho tiempo para comprobar, describir y volver a comprobar todo... (para que no sea un hecho que habrá una secuela)

La impresión general es que, o bien todo se hizo con mucha prisa, o bien la funcionalidad de Socket* llegó al desarrollador junior.
En cualquier caso, la solución actual es muy rudimentaria y abarca un enfoque más bien limitado del uso de sockets.

 
MQL5\Include\Math\AlgLib\dataanalysis.mqh - CLinReg::LRLine no funciona para 1M o más valores?
 
Kuzmich:

Suelo optimizar según mis propios criterios, pero aquí he probado también los estándar. El resultado es similar.

OnTester devuelve 0, por eso hay ceros en los resultados, es comprensible. La pregunta es ¿por qué devuelve "0" en la ejecución general (optimización) pero en la ejecución individual desde "resultados cero" (con los mismos parámetros) devuelve el resultado normal, el gráfico, etc.? Es decir, algo no funciona en "Superación total" y sin embargo la genética funciona bien. ¿Alguna otra idea?

¿Puedes compartir un EA (ex5 en privado) y las condiciones de optimización?

Queremos reproducir el problema que mencionas.

Después de la investigación, el EA se borrará irremediablemente

 
Slava:

¿Puedes compartir el EA (ex5 en un mensaje privado) y las condiciones de optimización?

Queremos reproducir el problema que mencionas.

Después de la investigación, el EA se borrará irremediablemente

¿Podrías mirar mi EA? Tengo un problema similar: el beneficio no se cuenta, por lo que la optimización no funciona.
 
Slava:

¿Puedes compartir el EA (ex5 en un mensaje privado) y las condiciones de optimización?

Queremos reproducir el problema que mencionas.

La EA se borrará irremediablemente después de la investigación

Respondido en un mensaje privado.

 
Sergey Dzyublik:
En el marco de la familiarización con la funcionalidad de Socket* surgieron una serie de preguntas a la implementación actual.
El objetivo es mejorar en lo posible lo que se hace, pido a los desarrolladores que no se ofendan por las posibles críticas.



1. No entiendo las razones de las diferencias tan fuertes en las "interfaces" para las funciones de lectura de sockets
: a) Para la conexión encriptada hay dos funciones para la lectura, y para la no encriptada - una.
b) EnSocketRead es necesario especificartimeout_ms explícitamente, y enSocketTlsRead ySocketTlsReadAvailable
no hay
tal parámetro en absoluto (establecido por la función separada SocketTimeouts)
.


2. El nombre de la función SocketIsReadable no tiene nada que ver con lo que realmente realiza:

De hecho, SocketIsReadable es análoga a la función ioctlsocket() con la bandera FIONREAD en Ws2_32.dll


3. ¿Cómo puede un usuario que utiliza la funcionalidad Socket* a través de una conexión no encriptada obtener una respuesta de un servidor con un retraso mínimo, si el servidor no rompe la conexión después de la transferencia de datos?

- La función SocketIsReadable sin el uso explícito de la demora (por ejemplo, sin Sleep) devuelve 0.
- La función SocketRead no sabe cuánto leer, si especificabuffer_maxlen con reserva - tendrá que esperartimeout_ms

Sí, así es como se hace:

- esperar 1 byte de datos en SocketRead;
- luego averiguar el tamaño de toda la respuesta utilizando SocketIsReadable;
- leer la longitud restante en SocketRead;
- fusionar los resultados copiando las matrices:

¿No es demasiado código?


4. SocketIsReadable devuelve información falsa.
Apague el internet y ejecute el código anterior.
Como resultado, SocketIsReadable devuelve un valor sano de 1. Maravillas.


He conseguido describir aproximadamente un tercio de todas las preguntas y problemas relacionados con Socket*.
Por desgracia, he necesitado mucho tiempo para comprobar, describir y volver a comprobar todo... (para que no sea un hecho que habrá una secuela)

La impresión general es que, o bien todo se hizo con mucha prisa, o bien la funcionalidad de Socket* llegó al desarrollador junior.
En cualquier caso, la solución actual es muy rudimentaria y abarca un enfoque más bien limitado del uso de sockets.

1. Esta es la interfaz.

Las funciones TLS son auxiliares para soportar casos complejos. No hay problema con la configuración de SocketTimeouts - estos son los mejores para usar.


2. Realiza su función correctamente.

No debe ser consciente de los problemas de detección de ruptura de la conexión TCP. Es bastante difícil (requiere muchos recursos a costa de llamadas adicionales) detectar que una conexión está garantizada para que se rompa correctamente. Todas las implementaciones de la red sufren este problema.

Nuestra implementación de SocketIsReadible es lo suficientemente inteligente y tiene un detector de ruptura. Cuando detecta un 0 bytes limpio, hace el trabajo extra de comprobar que el socket está completo:

   //+------------------------------------------------------------------+
   //| Доступно для чтения?                                             |
   //+------------------------------------------------------------------+
   UINT32 IsReadible(void)
     {
      unsigned long size=1;    // специально, чтобы убиться при попытке чтения, если сокет мертв
      //--- проверка
      if(m_socket!=INVALID_SOCKET)
        {
         //--- считаем количество доступных для чтения байт
         if(ioctlsocket(m_socket,FIONREAD,&size)!=0)
           {
            Close();
            return(1);        // вернем 1, чтобы убиться при попытке чтения
           }
         //--- если нет данных, проверим сокет на завершенность
         if(size==0)
           {
            timeval wait_time;
            fd_set  fd;
            //--- ждём
            FD_ZERO(&fd);
            FD_SET(m_socket,&fd);

            wait_time.tv_sec =0;          // секунды
            wait_time.tv_usec=1000;       // микросекунды
            //--- ждём
            if(select(0,&fd,NULL,NULL,&wait_time)>0)
               return(1);                 // вернем 1, чтобы убиться при попытке чтения
           }
        }
      //--- размер
      return(size);
     }

Dado que devuelve el número de bytes sin una bandera de terminación, emite 1 byte de modo que un intento de lectura posterior/imminente de SocketRead normalmente devolverá un error.

¿Por qué es esto correcto? Porque la mayor parte del código lo escriben los programadores de esta manera:

if(SocketIsReadible(...)>0)
  {
   if(SocketRead( )<1)
     return(false);
   ...
  }
... уходим на следующий круг ожидания

el resultado real de la operación se comprueba en un intento de lectura directa.


3. necesita hacer SocketIsReadible() antes de la lectura real, si no conoce el tamaño exacto de los datos a leer.

El bind SocketisReadible/SocketRead te da la posibilidad de no perder el control (minimizar a casi cero la pérdida de control) sobre el flujo de ejecución de tu programa. Esto evita que se produzcan tiempos muertos en la red.

Sí, unas cuantas líneas más de código, pero no perderás el control ni un milisegundo(aproximadamente). Tú decides qué hacer en los intervalos sin datos de la red.


4. explicada en el segundo párrafo.

Emitir 1 para la estimulación de la lectura y la salida como un error de lectura.



Sus conclusiones son erróneas.

Esta es la naturaleza del transporte TCP/IP, donde no hay ninguna garantía. Ahí también se puede entrar en agujeros negros de red en los filtros/firewalls cuando no hay parte de señalización TCP. El control del tiempo de espera y del flujo de datos le permite detectarlos y terminar las conexiones usted mismo.

Hemos dado una interfaz de acceso crudo/directo a las funciones de red, incluyendo las implementaciones de TLS. Si los utilizas, eres tú quien debe envolver adecuadamente las funciones raw en un manejador SocketIsReadible/SocketRead seguro/controlado.

Si quieres hacer peticiones de alto nivel sin tener que pensar en las minucias, existen las funciones WebRequest. Todas las protecciones están incorporadas.