![Sviluppare un Expert Advisor per il trading da zero (Parte 13): Times e Trade (II)](https://c.mql5.com/2/49/Developing_a_trading_Expert_Advisor_from_scratch_004_600x314.jpg)
Sviluppare un Expert Advisor per il trading da zero (Parte 13): Times e Trade (II)
Introduzione
Nel precedente articolo "Times & Trade (I)" abbiamo discusso di un sistema di organizzazione grafica alternativa, che è una condizione essenziale per creare un indicatore che consenta l'interpretazione più rapida possibile delle transazioni eseguite sul mercato. Ma non abbiamo completato questo sistema: manca ancora la possibilità di mostrare come si può accedere a determinate informazioni, e come tale accesso aiuterebbe a capire meglio cosa sta succedendo. Tali informazioni non possono essere presentate direttamente sul grafico. In realtà, tale presentazione potrebbe essere implementata, tuttavia l'interpretazione sarebbe molto confusa. Perciò, è meglio avere i dati rappresentati in modo classico, vale a dire i valori in formato testo. Il nostro Expert Advisor non dispone di un sistema in grado di svolgere questo compito. Quindi, dobbiamo implementarlo.
Per non complicare l'articolo precedente aggiungendo informazioni che alcuni lettori potrebbero non aver bisogno (poiché il sistema può essere utilizzato senza approfondire tali dettagli), ho deciso di espandere il sistema qui e renderlo più completo, ma non ho incluso alcune cose nel sistema che sono state proposte nel precedente articolo. Ma queste informazioni a volte possono essere necessarie per capire cosa sta realmente accadendo nel mercato.
Pianificazione
È importante qui comprendere una cosa. Sono solo dettagli, ma come si suol dire il diavolo vive nei dettagli. Quindi, dai un'occhiata alla seguente immagine:
Noti qualcosa di strano in questa immagine? Qualcosa che potrebbe non avere molto senso, ma è qui, quindi guarda molto attentamente.
Se non hai notato ancora nulla di strano, guarda l'area evidenziata qui sotto.
Vedi cosa sta succedendo? In questo punto ci sono stati dei cambiamenti nei valori BID e ASK, ma è stato eseguito solo un trade. Anche se ci sono stati cambiamenti nei valori BID o ASK, non ha ancora senso avere un solo trade. Ma queste cose sono in realtà più comuni di quanto si possa pensare. Il problema è che una cosa del genere di solito non può essere vista quando si utilizza la modalità di lettura mostrata di seguito:
Quando si utilizza questo metodo di analisi del mercato, non possiamo vedere il movimento dei valori BID e ASK. Sembra che il mercato funzioni sempre, che tutti cerchino di chiudere il contratto, ma non è così. In realtà, gli operatori di mercato piazzano posizioni in determinati punti e aspettano il movimento del mercato. Quando la posizione viene raggiunta, cercano di trarre vantaggio e profitto dal movimento — per questo motivo, i valori BID o ASK si muovono senza alcuna operazione. Questo è un dato reale che si può vedere nella piattaforma, che viene però ignorato dalla maggior parte delle persone che ritengono che questa informazione non sia molto importante.
La figura seguente mostra come sarà il nostro sistema Times & Trade:
Se guardi da vicino, vedrai che ci sono quattro configurazioni di candele sul grafico. Dovrebbero essercene cinque, ma gli ordini diretti sono esclusi dal sistema perché di fatto non muovono il mercato. Pertanto, in realtà abbiamo quattro configurazioni. Queste che seguono sono le formazioni:
L'ombra a volte non tocca il corpo della candela. Perché succede? L'ombra è formata dal valore dello spread, che a sua volta è la differenza tra BID e ASK, ma se un'operazione avviene all'interno di questo spread, come sarà la candela? Questo sarà il quinto tipo, mostrato di seguito:
Secondo il tipo di formazione è una DOJI. Questo è il motivo per cui gli ordini diretti non vengono visualizzati nel sistema. Ma non spiega perché il corpo a volte non tocchi l'ombra. Tale comportamento è connesso a situazioni in cui accade qualcosa che causa un movimento di prezzo troppo veloce, a causa del quale c'è una distanza tra il corpo e l'ombra. Si potrebbe pensare che questo sia un errore di sistema, perché non ha senso per il prezzo fare questo. Ma qui ha senso, poiché ciò accade esattamente quando vengono attivati gli ordini stop. Per vederlo, dai un'occhiata all'immagine qui sotto:
C'è una serie di casi in cui ci sono ordini, ma né BID né Ask vengono toccati. Tutti questi punti rappresentano ordini stop attivati. Quando ciò accade, il prezzo di solito salta, come si può vedere sul grafico. Lo stesso fatto può essere visibile su Times & Trade solo se si utilizza la modalità grafico per valutare il movimento. Senza questo, non vedi l'attivazione degli stop e potresti pensare che il movimento abbia guadagnato forza mentre in realtà può tornare indietro rapidamente e verrai colpito dallo stop.
Ora che sai questo, capirai che una grande serie di candele che non toccano l'ombra rappresentano ordini stop attivati. Infatti, è impossibile catturare esattamente questo movimento quando si verifica, poiché tutto avviene molto rapidamente. Ma puoi usare l'interpretazione dei valori BID e ASK per capire perché è successo. Questo dipende da te e dalla tua esperienza di mercato. Non entrerò nei dettagli, ma questo è qualcosa su cui dovresti concentrarti se vuoi davvero usare la Lettura del Nastro come indicatore.
Ora arriva il dettaglio: se queste informazioni possono essere viste solo usando le candele e esse stesse sono sufficienti per apprendere alcune informazioni, allora perché è così necessario avere più dati?
Il grande dettaglio è che ci sono momenti in cui il mercato è più lento, in attesa di qualche informazione che possa essere pubblicata al momento, ma non possiamo saperlo semplicemente guardando il Times & Trade con le candele. Abbiamo bisogno di qualcosa di più. Queste informazioni esistono nel sistema stesso, ma è difficile interpretarle così come arrivano. I dati dovrebbero essere modellati in modo che possano essere analizzati più facilmente.
Questa modellazione è la ragione per cui ho scritto questo articolo: dopo che questa modellazione è stata fatta, Times & Trade cambierà per assomigliare a questo:
In altre parole, avremo un quadro completo di ciò che sta accadendo. Inoltre, tutto sarà veloce, il che è importante per tutti quelli che vogliono utilizzare la lettura del nastro come un modo per fare trading.
Implementazione
Per implementare il sistema, dobbiamo aggiungere diverse nuove variabili alla classe C_TimesAndTrade. Queste sono mostrate nel codice sottostante:
#include <NanoEA-SIMD\Auxiliar\C_FnSubWin.mqh> #include <NanoEA-SIMD\Auxiliar\C_Canvas.mqh> //+------------------------------------------------------------------+ class C_TimesAndTrade : private C_FnSubWin { //+------------------------------------------------------------------+ #define def_SizeBuff 2048 #define macro_Limits(A) (A & 0xFF) #define def_MaxInfos 257 //+------------------------------------------------------------------+ private : string m_szCustomSymbol, m_szObjName; char m_ConnectionStatus; datetime m_LastTime; ulong m_MemTickTime; int m_CountStrings; struct st0 { string szTime; int flag; }m_InfoTrades[def_MaxInfos]; struct st1 { C_Canvas Canvas; int WidthRegion, PosXRegion, MaxY; string szNameCanvas; }m_InfoCanvas;
L'evidenziazione mostra le parti che sono state aggiunte al codice sorgente. Come puoi vedere, dobbiamo usare la classe C_Canvas, ma non ha tutti gli elementi di cui abbiamo bisogno. Infatti, dobbiamo aggiungere quattro subroutine a questa classe C_Canvas. Queste subroutine sono mostrate nel codice seguente:
// ... C_Canvas class code inline void FontSet(const string name, const int size, const uint flags = 0, const uint angle = 0) { if(!TextSetFont(name, size, flags, angle)) return; TextGetSize("M", m_TextInfos.width, m_TextInfos.height); } //+------------------------------------------------------------------+ inline void TextOutFast(int x, int y, string text, const uint clr, uint alignment = 0) { TextOut(text, x, y, alignment, m_Pixel, m_width, m_height, clr, COLOR_FORMAT_ARGB_NORMALIZE); } //+------------------------------------------------------------------+ inline int TextWidth(void) const { return m_TextInfos.width; } //+------------------------------------------------------------------+ inline int TextHeight(void) const { return m_TextInfos.height; } //+------------------------------------------------------------------+ // ... The rest of the code ...
Queste linee creano il testo. Molto semplice, niente di estremamente elegante.
La prossima funzione in questa classe che vale la pena menzionare è C_TimesAndTrade:
void PrintTimeTrade(void) { int ui1; m_InfoCanvas.Canvas.Erase(clrBlack, 220); for (int c0 = 0, c1 = m_CountStrings - 1, y = 2; (c0 <= 255) && (y < m_InfoCanvas.MaxY); c0++, c1--, y += m_InfoCanvas.Canvas.TextHeight()) if (m_InfoTrades[macro_Limits(c1)].szTime == NULL) break; else { ui1 = m_InfoTrades[macro_Limits(c1)].flag; m_InfoCanvas.Canvas.TextOutFast(2, y, m_InfoTrades[macro_Limits(c1)].szTime, macroColorRGBA((ui1 == 0 ? clrLightSkyBlue : (ui1 > 0 ? clrForestGreen : clrFireBrick)), 220)); } m_InfoCanvas.Canvas.Update(); }
Questa funzione visualizzerà i valori nell'apposita area riservata a questo scopo. Inoltre, anche la procedura di inizializzazione ha subito delle modifiche minori, che possono essere viste di seguito nella parte evidenziata:
void Init(const int iScale = 2) { if (!ExistSubWin()) { m_InfoCanvas.Canvas.FontSet("Lucida Console", 13); m_InfoCanvas.WidthRegion = (18 * m_InfoCanvas.Canvas.TextWidth()) + 4; CreateCustomSymbol(); CreateChart(); m_InfoCanvas.Canvas.Create(m_InfoCanvas.szNameCanvas, m_InfoCanvas.PosXRegion, 0, m_InfoCanvas.WidthRegion, TerminalInfoInteger(TERMINAL_SCREEN_HEIGHT), GetIdSubWinEA()); Resize(); m_ConnectionStatus = 0; } ObjectSetInteger(Terminal.Get_ID(), m_szObjName, OBJPROP_CHART_SCALE, (iScale > 5 ? 5 : (iScale < 0 ? 0 : iScale))); }
Ulteriori modifiche erano richieste anche nella routine di sostituzione nel Times & Trade. Le modifiche sono le seguenti:
void Resize(void) { static int MaxX = 0; int x = (int) ChartGetInteger(Terminal.Get_ID(), CHART_WIDTH_IN_PIXELS, GetIdSubWinEA()); m_InfoCanvas.MaxY = (int) ChartGetInteger(Terminal.Get_ID(), CHART_HEIGHT_IN_PIXELS, GetIdSubWinEA()); ObjectSetInteger(Terminal.Get_ID(), m_szObjName, OBJPROP_YSIZE, m_InfoCanvas.MaxY); if (MaxX != x) { MaxX = x; x -= m_InfoCanvas.WidthRegion; ObjectSetInteger(Terminal.Get_ID(), m_szObjName, OBJPROP_XSIZE, x); ObjectSetInteger(Terminal.Get_ID(), m_InfoCanvas.szNameCanvas, OBJPROP_XDISTANCE, x); } PrintTimeTrade(); }
Il sistema è quasi pronto, ma abbiamo ancora bisogno della subroutine che è nel cuore del sistema. Inoltre è stato modificato:
inline void Update(void) { MqlTick Tick[]; MqlRates Rates[def_SizeBuff]; int i0, p1, p2 = 0; int iflag; long lg1; static int nSwap = 0; static long lTime = 0; if (m_ConnectionStatus < 3) return; if ((i0 = CopyTicks(Terminal.GetFullSymbol(), Tick, COPY_TICKS_ALL, m_MemTickTime, def_SizeBuff)) > 0) { for (p1 = 0, p2 = 0; (p1 < i0) && (Tick[p1].time_msc == m_MemTickTime); p1++); for (int c0 = p1, c1 = 0; c0 < i0; c0++) { lg1 = Tick[c0].time_msc - lTime; nSwap++; if (Tick[c0].volume == 0) continue; iflag = 0; iflag += ((Tick[c0].flags & TICK_FLAG_BUY) == TICK_FLAG_BUY ? 1 : 0); iflag -= ((Tick[c0].flags & TICK_FLAG_SELL) == TICK_FLAG_SELL ? 1 : 0); if (iflag == 0) continue; Rates[c1].high = Tick[c0].ask; Rates[c1].low = Tick[c0].bid; Rates[c1].open = Tick[c0].last; Rates[c1].close = Tick[c0].last + ((Tick[c0].volume > 200 ? 200 : Tick[c0].volume) * (Terminal.GetTypeSymbol() == C_Terminal::WDO ? 0.02 : 1.0) * iflag); Rates[c1].time = m_LastTime; m_InfoTrades[macro_Limits(m_CountStrings)].szTime = StringFormat("%02.d.%03d ~ %02.d <>%04.d", ((lg1 - (lg1 % 1000)) / 1000) % 60 , lg1 % 1000, nSwap, Tick[c0].volume); m_InfoTrades[macro_Limits(m_CountStrings)].flag = iflag; m_CountStrings++; nSwap = 0; lTime = Tick[c0].time_msc; p2++; c1++; m_LastTime += 60; } CustomRatesUpdate(m_szCustomSymbol, Rates, p2); m_MemTickTime = Tick[i0 - 1].time_msc; } PrintTimeTrade(); }
Le linee evidenziate rappresentano il codice aggiunto alla subroutine per modellare i dati di cui abbiamo bisogno. Il codice seguente
lg1 = Tick[c0].time_msc - lTime; nSwap++;
controlla quanto tempo è trascorso tra i trades in millisecondi e quanti trades che non hanno causato una variazione di prezzo si sono verificati. Se questi numeri sono grandi, puoi capire che il volume d’affari sta diminuendo. Con questa funzione lo noterai prima di altri.
La parte seguente
m_InfoTrades[macro_Limits(m_CountStrings)].szTime = StringFormat("%02.d.%03d ~ %02.d <>%04.d", ((lg1 - (lg1 % 1000)) / 1000) % 60 , lg1 % 1000, nSwap, Tick[c0].volume); m_InfoTrades[macro_Limits(m_CountStrings)].flag = iflag; m_CountStrings++; nSwap = 0; lTime = Tick[c0].time_msc;
modellerà i valori che verranno presentati. Tieni presente che non testeremo il contatore m_CountStrings a causa del suo uso limitato. Aumenteremo semplicemente i suoi valori man mano che saranno disponibili nuove informazioni. Questo è un trucco che a volte può essere usato. Io stesso lo uso quando possibile, poiché è efficiente in termini di elaborazione, il che è importante in quanto il sistema di trading è progettato per essere utilizzato in tempo reale. Dovresti sempre cercare di ottimizzare il sistema quando possibile, anche se solo un po' — alla fine fa una grande differenza.
Dopo che tutto è stato implementato, compila l'Expert Advisor e otterrai qualcosa del genere:
Osservando i movimenti sopra descritti sul grafico Times & Trade, puoi vedere che le microstrutture iniziano ad apparire nello stesso Times & Trade. Tuttavia, anche dopo aver studiato queste microstrutture, non ho potuto trarre alcun vantaggio dal fatto che esistano. Tuttavia, non sono un trader così esperto, quindi chissà, forse qualcuno con più esperienza può farlo.
Questo indicatore è così potente e così informativo che ho deciso di realizzare un video che mostri un piccolo confronto tra i suoi valori e i dati reali mostrati dall'asset al momento della scrittura. Voglio dimostrare che filtra molte informazioni, permettendoti di leggere i dati molto più velocemente e capire meglio cosa sta succedendo. Spero che ti piaccia e che tu ne tragga vantaggio da questo fantastico e potente indicatore.
Conclusioni
Tradotto dal portoghese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/pt/articles/10412
![Impara come progettare un sistema di trading tramite MFI](https://c.mql5.com/2/47/why-and-how__1.png)
![Sviluppare un Expert Advisor per il trading da zero (Parte 12): Times e Trade (I)](https://c.mql5.com/2/46/development__3.png)
![Impara come progettare un sistema di trading tramite Volumes](https://c.mql5.com/2/47/why-and-how__2.png)
![Operazioni con matrici e vettori in MQL5](https://c.mql5.com/2/48/matrix_and_vectors_2.png)
![MQL5 - Linguaggio delle strategie di trading integrato nel client terminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso