Errori, bug, domande - pagina 2377

 
Slava:
Sì. Qualsiasi stampa da OnInit

Grazie. Interessante, se non l'ho notato per caso, come sarebbe stato possibile scoprirlo...


ZS lo lascerei solo per gli agenti locali. Nel Cloud, si può facilmente spammare il registro in questo modo.

 
fxsaber:

Grazie. Interessante, se non l'ho notato per caso, come sarebbe stato possibile scoprirlo...


ZS lo lascerei solo per gli agenti locali. Nel Cloud, si può facilmente spammare il registro in questo modo.

In Cloud, non apparirà. Perché non ce n'è motivo.
 
Slava:

Quando esegui la genetica, ottimizzi secondo il tuo criterio personalizzato?

In base ai log presentati, OnTester ha restituito 0 in tutti i casi

Di solito ottimizzo secondo il mio criterio, ma qui ho provato anche il criterio personalizzato. Il risultato è lo stesso.

OnTester restituisce 0, ecco perché restituisce degli zeri nei risultati - è comprensibile. La domanda è perché restituisce "0" nell'esecuzione generale (ottimizzazione), ma nell'esecuzione singola da "zero risultati" (con gli stessi parametri) restituisce il risultato normale, il grafico, ecc. Cioè qualcosa non funziona in "Full overshoot" eppure la genetica funziona bene. Altri pensieri/idee?

 
Kuzmich:

Altri pensieri/idee?

Tirare tutte le informazioni del passaggio di ottimizzazione in questo modo

Forum sul trading, sistemi di trading automatico e test di strategia

MT5. TESTER DI STRATEGIA. Divergenza dei risultati dei test e dell'ottimizzazione.

fxsaber, 2017.08.22 11:06

Inserite queste linee nell'EA

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

E corri l'ottimizzazione. Poi eseguire una corsa singola non corrispondente.

Poi confronta i due rapporti salvati del passaggio corrispondente da Optimisation e il passaggio singolo.

Il risultato del confronto dei due rapporti rivelerà rapidamente le cause.

 
Nel quadro della familiarizzazione con la funzionalità di Socket* sono sorte diverse domande sull'attuale implementazione.
L'obiettivo è quello di migliorare il più possibile ciò che viene fatto, chiedo agli sviluppatori di non essere offesi da eventuali critiche.



1. Non capisco le ragioni di tali forti differenze nelle "interfacce" per le funzioni di lettura dei socket
: a) Per la connessione criptata ci sono due funzioni per la lettura, e per quella non criptata - una.
b) InSocketRead è necessario specificare esplicitamentetimeout_ms, e inSocketTlsRead eSocketTlsReadAvailable
non c'è
affatto tale parametro (impostato dalla funzione separata 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. Il nome della funzione SocketIsReadable non ha nulla a che fare con ciò che effettivamente esegue:

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.

Infatti, SocketIsReadable è analogo alla funzione ioctlsocket() con flag FIONREAD in Ws2_32.dll


3. Come può un utente che usa la funzionalità Socket* su una connessione non criptata ottenere una risposta dal server con un ritardo minimo, se il server non interrompe la connessione dopo il trasferimento dei dati?

- La funzione SocketIsReadable senza usare esplicitamente un ritardo (per esempio senza Sleep) restituisce 0.
- la funzione SocketRead non sa quanto leggere, si specificabuffer_maxlen con una riserva - si dovrà aspettaretimeout_ms

Sì, è così che si fa:

- attendere 1 byte di dati in SocketRead;
- poi scoprire la dimensione dell'intera risposta usando SocketIsReadable;
- leggere la lunghezza rimanente in SocketRead;
- unire i risultati copiando gli array:

#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));
};

Non è troppo codice?


4. SocketIsReadable restituisce informazioni false.
Spegnete internet ed eseguite il codice di cui sopra.
Di conseguenza, SocketIsReadable restituisce un valore sano di 1. Meraviglie.


Sono riuscito a descrivere circa un terzo delle domande e dei problemi relativi a Socket*.
Purtroppo, ho avuto bisogno di molto tempo per controllare, descrivere e ricontrollare tutto... (in modo che non sia un fatto che ci sarà un sequel)

L'impressione generale è che o tutto è stato fatto in grande fretta, o la funzionalità Socket* è arrivata allo sviluppatore junior.
In ogni caso, la soluzione attuale è molto rozza e copre un approccio piuttosto limitato all'uso delle prese.

 
MQL5\Include\Math\AlgLib\dataanalysis.mqh - CLinReg::LRLine non funziona per 1M o più valori?
 
Kuzmich:

Di solito ottimizzo secondo i miei criteri, ma qui ho provato anche quelli standard. Il risultato è simile.

OnTester restituisce 0, ecco perché ci sono degli zeri nei risultati - è comprensibile. La domanda è perché restituisce "0" nell'esecuzione generale (ottimizzazione), ma nell'esecuzione singola da "zero risultati" (con gli stessi parametri) restituisce il risultato normale, il grafico, ecc. Cioè qualcosa non funziona in "Full overshoot" eppure la genetica funziona bene. Altri pensieri/idee?

Puoi condividere un EA (ex5 in privato) e le condizioni di ottimizzazione?

Vogliamo riprodurre il problema che hai menzionato.

Dopo la ricerca l'EA sarà irrevocabilmente cancellato

 
Slava:

Puoi condividere l'EA (ex5 in un messaggio privato) e le condizioni di ottimizzazione?

Vogliamo riprodurre il problema che hai menzionato.

