English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Crea i Tuoi Pannelli Grafici in MQL5

Crea i Tuoi Pannelli Grafici in MQL5

MetaTrader 5Esempi | 17 dicembre 2021, 14:30
243 0
MetaQuotes
MetaQuotes

Introduzione

C'è un nuovo set di classi disponibile nella Libreria Standard. Queste classi sono progettate per lo sviluppo indipendente di finestre di dialogo di controllo e pannelli di visualizzazione nei programmi MQL5.

Il nuovo set di classi consente a tutti di creare componenti di interfaccia personalizzati utilizzando il modello basato su eventi come modello di base. Tutto si basa sugli oggetti e gli eventi del grafico integrati del Terminale.

Le classi sviluppate possono essere utilizzate nei seguenti modi:
  1. Pannello di visualizzazione in una sottofinestra del grafico separata;
  2. Pannello di controllo per un Expert Advisor;
  3. Pannello di controllo del display personalizzato.

In questo articolo, verrà illustrato quanto sia facile creare pannelli di visualizzazione propri in una sottofinestra del grafico separata utilizzando le classi Libreria Standard.


Cosa Ha da Offrire la Libreria Standard?

La Libreria Standard fornisce allo sviluppatore i seguenti controlli pronti per l'uso:

1. Controlli semplici:

Controllo Applicazione Implementazione basata sull'oggetto integrato File della Libreria Standard

Pulsante con testo

Garantire l'interazione tra il mouse e il programma MQL

"Button"  <Controls\Button.mqh>

Pulsante con immagine

Garantire l'interazione tra il mouse e il programma MQL

"Etichetta grafica"  <Controls\BmpButton.mqh>

Modifica

Inserimento o visualizzazione di informazioni di testo (in modalità "Sola Lettura")

"Edit"  <Controls\Edit.mqh>

Didascalia

Visualizzazione di informazioni di testo ausiliarie

"Text label"  <Controls\Label.mqh>

Pannello

Controllo ausiliario (raggruppamento visivo dei controlli)

Etichetta Rettangolare  <Controls\Panel.mqh>

Immagine

Controllo decorativo

 "Etichetta grafica"  <Controls\Picture.mqh>



2. Controlli complessi:


Controllo Applicazione Implementazione basata sui controlli File della Libreria Standard

Lista

Visualizzazione di un elenco

"Rettangolo", "Pulsante con immagine" e "Modifica"  <Controls\List.mqh>

Campo con un elenco a tendina

Selezione da un elenco a tendina

"Modifica", "Pulsante con immagine" ed "Elenco"  <Controls\ComboBox.mqh>

Campo Incremento/decremento

Enumerazione dei valori

"Modifica" e "Pulsante con immagine"  <Controls\SpinEdit.mqh>

Radio button

Switch "Pulsante con immagine" e "Didascalia"  <Controls\RadioButton.mqh>
 Gruppo radio button  Modifica dei campi di tipo enum  "Rettangolo" e "Radio button"  <Controls\RadioGroup.mqh>

Checkbox

Opzione di selezione

"Pulsante con immagine" e "Didascalia"  <Controls\CheckBox.mqh>

Gruppo checkbox

Modifica di un set di flag

 "Rettangolo" e "Checkbox"  <Controls\CheckGroup.mqh>
 Dialogo  Modulo finestra di dialogo  "Rettangolo", "Pulsante con immagine" e "Modifica"  <Controls\Dialog.mqh>



Creazione di un Pannello di Visualizzazione

Definiamo prima i termini. Il pannello di Visualizzazione è un termine che useremo per descrivere una visualizzazione personalizzata della finestra separata che non ha buffer di disegno. Tale pannello mostra semplicemente le informazioni richieste utilizzando gli oggetti grafico integrati nel Terminale. Le informazioni possono essere visualizzate:

  • numericamente,
  • come testo,
  • come colore,
  • ecc.

Daremo uno sguardo dettagliato ad ogni passaggio richiesto e creeremo un pannello grafico come segue:



Per creare un pannello di visualizzazione, avremo bisogno di due file:

  1. Il file di include contenente la descrizione della classe del pannello di visualizzazione.
  2. File di codice sorgente dell'indicatore.

