English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Manuale MQL5: Scrittura della cronologia delle offerte in un file e creazione di grafici di bilanciamento per ogni simbolo in Excel

Manuale MQL5: Scrittura della cronologia delle offerte in un file e creazione di grafici di bilanciamento per ogni simbolo in Excel

MetaTrader 5Esempi | 11 gennaio 2022, 16:48
97 0
Anatoli Kazharski
Anatoli Kazharski

Introduzione

Quando comunicavo in vari forum, usavo spesso esempi dei risultati dei miei test visualizzati come schermate di grafici di Microsoft Excel. Molte volte mi è stato chiesto di spiegare come tali grafici possono essere creati. Excel offre ampie funzionalità per la creazione di grafici e ci sono molti libri su questo argomento. Per trovare le informazioni richieste in un libro, potrebbe essere necessario leggerle tutte. Ora finalmente, ho un po 'di tempo per spiegare tutto in questo articolo.

Nei due articoli precedenti Articolo Manuale MQL5: Multi-Currency Expert Advisor - Approccio semplice, pulito e veloce e Manuale MQL5: Sviluppando un Expert Advisor Multi-Valuta con numero Illimitato di Parametri ci siamo occupati dello sviluppo di EA multi-valuta in MQL5. Sappiamo che i risultati del test in MetaTrader 5 vengono visualizzati come una curva generale Balance/Equity, cioè se è necessario visualizzare i risultati per ciascun simbolo separatamente, si dovrebbe più e più volte andare su parametri esterni dell'Expert Advisor per disabilitare tutti i simboli tranne quello i cui risultati sono richiesti e quindi eseguire nuovamente il test. Questo è scomodo.

Quindi oggi ti mostrerò un semplice metodo su come ottenere grafici di bilanciamento per tutti i simboli insieme al risultato cumulativo di un Expert Advisor multi-valuta su un singolo diagramma Excel con solo un paio di clic. Per ricostruire l'esempio, prenderemo l'Expert Advisor multi-valuta dal Articolo precedente. Sarà potenziato con una funzione che scriverà la storia delle offerte e delle curve di bilanciamento per tutti i simboli in un file .csv al termine del test. Inoltre, aggiungeremo un'altra colonna al rapporto per mostrare i drawdown da tutti i massimi locali.

Creiamo un libro Excel impostato in modo da poter collegare il file di dati. Il libro può essere aperto tutto il tempo, quindi non sarà necessario chiuderlo prima di eseguire un altro test. Al termine del test, sarà sufficiente aggiornare i dati premendo un determinato tasto per poter vedere le modifiche nel report e nel grafico.


Sviluppo di Expert Advisor

Non ci saranno cambiamenti significativi nel nostro EA, aggiungeremo solo alcune funzioni. Iniziamo aggiungendo la struttura e l'array per i saldi di simboli al file principale.

//--- Arrays for balances
struct Balance
  {
   double            balance[];
  };
//--- Array of balances for all symbols
Balance symbol_balance[];

Quindi, creiamo il file di include Report.mqh separato per le funzioni che generano report di test e lo includiamo nel file principale di Expert Advisor (vedere la riga evidenziata nel codice seguente):

//--- Include custom libraries
#include "Include/Auxiliary.mqh"
#include "Include/Enums.mqh"
#include "Include/Errors.mqh"
#include "Include/FileFunctions.mqh"
#include "Include/InitializeArrays.mqh"
#include "Include/Report.mqh"
#include "Include/ToString.mqh"
#include "Include/TradeFunctions.mqh"
#include "Include/TradeSignals.mqh"

Creiamo prima una struttura di proprietà dell'affare, come quella che abbiamo già nel progetto per le proprietà di posizione e simbolo. A tale scopo, aggiungiamo l'enumerazione degli identificatori di proprietà al file Enums.mqh:

//+------------------------------------------------------------------+
//| Enumeration of deal properties                                   |
//+------------------------------------------------------------------+
enum ENUM_DEAL_PROPERTIES
  {
   D_SYMBOL     = 0, // Deal symbol
   D_COMMENT    = 1, // Deal comment
   D_TYPE       = 2, // Deal type
   D_ENTRY      = 3, // Deal entry - entry in, entry out, reverse
   D_PRICE      = 4, // Deal price
   D_PROFIT     = 5, // Deal result (profit/loss)
   D_VOLUME     = 6, // Deal volume
   D_SWAP       = 7, // Cumulative swap on close
   D_COMMISSION = 8, // Deal commission
   D_TIME       = 9, // Deal time
   D_ALL        = 10 // All of the above mentioned deal properties
  };

Inoltre, nel file Report.mqhcreiamo la struttura della proprietà del deal e la funzione GetHistoryDealProperties() che restituisce una proprietà deal. La funzione accetta due parametri: deal ticket e property identifier.

Di seguito, puoi vedere il codice della struttura e la funzione GetHistoryDealProperties():

//--- Deal properties in the history
struct HistoryDealProperties
  {
   string            symbol;     // Symbol
   string            comment;    // Comment
   ENUM_DEAL_TYPE    type;       // Deal type
   ENUM_DEAL_ENTRY   entry;      // Direction
   double            price;      // Price
   double            profit;     // Profit/Loss
   double            volume;     // Volume
   double            swap;       // Swap
   double            commission; // Commission
   datetime          time;       // Time
  };
//--- Variable of deal properties
HistoryDealProperties  deal;
//+------------------------------------------------------------------+
//| Gets deal properties by ticket                                   |
//+------------------------------------------------------------------+
void GetHistoryDealProperties(ulong ticket_number,ENUM_DEAL_PROPERTIES history_deal_property)
  {
   switch(history_deal_property)
     {
      case D_SYMBOL     : deal.symbol=HistoryDealGetString(ticket_number,DEAL_SYMBOL);                 break;
      case D_COMMENT    : deal.comment=HistoryDealGetString(ticket_number,DEAL_COMMENT);               break;
      case D_TYPE       : deal.type=(ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket_number,DEAL_TYPE);    break;
      case D_ENTRY      : deal.entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket_number,DEAL_ENTRY); break;
      case D_PRICE      : deal.price=HistoryDealGetDouble(ticket_number,DEAL_PRICE);                   break;
      case D_PROFIT     : deal.profit=HistoryDealGetDouble(ticket_number,DEAL_PROFIT);                 break;
      case D_VOLUME     : deal.volume=HistoryDealGetDouble(ticket_number,DEAL_VOLUME);                 break;
      case D_SWAP       : deal.swap=HistoryDealGetDouble(ticket_number,DEAL_SWAP);                     break;
      case D_COMMISSION : deal.commission=HistoryDealGetDouble(ticket_number,DEAL_COMMISSION);         break;
      case D_TIME       : deal.time=(datetime)HistoryDealGetInteger(ticket_number,DEAL_TIME);          break;
      case D_ALL        :
         deal.symbol=HistoryDealGetString(ticket_number,DEAL_SYMBOL);
         deal.comment=HistoryDealGetString(ticket_number,DEAL_COMMENT);
         deal.type=(ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket_number,DEAL_TYPE);
         deal.entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket_number,DEAL_ENTRY);
         deal.price=HistoryDealGetDouble(ticket_number,DEAL_PRICE);
         deal.profit=HistoryDealGetDouble(ticket_number,DEAL_PROFIT);
         deal.volume=HistoryDealGetDouble(ticket_number,DEAL_VOLUME);
         deal.swap=HistoryDealGetDouble(ticket_number,DEAL_SWAP);
         deal.commission=HistoryDealGetDouble(ticket_number,DEAL_COMMISSION);
         deal.time=(datetime)HistoryDealGetInteger(ticket_number,DEAL_TIME);                           break;
         //---
      default: Print("The passed deal property is not listed in the enumeration!");                          return;
     }
  }

Avremo anche bisogno di diverse funzioni che convertiranno alcune proprietà dell'affare in valori stringa. Queste semplici funzioni restituiscono un trattino ("-") se il valore passato è vuoto o zero. Scriviamoli nel file ToString.mqh:

//+------------------------------------------------------------------+
//| Returns the symbol name, otherwise - dash                        |
//+------------------------------------------------------------------+
string DealSymbolToString(string deal_symbol)
  {
   return(deal_symbol=="" ? "-" : deal_symbol);
  }
