English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Standart Kitaplık Sınıflarını kullanarak kendi Piyasa İzlemenizi oluşturun

Standart Kitaplık Sınıflarını kullanarak kendi Piyasa İzlemenizi oluşturun

MetaTrader 5Örnekler | 15 Aralık 2021, 11:08
129 0
Dmitriy Skub
Dmitriy Skub

Giriş

Görevin temel amacı, MetaTrader 5 istemci terminalinin grafiğinde rastgele seçilmiş metinsel bilgilerin çıktısı için kullanıcı dostu ve genişletilebilir bir araç geliştirmekti. Örneğin, bir tablo olarak sunulan Expert Advisor'ın mevcut ayarları veya belirli bir aralıktaki çalışmalarının sonuçları, yatırımcı tarafından kullanılan fiyat değerleri veya gösterge değerleri tablosu veya alım satım Expert Advisor günlüğü. Tüm bu bilgiler, bu kitaplığı kullanan EA'nın veya göstergenin çalışması sırasında grafik üzerinde dinamik olarak görüntülenebilir.

Kitaplığı geliştirmenin temeli olarak, MetaTrader 5 istemci terminalinin Standart Kitaplık sınıflarından oluşan bir koleksiyon kullanıldı. İlk olarak bu sınıfları ele alacağız ve sonra görevimizi yerine getirmek için onları genişleteceğiz.


Grafik Nesneler için Standart Sınıflar

İlgilendiğimiz sınıflar kümesi Include ve Include\ChartObjects klasörlerinde yer alır.

Bunlar, aşağıdaki dosyalardır:

  • Object.mqh - Grafik nesnelerle ilgili tüm diğer sınıfları oluşturmak için CObject temel sınıfını içerir.
  • ChartObject.mqh - Ayrıca, grafik nesnelerin genel verilerinin ve yöntemlerinin işlevselliğini ve kapsüllenmesini genişleten CObject sınıfından türetilen CChartObject sınıfını da içerir.
  • ChartObjectsTxtControls.mqh - Metin içeren çeşitli grafik nesnelerini grafik üzerinde görüntülemeyi amaçlayan bir dizi sınıf içerir. (CChartObjectText temel sınıf ve onun alt öğeleri: CChartObjectLabel, CChartObjectEdit ve CChartObjectButton.

Bu sınıfları daha ayrıntılı olarak ele alalım.


CObject: Temel Sınıf

Sınıf açıklaması kısa; dolayısıyla bunu burada açıklayalım:

class CObject
{
protected:
   CObject          *m_prev;
   CObject          *m_next;

public:
                     CObject();

   CObject          *Prev()                { return(m_prev); }
   void              Prev(CObject *node)   { m_prev=node;    }
   CObject          *Next()                { return(m_next); }
   void              Next(CObject *node)   { m_next=node;    }

   virtual bool      Save(int file_handle) { return(true);   }
   virtual bool      Load(int file_handle) { return(true);   }

   virtual int       Type() const          { return(0);      }

protected:
   virtual int       Compare(const CObject *node,int mode=0) const { return(0); }
};

//+------------------------------------------------------------------+
void CObject::CObject()
{
   m_prev=NULL;
   m_next=NULL;
}

Gördüğünüz üzere, bu sınıf yalnızca genel amaçlı veri ve yöntemleri içerir; bunlar, doğrudan grafik üzerindeki çıktı ile ilişkili değildir.

Ancak, çok önemli bir özelliğe sahiptir; bu, basit bağlantılı ve çift bağlantılı listeler oluşturmak için kullanılabilir. Bu özellikler, CObject* türündeki CObject::m_prev ve CObject::m_next veri alanları ve bunların okuma/yazma yöntemleriyle sağlanır. CObject::m_prev alanı, önceki liste öğesini belirtirken, CObject::m_next bir sonrakini belirtir. Listelerin yapısı hakkında daha fazla ayrıntı daha sonra sağlanacaktır.

Ayrıca, CObject* türündeki iki nesneyi karşılaştırmak için bir yöntem vardır: CObject::Compare yöntemi; bu, liste öğeleri sıralanırken kullanılabilir. Dosyalardaki veri alanlarını kaydetmenize/saymanıza olanak tanıyan iki yararlı yöntem daha vardır; bunlar, CObject::Save ve CObject::Load yöntemleridir. İstenen işlevselliği elde etmek için bu yöntemlerin alt öğe sınıflarında aşırı yüklenmesi gerekir.

CObject::Tür, nesne türü tanımlama yöntemidir. Bu yöntem, farklı türde nesneler içeren bir listeyi işlerken kullanışlıdır.

CObject sınıfı (ve örnekleri) aşağıdaki özelliklere sahiptir:

  • Listedeki komşu öğelere göre pozisyonunu tanımlama.
  • Nesne türü tanımlama.
  • Nesne verilerini kaydetme ve yükleme yöntemi.
  • Belirtilen nesnelerle karşılaştırma yöntemi.

Yukarıda açıklanan yöntemlerin çoğu sanal'dır ve temel sınıfta uygulanmaz. Temel sınıfın fiziksel anlamı olan herhangi bir gerçek özelliği yoktur. OOP'de olağan olduğu gibi, işlevsellik alt öğe sınıflarında uygulanmalıdır.


CChartObject: Grafik Nesneler için Temel Sınıf

CChartObject, CObject sınıfının alt öğesidir.

Adında, bunun bazı soyut grafik nesnelerini tanımlamak için bir sınıf olduğu görülebilir. Bununla birlikte, bu soyut nesne zaten bazı fiziksel özellikleri ve bu özelliklerle çalışma yöntemlerini içerir. Bu özellikler MetaTrader 5'teki tüm grafik nesneleri için ortaktır; bu nedenle onları bu sınıfa yerleştirmek mantıklıdır.

Bunları daha ayrıntılı olarak ele alalım. Grafik nesnesini grafik penceresine eklemek için aşağıdaki verileri kullanacağız:

protected:
  long       m_chart_id;    // identifier of the chart, which contains 
                               // specified graphic object (0 - current chart)
  int        m_window;      // number of chart sub-window (0 - main window)
  string     m_name;        // unique name of the object on the chart
  int        m_num_points;  // number of points for anchoring the object

Gerçek grafik nesnesinin özelliklerini belirtmeden veya okumadan önce, nesneye (sınıf örneği) eklenmelidir. Bu, CChartObject::Attach yöntemiyle yapılır. Alt öğe sınıflarında, grafik nesnesi grafik üzerinde oluşturulduktan hemen sonra çağrılır.

bool CChartObject::Attach(long chart_id,string name,int window,int points)
{
  if(ObjectFind(chart_id,name)<0)
  {
    return(false);
  }

  if(chart_id==0) chart_id=ChartID();

  m_chart_id  =chart_id;
  m_window    =window;
  m_name      =name;
  m_num_points=points;

  return(true);
}

İlk önce gerçek bir grafik nesnesinin varlığını doğrularız. Varsa, özellikleri CChartObject sınıf nesnesinin dahili alanlarına saklanır. Bundan sonra, grafik nesnesinin özelliklerini (renk, konum vb.) okuyabilir ve değiştirebiliriz.

Grafik nesnesi özelliklerini kaydetme/okuma yöntemleri CChartObject::Save ve CChartObject::Load yöntemlerinde halihazırda uygulanmaktadır. Ana kaydetme/okuma yöntemi, alt öğe sınıfında kendi yönteminden önce çağrılmalıdır.

CChartObject sınıfı (ve örnekleri), temel olanlarla karşılaştırıldığında aşağıdaki yeni özellikleri içerir:

  • Gerçek grafik nesnesini sınıf örneğiyle grafiğe ekleme.
  • Tüm grafik nesnelerinin ortak özelliklerini okuma ve değiştirme.
  • Grafik nesnesini grafikten silme.
  • Grafik nesnesinin grafik üzerindeki hareketi.


CChartObjectText: Metin-Grafik nesneleri için Sınıf

Şimdi ChartObjectsTxtControls.mqh dosyasına dönelim. Burada, metin içeren çeşitli grafik nesnelerinin grafik üzerine çıktısı için geliştirilmiş sınıfların tanımını bulacağız. Bunların temel özelliklerini ele alalım.

Bunlar için temel sınıf CChartObjectText sınıfıdır. Grafikteki metin çıktısıyla ilişkili özellikleri ve yöntemleri içerir.

Sınıf açıklaması şu şekildedir:

class CChartObjectText : public CChartObject
{
public:
   double            Angle() const;
   bool              Angle(double angle);
   string            Font() const;
   bool              Font(string font);
   int               FontSize() const;
   bool              FontSize(int size);
   ENUM_ANCHOR_POINT  Anchor() const;
   bool              Anchor(ENUM_ANCHOR_POINT anchor);

   bool              Create(long chart_id,string name,int window,datetime time,double price);

   virtual int       Type() const { return(OBJ_TEXT); }

   virtual bool      Save(int file_handle);
   virtual bool      Load(int file_handle);
};

CChartObject ile karşılaştırıldığında, metinsel grafik nesnelerinin özelliklerini okumak ve değiştirmek için yöntemler içerir - Grafikteki metin yönlendirme açısı, metnin yazı tipi adı, yazı tipi boyutu ve grafik nesnesinin koordinatları. Yeni bir yöntem ortaya çıktı CChartObjectText:: Create grafikte OBJ_TEXT türünde gerçek bir grafik nesnesi oluşturmamıza olanak tanır.

Uygulanması:

bool CChartObjectText::Create(long chart_id,string name,int window,datetime time,double price)
{
  bool result = ObjectCreate( chart_id, name, OBJ_TEXT, window, time, price );
  if(result)
  {
    result &= Attach(chart_id, name, window, 1 );
  }

  return(result);
}

Grafik nesnesinin başarılı bir şekilde oluşturulması durumunda (ObjectCreate yöntemi true değerini döndürdü), CChartObject:: Daha önce ele aldığımız Attach yöntemi çağrılır.

Bu nedenle, üst sınıfla karşılaştırıldığında CChartObjectText yeni özellikler içerir:

  • Metinsel grafik nesnelerinin özelliklerini okuma ve değiştirme.
  • Grafikte OBJ_TEXT türünde gerçek bir grafik nesnesi oluşturma.


CChartObjectLabel: "Metin Etiketi" Grafik nesneleri için Sınıf

Standart sınıflar hiyerarşisindeki bir sonraki sınıf, CChartObjectLabel sınıfıdır. Grafik üzerinde OBJ_LABEL türü (Metin etiketi) grafik nesneleri oluşturmanıza olanak tanır.

Bu sınıfın açıklaması şu şekildedir:

class CChartObjectLabel : public CChartObjectText
{
public:
   int               X_Distance() const;
   bool              X_Distance(int X);
   int               Y_Distance() const;
   bool              Y_Distance(int Y);
   int               X_Size() const;
   int               Y_Size() const;
   ENUM_BASE_CORNER  Corner() const;
   bool              Corner(ENUM_BASE_CORNER corner);

   bool              Time(datetime time) { return(false);  }
   bool              Price(double price) { return(false);  }

   bool              Create(long chart_id,string name,int window,int X,int Y);

   virtual int       Type() const        { return(OBJ_LABEL); }

   virtual bool      Save(int file_handle);
   virtual bool      Load(int file_handle);
};

Burada OBJ_TEXT türündeki grafik nesnesi ile OBJ_LABEL türündeki nesne arasındaki farka dikkat etmeliyiz.

Birincisi fiyat grafiğine (fiyat-zaman koordinatları) veya alt penceredeki grafiğe bağlanır. İkincisi, grafiğin penceresinin veya alt penceresinin (piksellerinin) grafik koordinatlarına bağlanır.

Bu nedenle, OBJ_TEXT türündeki nesneler kaydırma sırasında grafikle birlikte taşınırken, OBJ_LABEL türündeki nesneler kaydırma sırasında sabit kalır. Dolayısıyla, görevlere bağlı olarak, belirli bir grafik metin nesnesi türü seçmeliyiz.

Üst sınıfla karşılaştırıldığında, CChartObjectLabel sınıfı aşağıdaki ayırt edici özellikleri içerir:

  • Grafik nesnesi bulunurken grafik koordinatları kullanılır.
  • Yer işareti köşesinin okunmasına ve değiştirilmesine olanak tanır. Aslında bu, grafiğin penceresinin dört köşesinden birinde koordinatların başlangıcını belirliyor.
  • İstemci terminalinin grafiğinde OBJ_LABEL türünde gerçek bir grafik nesnesi oluşturma.


CChartObjectEdit: "Giriş Alanı" Grafik Nesneleri için Sınıf

Hiyerarşideki bir sonraki sınıf, CChartObjectEdit sınıfıdır. Bu, OBJ_EDIT türünde (Giriş alanı) bir grafik nesnesi oluşturmaya yönelik bir sınıftır.

Bu türdeki nesne, grafik koordinatlarını (pikselleri) kullanarak OBJ_LABEL türündeki nesneyle aynı şekilde bağlanır; onu standart sınıflarla aynı şekilde CChartObjectLabel sınıfından türetmek mantıklıdır:

class CChartObjectEdit : public CChartObjectLabel
{
public:
   bool              X_Size(int X);
   bool              Y_Size(int Y);
   color             BackColor() const;
   bool              BackColor(color new_color);
   bool              ReadOnly() const;
   bool              ReadOnly(bool flag);

   bool              Angle(double angle) { return(false);    }

   bool              Create(long chart_id,string name,int window,int X,int Y,int sizeX,int sizeY);

   virtual int       Type() const        { return(OBJ_EDIT); }

   virtual bool      Save(int file_handle);
   virtual bool      Load(int file_handle);
};

Metin etiketinden OBJ_EDIT türünün giriş alanları arasındaki fark şudur:

  • Giriş alanı, grafikteki grafik nesnesinin boyutunu sınırlayan genişlik ve yükseklik özelliklerine (ekran piksellerinde belirtilir) sahiptir. Metin etiketinin boyutu, metnin tamamı görülebilecek şekilde otomatik olarak ayarlanır.
  • Metin değişikliğini etkinleştirmek/devre dışı bırakmak için yöntemler vardır - CChartObjectEdit:: ReadOnly.
  • Grafik nesnesi tarafından işgal edilen alanın arka plan rengini değiştirmek için bir yöntem eklenir.
  • Nesnenin görüntülendiği açıyı değiştirme imkanı yoktur. Giriş alanı yalnızca yatay yönde görüntülenebilir.
  • Grafikte OBJ_EDIT türünde gerçek bir grafik nesnesi oluşturulmasına olanak tanır.


CChartObjectButton: "Düğme" Grafik nesnesi için Sınıf

Metinsel grafik nesneleri hiyerarşisindeki diğer bir sınıf, CChartObjectButton sınıfıdır. Bu nesne düğme olarak adlandırılır; bu, basılı bir düğme şeklinde grafik üzerinde bir kontrol öğesi oluşturmak için geliştirilmiştir. Bu sınıf, CChartObjectEdit sınıfının alt öğesidir ve işlevselliğini devralır:

class CChartObjectButton : public CChartObjectEdit
{
public:
  bool             State() const;
  bool             State(bool state);

  virtual int       Type() const { return(OBJ_BUTTON); }

  virtual bool      Save(int file_handle);
  virtual bool      Load(int file_handle);
};

OBJ_BUTTON türü düğmesinin giriş alanından farkı şudur:

  • Bu, Pencere iletişim kutularında kullanılanlara benzer şekilde basılı bir düğmeye benzer.
  • Düğme durumunu okumak/değiştirmek için yeni yöntemler içerir (basılı/basılı olmayan) - CChartObjectButton::State.
  • Grafikte OBJ_BUTTON türünde gerçek bir grafik nesnesi oluşturulmasına olanak tanır.


Grafik metin nesneleri için Standart Sınıfların genel yapısı

Standart Kitaplık sınıflarının yapısı (hiyerarşisi) şu şekilde özetlenebilir:

Standart sınıfların genel yapısı

Şekil 1. Standart sınıfların genel yapısı

CObject sınıfı, diğer standart sınıflar için bir temel sınıftır; örneğin, listeyi ve diğerlerini çalıştıran CList sınıfı.


Standart Kitaplık Sınıflarının İşlevselliğini Genişletme

Grafikte metinsel grafik nesneleri oluşturmak için geliştirilen standart sınıfların hiyerarşisini kısaca ele aldık. Şimdi bu hiyerarşiyi yeni sınıflarla genişletelim. Her şeyden önce, uygulama için gerekli olan işlevselliğe karar vermeliyiz. Gereklilikleri formüle edelim. Metinsel bilgilerin çıktısı ile ilgilendiğimiz için, bu bilgiyi aşağıdaki yapılandırılmış biçimde sağlamak mantıklıdır:

BAŞLIK BİLGİ METNİ


Metinsel bilgilerin temsilinin bu yapısı, basit durumların çoğu için uygundur.

Örneğin, sembol parametrelerinin göstergesi şu şekilde görünebilir:

Metinsel bilgilerin yapılandırılmış gösterimine ilişkin örnek

Şekil 2. Metinsel bilgilerin yapılandırılmış gösterimine ilişkin örnek

Yukarıda önerilen yapının altı bilgi alanını kullanır. Yapının bazı öğeleri eksik olabilir. Örneğin, Şekil 2'de üst alandaki kutucuk gösterilmemiştir. Diğer alanlar başlık ve metin içerir. Bu gösterge, bu makaleye eklenen PricelInfo.mq5 dosyasında bulunabilir.


Grafik nesnelerini konumlandırma

Dikkate almamız gereken ikinci nokta, grafik metin nesnelerini grafik üzerinde konumlandırma şeklidir. Ekran piksellerinde koordinatları belirtmek için benimsenen yöntem, nesnenin grafiğin rastgele seçilmiş bir konumunda konumlandırılmasına olanak tanır.

Ekranın tüm koordinatlarını hesaplamak gerektiği için birkaç metinsel nesneyi grafiğin farklı yerlerine yerleştirmeniz gerektiğinde pratikte elverişsizdir. Ayrıca, grafik boyutunu değiştirirseniz nesnelerin ekrandaki göreli pozisyonlarının değişmediğinden emin olmak için tüm piksel koordinatlarının yeniden hesaplanması gerekir.

Grafik penceresini aynı boyutta dikdörtgenler (alanlar) halinde izlersek ve bu dikdörtgenlerin her birine yatay ve dikey bir koordinat atarsak, ekran çözünürlüğünden bağımsız evrensel bir konumlandırma sistemi elde ederiz.

Grafik metin nesnesini oluştururken, kullanıcı dikey ve yatay yönlerde maksimum alan sayısını ve parametre gibi alanlarda nesnenin koordinatlarını ayarlayabilir. Uygun sınıfa gömülü olan işlevsellik, ekran çözünürlüğünü değiştirdiğinizde grafik nesnelerinin koordinatlarını otomatik olarak ayarlayacaktır. Bu şekilde, koordinatlar bir kez belirlenir ve başka bir ayar gerektirmez.


Benzersiz Nesne Adlarını Otomatik Olarak Oluşturma

Ele alınması gereken bir sonraki soru, grafik metin nesnesinin adının otomatik olarak oluşturulmasıdır. Oluşturma yöntemi için temel gereklilik, verilen pencerede benzersiz bir adın elde edilmesidir. Bu, yinelenmeyen adlar bulma ihtiyacı konusunda endişe etmeden ekranda yeterli sayıda nesnenin bulunmasına olanak tanıyacaktır.

Bir ad (alanlardan oluşan bir dize) oluşturmak için aşağıdaki yöntemi öneriyoruz:

Tarih Saat
Milisaniye sayısı


Dizenin tarih ve saati içeren kısmını almak için aşağıdaki çağrıyı kullanın:

TimeToString(TimeGMT(), TIME_DATE|TIME_MINUTES|TIME_SECONDS);

Milisaniye sayısını elde etmek için aşağıdaki çağrıyı kullanın:

DoubleToString(GetTickCount(), 0);

Ancak zamanı milisaniye cinsinden ölçsek dahi, GetTickCount () işlevini iki veya daha fazla kez arka arkaya çağırdığımızda aynı değeri elde etmemiz oldukça olasıdır. Bunun nedeni, işletim sistemi ve işlemcinin dahili zamanlayıcılarının ayrıklığının kısıtlanmasıdır. Bu nedenle, böyle bir durumu tespit etmek için ek önlemler almak gerekir.

Önerilen yöntem aşağıdaki işlevlerde uygulanmaktadır:

string GetUniqName()
{
  static uint prev_count = 0;

  uint count = GetTickCount();
  while(1)
  {
    if(prev_count == UINT_MAX)
    {
      prev_count = 0;
    }
    if(count <= prev_count)
    {
      prev_count++;
      count = prev_count;
    }
    else
    {
      prev_count = count;
    }

//  Verify that there is no object already existing with such a name:
    string name = TimeToString(TimeGMT(), TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" "+DoubleToString(count, 0);
    if(ObjectFind(0, name) < 0)
    {
      return(name);
    }
  }

  return(NULL);
}

Bu yöntemin sınırlaması: Saniyede en fazla 4294967295 (UINT_MAX) benzersiz ad oluşturulması. Görünüşe göre, bu pratikte yeterli olmalı. Her ihtimale karşı, aynı ada sahip bir grafik nesnesinin varlığına ilişkin ek bir doğrulama vardır.


Bilgi yapısının başlığının gösterimi - TTitleDisplay sınıfı

Başlığın terminal ekranında görüntülendiği sınıf aşağıda gösterilmiştir:

class TTitleDisplay : public CChartObjectLabel
{
protected:
  long    chart_id;
  int     sub_window;
  long    chart_width;       // width of the chart in pixels
  long    chart_height;      // height of the chart graph in pixels
  long    chart_width_step;  // step of the coordinates grid in the horizontal direction
  long    chart_height_step; // step of the coordinates grid in the vertical direction
  int     columns_number;    // number of columns
  int     lines_number;      // number of lines
  int     curr_column;
  int     curr_row;

protected:
  void    SetParams(long chart_id, int window, int cols, int lines);// specify the object's parameters

protected:
  string  GetUniqName();    // get a unique name
  bool    Create(long chart_id, int window, int cols, int lines, int col, int row);
  void    RecalcAndRedraw();// recount the coordinates and re-draw

        
public:
  void    TTitleDisplay();  // constructor
  void    ~TTitleDisplay(); // destructor
};

Bir grafik metin nesnesi oluşturan temel yöntem:

bool Create(long chart_id, int window, int _cols, int _lines, int _col, int _row);

Giriş parametrelerinin atanması aşağıdaki gibidir:

  • chart_id - Pencere tanımlayıcısı (0 - ana pencere),
  • pencere - Alt pencerenin numarası (0 - ana),
  • sütunlar - Yatay olarak maksimum grafik metin nesnesi sayısı (sütun sayısı),
  • çizgiler - Dikey olarak maksimum grafik metin nesnesi sayısı (satır sayısı),
  • sütun - Grafik nesnesinin yatay koordinatı (sıfır ila sütun - 1 arasında değişir),
  • satır - Grafik nesnesinin dikey koordinatı (sıfır ila çizgi - 1 arasında değişir),

TTitleDisplay yöntemi:: SetParams, ekrandaki konumlandırma ile ilişkili nesnenin parametrelerini hesaplar.

Uygulama aşağıdaki gibidir:

void TTitleDisplay::SetParams(long _chart_id, int _window, int _cols, int _lines)
{
  this.chart_id = _chart_id;
  this.sub_window = _window;
  this.columns_number = _cols;
  this.lines_number = _lines;

//  Specify the size of the window in pixels:
  this.chart_width = GetSystemMetrics(SM_CXFULLSCREEN);
  this.chart_height = GetSystemMetrics(SM_CYFULLSCREEN);

//  Calculate the step of the coordinates grid:
  this.chart_width_step = this.chart_width/_cols;
  this.chart_height_step = this.chart_height/_lines;
}

Burada, mevcut görüntü ayarlarını elde etmek için GetSystemMetrics WinAPI işlev çağrısını kullandık. Bu işlev, user32.dll Windows sistem kitaplığından içe aktarılır.

TFieldDisplay bilgilendirici metnini oluşturmak için bir sınıf benzer şekilde oluşturulmuştur. Ayrıntılar, bu makalenin ekindeki TextDisplay.mqh kitaplığında bulunabilir.


CList Sınıfı: Listedeki Nesneleri İşleme

Şimdi planımızın gerçekleşmesi için ihtiyaç duyacağımız başka bir standart sınıfı ele alalım. Bu sınıf, nesneleri listeler halinde gruplandırmamıza olanak tanır. Include\Arrays\List.mqh dosyasında yer alır.  Bu dosya, bu makalenin başlarında ele alınan CObject temel sınıfının alt öğesi olan standart bir CList sınıfının açıklamasını ve uygulamasını sağlar. Listedeki nesneleri işlemek için bir dizi yöntem içerir (listeye ekleme, listeden kaldırma, listenin rastgele seçilmiş bir öğesine erişme ve listeyi temizleme).

Temel yöntemleri ele alalım:

  • Listeye ekleme:
   int Add(CObject *new_node);
   int Insert(CObject *new_node,int index);

Bunlar, listeye yeni bir öğe eklemek için iki yöntemdir. İlki, CList::Add listenin sonuna yeni bir new_node öğesi eklemenize olanak tanır. İkincisi, CList::Insert, listede rastgele seçilmiş bir yere (indeks ile belirtilir) yeni bir new_node öğesi eklemenizi sağlar.

  • Listeden kaldırma:
   bool  Delete(int index);

CList::Delete yöntemi, belirtilen bir indeks içeren bir öğeyi listeden kaldırmanıza olanak tanır. Bu arada, öğeyi listeden kaldırmanın yanı sıra, CObject türündeki öğe tarafından işgal edilen CObject türündeki öğe tarafından işgal edilen bellek serbest bırakılır. Yani, nesne "fiziksel olarak" silinecektir.

  • Listenin rastgele seçilmiş öğesine erişme:
   int       IndexOf(CObject* node);
   CObject*  GetNodeAtIndex(int index);
   CObject*  GetFirstNode();
   CObject*  GetPrevNode();
   CObject*  GetNextNode();
   CObject*  GetLastNode();

CList:: IndexOf yöntemi, listedeki belirli bir öğenin indeksini döndürür. İndekslerin numaralandırılması sıfırdan başlar: İlk öğenin indeksi sıfırdır. Bu yöntem, öğenin işaretçisine göre indeksi döndürdüğü ters işlemi gerçekleştirir. Öğe listede yoksa -1 değerini döndürür.

Listede gezinmek için dört yöntem daha vardır CList:: GetFirstNode önceki öğeyi döndürür, CList:: GetNextNode sonrakini döndürür, CList:: GetLastNode listedeki son öğeyi döndürür.

  • Listeyi temizleme:
   void  Clear();

CList::Clear yöntemi, tüm öğeleri listeden kaldırmanıza olanak tanır ve ayrıca nesneler tarafından işgal edilen belleği boşaltır.

Bunlar CList sınıfının temel yöntemleridir, geri kalanı MQL5 Referansı içinde açıklanmıştır.


TableDisplay Sınıfı: Metni Grafikte Görüntülemek için Tablo Oluşturma

Böylelikle, planın gerçekleşmesi için ihtiyacımız olan her şeye sahibiz. Metinsel grafik nesnelerini rastgele seçilmiş boyutta bir tabloda düzenlemenize olanak tanıyan basit bir sınıf şu şekildedir:

class TableDisplay : public CList
{
protected:
  long  chart_id;
  int   sub_window;

public:
  void  SetParams(long _chart_id, int _window, ENUM_BASE_CORNER _corner = CORNER_LEFT_UPPER);
  int   AddTitleObject(int _cols, int _lines, int _col, int _row, 
                      string _title, color _color, string _fontname = "Arial", int _fontsize = 8);
  int   AddFieldObject(int _cols, int _lines, int _col, int _row, 
                          color _color, string _fontname = "Arial", int _fontsize = 8);
  bool  SetColor(int _index, color _color);
  bool  SetFont(int _index, string _fontname, int _fontsize);
  bool  SetText(int _index, string _text);

public:
  void  TableDisplay();
  void  ~TableDisplay();
};

Tabloya grafik nesneleri eklemeden önce parametreleri ayarlamanız gerekir: Karakter tanımlayıcısı, alt pencere indeksi ve yer işareti noktası. Bu, TableDisplay:: SetParams yöntemi çağrılarak yapılır. Bundan sonra tabloya istediğiniz sayıda başlık ve metin alanı ekleyebilirsiniz.

Geliştirdiğimiz kitaplığın tam metni bu makalenin ekindeki TextDisplay.mqh dosyasında bulunabilir.


3. Piyasa İzleme Oluşturma Örneği

Birkaç sembolün değerlerini bir gösterge şeklinde görüntülemek için bir tablo oluşturma örneğini düşünün.

Aşağı yukarı şu şekilde görünmelidir:

Ekran tablosu örneği

Рисунок 3. Ekran tablosu örneği

  • Adım 1 - Kitaplığı ekleyin (göstergenin kaynak kodunda):
#include  <TextDisplay.mqh>
  • Adım 2 - Başlıklar için adlar ve koordinatlarla diziler oluşturun:
#define  NUMBER  8
//---------------------------------------------------------------------
string  names[NUMBER]   = {"EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDCHF", "USDCAD", "USDJPY", "EURJPY"};
int     coord_y[NUMBER] = {2,        3,        4,        5,        6,      7,        8,       9};
Koordinatlar sıfırdan başlayarak sıralanır.
  • Adım 3 - Görüntülenen tüm metin nesnelerini depolamak için TableDisplay türünde bir tablo nesnesi oluşturun:
TableDisplay  Table1;
  • Adım 4 - Tabloya nesne-başlıkları ve nesne-bilgi alanları ekleyin:
int OnInit()
{
//  Creating a table
  Table1.SetParams(0, 0);

  for(int i=0; i<NUMBER; i++)
  {
    Table1.AddFieldObject(40, 40, 3, coord_y[i], Yellow);
  }

  for(int i=0; i<NUMBER; i++)
  {
    Table1.AddTitleObject(40, 40, 1, coord_y[i], names[i]+":", White);
  }

  ChartRedraw(0);
  EventSetTimer(1);

  return(0);
}

İdeal olanı, bunu OnInit olay işleyicisinde yapmaktır. İlk olarak, TableDisplay:: AddFieldObject yöntemini kullanarak bilgi alanlarını ekleyin. Ardından, TableDisplay:: AddTitleObject yöntemini kullanarak başlıkları bunlara ekleyin.

Ekleme işlemi iki nedenden dolayı ayrı döngüler halinde gerçekleştirilir: Birincisi, genel olarak başlık sayısı, bilgi alanlarının sayısıyla uyuşmayabilir ve ikincisi, güncellenmiş bilgi alanlarına erişimi düzenleme işlemi, bir satırda indekslendiklerinde daha kolaydır (bu durumda, sıfırdan değer NUMARASI - 1'e kadar).

  • Adım 5 - Dinamik bilgileri güncellemek için kodu ekleyin:

Bu durumda, dinamik bilgilerin güncellenmesi Zamanlayıcı olay işleyicisi tarafından düzenlenir. Bu olay için OnTimer işleyicisi, verilen enstrümanlar için fiyat değerlerini almalı ve bu değerleri grafikte göstermelidir.

Bunun metni aşağıda gösterilmiştir:

//---------------------------------------------------------------------
double    rates[NUMBER];
datetime  times[NUMBER];
MqlTick   tick;
//---------------------------------------------------------------------
// OnTimer event handler
//---------------------------------------------------------------------
void OnTimer()
{
  for(int i=0; i<NUMBER; i++)
  {
//  Obtain the price values:
    ResetLastError();
    if(SymbolInfoTick(names[i], tick) != true)
    {
      Table1.SetText(i,"Err "+DoubleToString(GetLastError(),0));
      Table1.SetColor(i,Yellow);
      continue;
    }

    if(tick.time>times[i])
    {
       Table1.SetText(i, DoubleToString(tick.bid, (int)(SymbolInfoInteger(names[i], SYMBOL_DIGITS))));

       if(tick.bid>rates[i])
       {
         Table1.SetColor(i, Lime);
       }
       else if(tick.bid<rates[i])
       {
         Table1.SetColor(i, Red);
       }
       else
       {
         Table1.SetColor(i, Yellow);
       }
       rates[i] = tick.bid;
       times[i] = tick.time;
    }
  }

  ChartRedraw(0);
}

Döngünün başlangıcında, belirtilen enstrüman için tick verileri okunur, ardından verilerin alakası doğrulanır; tick süresi öncekinden değiştiyse verilerin alakasız olduğunu kabul ederiz. Ayrıca, fiyat teklifi değerini önceki tick'e göre analiz ederiz.

Mevcut fiyat bir öncekinden daha büyükse bilgi alanı için yeşil bir renk belirtiriz. Küçükse kırmızı renk, eşitlerse sarı renkle belirtiriz. Döngünün sonunda, fiyatın mevcut değeri ve tick süresi, OnTimer olay işleyicisinin çağrısında analiz için saklanır.

Genel olarak, dinamik bilgiyi güncelleme kodu göreve bağlıdır. Temel olarak, kullanıcının yalnızca kodun bu kısmını uygulaması gerekir. Şekil 2'deki fiyatın sağ tarafına bir spread eklemeye karar verdiğimizi varsayalım. Bunun nasıl yapılabileceğine bakalım.

Yapılması gereken şey ek veri alanlarını tabloya eklemektir:

  for(int i=0; i<NUMBER; i++)
  {
    Table1.AddFieldObject(40, 40, 5, coord_y[i], Yellow);
  }

ve spread değerini güncelleyen kodu, OnTimer olay işleyicisine dahil etmektir:

  Table1.SetText(i+NUMBER, DoubleToString((tick.ask-tick.bid)/SymbolInfoDouble(names[i], SYMBOL_POINT), 0));

Sonuç olarak, aşağıdaki resmi elde ederiz:

Spread içeren fiyatlar

Şekil 4. Spread içeren fiyatlar

Spread için indeks alanlarının (i sıfıra eşitse) SAYI değerinden başladığına dikkat edin.

  • Adım 6 - Oluşturulan nesneleri kaldırın:
void OnDeinit(const int _reason)
{
  EventKillTimer();

//  Removing the elements of display:
  Table1.Clear();
}

Burada zamanlayıcı ve tablo temizlenir. Bu arada, tüm nesneler de bellekten serbest bırakılır.

Bu göstergenin tam metni, bu makaleye eklenen PriceList.mq5 dosyasında bulunabilir. Ek, spread'i gösteren göstergenin "geliştirilmiş" bir sürümünü içerir. Bu, bir tablonun başlığının renginin ve grafik içindeki pozisyonunun belirtilmesi için bir dizi harici parametreye sahiptir.


Sonuç

Ekte, MarketWatch.mq5 (ve dahil edilen MarketWatch.mqh), alım satım enstrümanlarının temel parametrelerini bir özet tablo şeklinde görüntülemek için bir gösterge yer alır. Her sembol için Şekil 2'ye benzer bilgiler gösterilir.

Ayrıca, belirtilen zaman aralıkları için fiyat değişim yüzdesini gösterir. Semboller (en fazla 16) ve zaman aralıkları, noktalı virgülle ayrılmış öğeler içeren bir dize olarak belirtilir.  Bu göstergeye ilişkin çalışma sonuçları Şekil 5'te gösterilmiştir:

Piyasa incelemesinin göstergesi

Şekil 5. Piyasa İzleme Göstergesi

MetaTrader 5 istemci terminali grafiğinde metin bilgilerini görüntülemenin bir yolunu düşündük.

İstemci terminali ile sağlanan Standart Kitaplık sınıflarını kullanarak, metinsel bilgileri iki boyutlu bir tablo biçiminde göstermek için yeni işlevselliği oldukça kolay ve hızlı bir şekilde geliştirebildik. MQL5 Dilinin nesne yönelimli yaklaşımı çok güçlüdür.


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

Ekli dosyalar |
marketwatch.mq5 (11.51 KB)
priceinfo.mq5 (8.76 KB)
pricelist.mq5 (7.29 KB)
textdisplay.mqh (15.54 KB)
marketwatch.mqh (9.48 KB)
Ek Arabellekler Kullanmadan Ara Hesaplamalar için Fiyat Serilerinin Ortalamasını Alma Ek Arabellekler Kullanmadan Ara Hesaplamalar için Fiyat Serilerinin Ortalamasını Alma
Bu makale, en basit ve tek tür sınıflarda paketlenmiş geleneksel ve sıra dışı ortalama alma algoritmaları hakkındadır. Bunlar, göstergelerin neredeyse tüm gelişmelerinde evrensel kullanım için tasarlanmıştır. Umarım önerilen sınıflar, özel ve teknik göstergelerin 'hantal' çağrılarına iyi bir alternatif olur.
Bulanık Mantık Kullanarak Gösterge Oluşturmanın Basit Örneği Bulanık Mantık Kullanarak Gösterge Oluşturmanın Basit Örneği
Makale, finansal piyasalar analizi için bulanık mantık kavramının pratik uygulamasına ayrılmıştır. Zarflar göstergesine dayalı iki bulanık kural temeline dayanan sinyal üreten gösterge örneğini öneriyoruz. Geliştirilen gösterge birkaç gösterge arabelleği kullanır: Hesaplamalar için 7 arabellek, grafikler için 5 arabellek ve 2 renk arabelleği.
Spektrum Analizörü Oluşturma Spektrum Analizörü Oluşturma
Bu makale, okuyucularını MQL5 dilinin grafik nesnelerini kullanmanın olası bir varyantı hakkında bilgilendirmeyi amaçlamaktadır. Ayrıca, grafik nesneleri kullanarak basit bir spektrum analizörü yönetme panelini uygulayan bir gösterge analiz edilmektedir. Makale, MQL5'in temelleri hakkında bilgi sahibi olan okuyuculara yöneliktir.
MQL5 Sihirbazı: Programlamadan Expert Advisor'lar Oluşturma MQL5 Sihirbazı: Programlamadan Expert Advisor'lar Oluşturma
Programlama için zaman kaybetmeden bir alım satım stratejisi denemek ister misiniz? MQL5 Sihirbazı'nda alım satım sinyallerinin türünü seçebilir, takip eden pozisyonlar ve para yönetimi modülleri ekleyebilirsiniz; böylelikle işiniz biter! Kendi modül uygulamalarınızı oluşturun veya İşler hizmeti aracılığıyla talimat verin ve yeni modüllerinizi mevcut olanlarla birleştirin.