Sistemi Esperti: MQL5 Programming for Traders – Source Codes from the Book. Parte 7 - pagina 3
Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
Allego alcuni bugfix e miglioramenti nelle classi websockets.
Nel codice sono state pubblicate altre correzioni e miglioramenti per la lettura del calendario economico e l'esportazione in CSV. In particolare, è stato corretto l'algoritmo di ordinamento per il caso di array di grandi dimensioni per lo più ordinati (che di solito vengono ricevuti dall'API calendario di MQL5), in modo da eliminare rallentamenti e stack-overflow.
C'è una piccola gemma alla riga 126 di msclient.mqh 'return connection.handshake(url, host, origin, custom_headers);' passando l'intero 'url' invece di 'path' si ottiene l'errore 403 su python websocket. Ho dovuto apportare questa modifica prima che l'EA potesse connettersi con successo al mio server websocket python.
Hoallegato il log del server da Postman (superato) e dall'EA prima che apportassi la modifica (fallita)
Ma ecco il problema successivo, il mio server invia automaticamente un ping keepalive a un intervallo configurato, ma l'implementazione del websocket MT5 non sembra rispondere e questo comportamento fa sì che il server abbandoni sempre la connessione del client subito dopo il timeout del ping.
Per favore, qualsiasi aiuto per quanto riguarda il ping pong keepalive sarà apprezzato.
C'è un piccolo germoglio nella riga 126 di msclient.mqh 'return connection.handshake(url, host, origin, custom_headers);' passando l'intero 'url' invece di 'path' si ottiene l'errore 403 su python websocket. Ho dovuto apportare questa modifica prima che l'EA potesse connettersi con successo al mio server websocket python.
Hoallegato il log del server da Postman (superato) e dall'EA prima che apportassi la modifica (fallita)
Ma ecco il problema successivo, il mio server invia automaticamente un ping keepalive a un intervallo configurato, ma l'implementazione del websocket MT5 non sembra rispondere e questo comportamento fa sì che il server abbandoni sempre la connessione del client subito dopo il timeout del ping.
Per favore, qualsiasi aiuto per quanto riguarda il ping pong keepalive sarà apprezzato.
Ciao, sì, puoi usare il percorso nella chiamata del client:
D'altra parte, la sintassi della richiesta HTTP supporta l'URI completo come target, e ho fatto dei test con i codici sorgente originali su diversi server (incluso wss://ws.postman-echo.com/raw) e hanno funzionato normalmente. Quindi non sono sicuro che si tratti di una violazione o che l'implementazione di python sia troppo rigida.
Per quanto riguarda ping/pong, dovrebbe funzionare. Date un'occhiata a wsprotocol.mqh:
Quindi, per favore, eseguite il debug di queste cose sul vostro lato, dato che il server invia i ping al vostro client.
BTW, ho dimenticato di aggiungere la nuova versione di MQL5Book/StringUtils.mqh utilizzata in ws/sources.
Il problema si trova alla riga 310 all'interno dello switch/case del frame ws ping, quando viene creato il frame websocket:
IWebSocketFrame *temp = WebSocketFrame::create(WS_FRAME_OPCODE::WS_PONG_FRAME, frame.getData());
frame.getData() il server sembra riconoscere il pong solo se i dati del ping sono basati su testo/stringa ma fallisce se è stato inviato un ping binario
quindi ho dovuto usare il sovraccarico frame.getData(uchar &buf[]) per farlo funzionare in entrambi i casi. Non so se incontrerò altri casi d'uso che (la mia modifica) romperà, ma per ora sembra tutto a posto.
Per curiosità, mi chiedo perché dobbiamo controllare manualmente i messaggi a intervalli con il gestore di eventi OnTimer(), mentre vedo qualcosa che sembra una funzione di gestore di eventi OnMessage per i messaggi in arrivo. Anche se la configurazione attuale funziona così com'è, apprezzerei se poteste illuminarmi di più sul perché di questo approccio.
@Stanislav Korotky grazie ancora per il tuo aiuto. Per quanto riguarda il problema del ping pong con il server websocket python, dopo un ulteriore debug ho notato che il server invia la richiesta di ping sia come testo che come dati binari e l'MT5 risponde correttamente solo quando viene inviato un ping basato sul testo. Questo mi ha aiutato a rintracciare e risolvere il problema.
Il problema si trova alla riga 310 all'interno dello switch/case del frame ws ping, quando viene creato il frame websocket:
IWebSocketFrame *temp = WebSocketFrame::create(WS_FRAME_OPCODE::WS_PONG_FRAME, frame.getData());
frame.getData() il server sembra riconoscere il pong solo se i dati del ping sono basati su testo/stringa ma fallisce se è stato inviato un ping binario
quindi ho dovuto usare il sovraccarico frame.getData(uchar &buf[]) per farlo funzionare in entrambi i casi. Non so se incontrerò altri casi d'uso che (la mia modifica) romperà, ma per ora sembra tutto a posto.
Per curiosità, mi chiedo perché dobbiamo controllare manualmente i messaggi a intervalli con il gestore di eventi OnTimer(), mentre vedo qualcosa che sembra una funzione di gestore di eventi OnMessage per i messaggi in arrivo. Anche se la configurazione attuale funziona così com'è, apprezzerei se poteste illuminarmi di più sul perché di questo approccio
Grazie per il tuo impegno. Prenderò in considerazione la possibilità di includere le tue modifiche nel codice sorgente.
Per quanto riguarda OnTimer e OnMessage, sono forniti perché si potrebbe voler implementare una logica di elaborazione diversa nella propria applicazione. Le letture dai socket sono bloccanti a livello di API MQL5, con un timeout specificato. Pertanto, se si è interessati solo ad attendere nuovi messaggi, alla loro elaborazione e alla generazione automatica di risposte, è possibile farlo in modalità bloccante (con timeout infinito in lettura e senza OnTimer) - cioè l'applicazione è una sorta di blocco in attesa dei dati. Ma se è necessario fornire un'interfaccia utente reattiva (come nel caso dell'applicazione di chat), si può impostare un piccolo timeout per i tentativi di lettura brevi in OnTimer-handler (possono produrre dati vuoti se il timeout è scaduto) e monitorare le azioni dell'utente nel mezzo.
Grazie per i vostri sforzi. Prenderò in considerazione la possibilità di includere le vostre modifiche nel codice sorgente.
Per quanto riguarda OnTimer e OnMessage, sono forniti perché si potrebbe voler implementare una logica di elaborazione diversa nella propria applicazione. Le letture dai socket sono bloccanti a livello di API MQL5, con un timeout specificato. Pertanto, se si è interessati solo ad attendere nuovi messaggi, alla loro elaborazione e alla generazione automatica di risposte, è possibile farlo in modalità bloccante (con timeout infinito in lettura e senza OnTimer) - cioè l'applicazione è una sorta di blocco in attesa dei dati. Ma se è necessario fornire un'interfaccia utente reattiva (come nel caso dell'applicazione di chat), si può impostare un piccolo timeout per i tentativi di lettura brevi in OnTimer-handler (possono produrre dati vuoti se il timeout è scaduto) e monitorare le azioni dell'utente nel mezzo.
Ecco un altro gruppo di correzioni di bug minori e miglioramenti dei codici sorgente di wss in un archivio zip.
Tra le altre cose, è ora possibile analizzare gli aggiornamenti non riusciti (ad esempio, se è richiesta l'autorizzazione e viene restituito un codice di stato diverso da 101) e prendere provvedimenti:
Anche StringUtils.mqh e URL.mqh hanno ricevuto importanti correzioni.
Ciao @Stanislav Korotky, sono nuovo di MQL5. Ho scoperto che hai pubblicato un file wss.zip per l'uso di websocket. Come si usa, c'è una demo o qualcosa che posso imparare. Grazie di cuore!