English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Sviluppare un Expert Advisor per il trading da zero (Parte 13): Times e Trade (II)

Sviluppare un Expert Advisor per il trading da zero (Parte 13): Times e Trade (II)

MetaTrader 5Sistemi di trading | 14 dicembre 2022, 09:31
460 0
Daniel Jose
Daniel Jose

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

Il sistema qui proposto è semplicemente una modifica del sistema di grafici disponibile nella stessa piattaforma MetaTrader 5. Ciò che è stato modificato è il metodo di modellazione dei dati. Può essere interessante vedere come i trades chiusi influenzino la direzione dei prezzi formando microstrutture nel timeframe più piccolo disponibile sulla piattaforma, ovvero 1 minuto. A molte persone piace dire che fanno trading su timeframe ad un minuto come se ciò significasse che hanno un alto livello di conoscenza del mercato. Ma se guardi più da vicino e comprendi i processi di trading, diventa chiaro che molte cose accadono all’interno di 1 minuto. Quindi, anche se questo sembra un breve lasso di tempo, questo può essere causa della perdita di molti trades potenzialmente profittevoli. Ricorda che in questo sistema Times & Trade non stiamo guardando cosa succede all’interno di 1 minuto — i valori che appaiono sullo schermo sono quotati in millisecondi.


Tradotto dal portoghese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/pt/articles/10412

File allegati |
EA_-_Times_m_Trade.zip (5983.76 KB)
Impara come progettare un sistema di trading tramite MFI Impara come progettare un sistema di trading tramite MFI
Il nuovo articolo della nostra serie sulla progettazione di un sistema di trading basato sugli indicatori tecnici più popolari considera un nuovo indicatore tecnico - il Money Flow Index (MFI). Lo impareremo in dettaglio e svilupperemo un semplice sistema di trading tramite MQL5 per eseguirlo in MetaTrader 5.
Sviluppare un Expert Advisor per il trading da zero (Parte 12): Times e Trade (I) Sviluppare un Expert Advisor per il trading da zero (Parte 12): Times e Trade (I)
Oggi creeremo Times & Trade con interpretazione rapida per la lettura del flusso degli ordini. È la prima parte in cui costruiremo il sistema. Nel prossimo articolo completeremo il sistema con le informazioni mancanti. Per implementare questa nuova funzionalità, dovremo aggiungere parecchie cose nuove al codice del nostro Expert Advisor.
Impara come progettare un sistema di trading tramite Volumes Impara come progettare un sistema di trading tramite Volumes
Ecco un nuovo articolo della nostra serie sull'apprendimento di come progettare sistemi di trading basati sugli indicatori tecnici più comuni. Questo articolo sarà dedicato all'indicatore Volumes. Il volume come concetto è uno dei fattori più importanti nel trading sui mercati finanziari e dobbiamo prestargli attenzione. Attraverso questo articolo, impareremo come progettare un semplice sistema di trading tramite l'indicatore Volumes.
Operazioni con matrici e vettori in MQL5 Operazioni con matrici e vettori in MQL5
Le matrici e i vettori sono stati introdotti in MQL5 per un’operatività efficiente con soluzioni matematiche. I nuovi tipi offrono metodi integrati per creare codice conciso e comprensibile, vicino alla notazione matematica. Gli array offrono ampie possibilità, ma ci sono molti casi in cui le matrici sono molto più efficienti.