English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
소스 코드의 트레이싱, 디버깅, 및 구조 분석

소스 코드의 트레이싱, 디버깅, 및 구조 분석

MetaTrader 5 | 4 8월 2021, 17:22
258 0
---
---


들어가며

이 문서에서 실행 도중 콜 스택을 만드는 방법 중 하나에 대해 알려드릴 것입니다. 이하의 기능들이 이 문서에서 다뤄졌습니다:

  • 사용된 클래스, 기능 및 파일의 구조 만들기.
  • 모든 과거 스택을 유지하는 콜 스택 생성하기. 스택들을 호출하는 시퀀스.
  • 실행 중 Watch 패러미터 상태 보기.
  • 코드 실행을 스텝 별로 분석하기
  • 획득한 스택을 그룹으로 묶고 정리하여 "극단적인" 정보를 얻기.


개발의 핵심 원칙

공통 접근방식은 구조물의 표현 방법으로 선택되며, 트리 구조의 형태로 표시됩니다. 이 목적을 위해 두개의 정보 클래스가 필요합니다. CNode - 스택에 관한 모든 정보를 쓸 "노드". CTreeCtrl - 모든 노드를 처리할 "트리". 그리고 트레이서 본체 - CTraceCtrl, 트리를 처리하는데에 씁니다.

클래스는 다음 서열에 따라 구현됩니다:


CNodeBaseCTreeBase 클래스들은 노드와 트리 작업에 관한 기본 속성들과 메소드들을 다룹니다.

상속받은 클래스 CNodeCNodeBase의 기본 기능의 연장선상으로,CTreeBase 클래스는 자식 클래스 CNode와 작업합니다. 이는 CNodeBase가 다른 표준 노드들의 부모이면서 서열과 상속의 편의성을 위해 독립된 클래스이기 때문에 성립되는 것입니다.

표준 라이브러리의 CTreeNode 와는 달리 CNodeBase 클래스는 노드들을 가리키는 포인터 어레이를 가지고 있어 이 노드에서 뻗어져나오는 "가지"의 수는 무한합니다.

CNodeBase 및 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);
  };

첨부된 파일에서 모든 클래스의 구현을 찾을 수 있습니다. 이 기사에서는 헤더와 중요한 함수만 보이려고 합니다.

분류에 따르면, CTreeBase는 비순환 그래프에서 유래되었으며 이를 나타냅니다. 파생 클래스 CTreeCtrl CNode를 사용하며 모든 기능성을 제공합니다: CNode 노드들을 추가하고, 변화시키고, 삭제하는 것.

CTreeCtrl CNode는 표준 라이브러리의 해당 클래스를 성공적으로 대체할 수 있습니다. 기능이 약간 더 풍부하기 때문입니다.

CTreeBase 및 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
  };

이 아키텍쳐는 두개의 클래스로 마무리됩니다: CTraceCtrl - 이 클래스의 인스턴스는 트레이싱에 직접적으로 이용됩니다. 필요한 함수 구축에 CTreeCtrl 클래스의 인스턴스 3개가 들어있으며; 임시 컨테이너 CIn 클래스가 있습니다. 이는 CTraceCtrl에 새 노드들을 추가하는 보조 클래스에 지나지 않습니다.

CTraceCtrl 및 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
  };


CIn 클래스 모델 작업

이 클래스는 스택 트리를 만드는 역할을 맡고있습니다.

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-Out-In-Out-In-In-Out-Out의 사전 콜 등이 형성된다는 것입니다.

In-Out 페어는 다음과 같이 작동합니다:

1. "{" 괄호 직후에 블록에 진입 (함수, 사이클, 조건, 등.).
블록 진입 후 CIn의 새 인스턴스가 생성됩니다. 기존 노드들에서 이미 시작된 CTraceCtrl 를 받습니다. CTraceCtrl::In 함수가 CIn에서 호출되어 스택 안에 새로운 노드를 만듭니다. 새 노드들은 현재 노드인 CTraceCtrl::m_cur 아래에 생깁니다. 파일 이름, 행 번호, 클래스 이름, 기능, 현재 시간 등 입력에 대한 실제 정보가 모두 기재되어 있습니다.

