Standart Kitaplık Sınıflarını kullanarak kendi Piyasa İzlemenizi oluşturun
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:
Ş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:
Ş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:
Рисунок 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:
Ş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:
Ş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
- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz