English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Kaynak Kodun İzlenmesi, Hata Ayıklanması ve Yapısal Analizi

Kaynak Kodun İzlenmesi, Hata Ayıklanması ve Yapısal Analizi

MetaTrader 5Örnekler | 16 Aralık 2021, 15:44
142 0
---
---


Tanıtım

Bu makale, yürütme sırasında bir çağrı yığını oluşturma yöntemlerinden birini anlatır. Aşağıdaki özellikler makalede açıklanmıştır:

  • Kullanılan sınıfların, fonksiyonların ve dosyaların yapısının yapılması.
  • Çağrı yığınını önceki tüm yığınları koruyarak yapmak. Onları çağırma sırası.
  • Yürütme sırasında İzleme parametrelerinin durumunu görüntüleme.
  • Kodun adım adım yürütülmesi.
  • Elde edilen yığınları gruplama ve sıralama, "aşırı" bilgi alma.


Gelişimin Temel İlkeleri

Yapının temsili yöntemi olarak ortak bir yaklaşım seçilmiştir – bir ağaç şeklinde görüntüleme. Bunun için iki bilgi sınıfına ihtiyacımız var. CNode - bir yığınla ilgili tüm bilgileri yazmak için kullanılan bir "düğüm". CtreeCtrl - tüm düğümleri işleyen bir "ağaç". Ve izleyicinin kendisi - ağaçları işlemek için kullanılan CTraceCtrl.

Sınıflar aşağıdaki hiyerarşiye göre uygulanır:


CNodeBase ve CTreeBase sınıfları, düğümler ve ağaçlarla çalışmanın temel özelliklerini ve yöntemlerini açıklar.

Devralınan CNode sınıfı, CNodeBase'in temel işlevselliğini genişletir ve CTreeBase sınıfı, türetilmiş CNode sınıfıyla çalışır. CNodeBase sınıfının diğer standart düğümlerin ebeveyni olması nedeniyle yapılır ve hiyerarşi ve kalıtım kolaylığı için bağımsız bir sınıf olarak izole edilir.

Standart kitaplıktaki CTreeNode'dan farklı olarak, CNodeBase sınıfı düğümlere yönelik bir dizi işaretçi içerir, dolayısıyla bu düğümden çıkan "dalların" sayısı sınırsızdır.

CNodeBase ve CNode Sınıfları

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

Tüm sınıfların uygulamasını ekteki dosyalarda bulabilirsiniz. Makalede sadece başlıklarını ve önemli işlevlerini göstereceğiz.

Kabul edilen sınıflandırmaya göre, CTreeBase döngüsel olmayan grafiği temsil eder ve yönlendirir. Türetilmiş sınıf CTreeCtrl, CNode'u kullanır ve tüm işlevselliğini yerine getirir: CNode düğümlerini ekleme, değiştirme ve silme.

CTreeCtrl ve CNode, biraz daha geniş bir işlevselliğe sahip olduklarından, standart kitaplığın karşılık gelen sınıflarını başarıyla değiştirebilir.

CTreeBase ve CTreeCtrl Sınıfları

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

Mimari iki sınıfla sona erer: CTraceCtrl - tek örneği doğrudan izleme için kullanılır, gerekli işlev yapısının oluşturulması için CTreeCtrl sınıfının üç örneğini içerir; ve geçici bir kapsayıcı - CIn sınıfı. Bu sadece CTraceCtrl'ye yeni düğümler eklemek için kullanılan bir yardımcı sınıftır.

CTraceCtrl ve CIn Sınıfları

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 Sınıfının Çalışma Modeli

Bu sınıf, yığın ağacının oluşturulmasından sorumludur.

Grafiğin oluşturulması, iki CTraceCtrl işlevi kullanılarak iki aşamada adım adım gerçekleştirilir:

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

Başka bir deyişle, bir ağaç oluşturmak için sürekli Giriş-Çıkış-Giriş-Çıkış-Giriş-Giriş-Çıkış-Çıkış vb. çağrıları yapılır.

Giriş-Çıkış çifti şu şekilde çalışır:

1. Bir blok (fonksiyon, döngü, koşul, vb.) girme, yani "{" parantezinden hemen sonra.
Bloğu girerken, yeni bir CIn örneği oluşturulur, önceki bazı düğümlerle zaten başlatılmış olan mevcut CTraceCtrl'yi alır. CTraceCtrl::Giriş işlevi CIn'de çağrılır, yığında yeni bir düğüm oluşturur. Düğüm, geçerli CTraceCtrl::m_cur düğümü altında oluşturulur. Girmeyle ilgili tüm gerçek bilgiler içinde yazılıdır: dosya adı, satır numarası, sınıf adı, işlevler, geçerli saat vb.

2. Bir "}" ayracı ile karşılaşıldığında bloktan çıkılıyor.
Bloktan çıkarken, MQL otomatik olarak yıkıcı CIn::~CIn'i çağırır. Yıkıcıda CTraceCtrl::Çıkış çağrılır. Mevcut CTraceCtrl::-m_cur düğümünün işaretçisi ağaçta bir seviye yukarıya yükseltilir. Yıkıcı yeni düğüm için çağrılmaz, düğüm ağaçta kalır.

Yığın Oluşturma Şeması


Bir çağrı ile ilgili tüm bilgilerin doldurularak bir ağaç şeklinde çağrı yığınının oluşturulması CIn konteyneri kullanılarak gerçekleştirilir.



Aramaları Kolaylaştıran Makrolar

CIn nesnesini oluştururken ve kodunuza bir düğüm girerken uzun kod satırlarını yeniden yazmaktan kaçınmak için makronun çağrısı ile değiştirmek uygundur:
#define _IN    CIn _in; _in.In(__FILE__, __LINE__, __FUNCTION__)
Gördüğünüz gibi CIn nesnesi oluşturuluyor ve ardından düğüme giriyoruz.


MQL, yerel değişkenlerin adlarının global değişkenlerle aynı olması durumunda bir uyarı verdiği için aşağıdaki biçimde diğer değişken adlarıyla 3-4 benzer tanım oluşturmak daha iyidir (daha doğru ve net):

#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__)
Alt bloklarda daha derine indikçe, sonraki makroları _INx kullanın
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 derlemesinde makroların görünmesiyle, #define kullanarak parametrelerin geçişini tam olarak kullanabilirsiniz.

Bu nedenle CTraceCtrl sınıfında aşağıdaki makro tanımını bulacaksınız:

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

İşaretçinin geçerlilik kontrolünün kısaltılmasına izin verir.

Örneğin, satır:

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

daha kısa varyantla değiştirilir:

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



Dosyalarınızı İzleme İçin Hazırlama

Yığını kontrol etmek ve almak için üç adım atmanız gerekir.

1. Gerekli dosyaları ekleyin
#include <Trace.mqh>

Tüm standart kitaplık şu anda CObject sınıfına dayanmaktadır. Bu nedenle, dosyalarınızda temel sınıf olarak da kullanılıyorsa, Trace.mqh'yi yalnızca Object.mqh'ye eklemeniz yeterlidir.

2. _IN makrolarını gerekli bloklara yerleştirin (arama/değiştirme özelliğini kullanabilirsiniz)

_IN makrosunu kullanma örneği:
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. Programın ana modülünü oluşturan OnInit, OnTime ve OnDeinit fonksiyonlarında sırasıyla CTraceCtrl global nesnesinin oluşturulmasını, değiştirilmesini ve silinmesini ekleyin. Eklemek için hazır kodu aşağıda bulabilirsiniz:

İzleyiciyi ana koda gömmek

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


İz Görüntüleme Sınıfları

Böylece yığın düzenlendi. Şimdi elde edilen bilgilerin görüntülenmesini ele alalım.

Bunun için iki sınıf oluşturmalıyız. CTreeView – ağacın görüntülenmesi için ve CTraceView – ağaçların görüntülenmesinin kontrolü ve yığın hakkında ek bilgiler için. Her iki sınıf da CView temel sınıfından türetilmiştir.


CTreeView ve CTraceView Sınıfları

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

En uygun değişken olarak yığını ayrı bir alt pencerede görüntülemeyi seçtik.

Başka bir deyişle, CTraceView::Create işlevinde CTraceView sınıfı oluşturulduğunda, CTraceView başka bir pencerede Uzman Danışman’da oluşturulup çalışmasına rağmen, grafik penceresi oluşturulur ve tüm nesneler bunun içine çizilir. Takip edilen programın kaynak kodunun çalışmasını ve kendi bilgilerinin büyük miktarda bilgi ile çizelge üzerinde görüntülenmesini engellemek için yapılır.

Ancak iki pencere arasındaki etkileşimi mümkün kılmak için, kullanıcının tüm olaylarını izlenen programla temel pencereye gönderecek olan pencereye bir gösterge eklememiz gerekiyor.

Gösterge, aynı CTraceView::Create işlevinde oluşturulur. Tüm olayları göndermesi gereken grafiğin kimliği olan yalnızca bir harici parametreye sahiptir.

TraceAgent Göstergesi

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

Sonuç olarak, yığının oldukça yapılandırılmış bir temsiline sahibiz.



Solda görüntülenen TRACE ağacında ilk yığın görüntülenir.

Altında, seçilen düğüm hakkında ayrıntılı bilgi içeren INFO penceresi vardır (bu örnekte CTraceView::OnChartEvent). Ağaçları içeren iki bitişik pencere aynı yığını görüntüler, ancak sınıflara (ortadaki SINIF ağacı) ve dosyalara (sağdaki DOSYA ağacı) göre gruplandırılmıştır.

Sınıfların ve dosyaların ağaçları, uygun kontrol araçlarının yanı sıra yığının ana ağacıyla gömülü senkronizasyon mekanizmasına sahiptir. Örneğin, sınıf ağacında bir sınıf adına tıkladığınızda, bu sınıfın tüm işlevleri yığın ağacında ve dosya ağacında seçilir. Aynı şekilde bir dosya adına tıkladığınızda o dosyadaki tüm fonksiyonlar ve sınıflar seçilir.



Bu mekanizma, gerekli işlev gruplarının hızlı bir şekilde seçilmesine ve görüntülenmesine olanak tanır.



Yığınla Çalışmanın Özellikleri

  • İzleme Parametreleri Ekleme

Daha önce fark ettiğiniz gibi, CNode düğümünün parametreleri tagWatch yapı dizisini içerir. Sadece bilginin temsili kolaylığı için yaratılmıştır. Bir değişkenin veya ifadenin adlandırılmış değerini içerir.

İzleme Değerinin Yapısı

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

Geçerli düğüme yeni bir İzleme değeri eklemek için CTrace::AddWatch işlevini çağırmanız ve _WATCH makrosunu kullanmanız gerekir.

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


Eklenen değerler üzerindeki özel sınırlama (düğümlerle aynı) adların benzersizliğinin kontrolüdür. Bu, CNode::m_watch[] dizesine eklenmeden önce bir Watch değerinin adının benzersiz olup olmadığının kontrol edildiği anlamına gelir. Dize aynı ada sahip bir değer içeriyorsa, yenisi eklenmez, ancak mevcut olanın değeri güncellenir.

İzlenen tüm İzleme değerleri bilgi penceresinde görüntülenir.



  • Kodun adım adım yürütülmesi.

MQL5 tarafından sağlanan bir başka kullanışlı özellik, yürütme sırasında kodda zorunlu bir kesintinin düzenlenmesidir.

Duraklatma, basit bir sonsuz döngü while (true) kullanılarak gerçekleştirilir. MQL5'in buradaki rahatlığı, bu döngüden çıkış olayının kontrol eden kırmızı düğmeye tıklanarak gerçekleştirilmesidir. Yürütme sırasında bir kesme noktası oluşturmak için CTrace::Break işlevini kullanın.


Kırılma Noktalarını Uygulama Fonksiyonu

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


Böyle bir kırılma noktasıyla karşılaşıldığında, yığın ağaçları bu makroyu çağıran işlevi görüntülemek için senkronize edilir. Bir düğüm kapalıysa, üst düğüm onu gösterecek şekilde genişletilir. Ve gerekirse, düğümü görünür alana getirmek için ağaç yukarı veya aşağı kaydırılır.


CTraceCtrl::Break'ten çıkmak için, düğüm adının yanında bulunan kırmızı düğmeye tıklayın.


Sonuç

Şimdi ilginç bir "oyuncağımız" oldu. Makaleyi yazarken, CTraceCtrl ile çalışmanın birçok çeşidini denedim ve MQL5'in Uzman Danışmanları kontrol etme ve operasyonlarını organize etme konusunda benzersiz bakış açılarına sahip olduğundan emin oldum. İzleyiciyi geliştirmek için kullanılan tüm özellikler MQL4'te mevcut değildir, bu da MQL5'in avantajlarını ve geniş olanaklarını bir kez daha kanıtlamaktadır.

Ekli kodda, makalede açıklanan tüm sınıfları hizmet kitaplıkları ile birlikte bulabilirsiniz (amaç olmadığı için gereken minimum set). Ayrıca, _IN makrolarının yerleştirildiği standart kitaplığın hazır örnek - güncellenmiş dosyalarını ekledim. Tüm deneyler, MetaTrader 5 - MACD Sample.mq5'in standart teslimatına dahil olan Expert Advisor ile gerçekleştirilmiştir.


MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/272

Ekli dosyalar |
mql5.zip (24.67 KB)
İstatistiksel Tahminler İstatistiksel Tahminler
Matematiksel model ve yöntemlerin çoğu farklı varsayımlara dayandığı için bir dizinin istatistiksel parametrelerinin tahmini çok önemlidir. Örneğin, dağılım yasasının normalliği veya ayrılma değeri veya diğer parametreler. Bu nedenle, zaman serilerini analiz ederken ve tahmin ederken, ana istatistiksel parametreleri hızlı ve net bir şekilde tahmin etmeye izin veren basit ve kullanışlı bir araca ihtiyacımız var. Makale, rastgele bir dizinin en basit istatistiksel parametrelerini ve görsel analizinin çeşitli yöntemlerini kısaca açıklamaktadır. Bu yöntemlerin MQL5'te uygulanmasını ve Gnuplot uygulamasını kullanarak hesaplama sonuçlarının görselleştirilmesi yöntemlerini sunar.
MQL5'te İstatistiksel Olasılık Dağılımları MQL5'te İstatistiksel Olasılık Dağılımları
Makale, Uygulamalı İstatistiklerde kullanılan rastgele değişkenlerin olasılık dağılımlarını (normal, log-normal, binom, lojistik, üstel, Cauchy dağılımı, Öğrencinin t dağılımı, Laplace dağılımı, Poisson dağılımı, Hiperbolik Secant dağılımı, Beta ve Gama dağılımı) ele alıp verir. Ayrıca bu dağılımları işlemek için sınıflar özelliğine sahiptir.
MetaTrader 5'te Kendi Kendini Düzenleyen Özellik Haritalarını (Kohonen Haritaları) Kullanma MetaTrader 5'te Kendi Kendini Düzenleyen Özellik Haritalarını (Kohonen Haritaları) Kullanma
Kendi Kendini Düzenleyen Özellik Haritalarının (Kohonen haritaları) en ilginç yönlerinden biri, verileri denetim olmadan sınıflandırmayı öğrenmeleridir. Temel biçiminde, girdi verilerinin (kümeleme) bir benzerlik haritası üretir. SOM haritaları, yüksek boyutlu verilerin sınıflandırılması ve görselleştirilmesi için kullanılabilir. Bu yazıda Kohonen haritalarının birkaç basit uygulamasını ele alacağız.
Doğrusal Regresyon Örneğiyle 3 Gösterge Hızlandırma Yöntemi Doğrusal Regresyon Örneğiyle 3 Gösterge Hızlandırma Yöntemi
Makale, gösterge hesaplama algoritmaları optimizasyonu yöntemlerini ele alır. Herkes kendi ihtiyaçlarına en uygun yöntemi bulacaktır. Burada üç yöntem açıklanmıştır. Bunlardan biri oldukça basittir, bir sonraki ise sağlam bir matematik bilgisi gerektirir ve sonuncusu ise biraz zeka gerektirir. Göstergeler veya MetaTrader5 terminal tasarım özellikleri, açıklanan yöntemlerin çoğunu gerçekleştirmek için kullanılır. Yöntemler oldukça evrenseldir ve sadece doğrusal regresyon hesaplamasının hızlandırılması için değil, aynı zamanda diğer birçok gösterge için de kullanılabilir.