2. "}" 괄호를 만나면 블록에서 이탈합니다.
블록에서 이탈할 때 MQL은 소멸자 CIn::~CIn를 호출합니다. 소멸자 안에선 CTraceCtrl::Out 이 호출됩니다. 현 노드 CTraceCtrl::m_cur 의 포인터는 트리 안에서 1단계 높게 호출됩니다 . 새 노드에 대해 소멸자가 호출되지 않으면 노드는 트리에 유지됩니다.

스택 형성 스키마


트리 안에서 어떠한 콜에 대한 정보를 담아 콜 스택을 만드는 것은 CIn 컨테이너 안에서 이루어집니다.



매크로를 통해 콜을 더욱 쉽게 만들기

CIn 객체 생성에 코드를 길게 쓰는 것을 방지하려면 콜을 매크로로 전환하는 편이 편합니다:
#define _IN    CIn _in; _in.In(__FILE__, __LINE__, __FUNCTION__)
보시다시피 CIn 객체가 생성되었고, 우리는 노드에 진입합니다.


MQL은 지역 변수 이름이 전역 변수와 동일한 경우 경고를 제공하므로 다음 형식의 다른 변수 이름으로 3-4개의 유사 정의를 생성하는 것이 좋습니다(더 정확하고 명확함).

#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__)
하위 블록으로 깊게 들어감에 따라 _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());

411 빌드의 매크로들이 나타남에 따라 #define을 통해 패러미터 패싱을 쓸 수 있습니다.

CTraceCtrl 클래스 내에서 다음의 매크로 정의를 볼 수 있는 이유입니다:

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

포인터의 정상성 체크 역시 단축시킵니다

예를들어 이 라인을 보면:

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

더 짧은 버전으로 줄어듭니다:

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



파일을 트레이싱에 대응하게 준비하기

스택을 관리하고 얻기 위해선 세가지 단계를 밟아야 합니다.

1. 필요한 파일을 추가합니다
#include <Trace.mqh>

표준 라이브러리 전체는 CObject 클래스에 기반을 두고 있습니다. 그러므로 만약에 이 클래스가 당신의 파일 안에서 기반 클래스로 사용되고 있을 경우 Trace.mqh Object.mqh에만 연결해도 됩니다.

2. _IN 매크로를 필요한 블록에 배치하기 (탐색/교체 를 쓸 수 있습니다)

_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. OnInit, OnTime, OnDeinit 함수 안에서 각각 글로벌 객체 CTraceCtrl 의 추가, 수정, 삭제가 이루어집니다. 아래에서 삽입용 레디메이드 코드를 찾을 수 있습니다:

메인 코드에서의 트레이서 임베딩

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


트레이스 표시 클래스

이제 스택이 정리되었습니다. 이제 얻은 정보를 표시해봅시다.

이를 위해선 2개의 클래스를 생성해야합니다. CTreeView – 는 트리 표시용, 그리고 CTraceView – 트리와 스택에 관련된 추가 정보의 표시 및 관리용 양쪽 클래스 모두 기반 클래스 CView에서 파생되었습니다.


CTreeView 및 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
  };

스택을 최적의 변형으로 별도의 하위 창에 표시하기로 선택했습니다.

CTraceView 클래스는 CTraceView::Create 함수에서 생성되며, 차트 창이 생기고 다른 모든 객체가 그 안에 그려집니다 CTraceView는 다른 창의 Expert Advisor를 통해 생성되어 작업하긴 하지만. 이는 추적된 프로그램의 소스 코드 작동에 방해가 되는 것을 방지하고 엄청난 양의 정보에 의해 자체 정보를 차트에 표시하는 것을 방지하기 위해 수행됩니다.

그러나 두 윈도우 간의 상호 작용을 가능하게 하려면 윈도우에 인디케이터를 추가해야 합니다. 그러면 사용자의 모든 이벤트가 추적된 프로그램과 함께 기본 윈도우로 전송됩니다.

해당 인디케이터는 같은 함수 CTraceView::Create에서 생성됩니다. 외부 패러미터는 하나뿐입니다. 즉, 모든 이벤트를 전송할 차트의 ID입니다.

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

결과적으로 스택을 상당히 구조적으로 표현할 수 있게되었습니다.



왼쪽에 표시된 TRACE 트리에서 초기 스택이 표시됩니다.

아래의 INFO 창에는 선택된 노드 (이 예시의 경우엔 CTraceView::OnChartEvent) 에 대한 구체적인 정보가 담겨있습니다 . 두개의 인접한 창에 같은 스택의 트리가 표시되지만 하나는 클래스에 따라(중앙의 CLASS 트리) 그룹되며 다른 쪽은 파일에 따라 (우측의 FILE 트리) 표시됩니다.

클래스 및 파일 트리는 스택의 메인 트리와의 동기화 메커니즘과 편리한 제어 수단을 내장하고 있습니다. 예를 들어 클래스 트리에서 클래스 이름을 누르면 스택 트리와 파일 트리에서 이 클래스의 모든 기능이 선택됩니다. 이와 마찬가지로 파일 이름을 클릭하면 해당 파일의 모든 함수와 클래스가 선택됩니다.



이 메커니즘을 사용하면 필요한 함수 그룹을 빠르게 선택하고 볼 수 있습니다.



스택 다루기

  • Watch 패러미터 추가하기

눈치 채셨겠다시피 CNode 노드의 패러미터에는 구조의 어레이인 tagWatch가 포함되어 있습니다. 이는 정보를 표현하기 쉽게 만들기 위해서 만들어졌습니다 변수의 값이나 표현식이 들어있습니다.

Watch 값의 구조

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

기존 노드에 새 Watch 값을 추가하기 위해서는 CTrace::AddWatch 함수를 호출하고 _WATCH 매크로를 사용해야 합니다.

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


추가 값(노드와 같음)에 대한 특별한 제한은 이름이 겹치지않게 제어하는 것이 목적입니다. 이는 Watch 값의 이름이 CNode::m_watch[] 어레이에 추가되기 전에 고유성을 체크받는다는 의미입니다. 어레이에 동일한 이름의 값이 포함된 경우 새 값이 추가되지 않지만 기존 값의 값이 업데이트됩니다.

추적된 Watch 값은 정보 창에 표시됩니다



  • 코드 실행을 스텝 별로 분석하기

MQL5에서 제공하는 또 다른 편리한 기능은 실행 중 코드의 강제 차단을 구성하는 것입니다.

일시 중지는 간단한 무한 루프 while (true)를 사용하여 구현됩니다. MQL5이 이에 관해 상당히 편한 점은 이 루프에서 빠져나가는 부분입니다 - 그냥 빨간버튼을 누르면 되기 때문입니다. 실행 중에 브레이크 포인트를 만들려면 CTrace::Break 함수를 활용하십시오.


브레이크 포인트를 구현하기 위한 함수

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


이러한 중단점을 충족하면 스택 트리가 동기화되어 이 매크로라는 함수를 표시합니다. 노드가 닫히면 부모 노드가 확장되어 노드가 표시됩니다. 필요한 경우 트리를 위 또는 아래로 스크롤하여 노드를 가시 영역으로 가져옵니다.


CTraceCtrl::Break에서 이탈하려면 노드 이름 근처에 위치한 빨간 버튼을 누르면 됩니다.


마치며

이제 흥미로운 "장난감"이 준비되었습니다. 이 문서를 쓰는 동안 저는 CTraceCtrl 와 함께 작업하는 많은 바리에이션들을 시도했고 MQL5가 Expert Advisors를 통제하고 운영을 정리하는 독특한 관점을 가지고 있는지 확인했습니다. 트레이서 개발에 사용되는 기능은 어떤 것도 MQL4에서 사용할 수 없으며, 이는 MQL5의 장점과 그 뛰어난 가능성을 다시 한 번 입증하는 것입니다.

첨부된 코드에서는 서비스 라이브러리와 함께 기사에 설명된 모든 클래스를 찾을 수 있습니다(핵심이 아니므로 최소 필수 클래스 세트만). 덤으로 레디메이드 예제를 첨부해두었습니다 - _IN 매크로가 준비된 표준 라이브러리의 업데이트버전 파일들입니다. 우리가 Expert Advisor를 통해 시행한 모든 실험은 MetaTrader 5의 표준 딜리버리 - MACD Sample.mq5에 포함되어 있습니다.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/272

파일 첨부됨 |
mql5.zip (24.67 KB)
통계적 추정 통계적 추정
대부분의 수학적 모델과 방법은 서로 다른 가정을 기반으로 하기 때문에 시퀀스의 통계적 모수 추정은 매우 중요합니다. 예를 들어 분포 법칙의 정규성이나 분산 값 또는 기타 모수가 있습니다. 따라서 시계열 분석 및 예측 시 주요 통계 모수를 빠르고 명확하게 추정할 수 있는 간단하고 편리한 도구가 필요합니다. 이 문서는 랜덤 시퀀스의 가장 간단한 통계적 모수와 시각적 분석의 여러 메소드에 대해 설명할 것입니다. MQL5에서는 이러한 방법의 구현과 Gnuplot 애플리케이션을 사용한 계산 결과의 시각화 메소드를 제공합니다.
MQL5 에서의 통계적 확률 분산 MQL5 에서의 통계적 확률 분산
이 문서에서는 적용 통계에 사용되는 랜덤 변수의 확률 분포(정규 분포, 로그-정규 분포, 이항 분포, 로그 분포, 지수 분포, 코시 분포, 스튜던트 t 분포, 라플라스 분포, 푸아송 분포, 쌍곡 시컨트 분포, 베타 및 감마 분포)를 다룹니다. 또한 이러한 배포를 처리하기 위한 클래스도 제공됩니다.
MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기 MetaTrader 5에서 자동 정리 기능 맵 (코호넨 맵) 이용하기
자체 구성 기능 맵(코호넨 맵)의 가장 흥미로운 측면 중 하나는 사람이 관리하지 않아도 스스로 데이터를 분류하는 법을 배운다는 것입니다. 기본적인 형태로 입력 데이터의 유사성 맵(클러스터링)을 생성합니다. SOM 맵은 고차원 데이터의 분류 및 시각화에 사용할 수 있습니다. In this article we will consider several simple applications of Kohonen maps.
선형 회귀 예시를 통한 인디케이터 가속 그 3가지 방법 선형 회귀 예시를 통한 인디케이터 가속 그 3가지 방법
이 문서에서는 인디케이터들의 메소드와 최적화 알고리즘에 대해 다루어볼 것입니다. 모든 독자분이 자신에게 적합한 메소드를 찾을 수 있을것입니다. 총 3개의 메소드가 다뤄집니다. 그 중 하나는 몹시 간단하며, 두번째 것은 탄탄한 수학적 지식을 필요로 하며 마지막 것은 약간 지혜가 필요합니다. 설명된 메소드 대부분을 이해하기 위해 인디케이터나 MetaTrader5 터미널 디자인 기능이 사용되었습니다. 이 메소드들은 매우 보편적이며 선형 회귀 계산의 가속뿐만 아니라 다른 많은 지표에도 사용할 수 있습니다.