English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Tracciamento, debug e analisi strutturale del codice sorgente

Tracciamento, debug e analisi strutturale del codice sorgente

MetaTrader 5Esempi | 17 dicembre 2021, 15:34
101 0
---
---


Introduzione

Questo articolo parla di uno dei metodi per creare un call stack durante l'esecuzione. Le seguenti caratteristiche sono descritte nell'articolo:

  • Realizzare la struttura delle classi, delle funzioni e dei file utilizzati.
  • Creare il call stack mantenendo tutti gli stack precedenti. Sequenza di chiamate.
  • Visualizzazione dello stato dei parametri Watch durante l'esecuzione.
  • Esecuzione graduale del codice.
  • Raggruppare e ordinare gli stack ottenuti, ottenendo informazioni "estreme".


Principi fondamentali dello sviluppo

Viene scelto un approccio comune come metodo di rappresentazione della struttura – la visualizzazione sotto forma di albero. A tal fine, abbiamo bisogno di due classi informative. CNode - un "nodo" utilizzato per scrivere tutte le informazioni su uno stack. CTreeCtrl - un "albero" che elabora tutti i nodi. E il tracciatore - CTraceCtrl, utilizzato per l'elaborazione degli alberi.

Le classi sono implementate secondo la seguente gerarchia:


Le classi CNodeBase e CTreeBase descrivono proprietà e metodi di base per lavorare con nodi e alberi.

La classe ereditata CNode estende le funzionalità di base di CNodeBase, mentre la classe CTreeBase funziona con la classe derivata CNode. È così perché la classe CNodeBase è il genitore degli altri nodi standard ed è isolata come classe indipendente per comodità della gerarchia e dell'ereditarietà.

A differenza di CTreeNode della libreria standard, la classe CNodeBase contiene un array di puntatori ai nodi, quindi il numero di "rami" che escono da questo nodo è illimitato.

Le classi CNodeBase e CNode

class CNode; // forward declaration
//------------------------------------------------------------------    class CNodeBase
class CNodeBase
  {
public:
   CNode   *m_next[]; // list of nodes it points to
   CNode   *m_prev; // parent node
   int     m_id; // unique number
   string  m_text; // text

public:
          CNodeBase() { m_id=0; m_text=""; } // constructor
          ~CNodeBase(); // destructor
  };

//------------------------------------------------------------------    class CNode
class CNode : public CNodeBase
  {
public:
   bool    m_expand; // expanded
   bool    m_check; // marked with a dot
   bool    m_select; // highlighted

   //--- run-time information
   int     m_uses; // number of calls of the node
   long    m_tick; // time spent in the node
   long    m_tick0; // time of entering the node
   datetime    m_last; // time of entering the node
   tagWatch   m_watch[]; // list of name/value parameters
   bool    m_break; // debug-pause

   //--- parameters of the call
   string   m_file; // file name
   int      m_line; // number of row in the file
   string   m_class; // class name
   string   m_func; // function name
   string   m_prop; // add. information

public:
           CNode(); // constructor
           ~CNode(); // destructor
   void    AddWatch(string watch,string val);
  };

Puoi trovare l'implementazione di tutte le classi nei file allegati. Nell'articolo, mostreremo solo le loro intestazioni e le funzioni importanti.

Secondo la classificazione accettata, CTreeBase rappresenta un grafico aciclico orientato. La classe derivata CTreeCtrl utilizza CNode e serve tutte le sue funzionalità: aggiunta, modifica ed eliminazione dei nodi CNode.

CTreeCtrl e CNode possono sostituire con successo le classi corrispondenti della libreria standard, poiché hanno una funzionalità leggermente più ampia.

Le classi CTreeBase e CTreeCtrl

//------------------------------------------------------------------    class CTreeBase
class CTreeBase
  {
public:
   CNode   *m_root; // first node of the tree
   int     m_maxid;    // counter of ID

   //--- base functions
public:
           CTreeBase(); // constructor
           ~CTreeBase(); // destructor
   void    Clear(CNode *root=NULL); // deletion of all nodes after a specified one
   CNode   *FindNode(int id,CNode *root=NULL); // search of a node by its ID starting from a specified node
   CNode   *FindNode(string txt,CNode *root=NULL); // search of a node by txt starting from a specified node
   int     GetID(string txt,CNode *root=NULL); // getting ID for a specified Text, the search starts from a specified node
   int     GetMaxID(CNode *root=NULL); // getting maximal ID in the tree
   int     AddNode(int id,string text,CNode *root=NULL); // adding a node to the list, search is performed by ID starting from a specified node
   int     AddNode(string txt,string text,CNode *root=NULL); // adding a node to the list, search is performed by text starting from a specified node
   int     AddNode(CNode *root,string text); // adding a node under root
  };

//------------------------------------------------------------------    class CTreeCtrl
class CTreeCtrl : public CTreeBase
  {
   //--- base functions
public:
          CTreeCtrl() { m_root.m_file="__base__"; m_root.m_line=0; 
                        m_root.m_func="__base__"; m_root.m_class="__base__"; } // constructor
          ~CTreeCtrl() { delete m_root; m_maxid=0; } // destructor
   void    Reset(CNode *root=NULL); // reset the state of all nodes
   void    SetDataBy(int mode,int id,string text,CNode *root=NULL); // changing text for a specified ID, search is started from a specified node
   string  GetDataBy(int mode,int id,CNode *root=NULL); // getting text for a specified ID, search is started from a specified node

   //--- processing state
public:
   bool    IsExpand(int id,CNode *root=NULL); // getting the m_expand property for a specified ID, search is started from a specified node
   bool    ExpandIt(int id,bool state,CNode *root=NULL); // change the m_expand state, search is started from a specified node
   void    ExpandBy(int mode,CNode *node,bool state,CNode *root=NULL); // expand node of a specified node

   bool    IsCheck(int id,CNode *root=NULL); // getting the m_check property for a specified ID, search is started from a specified node
   bool    CheckIt(int id,bool state,CNode *root=NULL); // change the m_check state to a required one starting from a specified node
   void    CheckBy(int mode,CNode *node,bool state,CNode *root=NULL); // mark the whole tree

   bool    IsSelect(int id,CNode *root=NULL); // getting the m_select property for a specified ID, search is started from a specified node
   bool    SelectIt(int id,bool state,CNode *root=NULL); // change the m_select state to a required one starting from a specified node
   void    SelectBy(int mode,CNode *node,bool state,CNode *root=NULL); // highlight the whole tree

   bool    IsBreak(int id,CNode *root=NULL); // getting the m_break property for a specified ID, search is started from a specified node
   bool    BreakIt(int id,bool state,CNode *root=NULL); // change the m_break state, search is started from a specified node
   void    BreakBy(int mode,CNode *node,bool state,CNode *root=NULL); // set only for a selected one 

   //--- operations with nodes
public:
   void    SortBy(int mode,bool ascend,CNode *root=NULL); // sorting by a property
   void    GroupBy(int mode,CTreeCtrl *atree,CNode *node=NULL); // grouping by a property
  };

L'architettura si conclude con due classi: CTraceCtrl - la sua unica istanza viene utilizzata direttamente per il tracciamento, contiene tre istanze della classe CTreeCtrl per la creazione della struttura richiesta delle funzioni; e un contenitore temporaneo - la classe CIn. Questa è solo una classe ausiliaria che viene utilizzata per aggiungere nuovi nodi a CTraceCtrl.

Le classi CTraceCtrl e CIn

class CTraceView; // provisional declaration
//------------------------------------------------------------------    class CTraceCtrl
class CTraceCtrl
  {
public:
   CTreeCtrl   *m_stack; // object of graph
   CTreeCtrl   *m_info; // object of graph
   CTreeCtrl   *m_file; // grouping by files
   CTreeCtrl   *m_class; // grouping by classes
   CTraceView  *m_traceview; // pointer to displaying of class

   CNode   *m_cur; // pointer to the current node
           CTraceCtrl() { Create(); Reset(); } // tracer created
           ~CTraceCtrl() { delete m_stack; delete m_info; delete m_file; delete m_class; } // tracer deleted
   void    Create(); // tracer created
   void    In(string afile,int aline,string aname,int aid); // entering a specified node 
   void    Out(int aid); // exit from a specified node
   bool    StepBack(); // exit from a node one step higher (going to the parent)
   void    Reset() { m_cur=m_stack.m_root; m_stack.Reset(); m_file.Reset(); m_class.Reset(); } // resetting all nodes
   void    Clear() { m_cur=m_stack.m_root; m_stack.Clear(); m_file.Clear(); m_class.Clear(); } // resetting all nodes

public:
   void    AddWatch(string name,string val); // checking the debug mode for a node
   void    Break(); // pause for a node
  };

//------------------------------------------------------------------    CIn
class CIn
  {
public:
   void In(string afile,int aline,string afunc)
     {
      if(NIL(m_trace)) return; // exit if there is no graph
      if(NIL(m_trace.m_tree)) return;
      if(NIL(m_trace.m_tree.m_root)) return;
      if(NIL(m_trace.m_cur)) m_trace.m_cur=m_trace.m_tree.m_root;
      m_trace.In(afile,aline,afunc,-1); // entering the next one
     }
   void ~CIn() { if(!NIL(m_trace)) m_trace.Out(-1); } // exiting higher
  };


Modello di funzionamento della Classe CIn

Questa classe è responsabile della creazione dell'albero dello stack.

La formazione del grafico viene eseguita gradualmente in due fasi utilizzando due funzioni CTraceCtrl:

void In(string afile, int aline, string aname, int aid); // entering a specified node
void Out(int aid);  // exit before a specified node

In altre parole, per formare un albero si effettuano chiamate continue di In-Out-In-Out-In-In-Out-Out, ecc.

La coppia In-Out funziona in questo modo:

1. Inserimento di un blocco (funzione, ciclo, condizione, ecc.), ovvero subito dopo la parentesi "{".
Quando si entra nel blocco, viene creata una nuova istanza di CIn, la quale ottiene il CTraceCtrl corrente che è già stato avviato con alcuni nodi precedenti. La funzione CTraceCtrl::In viene chiamata in CIn e crea un nuovo nodo nello stack. Il nodo viene creato sotto il nodo corrente CTraceCtrl::m_cur. In esso sono scritte tutte le informazioni effettive sull'inserimento: nome del file, numero di riga, nome della classe, funzioni, ora corrente, ecc.

2. Uscita dal blocco quando si incontra una parentesi "}".
All'uscita dal blocco, MQL chiama automaticamente il distruttore CIn::~CIn. CTraceCtrl::Out viene chiamato nel distruttore. Il puntatore del nodo corrente CTraceCtrl::m_cur viene sollevato di un livello più in alto nell'albero. A quel punto, il distruttore non viene chiamato per il nuovo nodo e il nodo rimane nell'albero.

Schema di formazione di uno stack


La formazione del call stack sotto forma di albero con il riempimento di tutte le informazioni su una chiamata viene eseguita utilizzando il contenitore CIn.



Macro per semplificare le chiamate

Per evitare di riscrivere le lunghe righe di codice di creazione dell'oggetto CIn e di inserire un nodo nel codice, è conveniente sostituirlo con la chiamata della macro:
#define _IN    CIn _in; _in.In(__FILE__, __LINE__, __FUNCTION__)
Come vedete, viene creato l'oggetto CIn e quindi entriamo nel nodo.


Poiché MQL fornisce un avviso nel caso in cui i nomi delle variabili locali siano gli stessi delle variabili globali, è meglio (più preciso e chiaro) creare 3-4 definizioni analoghe con gli altri nomi di variabili nella seguente forma:

#define _IN1    CIn _in1; _in1.In(__FILE__, __LINE__, __FUNCTION__)
#define _IN2    CIn _in2; _in2.In(__FILE__, __LINE__, __FUNCTION__)
#define _IN3    CIn _in3; _in3.In(__FILE__, __LINE__, __FUNCTION__)
Man mano che approfondisci i sottoblocchi, usa le macro successive _INx
bool CSampleExpert::InitCheckParameters(int digits_adjust)
  { _IN;
//--- initial data checks
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     { _IN1;
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());

Con la comparsa delle macro nella versione 411, puoi utilizzare completamente il passaggio di parametri usando #define.

Ecco perché nella classe CTraceCtrl troverai la seguente definizione di macro:

#define NIL(p)    (CheckPointer(p)==POINTER_INVALID)

Consente di abbreviare il controllo di validità del puntatore.

Ad esempio, la riga:

if (CheckPointer(m_tree))==POINTER_INVALID || CheckPointer(m_cur))==POINTER_INVALID) return;  

viene sostituita con la variante più corta:

if (NIL(m_tree) || NIL(m_cur)) return;



Preparare i file per il tracciamento

Per controllare e ottenere lo stack, devi compiere tre passaggi.

1. Aggiungi i file richiesti
#include <Trace.mqh>

L'intera libreria standard è attualmente basata sulla classe CObject. Quindi, se viene utilizzato anche come classe base nei tuoi file, è sufficiente aggiungere Trace.mqh solo a Object.mqh.

2. Posiziona le macro _IN nei blocchi richiesti (puoi usare cerca/sostituisci)

L'esempio dell'utilizzo della macro _IN:
bool CSampleExpert::InitCheckParameters(int digits_adjust)
  { _IN;
//--- initial data checks
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     { _IN1;
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());


3. Nelle funzioni OnInit, OnTime e OnDeinit, che costituiscono il modulo principale del programma, aggiungere rispettivamente la creazione, la modifica e la cancellazione dell'oggetto globale CTraceCtrl. Di seguito puoi trovare il codice già pronto per l'inserimento:

Incorporare il tracciatore nel codice principale

//------------------------------------------------------------------    OnInit
int OnInit()
  {
   //****************
   m_traceview= new CTraceView; // created displaying of the graph
   m_trace= new CTraceCtrl; // created the graph
   m_traceview.m_trace=m_trace; // attached the graph
   m_trace.m_traceview=m_traceview; // attached displaying of the graph
   m_traceview.Create(ChartID()); // created chart
   //****************
   // remaining part of your code…
   return(0);
  }
//------------------------------------------------------------------    OnDeinit
void OnDeinit(const int reason)
  {
   //****************
   delete m_traceview;
   delete m_trace;
   //****************
   // remaining part of your code…
  }
//------------------------------------------------------------------    OnTimer
void OnTimer()
  {
   //****************
   if (m_traceview.IsOpenView(m_traceview.m_chart)) m_traceview.OnTimer();
   else { m_traceview.Deinit(); m_traceview.Create(ChartID()); } // if the window is accidentally closed
   //****************
   // remaining part of your code…
  }
//------------------------------------------------------------------    OnChartEvent
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   //****************
   m_traceview.OnChartEvent(id, lparam, dparam, sparam);
   //****************
   // remaining part of your code…
  }


Classi di visualizzazione delle tracce

Quindi lo stack è stato organizzato. Consideriamo ora la visualizzazione delle informazioni ottenute.

A questo scopo, dobbiamo creare due classi. CTreeView per la visualizzazione dell'albero e CTraceView per il controllo della visualizzazione degli alberi e informazioni aggiuntive sullo stack. Entrambe le classi sono derivate dalla classe base CView.


Le classi CTreeView e CTraceView

//------------------------------------------------------------------    class CTreeView
class CTreeView: public CView
  {
   //--- basic functions
public:
           CTreeView(); // constructor
           ~CTreeView(); // destructor
   void    Attach(CTreeCtrl *atree); // attached the tree object for displaying it
   void    Create(long chart,string name,int wnd,color clr,color bgclr,color selclr,
                    int x,int y,int dx,int dy,int corn=0,int fontsize=8,string font="Arial");

   //--- functions of processing of state
public:
   CTreeCtrl        *m_tree; // pointer to the tree object to be displayed
   int     m_sid; // last selected object (for highlighting)
   int     OnClick(string name); // processing the event of clicking on an object

   //--- functions of displaying
public:
   int     m_ndx, m_ndy; // size of margins from button for drawing
   int     m_bdx, m_bdy; // size of button of nodes
   CScrollView       m_scroll;
   bool    m_bProperty; // show properties near the node

   void    Draw(); // refresh the view
   void    DrawTree(CNode *first,int xpos,int &ypos,int &up,int &dn); // redraw
   void    DeleteView(CNode *root=NULL,bool delparent=true); // delete all displayed elements starting from a specified node
  };

//------------------------------------------------------------------    class CTreeView
class CTraceView: public CView
  {
   //--- base functions
public:
           CTraceView() { }; // constructor
           ~CTraceView() { Deinit(); } // destructor
   void    Deinit(); // full deinitialization of representation
   void    Create(long chart); // create and activate the representation

   //--- function of processing of state
public:
   int     m_hagent; // handler of the indicator-agent for sending messages
   CTraceCtrl   *m_trace; // pointer to created tracer
   CTreeView    *m_viewstack; // tree for displaying the stack
   CTreeView    *m_viewinfo; // tree for displaying of node properties
   CTreeView    *m_viewfile; // tree for displaying of the stack with grouping by files
   CTreeView    *m_viewclass; // tree for displaying of stack with grouping by classes
   void    OnTimer(); // handler of timer
   void    OnChartEvent(const int,const long&,const double&,const string&); // handler of event

   //--- functions of displaying
public:
   void    Draw(); // refresh objects
   void    DeleteView(); // delete the view

   void    UpdateInfoTree(CNode *node,bool bclear); // displaying the window of detailed information about a node
   string  TimeSeparate(long time); // special function for transformation of time into string
  };

Abbiamo scelto di visualizzare lo stack in una sottofinestra separata come variante ottimale.

In altre parole, quando viene creata la classe CTraceView nella funzione CTraceView::Create, viene creata la finestra del grafico e tutti gli oggetti vengono disegnati in essa, nonostante il fatto che CTraceView venga creata e funzioni nell’Expert Advisor in un'altra finestra. È fatto per impedire che l'enorme quantità di informazioni impedisca il funzionamento del codice sorgente del programma tracciato e la visualizzazione delle proprie informazioni sul grafico.

Ma, per rendere possibile l'interazione tra due finestre, dobbiamo aggiungere un indicatore alla finestra, il quale invierà tutti gli eventi dell'utente alla finestra di base con il programma tracciato.

L'indicatore viene creato nella stessa funzione CTraceView::Create. Ha un solo parametro esterno: l'ID del grafico a cui deve inviare tutti gli eventi.

L'indicatore TraceAgent

#property indicator_chart_window
input long cid=0; // чарт получателя
//------------------------------------------------------------------    OnCalculate
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double& price[])
{ return(rates_total); }
//------------------------------------------------------------------    OnChartEvent
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
  {
    EventChartCustom(cid, (ushort)id, lparam, dparam, sparam);
  }

Nel risultato, abbiamo una rappresentazione piuttosto strutturata dello stack.



Nell'albero TRACE, a sinistra, viene visualizzato lo stack iniziale.

Sotto c'è la finestra INFO contenente informazioni dettagliate sul nodo selezionato (CTraceView::OnChartEvent in questo esempio). Due finestre adiacenti contenenti degli alberi mostrano lo stesso stack, ma che è raggruppato per classi (l'albero CLASS al centro) e per file (l'albero FILE a destra).

Gli alberi delle classi e dei file hanno il meccanismo incorporato di sincronizzazione con l'albero principale dello stack oltre a comodi mezzi di controllo. Ad esempio, quando si fa clic sul nome di una classe nell'albero delle classi, tutte le funzioni di questa classe vengono selezionate nell'albero dello stack e nell'albero dei file. E allo stesso modo, quando fai clic sul nome di un file, vengono selezionate tutte le funzioni e le classi in quel file.



Questo meccanismo consente di selezionare e visualizzare rapidamente i gruppi di funzioni richiesti.



Caratteristiche del lavoro con lo stack

  • Aggiunta di parametri Watch

Come avrai già notato, i parametri del nodo CNode includono l'array di strutture tagWatch. Viene creato solo per comodità di rappresentazione delle informazioni. Contiene un valore denominato di una variabile o di un'espressione.

Struttura di un valore Watch

//------------------------------------------------------------------    struct tagWatch
struct tagWatch
{
    string m_name;     // name
    string m_val;    // value
};

Per aggiungere un nuovo valore Watch al nodo corrente, è necessario chiamare la funzione CTrace::AddWatch e utilizzare la macro _WATCH.

#define _WATCH(w, v)         if (!NIL(m_trace) && !NIL(m_trace.m_cur)) m_trace.m_cur.AddWatch(w, string(v));


La limitazione speciale sui valori aggiunti (la stessa dei nodi) è il controllo dell'unicità dei nomi. Significa che il nome di un valore Watch viene controllato per l'unicità prima di essere aggiunto all'array CNode::m_watch[]. Se l'array contiene un valore con lo stesso nome, quello nuovo non verrà aggiunto, ma verrà aggiornato il valore di quello esistente.

Tutti i valori tracciati del Watch vengono visualizzati nella finestra delle informazioni.



  • Esecuzione graduale del codice.

Un'altra comoda funzionalità data da MQL5 è l'organizzazione di un'interruzione forzata del codice durante la sua esecuzione.

La pausa viene implementata utilizzando un semplice ciclo infinito while (true). La comodità di MQL5 qui è data dalla gestione dell'evento di uscita da questo ciclo - cliccando il pulsante rosso di controllo. Per creare un punto di interruzione durante l'esecuzione, utilizzare la funzione CTrace::Break.


La funzione per l'implementazione dei punti di interruzione

//------------------------------------------------------------------    Break
void CTraceCtrl::Break() // checking the debug mode of a node
  {
   if(NIL(m_traceview)) return; // check of validity
   m_stack.BreakBy(TG_ALL,NULL,false); // removed the m_break flags from all nodes
   m_cur.m_break=true; // activated only at the current one
   m_traceview.m_viewstack.m_sid=m_cur.m_id; // moved selection to it
   m_stack.ExpandBy(TG_UP,m_cur,true,m_cur); // expand parent node if they are closed
   m_traceview.Draw(); // drew everything
   string name=m_traceview.m_viewstack.m_name+string(m_cur.m_id)+".dbg"; // got name of the BREAK button
   bool state=ObjectGetInteger(m_traceview.m_chart,name,OBJPROP_STATE);
   while(!state) // button is not pressed, execute the loop
     {
      Sleep(1000); // made a pause
      state=ObjectGetInteger(m_traceview.m_chart,name,OBJPROP_STATE);  // check its state
      if(!m_traceview.IsOpenView()) break; // if the window is closed, exit
      m_traceview.Draw(); // drew possible changes
     }
   m_cur.m_break=false; // removed the flag
   m_traceview.Draw(); // drew the update
  }


Quando si incontra tale punto di interruzione, gli alberi dello stack vengono sincronizzati per visualizzare la funzione che ha chiamato questa macro. Se un nodo è chiuso, il nodo genitore verrà espanso per visualizzarlo. E se necessario, l'albero viene fatto scorrere verso l'alto o verso il basso per portare il nodo nell'area visibile.


Per uscire da CTraceCtrl::Break, cliccare sul pulsante rosso situato vicino al nome del nodo.


Conclusione

Bene, ora abbiamo un "giochino" interessante. Durante la stesura dell'articolo, ho provato molte varianti del lavoro con CTraceCtrl e mi sono assicurato che MQL5 avesse prospettive uniche di controllare gli Expert Advisor e di organizzare il loro funzionamento. Tutte le funzionalità utilizzate per lo sviluppo del tracciatore non sono disponibili in MQL4, il che dimostra ancora una volta i vantaggi di MQL5 e le sue ampie possibilità.

Nel codice allegato, puoi trovare tutte le classi descritte nell'articolo insieme alle librerie di servizi (il set minimo richiesto di esse, poiché non sono l'obiettivo). Inoltre, ho allegato l'esempio già pronto: file aggiornati della libreria standard in cui sono posizionate le macro _IN. Tutti gli esperimenti sono stati condotti con l'Expert Advisor incluso nella fornitura standard di MetaTrader 5 - MACD Sample.mq5.


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

File allegati |
mql5.zip (24.67 KB)
Stime statistiche Stime statistiche
La stima dei parametri statistici di una sequenza è molto importante poiché la maggior parte dei modelli e metodi matematici si basa su ipotesi diverse. Ad esempio, normalità della legge di distribuzione o valore di dispersione o altri parametri. Pertanto, durante l'analisi e la previsione delle serie temporali abbiamo bisogno di uno strumento semplice e conveniente che consenta di stimare in modo rapido e chiaro i principali parametri statistici. L'articolo descrive brevemente i parametri statistici più semplici di una sequenza casuale e diversi metodi della sua analisi visiva. Offre l'implementazione di questi metodi in MQL5 e i metodi di visualizzazione del risultato dei calcoli utilizzando l'applicazione Gnuplot.
Distribuzioni statistiche di probabilità in MQL5 Distribuzioni statistiche di probabilità in MQL5
L'articolo affronta le distribuzioni di probabilità (normale, log-normale, binomiale, logistica, esponenziale, distribuzione di Cauchy, distribuzione t di Student, distribuzione di Laplace, distribuzione di Poisson, distribuzione iperbolica delle secanti, distribuzione Beta e Gamma) delle variabili casuali utilizzate nella statistica applicata. Dispone anche di classi per la gestione di queste distribuzioni.
Utilizzo di feature map auto-organizzanti (mappe Kohonen) su MetaTrader 5 Utilizzo di feature map auto-organizzanti (mappe Kohonen) su MetaTrader 5
Uno degli aspetti più interessanti delle feature map auto-organizzanti (mappe Kohonen) è che imparano a classificare i dati senza supervisione. Nella sua forma base, produce una mappa di similarità dei dati di input (clustering). Le mappe SOM (Self-Organizing Map) possono essere utilizzate per la classificazione e la visualizzazione di dati ad alta dimensionalità. In questo articolo considereremo alcune semplici applicazioni delle mappe Kohonen.
3 Metodi di accelerazione degli indicatori mediante l'esempio della regressione lineare 3 Metodi di accelerazione degli indicatori mediante l'esempio della regressione lineare
L'articolo tratta i metodi di ottimizzazione degli algoritmi di calcolo degli indicatori. Ciascuno troverà il metodo più adatto alle proprie esigenze. Qui sono descritti tre metodi. Uno di questi è abbastanza semplice, il successivo richiede una solida conoscenza della matematica e l'ultimo richiede un po' di arguzia. Gli indicatori o le funzionalità di progettazione del terminale MetaTrader5 vengono utilizzati per realizzare la maggior parte dei metodi descritti. I metodi sono abbastanza universali e possono essere utilizzati non solo per l'accelerazione del calcolo della regressione lineare, ma anche per molti altri indicatori.