Dopo la ricerca l'EA sarà irrevocabilmente cancellato

Darebbe un'occhiata al mio EA? Ho un problema simile - il profitto non viene contato, di conseguenza l'ottimizzazione non funziona.
 
Slava:

Puoi condividere l'EA (ex5 in un messaggio privato) e le condizioni di ottimizzazione?

Vogliamo riprodurre il problema che hai menzionato.

EA sarà irrimediabilmente cancellata dopo la ricerca

Risposto in un messaggio privato.

 
Sergey Dzyublik:
Nell'ambito della familiarizzazione con la funzionalità di Socket* sono sorte diverse domande sull'attuale implementazione.
L'obiettivo è quello di migliorare il più possibile ciò che viene fatto, chiedo agli sviluppatori di non essere offesi da eventuali critiche.



1. Non capisco le ragioni di tali forti differenze nelle "interfacce" per le funzioni di lettura dei socket
: a) Per la connessione criptata ci sono due funzioni per la lettura, e per quella non criptata - una.
b) InSocketRead è necessario specificare esplicitamentetimeout_ms, e inSocketTlsRead eSocketTlsReadAvailable
non c'è
affatto tale parametro (impostato dalla funzione separata SocketTimeouts)
.


2. Il nome della funzione SocketIsReadable non ha nulla a che fare con ciò che effettivamente esegue:

Infatti, SocketIsReadable è analogo alla funzione ioctlsocket() con flag FIONREAD in Ws2_32.dll


3. Come può un utente che usa la funzionalità Socket* su una connessione non criptata ottenere una risposta da un server con un ritardo minimo, se il server non interrompe la connessione dopo il trasferimento dei dati?

- La funzione SocketIsReadable senza l'uso esplicito del ritardo (ad esempio senza Sleep) restituisce 0.
- La funzione SocketRead non sa quanto leggere, se si specificabuffer_maxlen con riserva - si dovrà aspettaretimeout_ms

Sì, è così che si fa:

- attendere 1 byte di dati in SocketRead;
- poi scoprire la dimensione dell'intera risposta usando SocketIsReadable;
- leggere la lunghezza rimanente in SocketRead;
- unire i risultati copiando gli array:

Non è troppo codice?


4. SocketIsReadable restituisce informazioni false.
Spegnete internet ed eseguite il codice di cui sopra.
Di conseguenza, SocketIsReadable restituisce un valore sano di 1. Meraviglie.


Sono riuscito a descrivere circa un terzo delle domande e dei problemi relativi a Socket*.
Purtroppo, ho avuto bisogno di molto tempo per controllare, descrivere e ricontrollare tutto... (in modo che non sia un fatto che ci sarà un sequel)

L'impressione generale è che o tutto è stato fatto in grande fretta, o la funzionalità Socket* è arrivata allo sviluppatore junior.
In ogni caso, la soluzione attuale è molto rozza e copre un approccio piuttosto limitato all'uso delle prese.

1. Questa è l'interfaccia.

Le funzioni TLS sono ausiliarie per supportare casi complessi. Nessun problema con l'impostazione di SocketTimeouts - questi sono i migliori da usare.


2. Svolge correttamente la sua funzione.

Non dovete essere a conoscenza dei problemi con il rilevamento della rottura della connessione TCP. È abbastanza difficile (richiede risorse a costo di chiamate extra) rilevare che una connessione è garantita per essere interrotta correttamente. Tutte le implementazioni di rete soffrono di questo problema.

La nostra implementazione di SocketIsReadible è abbastanza intelligente e ha un rilevatore di rottura. Quando rileva uno 0 byte pulito, fa il lavoro extra di controllare che il socket sia 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);
     }

Poiché restituisce il numero di byte senza un flag di terminazione, emette 1 byte in modo che un successivo/imminente tentativo di lettura di SocketRead restituisca normalmente un errore.

Perché questo è corretto? Perché la maggior parte del codice è scritto dai programmatori in questo modo:

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

il risultato effettivo dell'operazione è controllato su un tentativo di lettura diretta.


3. ha bisogno di fare SocketIsReadible() prima della lettura effettiva, se non si conosce la dimensione esatta dei dati da leggere.

Il binding SocketisReadible/SocketRead vi dà la possibilità di non perdere il controllo (minimizzare a quasi zero la perdita di controllo) sul flusso di esecuzione del vostro programma. Questo evita di volare nei timeout di rete.

Sì, qualche riga di codice in più, ma non perderai il controllo per un millisecondo (circa). Sta a voi decidere cosa fare negli intervalli di assenza di dati di rete.


4. spiegato nel secondo paragrafo.

L'emissione di 1 per la stimolazione della lettura e dell'uscita come un errore di lettura.



Le vostre conclusioni sono sbagliate.

Questa è la natura del trasporto TCP/IP, dove non ci sono garanzie. Si può entrare nei buchi neri della rete anche lì sui filtri/firewall quando non c'è una parte di segnalazione TCP. Il timeout grezzo e il controllo del flusso di dati vi permettono di rilevarli e di terminare le connessioni da soli.

Abbiamo dato un'interfaccia di accesso grezzo/diretto alle funzioni di rete, comprese le implementazioni TLS. Se li usate, siete voi che dovete avvolgere correttamente le funzioni grezze in un gestore SocketIsReadible/SocketRead sicuro/controllato.

Se volete fare richieste di alto livello senza dover pensare alle minuzie, ci sono le funzioni WebRequest. Tutte le protezioni sono costruite lì dentro.