English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Rastreamento, Depuração e Análise Estrutural de Código Fonte

Rastreamento, Depuração e Análise Estrutural de Código Fonte

MetaTrader 5Exemplos | 17 fevereiro 2014, 16:40
1 631 1
---
---

Introdução

Esse artigo fala sobre um dos métodos de criação de uma pilha de chamadas durante a execução. As seguintes características estão descritas neste artigo:

  • Fazer a estrutura das classes usadas, funções e pastas.
  • Fazer a pilha de ligação mantendo todas as pilhas anteriores. Sequência de chamada.
  • Visualizar o estado dos parâmetros de Observação durante a execução.
  • Execução do código passo a passo.
  • Agrupar e selecionar pilhas obtidas, recebendo "extrema" informação.


Principais Princípios de Desenvolvimento

Uma abordagem comum é escolhida como método de representação de estrutura - exibida na forma de uma árvore. Para esta finalidade, nós precisaremos de duas classes informacionais. CNode - um "nó" usado para escrever toda informação sobre uma pilha. CTreeCtrl - uma "árvore" que processa todos os nós. E o próprio rastreador - CTraceCtrl, usado para processar árvores.

As classes são implementadas de acordo com a hierarquia a seguir:


As classes CNodeBase e CTreeBase descrevem propriedades e métodos básicos de trabalho com nós e árvores.

A classe herdada CNode estende a funcionalidade básica da CNodeBase, e a classe CTreeBase trabalha com a classe derivada CNode. Isso é feito devido à classe CNodeBase ser o pai de outros nós padrão, e é isolado como uma classe independente por conveniência da hierarquia e herança.

Ao contrário CTreeNode da biblioteca padrão, a classe CNodeBase contém um arranjo de indicadores para nós, deste modo o numero de "ramos" que saem deste nó é ilimitado.

As classes 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);
  };

Você pode encontrar a implementação de todas as classes nas pastas anexadas. Nesse artigos, somente vamos mostrar seus cabeçalhos e importantes funções.

De acordo com a classificação aceitada, CTreeBase representa e orienta o gráfico acíclico. A classe derivada CTreeCtrl usa CNode e serve toda sua funcionalidade: adicionando alterando e excluindo os nós CNode.

CTreeCtrl e CNode podem substituir as correspondentes classes da biblioteca padrão com sucesso, já que eles tem uma funcionalidade um pouco mais ampla.

As classes 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
  };

A arquitetura termina com duas classes: CTraceCtrl - sua única instância é usada para rastreamento, a mesma contém três instâncias da classe CTreeCtrl para criação da estrutura requirida das funções; e um container temporário - a classe CIn. Essa é só uma classe auxiliar que é usada para acrescentar novos nós a CTraceCtrl.

As classes 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
  };


Modelo de Operação da Classe Cln

Essa classe é responsável pela criação da árvore de pilha.

Formação de gráfico é executada passo-a-passo em duas etapas usando duas funções CTraceCtrl:

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

Em outras palavras, para formar uma árvore, contínuas chamadas In-Out-In-Out-In-In-Out-Out, etc. são realizadas.

O par In-Out funciona da seguinte maneira:

1. Introduzindo um bloco (função, ciclo, condição, etc.), i.e. logo após o colchete"{".
Quando introduzir o bloco, uma nova instância do CIn é criada, ele obtém o CTraceCtrl atual que já foi iniciado com alguns nós anteriores. A função CTraceCtrl::In é chamada CIn, a qual cria um novo nó na pilha. O nó é criado sob o atual nó CTraceCtrl::m_cur. Toda a atual informação sobre introduzir esta escrito aqui: nome do arquivo, número da fileira, nome da classe, funções, tempo atual, etc.

2. Sair do bloco quando encontrar um "}" colchete.
Quando sair de um bloco, o MQL automaticamente chama o destruidor CIn::~CIn. CTraceCtrl::Out é chamado no destruidor. O indicador no nó atual CTraceCtrl::m_cur é elevado a um nível acima na árvore. Neste ponto o destruidor não é chamado pelo novo nó, o nó continua na árvore.

Modelo de Criação de uma Pilha


Formação de uma pilha de chamada na forma de uma árvore com o preenchimento de toda informação sobre uma chamada é realizada usando o container CIn.



Macros para Fazer Chamadas Mais Fácil

Para evitar reescrever as longas linhas do código de criação do objeto CIn e introduzir um nó no seu código, é conveniente substitui-lo com a chamada do macro:
#define _IN    CIn _in; _in.In(__FILE__, __LINE__, __FUNCTION__)
Como você vê, o objeto CIn está criado e então nós introduzimos o nó.


Já que MQL dá um aviso no caso de nomes de variáveis locais ser as mesmas das variáveis globais, é melhor (mais preciso e claro) criar 3-4 definições análogas com outros nomes das variáveis da seguinte maneira:

#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__)
Conforme você vai mais fundo até os sub-blocos, utilize os próximos macros _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());

Com o aparecimento de macros na versão 411, você pode usar totalmente a passagem de parâmetros utilizando o #define.

Por isso que na classe CTraceCtrl você encontrará a seguinte definição macro:

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

Ele permite encurtar a verificação de validade do indicador.

Por exemplo, a linha:

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

é substituído com a menor variante:

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



Preparando Suas Pastas Para Rastreamento

Para controlar e obter a pilha, você precisa seguir três passos.

1. Adicionar as pastas requiridas
#include <Trace.mqh>

Toda a biblioteca padrão é baseada na classe CObject no momento. Assim, se isso também é usado como uma classe base nas suas pastas, é o suficiente para adicionar Trace.mqh apenas a Object.mqh.

2. Coloque o _IN macros nos blocos requeridos (você pode usar procurar/substituir)

O exemplo de utilização do _IN macro:
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. Nas funções OnInit, OnTime, e OnDeinit consistem o módulo principal do programa, adicionar a criação, modificar e deletar do objeto global CTraceCtrl respectivamente. Abaixo você pode encontrar o código já pronto para inserção:

Incorporando o rastreador no código principal

//------------------------------------------------------------------    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…
}


Exibindo Classes de Rastreamento

Então, a pilha tem sido organizada. Agora vamos considerar a exibição de informações obtidas.

Para esta finalidade, nós devemos criar duas classes. CTreeView – para exibir a árvore, e CTraceView – para controlar a exibição das árvores e informação adicional sobre pilha. Ambas classes são derivadas da classe base CView.


As classes 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
  };
    

Nós escolhemos exibir a pilha em uma sub janela separada como uma variante otimizada.

Em outras palavras, quando a classe CTraceView é criada na funçãoCTraceView::Create, a janela da tabela é criada e todos os objetos são desenhados nela, apesar do fato que o CTraceView está criado e funciona com o consultor especialista em outra janela. é feito para evitar a operação iminente do código fonte do programa rastreado e a exibição de sua própria informação no gráfico pela grande quantidade de informação.

Mas, para fazer a interação entre duas janelas possíveis, nós precisamos adicionar um indicador para a janela, o qual irá enviar todos os eventos do usuário para a janela base com o programa rastreado.

O indicador é criado na mesma função CTraceView::Create. Tendo apenas um parâmetro externo - o ID da tabela para o qual deve-se enviar todos os eventos.

O Indicador 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);
}

Em resultado, temos uma representação bem estruturada da pilha.



Na árvore TRACE mostrada à esquerda, a pilha inicial é exibida.

Abaixo dele, está a janela INFO contendo informações detalhadas sobre o nó selecionado (CTraceView::OnChartEvent nesse exemplo). Duas janelas adjacentes contendo árvores exibe a mesma pilha, mas é agrupado por classes (a árvore CLASS no meio) e por arquivos (a árvore FILE para a direita).

As árvores de classes e arquivos tem o mecanismo incorporado de sincronização com a árvore principal da pilha, assim como meios convenientes de controle. Por exemplo, quando você clica no nome de uma classe na árvore de classes, todas as funções dessa classe são selecionadas na árvore de pilha e na árvore de arquivos. Da mesma maneira, quando você clica no nome de um arquivo, todas as funções e classes daquele arquivo são selecionadas.



Esse mecanismo permite rápida seleção e exibição dos grupos requeridos de funções.



Características de Trabalhar com a Pilha

  • Adicionando Parâmetros de Observação

Como você já tem notado, os parâmetros do nó CNode incluem o arranjo de estruturas tagWatch. é criado somente para a conveniência de representação de informação. O mesmo contém um valor nomeado de uma variável ou expressão.

Estrutura de um Valor de Observação

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

Para adicionar um valor de Observação para o nó atual, você precisa chamar a função CTrace::AddWatch e usar _WATCH macro.

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


A particular limitação nos valores acrescentados (o mesmo que com os nós) é o controle da singularidade de nomes. Isso significa que o nome de um valor de Observação é verificado se é singular antes de ser adicionado ao arranjo CNode::m_watch[]. Se o arranjo contém um valor com o mesmo nome, o novo não será adicionado, mas o valor do existente será atualizado.

Todos os valores de Observação rastreados estão exibidos na janela de informação.



  • Execução do código passo a passo.

Outro recurso conveniente dado pelo MQL5 é a organização de uma pausa forçada no código durante sua execução.

A pausa é implementada usando um ciclo infinito simples enquanto (verdadeiro). A conveniência do MQL5 aqui é como lidar com o evento de saída deste ciclo - clicando no botão vermelho de controle. Para criar um ponto de parada durante a execução, use a função CTrace::Break.


A Função de Implementação de Pontos de Parada

//------------------------------------------------------------------    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 encontra tal ponto de parada, as árvores de pilhas são sincronizadas para exibir a função que chama esse macro. Se um nó é fechado o nó pai será expandido para exibí-lo. E, se necessário, a árvore é deslocada para cima ou para baixo para trazer o nó para uma área visível.


Para sair do CTraceCtrl::Break, clique no botão vermelho localizado perto do nome do nó.


Conclusão

Bom, nós temos um "brinquedo" interessante agora. Enquanto escrevi esse artigo, eu tentei muitas variantes de trabalho com CTraceCtrl e me certifiquei que MQL5 tem perspectivas únicas de controlar consultores especialistas e organizar sua operação. Todos os recursos usados para desenvolver o rastreador não estão disponíveis no MQL4, oque prova as vantagens do MQL5 e suas amplas possibilidades mais uma vez.

No código anexado, você pode encontrar todas as classes descritas nesse artigo junto com as bibliotecas de serviço (conjunto mínimo necessário deles, já que não são o conjunto alvo deles). Além disso, eu anexei o exemplo já pronto - arquivos atualizados da biblioteca padrão onde o _IN macros são colocados. Todos os experimentos foram conduzidos com o consultor especialista incluso na distribuição padrão de MetaTrader 5 - MACD Sample.mq5.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/272

Arquivos anexados |
mql5.zip (24.67 KB)
Últimos Comentários | Ir para discussão (1)
Sumet Saengkeaw
Sumet Saengkeaw | 3 dez 2017 em 18:10
MetaQuotes Software Corp.:

Novo artigo Rastreamento, Depuração e Análise Estrutural de Código Fonte foi publicado:

Autor: o_Omp.5

Pagamentos e métodos de pagamento Pagamentos e métodos de pagamento
A MQL5.community oferece amplas oportunidades de ganhar aos traders e desenvolvedores de aplicativos de negociação para o terminal MetaTrader. Neste artigo, explicaremos como o pagamento de serviços MQL5 e a retirada de fundos acorrem, também veremos como é mantida a segurança ao realizar operações.
Distribuições de probabilidade estatística em MQL5 Distribuições de probabilidade estatística em MQL5
O artigo aborda as distribuições de probabilidade (normal log-normal, binominal, logística, exponencial, distribuição de Cauchy, distribuição T de Student, distribuição Laplace, distribuição Poisson, distribuição Secante Hiperbólica, distribuição Beta e Gama) de variáveis aleatórias usadas nas Estatísticas Aplicadas. Também apresenta classes para lidar com estas distribuições.
Estimativas estatísticas Estimativas estatísticas
Estimativa de parâmetros estatísticos de uma sequência é muito importante, desde que muitos dos modelos e métodos matemáticos são baseados em diferentes suposições. Por exemplo, normalidade da lei de distribuição ou valor de dispersão, ou outros parâmetros. Assim, quando analisando e realizando previsões de séries de tempo, nós precisamos uma ferramenta simples e conveniente que permite rápida e clara estimativa dos principais parâmetros estatísticos. O arquivo descreve brevemente os parâmetros estatísticos mais simples de uma sequência aleatória e vários métodos de análise visual. Ele oferece a implementação desses métodos em MQL5 e os métodos de visualização dos resultados dos cálculos usando o aplicativo Gnuplot.
3 Métodos de Aceleração de Indicadores através do Exemplo da Regressão Linear 3 Métodos de Aceleração de Indicadores através do Exemplo da Regressão Linear
O artigo lida com os métodos de otimização de algorítimos computacionais de indicadores. Todos encontrarão um método que seja melhor para suas necessidades. Três métodos são descritos aqui. Um deles é bastante simples, o outro requer conhecimento sólido em matemática e o último requer um pouco de perspicácia. Indicadores ou o design do terminal do MetaTrader 5 são usados para realizar a maioria dos métodos descritos. Os métodos são bastante universais e podem ser usados não apenas para aceleração do cáluclo de regressão linar, mas também para muitos outros indicadores.