I modelli di questi file possono essere ottenuti utilizzandoMQL5 Wizard. Nella directory degli indicatori (MQL5\Indicators), creare una cartella separata MyIndicators e una sottocartella MyPanel. Il processo di creazione delle cartelle non verrà trattato qui come è ben descritto nella Guida.


Descrizione della Classe

Quindi, abbiamo già creato la cartella di lavoro. Cerchiamo ora di trovarlo nella finestra "Navigator" e fare click con il pulsante destro del mouse su di esso. Seleziona "Nuovo file" nel menu che compare. Seleziona la "Nuova classe" tra le opzioni fornite dalla MQL5 Wizard e fai click su "Avanti >". Completa la finestra di dialogo della descrizione della classe come mostrato di seguito:

Creazione di una nuova classe in MQL Wizard

Fai click su "Fine". Di conseguenza, abbiamo il seguente codice:

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog();
                    ~CPanelDialog();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog()
  {
  }
//+------------------------------------------------------------------+


Aggiungere il file include <Controls\Dialog.mqh> dalla Libreria Standard con la descrizione della classe CAppDialog di base e i commenti.

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+

Ora, abbiamo la descrizione della classe che ci permetterà di utilizzare una finestra di dialogo nel suo indicatore. La nostra finestra di dialogo è attualmente vuota, ma aggiungeremo controlli un po’ più tardi. Al momento, passiamo all'indicatore.


Il Codice Sorgente dell'Indicatore

L'indicatore verrà creato anche utilizzando MQL5 Wizard. Le nostre azioni saranno simili a quelle richieste quando si scrive la descrizione della classe. C'è solo una differenza: selezioniamo "Indicatore personalizzato" tra le opzioni fornite da MQL5 Wizard. Per creare un indicatore, è necessario completare tre finestre di dialogo.

Il primo richiede di specificare il nome dell'indicatore:

Creazione di un nuovo indicatore in MQL Wizard


Nella seconda finestra di dialogo, spuntare "OnChartEvent" (obbligatorio) e "OnTimer":

Impostazione dei gestori eventi per l'indicatore personalizzato in MQL Wizard



Spuntare "Separate Window Indicator" (obbligatorio) nella terza finestra di dialogo:

Impostazione delle proprietà del disegno dell'indicatore in MQL Wizard


E fai click su "Fine". Il codice prodotto è il seguente:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+


Il nostro modello può ora essere completato aggiungendo:

  • le descrizioni mancanti delle proprietà dell'indicatore;
  • includere il file contenente la descrizione della classe della nostra finestra di dialogo;
  • una variabile globale - l'oggetto classe della nostra finestra di dialogo;
  • il codice per la creazione della finestra di dialogo, l'avvio dell'applicazione e la creazione del timer nel corpo della funzione OnInit();
  • OnDeinit() contenente un codice che distrugge la finestra di dialogo e spegne il timer;
  • la funzione OnChartEvent(...) al codice chiamante del gestore eventi;
  • commenti.

Abbiamo l'indicatore pronto per l'uso:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
     return(-1);
//--- starting the application
   if(!ExtDialog.Run())
     return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
int OnDeinit()
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {  
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


L'indicatore nel modulo di cui sopra non mostra ancora nulla. Una volta compilato e rilasciato dal Navigatore sul grafico, verrà visualizzato come una finestra di dialogo vuota in una finestra separata.

Nonostante la finestra di dialogo sia vuota, il nostro indicatore ha già acquisito alcune funzionalità:

  • l'altezza della sottofinestra è stata regolata all'altezza della finestra di dialogo dall'indicatore durante la creazione;
  • la larghezza della finestra di dialogo è sempre uguale alla larghezza del grafico;
  • l'indicatore può ridurre al minimo e ottimizzare la propria sottofinestra.

Lascia che si visualizzi

Affinché il nostro pannello inizi a visualizzare qualsiasi informazione, dovremmo decidere le risposte a tre domande:

  1. Che tipo di informazioni vogliamo visualizzare?
  2. Quali elementi di visualizzazione e/o controlli aggiuntivi devono essere inseriti nella nostra finestra di dialogo?
  3. Come interagiranno questi elementi/controlli aggiuntivi?

Un altro fattore importante è che la nostra finestra di dialogo deve essere visivamente accattivante e facile da usare. Non influisce sulla funzionalità della finestra di dialogo, ma mostra che ci preoccupiamo degli utenti del futuro programma MQL5.

   Fase 1. Che tipo di informazioni vogliamo visualizzare?

Poiché l'articolo funge da strumento di apprendimento, non soffermiamoci sull'usabilità dell'indicatore. Il colore verrà visualizzato in funzione di tre parametri. Non complicheremo eccessivamente i parametri: questi saranno livelli "rosso", "verde" e "blu".

I valori dei parametri verranno impostati come segue:

  • Il valore del livello "rosso" verrà impostato nell'intervallo da 0 a 255 cambiando in modo casuale ad ogni evento Calculate;
  • Il valore del livello "verde" verrà impostato nell'intervallo da 0 a 255 cambiando in modo casuale ad ogni evento Timer;
  • Il valore del livello "blu" verrà impostato nell'intervallo da 0 a 255 e verrà modificato manualmente mediante uno speciale controllo.

A tal proposito, i valori di questi livelli verranno visualizzati anche nel nostro indicatore.


   Step 2. Quali controlli aggiuntivi saranno necessari?

  1. Il colore verrà visualizzato utilizzando il controllo "Pannello".
  2. I livelli "rosso" e "verde" verranno visualizzati utilizzando il controllo "Modifica" in modalità "Sola lettura".
  3. Il livello "blu" sarà gestito dal controllo "Spin Edit". Lo stesso controllo aiuterà a visualizzare il valore del livello.
  4. Entrambi i controlli "Edit" e "Spin Edit" verranno migliorati con didascalie esplicative tramite il controllo "Didascalia".

Aggiungere i file di include dalla Libreria Standard, nonché i controlli e le variabili necessari che memorizzano i valori dei parametri nella descrizione della classe dopo aver fornito i commenti.

Avremo:

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Panel.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Label.mqh>
#include <Controls\SpinEdit.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:
   //--- additional controls
   CPanel            m_color;                         // object for displaying color
   CLabel            m_label_red;                     // "red" level caption object
   CEdit             m_field_red;                     // "red" value display object
   CLabel            m_label_green;                   // "green" level caption object
   CEdit             m_field_green;                   // "green" value display object
   CLabel            m_label_blue;                    // "blue" level caption object
   CSpinEdit         m_edit_blue;                     // "blue" value control object
   //--- parameter values
   int               m_red;                           // "red" value
   int               m_green;                         // "green" value
   int               m_blue;                          // "blue" value

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+


   Fase 3. Come interagiranno questi controlli di dialogo aggiuntivi?
Il principio di interazione tra i controlli della finestra di dialogo sarà molto semplice: "La finestra di dialogo visualizzerà le modifiche in qualsiasi parametro (livelli "rosso", "verde" e "blu")". L'implementazione degli algoritmi di interazione verrà affrontata in seguito poiché ora è giunto il momento di iniziare a creare la finestra di dialogo.


Qualche parola sul richiamo visivo

Prima di procedere alla creazione della finestra di dialogo, cerchiamo di avere una rapida panoramica del richiamo visivo. O per meglio dire, un’organizzazione user-friendly e (possibile) futura riorganizzazione dei controlli delle finestre di dialogo. Le costanti denominate (#define) servono meglio a questo scopo.

Ci sono alcuni vantaggi offerti dalle costanti denominate predefinite:

  • alcuni valori numerici utilizzati in casi specifici non devono essere ricordati. I nomi costanti accuratamente selezionati forniranno un rapido accesso ad essi tramite l’"Auto List Names";
  • quando i valori costanti vengono ulteriormente modificati, non è necessario cercare e sostituire numerose inclusioni di valori numerici. È sufficiente modificare solo la descrizione della costante.

Si suggerisce l'uso delle seguenti costanti:

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and spacing
#define INDENT_LEFT                         (11)      // left indent (including the border width)
#define INDENT_TOP                          (11)      // top indent (including the border width)
#define INDENT_RIGHT                        (11)      // right indent (including the border width)
#define INDENT_BOTTOM                       (11)      // bottom indent (including the border width)
#define CONTROLS_GAP_X                      (10)      // spacing along the X-axis
#define CONTROLS_GAP_Y                      (10)      // spacing along the Y-axis
//--- for labels
#define LABEL_WIDTH                         (50)      // size along the X-axis
//--- for edits
#define EDIT_WIDTH                          (50)      // size along the Y-axis
#define EDIT_HEIGHT                         (20)      // size along the Y-axis
//--- for base colors (RGB)
#define BASE_COLOR_MIN                      (0)       // minimum value of the color component
#define BASE_COLOR_MAX                      (255)     // maximum value of the color component


Riempimento del Pannello di Visualizzazione

In precedenza abbiamo creato la classe del pannello di visualizzazione;ora, per ottenere la funzionalità richiesta, dobbiamo fare quanto segue:

1. Ridefinire il metodo Create(...) della classe padre. Inizialmente, il nostro metodo apparirà come segue:

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the method of the parent class
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))  return(false);
//--- additional controls shall be created here

//--- success
   return(true);
  }


2. Creare controlli aggiuntivi.

Una leggera digressione poetica. I codici per la creazione di tutti i controlli aggiuntivi possono ovviamente essere inseriti direttamente nel corpo del metodo Create(...), ma in questo modo rischiamo di ottenere un grande "volume" illeggibile.

Divideremo quindi il processo di creazione in parti autonome rappresentate da metodi:

  • bool CreateColor(void) - creazione di pannelli di colore,
  • bool CreateRed(void) - creazione dell'elemento di visualizzazione "Red" con didascalia esplicativa,
  • bool CreateGreen(void) - creazione dell'elemento di visualizzazione "Green" con didascalia esplicativa,
  • bool CreateBlue(void) - creazione del controllo "Blue" con didascalia esplicativa.

Questi metodi vengono chiamati in sequenza dal metodo Create(...):

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,
                             const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the parent class method
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false);

//--- creating additional elements
   if(!CreateColor()) return(false);
   if(!CreateRed())   return(false);
   if(!CreateGreen()) return(false);
   if(!CreateBlue())  return(false);
//--- success
   return(true);
  }


Creazione di Controlli

Non esamineremo la creazione di ogni controllo aggiuntivo, ma daremo un'occhiata dettagliata al metodo bool CreateBlue(void).

È il seguente:

//+------------------------------------------------------------------+
//| Creating the "Blue" control with explanatory caption             |
//+------------------------------------------------------------------+
bool CPanelDialog::CreateBlue(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+2*(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+EDIT_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- creating the caption
   if(!m_label_blue.Create(m_chart_id,m_name+"LabelBlue",m_subwin,x1,y1+1,x2,y2)) return(false);
   if(!m_label_blue.Text("Blue")) return(false);
   if(!Add(m_label_blue)) return(false);
//--- adjusting coordinates
   x1+=LABEL_WIDTH+CONTROLS_GAP_X;
   x2=x1+EDIT_WIDTH;
//--- creating the control
   if(!m_edit_blue.Create(m_chart_id,m_name+"Blue",m_subwin,x1,y1,x2,y2)) return(false);
   if(!Add(m_edit_blue)) return(false);
   m_edit_blue.MinValue(BASE_COLOR_MIN);
   m_edit_blue.MaxValue(BASE_COLOR_MAX);
   m_edit_blue.Value(m_blue);
//--- success
   return(true);
  }

Ci sono due sfumature:

  1. Il controllo viene creato con le relative coordinate, ovvero l'offset viene impostato rispetto all'angolo in alto a sinistra del contenitore (elemento complesso) a cui verrà aggiunto il controllo dopo la creazione.
  2. Dopo la creazione, è necessario aggiungere il controllo a un contenitore utilizzando il metodo Add(...). Nel nostro caso, la finestra di dialogo funge da contenitore.


Modifica dei Parametri

Aggiungete il metodo void SetColor(void) per modificare il colore del pannello dei colori;

Per poter modificare i parametri (livelli dei colori di base) esternamente, aggiungeremo tre metodi pubblici:

  • void SetRed(const int value) - cambia il livello "rosso" e visualizza il cambiamento nell'indicatore,
  • void SetGreen(const int value) - cambia il livello "verde" e visualizza il cambiamento nell'indicatore,
  • void SetBlue(const int value) - cambia il livello "blu" e visualizza la variazione nell'indicatore.

La frase "visualizza il cambiamento nell'indicatore" significa che il nuovo valore del livello di colore di base viene visualizzato nella forma numerica nel controllo corrispondente e il pannello dei colori cambia colore.

Di seguito, viene riportato un codice di uno dei metodi che fungono da esempio:

//+------------------------------------------------------------------+
//| Setting the "Red" value                                          |
//+------------------------------------------------------------------+
void CPanelDialog::SetRed(const int value)
  {
//--- checking
   if(value<0 || value>255) return;
//--- saving
   m_red=value;
//--- setting
   m_field_red.Text(IntegerToString(value));
//--- setting the panel color
   SetColor();
  }

Come concordato in precedenza:

  • Il valore del livello "rosso" cambierà in modo casuale ad ogni evento Calculate;
  • Il valore del livello "verde" cambierà in modo casuale ad ogni evento Timer;

Aggiungiamo il codice corrispondente nell'indicatore originale:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
      return(-1);
//--- starting the application
   if(!ExtDialog.Run())
      return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- changing the dialog property
   ExtDialog.SetRed(MathRand()%256);
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- changing the dialog property
   ExtDialog.SetGreen(MathRand()%256);
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


Gestione degli Eventi

L'intera interazione tra la finestra di dialogo e il Terminale, nonché l'interazione tra i controlli della finestra di dialogo si basa sul meccanismo event. Non esamineremo le sue funzioni, ma semplicemente lo useremo.

Gli eventi possono essere convenzionalmente suddivisi in due gruppi:

  • Eventi interni gestiti ignorando la coda degli eventi del Terminale;
  • Eventi esterni gestiti tramite la coda di eventi del Terminale.

Gestiremo entrambi i tipi di eventi.

Tra gli eventi interni, devono essere gestiti solo gli eventi di ridimensionamento della finestra di dialogo. A tale scopo, ricarica il metodo OnResize() della classe padre. Il nostro metodo sarà semplice in quanto non vi è alcun cambiamento nell'altezza della finestra di dialogo; se la larghezza della finestra di dialogo cambia, dobbiamo solo modificare la larghezza del pannello di colore:

//+------------------------------------------------------------------+
//| Resize handler                                                   |
//+------------------------------------------------------------------+
bool CPanelDialog::OnResize(void)
  {
//--- calling the parent class method
   if(!CAppDialog::OnResize()) return(false);
//--- changing the color panel width
   m_color.Width(ClientAreaWidth()-(INDENT_RIGHT+LABEL_WIDTH+CONTROLS_GAP_X+EDIT_WIDTH+CONTROLS_GAP_X+INDENT_LEFT));
//--- success
   return(true);
  }

Anche l'elenco degli eventi esterni sarà limitato a un elemento: l'evento di modifica del livello "blu". I requisiti per il gestore eventi esterno sono minimi: il gestore deve essere il metodo di classe senza parametri di tipo void.

Descriviamo il gestore di questo evento:

//+------------------------------------------------------------------+
//| Handler of the event of changing the "blue" level                |
//+------------------------------------------------------------------+
void CPanelDialog::OnChangeBlue(void)
  {
//--- saving
   m_blue=m_edit_blue.Value();
//--- setting the panel color
   SetColor();
  }

Come si può vedere, non c'è nulla di difficile in esso.

Affinché la nostra finestra di dialogo gestisca eventi esterni, il metodo della classe padre deve essere ricaricato:

virtual bool  OnEvent(const int id,const long &lparam,
                       const double &dparam,const string &sparam);

E ora un po' di mistero. Se il file PanelDialog.mqh è già stato aperto nell'editor, si vedrà che non è presente alcun corpo del metodo OnEvent(...).

Non confonderti - il fatto è che, per la descrizione della gestione degli eventi esterni, è stato creato un set di macro (vedere <Controls\Defines.mqh> file nella Libreria Standard).

Il gestore eventi è il seguente:

//+------------------------------------------------------------------+
//| Handling events                                                  |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CPanelDialog)
   ON_EVENT(ON_CHANGE,m_edit_blue,OnChangeBlue)
EVENT_MAP_END(CAppDialog)

Questo pseudocodice, che potrebbe non essere chiaro a prima vista, fa quanto segue:

  • Quando l'evento ON_CHANGE viene ricevuto dal controllo m_edit_blue, viene chiamato il metodo OnChangeBlue e la gestione dell'evento viene completata (restituendo true);
  • Nel ricevere qualsiasi altro evento, il controllo viene trasferito al metodo della classe padre.

Conclusione

In questo articolo, è stata fornita la revisione del processo di creazione di un pannello di visualizzazione utilizzando le classi Libreria Standard.

È improbabile che utilizzi l'indicatore così come è stato creato, tuttavia non è sovraccarico di informazioni inutili e siamo riusciti a coprire quasi tutte le peculiarità del processo durante la sua creazione.

Esempi di consegna standard più complessi sono disponibili nelle seguenti directory del Terminale:

  • Esperti\Esempi\Controlli\
  • Indicatori\Esempi\Pannelli\ChartPanel\
  • Indicators\Examples\Panels\SimplePanel\

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/345

File allegati |
paneldialog.mqh (13.04 KB)
panelindicator.mq5 (3.38 KB)
MetaTrader 5 - Più di Quanto Tu Possa Immaginare! MetaTrader 5 - Più di Quanto Tu Possa Immaginare!
Il client terminal MetaTrader 5 è stato sviluppato da zero e supera di gran lunga il suo predecessore, ovviamente. La nuova piattaforma di trading offre opportunità illimitate per il trading in qualsiasi mercato finanziario. Inoltre, la sua funzionalità continua ad espandersi per offrire funzionalità e praticità ancora più utili. Quindi, ora è abbastanza difficile elencare tutti i numerosi vantaggi di MetaTrader 5. Abbiamo cercato di descriverli brevemente in un articolo e siamo rimasti sorpresi dal risultato; l'articolo è tutt'altro che breve!
Uso delle Risorse in MQL5 Uso delle Risorse in MQL5
I programmi MQL5 non solo automatizzano i calcoli di routine, ma possono anche creare un ambiente grafico completo. Le funzioni per la creazione di controlli realmente interattivi sono ora virtualmente altrettanto ricche, come quelle nei classici linguaggi di programmazione. Se vuoi scrivere un programma autonomo completo in MQL5, utilizzare le risorse al loro interno. I programmi con risorse sono più facili da mantenere e distribuire.
Visualizza una Strategia nel Tester MetaTrader 5 Visualizza una Strategia nel Tester MetaTrader 5
Conosciamo tutti il detto "Meglio vedere una volta che sentire cento volte". Puoi leggere vari libri su Parigi o Venezia, ma in base alle immagini mentali non avresti le stesse sensazioni di una passeggiata serale in queste favolose città. Il vantaggio della visualizzazione può essere facilmente proiettato su qualsiasi aspetto della nostra vita, incluso il lavoro sul mercato, ad esempio l'analisi dei prezzi sui grafici utilizzando indicatori e, naturalmente, la visualizzazione dello strategy testing. Questo articolo contiene le descrizioni di tutte le funzionalità di visualizzazione del Tester MetaTrader 5 Strategy.
Indicatori e Sistemi di Trading di William Blau in MQL5. Parte 1: Indicatori Indicatori e Sistemi di Trading di William Blau in MQL5. Parte 1: Indicatori
L'articolo presenta gli indicatori, descritti nel libro di William Blau "Momentum, Direction, and Divergence". L'approccio di William Blau ci consente di approssimare tempestivamente e accuratamente le fluttuazioni della curva dei prezzi, di determinare l'andamento dei movimenti dei prezzi e dei punti di svolta ed eliminare il rumore dei prezzi. Nel frattempo, siamo anche in grado di rilevare gli stati di ipercomprato/ipervenduto del mercato e segnali, che indicano la fine di una tendenza e l'inversione del movimento dei prezzi.