//+------------------------------------------------------------------+
//| Converts deal type to string                                     |
//+------------------------------------------------------------------+
string DealTypeToString(ENUM_DEAL_TYPE deal_type)
  {
   string str="";
//---
   switch(deal_type)
     {
      case DEAL_TYPE_BUY                      : str="buy";                      break;
      case DEAL_TYPE_SELL                     : str="sell";                     break;
      case DEAL_TYPE_BALANCE                  : str="balance";                  break;
      case DEAL_TYPE_CREDIT                   : str="credit";                   break;
      case DEAL_TYPE_CHARGE                   : str="charge";                   break;
      case DEAL_TYPE_CORRECTION               : str="correction";               break;
      case DEAL_TYPE_BONUS                    : str="bonus";                    break;
      case DEAL_TYPE_COMMISSION               : str="commission";               break;
      case DEAL_TYPE_COMMISSION_DAILY         : str="commission daily";         break;
      case DEAL_TYPE_COMMISSION_MONTHLY       : str="commission monthly";       break;
      case DEAL_TYPE_COMMISSION_AGENT_DAILY   : str="commission agent daily";   break;
      case DEAL_TYPE_COMMISSION_AGENT_MONTHLY : str="commission agent monthly"; break;
      case DEAL_TYPE_INTEREST                 : str="interest";                 break;
      case DEAL_TYPE_BUY_CANCELED             : str="buy canceled";             break;
      case DEAL_TYPE_SELL_CANCELED            : str="sell canceled";            break;
      //--- Unknown deal type
      default : str="unknown";
     }
//---
   return(str);
  }
//+------------------------------------------------------------------+
//| Converts direction of deal to string                             |
//+------------------------------------------------------------------+
string DealEntryToString(ENUM_DEAL_ENTRY deal_entry)
  {
   string str="";
//---
   switch(deal_entry)
     {
      case DEAL_ENTRY_IN    : str="in";            break;
      case DEAL_ENTRY_OUT   : str="out";           break;
      case DEAL_ENTRY_INOUT : str="in/out";        break;
      case DEAL_ENTRY_STATE : str="status record"; break;
      //--- Unknown direction type
      default : str="unknown";
     }
//---
   return(str);
  }
//+------------------------------------------------------------------+
//| Converts volume to string                                        |
//+------------------------------------------------------------------+
string DealVolumeToString(double deal_volume)
  {
   return(deal_volume<=0 ? "-" : DoubleToString(deal_volume,2));
  }
//+------------------------------------------------------------------+
//| Converts price to string                                         |
//+------------------------------------------------------------------+
string DealPriceToString(double deal_price,int digits)
  {
   return(deal_price<=0 ? "-" : DoubleToString(deal_price,digits));
  }
//+------------------------------------------------------------------+
//| Converts deal result to string                                   |
//+------------------------------------------------------------------+
string DealProfitToString(string deal_symbol,double deal_profit)
  {
   return((deal_profit==0 || deal_symbol=="") ? "-" : DoubleToString(deal_profit,2));
  }
//+------------------------------------------------------------------+
//| Converts swap to string                                          |
//+------------------------------------------------------------------+
string DealSwapToString(double deal_swap)
  {
   return(deal_swap<=0 ? "-" : DoubleToString(deal_swap,2));
  }

Ora tutto è pronto per scrivere la funzione CreateSymbolBalanceReport() che prepara i dati per il report e li scrive nel file LastTest.csv . È piuttosto semplice: prima scriviamo l'intestazione (nota come viene regolata la stringa se il test è stato eseguito per più di un simbolo), quindi le proprietà di deal richieste per il report vengono concatenato consecutivamente in stringa che viene ulteriormente scritta nel file.

Di seguito è riportato il codice della funzione CreateSymbolBalanceReport():

//+------------------------------------------------------------------+
//| Creates the test report on deals in .csv format                  |
//+------------------------------------------------------------------+
void CreateSymbolBalanceReport()
  {
   int    file_handle =INVALID_HANDLE; // File handle
   string path        ="";             // File path

//--- If an error occurred when creating/getting the folder, exit
   if((path=CreateInputParametersFolder())=="")
      return;
//--- Create file to write data in the common folder of the terminal
   file_handle=FileOpen(path+"\\LastTest.csv",FILE_CSV|FILE_WRITE|FILE_ANSI|FILE_COMMON);
//--- If the handle is valid (file created/opened)
   if(file_handle>0)
     {
      int    digits          =0;   // Number of decimal places in the price
      int    deals_total     =0;   // Number of deals in the specified history
      ulong  ticket          =0;   // Deal ticket
      double drawdown_max    =0.0; // Maximum drawdown
      double balance         =0.0; // Balance
      //---
      string delimeter       =","; // Delimiter
      string string_to_write ="";  // To generate the string for writing

      //--- Generate the header string
      string headers="TIME,SYMBOL,DEAL TYPE,ENTRY TYPE,VOLUME,PRICE,SWAP($),PROFIT($),DRAWDOWN(%),BALANCE";
      //--- If more than one symbol is involved, modify the header string
      if(SYMBOLS_COUNT>1)
        {
         for(int s=0; s<SYMBOLS_COUNT; s++)
            StringAdd(headers,","+InputSymbols[s]);
        }
      //--- Write the report headers
      FileWrite(file_handle,headers);
      //--- Get the complete history
      HistorySelect(0,TimeCurrent());
      //--- Get the number of deals
      deals_total=HistoryDealsTotal();
      //--- Resize the array of balances according to the number of symbols
      ArrayResize(symbol_balance,SYMBOLS_COUNT);
      //--- Resize the array of deals for each symbol
      for(int s=0; s<SYMBOLS_COUNT; s++)
         ArrayResize(symbol_balance[s].balance,deals_total);
      //--- Iterate in a loop and write the data
      for(int i=0; i<deals_total; i++)
        {
         //--- Get the deal ticket
         ticket=HistoryDealGetTicket(i);
         //--- Get all the deal properties
         GetHistoryDealProperties(ticket,D_ALL);
         //--- Get the number of digits in the price
         digits=(int)SymbolInfoInteger(deal.symbol,SYMBOL_DIGITS);
         //--- Calculate the overall balance
         balance+=deal.profit+deal.swap+deal.commission;
         //--- Generate a string for writing via concatenation
         StringConcatenate(string_to_write,
                           deal.time,delimeter,
                           DealSymbolToString(deal.symbol),delimeter,
                           DealTypeToString(deal.type),delimeter,
                           DealEntryToString(deal.entry),delimeter,
                           DealVolumeToString(deal.volume),delimeter,
                           DealPriceToString(deal.price,digits),delimeter,
                           DealSwapToString(deal.swap),delimeter,
                           DealProfitToString(deal.symbol,deal.profit),delimeter,
                           MaxDrawdownToString(i,balance,max_drawdown),delimeter,
                           DoubleToString(balance,2));

         //--- If more than one symbol is involved, write their balance values
         if(SYMBOLS_COUNT>1)
           {
            //--- Iterate over all symbols
            for(int s=0; s<SYMBOLS_COUNT; s++)
              {
               //--- If the symbols are equal and the deal result is non-zero
               if(deal.symbol==InputSymbols[s] && deal.profit!=0)
                 {
                  //--- Display the deal in the balance for the corresponding symbol
                  //    Take into consideration swap and commission
                  symbol_balance[s].balance[i]=symbol_balance[s].balance[i-1]+
                                               deal.profit+
                                               deal.swap+
                                               deal.commission;
                  //--- Add to the string
                  StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                 }
               //--- Otherwise write the previous value
               else
                 {
                  //--- If the deal type is "Balance" (the first deal)
                  if(deal.type==DEAL_TYPE_BALANCE)
                    {
                     //--- the balance is the same for all symbols
                     symbol_balance[s].balance[i]=balance;
                     StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                    }
                  //--- Otherwise write the previous value to the current index
                  else
                    {
                     symbol_balance[s].balance[i]=symbol_balance[s].balance[i-1];
                     StringAdd(string_to_write,","+DoubleToString(symbol_balance[s].balance[i],2));
                    }
                 }
              }
           }
         //--- Write the generated string
         FileWrite(file_handle,string_to_write);
         //--- Mandatory zeroing out of the variable for the next string
         string_to_write="";
        }
      //--- Close the file
      FileClose(file_handle);
     }
//--- If the file could not be created/opened, print the appropriate message
   else
      Print("Error creating file: "+IntegerToString(GetLastError())+"");
  }

La funzione MaxDrawdownToString() evidenziata nel codice precedente calcola tutti i drawdown dai massimi locali e restituisce una rappresentazione in stringa dell'ora del nuovo massimo locale. In tutti gli altri casi la funzione restituisce una stringa contenente "-" (un trattino).

//+------------------------------------------------------------------+
//| Returns the maximum drawdown from the local maximum              |
//+------------------------------------------------------------------+
string MaxDrawdownToString(int deal_number,double balance,double &max_drawdown)
  {
//--- The string to be displayed in the report
   string str="";
//--- To calculate the local maximum and drawdown
   static double max=0.0;
   static double min=0.0;
//--- If this is the first deal
   if(deal_number==0)
     {
      //--- No drawdown yet
      max_drawdown=0.0;
      //--- Set the initial point as the local maximum
      max=balance;
      min=balance;
     }
   else
     {
      //--- If the current balance is greater than in the memory
      if(balance>max)
        {
         //--- calculate the drawdown using the previous values
         max_drawdown=100-((min/max)*100);
         //--- update the local maximum
         max=balance;
         min=balance;
        }
      else
        {
         //--- Return zero value of the drawdown
         max_drawdown=0.0;
         //--- Update the minimum
         min=fmin(min,balance);
        }
     }
//--- Determine the string for the report
   if(max_drawdown==0)
      str="-";
   else
      str=DoubleToString(max_drawdown,2);
//--- Return result
   return(str);
  }

Quindi tutte le funzioni di generazione dei report sono pronte. Abbiamo solo bisogno di vedere come dovremmo usare tutto quanto sopra. Ciò richiederà la della funzione OnTester() chiamata al termine del test. Assicurarsi di controllare la descrizione dettagliata di questa funzione in MQL5 Reference.

È sufficiente scrivere alcune righe di codice nel corpo della funzione OnTester() per specificare la condizione in cui il report deve essere generato. Lo snippet di codice corrispondente è fornito di seguito:

//+------------------------------------------------------------------+
//| Handler of the event of testing completion                       |
//+------------------------------------------------------------------+
double OnTester()
  {
//--- Write the report only after testing
   if(IsTester() && !IsOptimization() && !IsVisualMode())
      //--- Generate the report and write it to the file
      CreateSymbolBalanceReport();
//---
   return(0.0);
  }

Ora, se esegui Expert Advisor in Strategy Tester, al termine del test vedrai una cartella di Expert Advisor creata nella cartella dei terminali comuni C:\ProgramData\MetaQuotes\Terminal\Common\Files. E il file di report LastTest.csv verrà generato nella cartella dell'Expert Advisor. Se apri il file con Blocco note, vedrai qualcosa di simile a questo:

Figura 1. Il file di report in formato .csv

Figura 1. File di report in formato .csv.

Creazione di grafici in Excel

Possiamo aprire il file creato in Excel e vedere che ogni tipo di dati si trova in una colonna separata. In questo modo i dati appaiono molto più convenienti per la visualizzazione. A questo punto, siamo tecnicamente pronti per creare grafici e salvare il file come libro Excel in formato *.xlsx. Tuttavia, se in seguito eseguiamo il test e riapriamo il libro, vedremo ancora i vecchi dati.

Se proviamo ad aggiornare i dati, mentre il file LastTest.csv è già in uso in Excel, il file non verrà aggiornato, poiché Expert Advisor non sarà in grado di aprirlo per la scrittura mentre viene utilizzato da un'altra applicazione.

Figura 2. Il file di report in formato .csv in Excel 2010

Figura 2. Il file di report in formato .csv in Excel 2010.

C'è una soluzione che può essere utilizzata nel nostro caso. Per prima cosa crea un libro Excel in formato *.xlsx in qualsiasi cartella che ti piace. Quindi aprilo e vai alla scheda Dati.

Figura 3. Scheda Dati in Excel 2010

Figura 3. Scheda Dati in Excel 2010.

Sulla barra multifunzione di questa scheda selezionare l'opzione Da testo. Verrà visualizzata la finestra di dialogo Importa file di testo in cui è necessario selezionare il file "LastTest.csv". Selezionare il file e fare clic sul pulsante Apri. Verrà visualizzata la finestra di dialogo Importazione guidata testo - Passaggio 1 di 3 come mostrato di seguito:

Figura 4. La finestra di dialogo "Importazione guidata testo - Passaggio 1 di 3"

Figura 4. La finestra di dialogo "Importazione guidata testo - Passaggio 1 di 3".

Regolare le impostazioni come mostrato sopra e fare clic su Avanti >. Qui, (Passaggio 2 di 3) è necessario specificare il delimitatore utilizzato nel file di dati. Nel nostro file, è "," (virgola).

Figura 5. La finestra di dialogo "Importazione guidata testo - Passaggio 2 di 3"

Figura 5. La finestra di dialogo "Importazione guidata testo - Passaggio 2 di 3".

Fare clic su Avanti > per passare all'Importazione guidata testo - Passaggio 3 di 3. Qui, lasciare il generale come formato di dati per tutte le colonne. È possibile modificare il formato in un secondo momento.

Figura 6. La finestra di dialogo "Importazione guidata testo - Passaggio 3 di 3"

Figura 6. La finestra di dialogo "Importazione guidata testo - Passaggio 3 di 3".

Dopo aver fatto clic sul pulsante Fine, verrà visualizzata la finestra Importa dati in cui è necessario specificare il foglio di lavoro e la cella per l'importazione dei dati.

Figura 7. Selezione della cella per l'importazione dei dati in Excel 2010

Figura 7. Selezione della cella per l'importazione dei dati in Excel 2010.

Di solito, selezioniamo la cella in alto a sinistra A1. Prima di fare clic su OK, fare clic sul pulsante Proprietà... per impostare le proprietà dell'intervallo di dati esterno. Verrà visualizzata una finestra di dialogo come mostrato di seguito.

Figura 8. Proprietà dell'intervallo di dati esterni durante l'importazione di dati da file di testo in Excel 2010

Figura 8. Proprietà dell'intervallo di dati esterni durante l'importazione di dati da file di testo in Excel 2010.

Regolare le impostazioni esattamente come mostrato sopra e fare clic su OK nella finestra corrente e successiva.

Di conseguenza, i tuoi dati appariranno come se avessi semplicemente caricato il file .csv. Ma ora puoi eseguire test ripetuti in MetaTrader 5, senza dover chiudere il libro Excel. Tutto quello che devi fare dopo aver eseguito il test è semplicemente aggiornare i dati usando il collegamento Ctrl + Alt + F5 o il pulsante Aggiorna tutto sulla barra multifunzione della scheda Dati.

Utilizzando le opzioni di formattazione condizionale sulla barra multifunzione della scheda Home è possibile impostare le proprietà visive necessarie per la rappresentazione dei dati.

Figura 9. Formattazione condizionale in Excel 2010

Figura 9. Formattazione condizionale in Excel 2010.

Ora dobbiamo visualizzare i dati sui grafici di Excel. Un grafico mostrerà tutti i grafici di equilibrio e l'altro mostrerà tutti i prelievi dai massimi locali come istogramma.

Creiamo prima un diagramma per i grafici di equilibrio. Selezionare le intestazioni di tutti i saldi e l'intero array di dati dall'alto verso il basso (tenendo premuto il tasto Maiusc, premere il tasto Fine e quindi il tasto freccia GIÙ). Ora nella scheda Inserisci, selezionare il tipo di grafico desiderato.

Figura 10. Selezione di un tipo di grafico in Excel 2010

Figura 10. Selezione di un tipo di grafico in Excel 2010.

Di conseguenza, verrà creato il grafico che può essere spostato in un altro foglio di lavoro per comodità. Per fare ciò, è sufficiente selezionarlo e premere Ctrl + X (Taglia). Quindi vai al foglio di lavoro appena creato, seleziona la cella A1 e premi Ctrl + V (Incolla).

Il grafico creato con le impostazioni predefinite è mostrato nell'immagine seguente:

Figura 11. Aspetto del grafico con impostazioni predefinite.

Figura 11. Aspetto del grafico con impostazioni predefinite.

Puoi personalizzare qualsiasi elemento del grafico: cambiane le dimensioni, il colore, lo stile, ecc.

Nell'immagine sopra, l'asse orizzontale mostra il numero di offerte. Modifichiamolo in modo che visualizzi invece le date. A tale scopo, fare clic con il pulsante destro del mouse sul grafico e selezionare l'opzione Seleziona dati dal menu di scelta rapida. Verrà visualizzata la finestra di dialogo Seleziona origine dati. Fare clic sul pulsante Modifica quindi selezionare l'intervallo di dati richiesto nella colonna TIME e fare clic su OK.

Figura 12. La finestra di dialogo "Seleziona origine dati"

Figura 12. Finestra di dialogo "Seleziona origine dati".

Prova a creare il grafico dei drawdown da solo e posizionalo sotto il primo grafico. Ora le loro proprietà visive possono essere personalizzate, se necessario. Personalmente, di solito lo faccio:

Figura 13. Grafici personalizzati in Excel 2010.

Figura 13. Grafici personalizzati in Excel 2010.


Conclusione

Quindi, abbiamo i grafici excel con risultati di test che sembrano abbastanza decenti. In uno dei miei prossimi articoli, ti mostrerò come creare report ancora più informativi. Allegato all'articolo è l'archivio scaricabile con i file dell'Expert Advisor per la vostra considerazione.

Dopo aver estratto i file dall'archivio, posizionare la cartella ReportInExcel nella directory MetaTrader 5\MQL5\Experts. Inoltre, l'indicatore EventsSpy.mq5 deve essere inserito nella directory MetaTrader 5\MQL5\Indicators.

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

File allegati |
eventsspy__4.mq5 (7.59 KB)
reportinexcel.zip (26.73 KB)
Manuale MQL5: Ridurre l'effetto dell'overfitting e gestire la mancanza di preventivi Manuale MQL5: Ridurre l'effetto dell'overfitting e gestire la mancanza di preventivi
Qualunque sia la strategia di trading che utilizzi, rimarrà sempre la domanda: “quali parametri scegliere per garantire profitti futuri?” Questo articolo fornisce un esempio di Expert Advisor con la possibilità di ottimizzare più parametri di simboli contemporaneamente. Questo metodo ha lo scopo di ridurre l'effetto dei parametri di overfitting e gestire situazioni in cui i dati di un singolo simbolo non sono sufficienti per lo studio.
Manuale MQL5: Sviluppo di un Expert Advisor multi-valuta con un numero illimitato di parametri Manuale MQL5: Sviluppo di un Expert Advisor multi-valuta con un numero illimitato di parametri
In questo articolo, creeremo un modello che utilizza un singolo set di parametri per l'ottimizzazione di un sistema di trading, consentendo al contempo un numero illimitato di parametri. L'elenco dei simboli verrà creato in un file di testo standard (*.txt). Anche i parametri di input per ciascun simbolo verranno memorizzati nei file. In questo modo saremo in grado di aggirare la restrizione del terminale sul numero di parametri di input di un Expert Advisor.
Debug dei programmi MQL5 Debug dei programmi MQL5
Questo articolo è destinato principalmente ai programmatori che hanno già imparato il linguaggio ma non padroneggiano completamente lo sviluppo del programma. Rivela alcune tecniche di debug e presenta un'esperienza combinata dell'autore e di molti altri programmatori.
Manuale MQL5: Expert Advisor multivaluta: approccio semplice, accurato e rapido Manuale MQL5: Expert Advisor multivaluta: approccio semplice, accurato e rapido
Questo articolo descriverà l'implementazione di un approccio semplice, adatto a un Expert Advisor multivaluta. Ciò significa che sarai in grado di impostare l'Expert Advisor per testare/tradare in condizioni identiche ma con parametri diversi per ogni simbolo. Ad esempio creeremo un pattern per due simboli ma in modo tale da poter aggiungere ulteriori simboli, se necessario, apportando piccole modifiche al codice.