English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Spektrum Analizörü Oluşturma

Spektrum Analizörü Oluşturma

MetaTrader 5Örnekler | 15 Aralık 2021, 11:10
222 0
Victor
Victor

Giriş

Bu makale, okuyucularını MQL5 dilinin grafik nesnelerini kullanmanın olası bir varyantı hakkında bilgilendirmeyi amaçlamaktadır. Grafik nesneleri kullanarak basit bir spektrum analizörünün kontrol panelini uygulayan bir göstergeyi analiz eder.

Makaleye üç dosya eklenmiştir:

  1. SpecAnalyzer.mq5 – Bu makalede açıklanan gösterge.
  2. SpecAnalyzer.mqh – SpecAnalyzer.mq5 için içerme dosyası.
  3. SAInpData.mq5 – Harici verilere erişimin düzenlenmesi için kullanılan gösterge.

SpecAnalyzer göstergesini normal olarak yüklemek için üç dosyayı da istemci terminalinin \MQL5\Indicators klasörüne yerleştirmelisiniz. Daha sonra SpecAnalyzer.mq5 ve SAInpData.mq5 dosyalarını derlemelisiniz. Göstergenin ana grafik penceresine yüklenmesi amaçlanmıştır. Gösterge yüklendiğinde, bu pencerenin görüntüleme parametrelerini değiştirir ve kaldırıldığında tüm grafik nesneleri pencereden silinir. Bu nedenle, terminalin mevcut pencerelerinin görüntüleme modunun yanlışlıkla değiştirilmesini önlemek için göstergeyi onun için oluşturulan özel bir ayrı pencereye yüklemelisiniz.

Makalenin göstergenin tam kaynak kodunu içermediği gerçeği göz önüne alındığında, makale okunurken ekli dosyalardaki kodun açık olması önerilir.

Makalede anlatılan gösterge, hazır bir uygulama gibi görünmemektedir. Bu yalnızca dilin grafik nesnelerinin kullanımına ilişkin bir örnektir. İlgilenen kişiler, makalede gösterilen kodu kendi başlarına yükseltebilir ve optimize edebilir.

Koordinatlar

Grafik nesneleri çizerken koordinatları belirlemek için MQL5'te iki yol kullanılabilir. Bazı nesneler için koordinatlar, pencerenin belirli bir noktasından piksel sayısı olarak belirtilir ve diğerleri için koordinatlar, pencerede görüntülenen grafiğin fiyat ve zaman değerleri olarak belirtilir.

Örneğin, “Etiket” veya “Düğme” gibi bir nesneyi bir grafiğe yerleştirmek için koordinatlarını, grafik penceresinin köşelerinden birinden piksel cinsinden uzaklık olarak belirtmelisiniz. Bu yolla adreslenen nesneler, mevcut pencerenin özelliklerinden ve içinde görüntülenen grafiğin ölçeğinden bağımsız olarak pozisyonlarını korurlar. Pencere boyutu değişse dahi, bu tür nesneler pozisyonlarını ve birbirlerine bağlanmalarını korurlar. Grafiği pencerede sol fare düğmesini kullanarak hareket ettirirseniz bu nesneler pencerenin seçilen yer işareti noktasına göre pozisyonlarını korurlar.

Diğer nesne grubu, pencere koordinatları yerine penceredeki bir grafiğe bağlanmayı gerektirir. Bu nesneler “Trend Çizgisi”, “Dikdörtgen” vb.'dir. Bu tür nesneleri oluştururken ve yerleştirirken, koordinatlar, pencerede görüntülenen bir grafiğin zaman ve fiyat değeri olarak belirtilir. Bu koordinat belirleme moduyla, nesneler grafik ölçeği değiştirildiğinde veya kaydırıldığında grafik penceresine ve birbirlerine göre pozisyonlarını değiştirirler. Grafikte yeni bir çubuk göründüğünde, nesneler de pozisyonlarını değiştirir; zira zaman ekseni zaman dilimi boyutunda sola hareket eder.

SpecAnalyzer göstergesinde, spektrum analizörünün kontrol panelini oluşturmak için her iki grafik nesne türü aynı anda kullanılır. Grafiğe bağlı nesnelerin pencereye göre hareket etmemesi için, grafiğin dikey eksen boyunca sabit görüntülenme modunu ve grafiğin yatay ölçeği boyunca olası minimum görüntüleme ölçeğine karşılık gelen modu belirledik. Buna ek olarak, dikey ölçeğin minimum değerini 0,0 olarak belirledik ve yatay eksen için modu, sıfır çubuğunu sağ kenardan kaydırmadan ve grafiğin sağ kenarına otomatik kaydırma yapmadan ayarladık. Bu nedenle, grafiğin sıfır çubuğu ve 0,0 değeri ile eşleşen koordinat noktası sağ alt köşede görünür ve sabit ölçek ile “Trend Çizgisi” ve “Dikdörtgen” gibi nesneler için bir yer işareti noktası kullanılabilir. Bu durumda, “Etiket” veya “Düğme” gibi nesnelerin yer işareti noktası olarak aynı sağ alt köşeyi ayarlarsak o zaman her iki nesne türü kesinlikle birbirine bağlı olacaktır.

Tüm gerekli grafik özellikleri, SpecAnalyzer.mqh dosyasındaki SetOwnProperty() işlevinde ayarlanır.

void GRaphChart::SetOwnProperty(void)
  {
  ChartSetInteger(m_chart_id,CHART_FOREGROUND,1);
  ChartSetInteger(m_chart_id,CHART_SHIFT,0);
  ChartSetInteger(m_chart_id,CHART_AUTOSCROLL,0);
  ChartSetInteger(m_chart_id,CHART_AUTOSCROLL,1);
  ChartSetInteger(m_chart_id,CHART_SCALE,0);
  ChartSetInteger(m_chart_id,CHART_SCALEFIX_11,1);
  ChartSetInteger(m_chart_id,CHART_SHOW_OHLC,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_BID_LINE,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_ASK_LINE,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_LAST_LINE,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_PERIOD_SEP,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_GRID,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_VOLUMES,CHART_VOLUME_HIDE);
  ChartSetInteger(m_chart_id,CHART_SHOW_OBJECT_DESCR,0);
  ChartSetInteger(m_chart_id,CHART_SHOW_TRADE_LEVELS,0);
  ChartSetInteger(m_chart_id,CHART_COLOR_BACKGROUND,Black);
  ChartSetInteger(m_chart_id,CHART_COLOR_FOREGROUND,Black);
  ChartSetDouble(m_chart_id,CHART_FIXED_MIN,0.0);
  }

Grafik nesnelerinin bağlanmasını sağlamak için grafiğin gerekli özelliklerini ayarlamaya ek olarak, bu işlev, bir renk atamaya ve grafiğin bazı öğelerinin görüntülenmesini kısıtlamaya olana tanıyan özellikleri ayarlar.

SpecAnalyzer göstergesi çalışırken grafik özelliklerini değiştirdiği için göstergenin yüklenmesi sırasında grafiğin önceki ayarlarının kaydedilmesini ve göstergenin kaldırılması sırasında ayarların geri yüklenmesini sağlamalıyız. MQL5'in standart kitaplığı bu amaç için özel sanal işlevler içerir - CChart sınıfına ait Save() ve Load(). Bu işlevler, CChart sınıfının bir nesnesinin özelliklerini bir dosyaya kaydetmek ve bu özellikleri oluşturulan dosyadan geri yüklemek için tasarlanmıştır. Kaydedilen özellikler kümesini değiştirmek ve bir grafiğin özelliklerini kaydederken dosya işlemlerini kullanmaktan kaçınmak için CChart sınıfının Save() ve Load() sanal işlevleri, yeni GRaphChart sınıfı oluşturulurken geçersiz kılınır (SpecAnalyzer.mqh dosyasına bakınız). 

class GRaphChart : public CChart
  {
  protected:
    struct ChartPropertyes
      {
      double shift_size;
      double fixed_max;
      double fixed_min;
      double points_per_bar;
      long   mode;
      bool   foreground;
      bool   shift;
      bool   autoscroll;
      long   scale;
      bool   scalefix;
      bool   scalefix_11;
      bool   scale_pt_per_bar;
      bool   show_ohls;
      bool   show_bid_line;
      bool   show_ask_line;
      bool   show_last_line;
      bool   show_period_sep;
      bool   show_grid;
      long   show_volumes;
      bool   show_object_descr;
      bool   show_trade_levels;
      long   color_background;
      long   color_foreground;
      long   color_grid;
      long   color_volume;
      long   color_chart_up;
      long   color_chart_down;
      long   color_chart_line;
      long   color_candle_bull;
      long   color_candle_bear;
      long   color_bid;
      long   color_ask;
      long   color_last;
      long   color_stop_level;
      string ch_comment;
      };
      ChartPropertyes ChProp;
  
  public:
                   GRaphChart();
                  ~GRaphChart();
                   
         void      SetOwnProperty();
  virtual void      Save();
  virtual void      Load();
  };

GRaphChart'ın temel sınıfı, MQL5'in standart kitaplığının CChart sınıfıdır. GRaphChart sınıfı, ChartPropertyes yapısının tanımını ve grafik özelliklerini temel sınıfta uygulandığı gibi bir dosya yerine bellekte saklamaya yönelik ChProp nesnesinin oluşturulmasını içerir. Save() işlevi, ChProp yapısını, grafiğin geçerli özelliklerine göre verilerle doldurur ve Load() işlevi, ondan önceden kaydedilmiş özellikleri geri yükler.

GRaphChart sınıfının kurucusunda Save() işlevi ve yıkıcısında Load() işlevi çağrılır. Bu nedenle, GRaphChart sınıfının nesnesi oluşturulurken ve silinirken grafiğin önceki durumunu kaydetme ve geri yükleme işlemleri otomatik olarak gerçekleştirilir. Yukarıda bahsedilen SetOwnProperty(), sınıf oluşturucusunda da çağrılır.

//---------------------------------------------------- Constructor GRaphChart --
GRaphChart::GRaphChart()
  {
  m_chart_id=ChartID();
  Save();                                // Keep a original chart settings
  SetOwnProperty();                             // Set own chart settings
  }
//----------------------------------------------------- Destructor GRaphChart --
GRaphChart::~GRaphChart()
  {
  Load();                             // Restore a previous chart settings
  m_chart_id=-1;
  }

Basit bir örnekle GRaphChart sınıfının kullanımını gösterelim. Bunu yapmak için MetaEditor'da yeni özel gösterge oluşturalım ve Test olarak adlandıralım. Gösterge koduna SpecAnalyzer.mqh üst bilgi dosyasını ekleyin ve iki satır ekleyerek GRaphChart sınıfının bir nesnesini oluşturun.

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#include "SpecAnalyzer.mqh"    // <----- Including header file 

GRaphChart  MainChart; // <----- Creating object of the class GRaphChart

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Yukarıdaki kodun başarılı bir şekilde derlenmesi için SpecAnalyzer.mqh dosyası, istemci terminalinin \MQL5\Indicators klasörüne yerleştirilmelidir.

İstemci terminalinde bir grafik oluşturup test örneğimizi buna yüklemeye çalışırsanız, grafik özellikleri değişecektir; bu durumda yalnızca içindeki grafik nesnelerin görüntülenmesi için hazırlanmış boş bir pencere göreceksiniz. Test göstergemizi grafikten kaldırdığınızda, yeni bir tick'in gelmesiyle ilk görünümü geri yüklenecektir.

SpecAnalyzer göstergesine dönelim. Göstergenin başlangıcında (SpecAnalyzer.mq5 dosyasına bakınız), GRaphChart sınıfına ait MainChart nesnesini oluşturma işlemi gerçekleştirilir; bu da göstergenin yüklenmesine ve grafik özelliklerinin kaydedilmesine yol açar.

                 button. button. button.
GRaphChart MainChart; // Create MainChart object
                 button. button. button.

Göstergeyi kaldırırken, MainChart nesnesi otomatik olarak sonlandırılır; bu durumda grafiğin ilk özellikleri sınıf yıkıcıda geri yüklenir. 

Kontrol Paneli

SpecAnalyzer göstergesindeki kontrol panelinin görünümü, pencereye yerleştirilen grafik nesneler tarafından belirlenir. AllGrObject sınıfı, bunları oluşturmak ve bunlarla etkileşim kurmak için gerekli tüm işlevleri birleştirir; SpecAnalyzer.mqh dosyasına bakınız.

class AllGrObject : public CChart
  {
  protected:
    long      m_chart_id;                                    // chart identifier
    
  public:
              AllGrObject();
             ~AllGrObject();
                   
    void      AddLabel(string name,int fsize,string font,
                             color col,int x,int y,string text="");
    void      AddButton(string name,int xsize,int ysize,color bgcol,
                        int fsize,string font,color col,int x,int y,
                        string text="",int state=0);
    void      AddEdit(string name,int xsize,int ysize,color bgcol,int fsize,
                      string font,color col,int x,int y,string text="");
    void      AddTrendLine(string name,color col,int style=0,int width=1);
    void      AddArrowline(string name,color col,int style=0,int width=1);
    void      AddRectangle(string name,color col,int style=0,int width=1);
    void      MoveGrObject(string name,int x1,int y1,int x2,int y2);
    void      SetButtonProp(string name,bool state,color col);
    long      GetRowNumber(string name);
    void      LabelTxt(string name,string str);
    
  };

Adları Add ile başlayan sınıfın işlevleri, grafik nesneleri oluşturmaya yöneliktir. Örneğin, AddButton(), “Düğme” nesnesini oluşturur.

Uygulamada, tüm grafik nesnelerinin koordinatları, grafiğin sağ alt köşesinden piksel cinsinden uzaklık olarak ayarlanır. “Trend Çizgisi”, “Oklu Çizgi” ve “Dikdörtgen” nesneleri için bu koordinatları zaman ve fiyat değerlerine dönüştürmeliyiz. Bu tür bir dönüştürme, bir nesneye koordinatlar atanmadan önce MoveGrObject() işlevinde gerçekleştirilir. Bir yatay piksel bir çubuğa ve bir dikey piksel bir noktaya karşılık gelir.

void AllGrObject::MoveGrObject(string name,int x1,int y1,int x2,int y2)
  {
  datetime t1[1],t2[1];
  long typ;
  
  typ=ObjectGetInteger(m_chart_id,name,OBJPROP_TYPE);
  if(typ==OBJ_TREND||typ==OBJ_ARROWED_LINE||typ==OBJ_RECTANGLE)
    {
    CopyTime(_Symbol,_Period,x1,1,t1);
    CopyTime(_Symbol,_Period,x2,1,t2);
    ObjectSetInteger(m_chart_id,name,OBJPROP_TIME,0,t1[0]);
    ObjectSetDouble(m_chart_id,name,OBJPROP_PRICE,0,_Point*y1);
    ObjectSetInteger(m_chart_id,name,OBJPROP_TIME,1,t2[0]);
    ObjectSetDouble(m_chart_id,name,OBJPROP_PRICE,1,_Point*y2);
    }
  }

Tüm grafik nesneleri göstergede yalnızca bir kez oluşturulur, bu, göstergenin OnInit() işlevinden gr_object_create() işlevi çağrıldığında yapılır; SpecAnalyzer.mq5 dosyasına bakınız. “Trend Çizgisi”, “Oklu Çizgi” ve “Dikdörtgen” dışındaki tüm nesneler için koordinatlar hemen ayarlanır. “Trend Çizgisi”, “Oklu Çizgi” ve “Dikdörtgen” gibi nesneler için koordinatlar adresleme modunu dönüştüren yukarıda belirtilen MoveGrObject() işlevini kullanan gr_object_coordinate() işlevi çağrılarak ayarlanır. 

void gr_object_coordinate()
  {
  GObj.MoveGrObject("Trdline1",48,150,48,360);
  GObj.MoveGrObject("Trdline2",176,150,176,360);
  GObj.MoveGrObject("Trdline3",304,150,304,360);
  GObj.MoveGrObject("Trdline4",432,150,432,360);
  GObj.MoveGrObject("Trdline5",42,350,560,350);
  GObj.MoveGrObject("Trdline6",42,300,560,300);
  GObj.MoveGrObject("Trdline7",42,250,560,250);
  GObj.MoveGrObject("Trdline8",42,200,560,200);
  GObj.MoveGrObject("Arrline1",560,150,28,150);
  GObj.MoveGrObject("Arrline2",560,150,560,370);
  GObj.MoveGrObject("Rect1",0,1,208,110);
  GObj.MoveGrObject("Rect2",208,1,416,110);
  GObj.MoveGrObject("Rect3",416,1,624,110);
  GObj.MoveGrObject("Rect4",0,1,624,400);
  GObj.MoveGrObject("Rect5",20,10,195,80);
  }

gr_object_coordinate() işlevinin çağrısı, göstergenin OnCalculate() işlevine dahil edilmiştir. Her yeni tick geldiğinde işlev çağrıldığı için, grafikte yeni bir çubuk oluşturulduğunda koordinatların doğru bir şekilde yeniden hesaplanmasını sağlar.

Gösterge panelindeki düğmeler üç gruba ayrılmıştır. İlk grup, solda bulunan dört düğmeden oluşur; bunlar, gösterge tarafından giriş dizisinin spektrumunun tahmin edilmesine ilişkin sonucu görüntüleme modunun seçilmesine olanak tanır. Dört görüntüleme modu desteklenir (düğme sayısına göre):

  1. Genlik/Çizgi - Fourier dönüşüm modülünü Y ekseni boyunca doğrusal bir ölçekte görüntüleme.
  2. Genlik/dB - Fourier dönüşüm modülünü Y ekseni boyunca logaritmik bir ölçekte görüntüleme.
  3. Güç/Çizgi - Fourier dönüşüm modülünün karesini Y ekseni boyunca doğrusal bir ölçekte görüntüleme.
  4. Güç/dB - Fourier dönüşüm modülünün karesini Y ekseni boyunca logaritmik bir ölçekte görüntüleme.

Bu grubun düğmelerine tıklamayı işlemek için göstergenin OnChartEvent() işlevinde aşağıdaki kod bulunur: 

  if(id==CHARTEVENT_OBJECT_CLICK)                       // Click on the gr. object
    {
    if(sparam=="Butt1")                                   // Click on the button
      {
      GObj.SetButtonProp("Butt1",1,Chocolate);
      GObj.SetButtonProp("Butt2",0,SlateGray);
      GObj.SetButtonProp("Butt3",0,SlateGray);
      GObj.SetButtonProp("Butt4",0,SlateGray);
      YPowerFlag=0;YdBFlag=0;
      }
    if(sparam=="Butt2")                                   // Click on the button
      {
      GObj.SetButtonProp("Butt1",0,SlateGray);
      GObj.SetButtonProp("Butt2",1,Chocolate);
      GObj.SetButtonProp("Butt3",0,SlateGray);
      GObj.SetButtonProp("Butt4",0,SlateGray);
      YPowerFlag=0;YdBFlag=1;
      }
    if(sparam=="Butt3")                                   // Click on the button
      {
      GObj.SetButtonProp("Butt1",0,SlateGray);
      GObj.SetButtonProp("Butt2",0,SlateGray);
      GObj.SetButtonProp("Butt3",1,Chocolate);
      GObj.SetButtonProp("Butt4",0,SlateGray);
      YPowerFlag=1;YdBFlag=0;
      }
    if(sparam=="Butt4")                                   // Click on the button
      {
      GObj.SetButtonProp("Butt1",0,SlateGray);
      GObj.SetButtonProp("Butt2",0,SlateGray);
      GObj.SetButtonProp("Butt3",0,SlateGray);
      GObj.SetButtonProp("Butt4",1,Chocolate);
      YPowerFlag=1;YdBFlag=1;
      }

Düğmelerden birine tıklandığı algılandığında, diğer düğmelerin durumu basılmamış olarak değiştirilir; bu da bir grupta birden fazla düğmeye aynı anda basılmasını önler. Aynı zamanda, geçerli görüntüleme modunu belirleyen YPowerFlag ve YdBFlag bayrakları için karşılık gelen değerler ayarlanır.

Dört düğmeden oluşan ikinci grup, bir giriş verisi kaynağı seçme olanağı sağlar. Bu, SAInpData.mq5 göstergesinin çağrılmasıyla elde edilen harici veriler veya uygulamanın kendisi tarafından oluşturulan üç test dizisi olabilir. Son düğme grubu, listeyi metin bilgilerini girme alanında kaydırmak için kullanılan iki düğmeyi içerir. Tüm bu düğmelere tıklama işlemi, göstergenin OnChartEvent() işlevinde de ilk grubun düğmeleriyle aynı şekilde gerçekleştirilir; SpecAnalyzer.mq5 dosyasına bakınız.

Önceden oluşturulmuş test göstergesi Test.mq5'i kullanarak AllGrObject sınıfını kullanmanın bir örneğini gösterelim. Bunu yapmak için, kaynak koduna birkaç satır ekleyin ve SpecAnalyzer.mq5 dosyasından daha önce bahsedilen gr_object_create() ve gr_object_coordinate() işlevlerini ekleyin.

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#include "SpecAnalyzer.mqh" 

GRaphChart  MainChart;

AllGrObject GObj;        // <----- Creating object of the class AllGrObject

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
//---

  gr_object_create();          // <----- creating graphical objects

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
//---

  MainChart.SetOwnProperty();    // <----- restoring current properties of the chart
  gr_object_coordinate();     // <----- setting coordinates for the graphical objects


//--- return value of prev_calculated for next call
   return(rates_total);
  }

//----------------------------------------------- Create all graphical objects --
void gr_object_create()
  {
  GObj.AddLabel("Title",10,"Arial",DarkGray,256,367,"Spectrum Analyzer");
  GObj.AddLabel("Label1",9,"Arial",LightSteelBlue,557,128,"0");
  GObj.AddLabel("Label2",9,"Arial",LightSteelBlue,422,128,"128");
  GObj.AddLabel("Label3",9,"Arial",LightSteelBlue,294,128,"256");
  GObj.AddLabel("Label4",9,"Arial",LightSteelBlue,166,128,"384");
  GObj.AddLabel("Label5",9,"Arial",LightSteelBlue,40,128,"512");
  GObj.AddLabel("Label6",9,"Arial",LightSteelBlue,28,156,"N");
  GObj.AddLabel("Label7",9,"Arial",LightSteelBlue,569,141,"0.00");
  GObj.AddLabel("Label8",9,"Arial",LightSteelBlue,569,191,"0.25");
  GObj.AddLabel("Label9",9,"Arial",LightSteelBlue,569,241,"0.50");
  GObj.AddLabel("Label10",9,"Arial",LightSteelBlue,569,291,"0.75");
  GObj.AddLabel("Label11",9,"Arial",LightSteelBlue,569,341,"1.00");
  GObj.AddLabel("Label12",9,"Arial",LightSteelBlue,569,358,"U");
  GObj.AddLabel("Label13",9,"Arial",DarkGray,490,86,"Y-axis Mode");
  GObj.AddLabel("Label14",9,"Arial",DarkGray,285,86,"Input Data");
  GObj.AddLabel("Label15",9,"Arial",DarkGray,75,86,"Level");
  GObj.AddLabel("Label16",9,"Arial",DarkGray,185,86,"N");
  GObj.AddLabel("Label17",8,"Courier",DarkOliveGreen,64,64);
  GObj.AddLabel("Label18",8,"Courier",DarkOliveGreen,64,51);
  GObj.AddLabel("Label19",8,"Courier",DarkOliveGreen,64,38);
  GObj.AddLabel("Label20",8,"Courier",DarkOliveGreen,64,25);
  GObj.AddLabel("Label21",8,"Courier",DarkOliveGreen,64,12);
  GObj.AddButton("Butt1",185,18,C'32,32,32',8,"Arial",SlateGray,612,79,"Amplitude (line)",0);
  GObj.AddButton("Butt2",185,18,C'32,32,32',8,"Arial",Chocolate,612,61,"Amplitude (log)",1);
  GObj.AddButton("Butt3",185,18,C'32,32,32',8,"Arial",SlateGray,612,43,"Power (line)",0);
  GObj.AddButton("Butt4",185,18,C'32,32,32',8,"Arial",SlateGray,612,25,"Power (log)",0);
  GObj.AddButton("Butt5",185,18,C'32,32,32',8,"Arial",SlateGray,403,79,"External Data",0);
  GObj.AddButton("Butt6",185,18,C'32,32,32',8,"Arial",SlateGray,403,61,"Test 1. SMA(3)",0);
  GObj.AddButton("Butt7",185,18,C'32,32,32',8,"Arial",Chocolate,403,43,"Test 2. SMA(32)",1);
  GObj.AddButton("Butt8",185,18,C'32,32,32',8,"Arial",SlateGray,403,25,"Test 3. LWMA(12)",0);
  GObj.AddButton("Butt9",14,34,C'32,32,32',8,"Wingdings",SlateGray,36,78,"\x0431",0);
  GObj.AddButton("Butt10",14,34,C'32,32,32',8,"Wingdings",SlateGray,36,44,"\x0432",0);
  GObj.AddEdit("Edit1",35,18,Black,9,"Arial",SlateGray,180,102);
  GObj.AddTrendLine("Trdline1",C'32,32,32');
  GObj.AddTrendLine("Trdline2",C'32,32,32');
  GObj.AddTrendLine("Trdline3",C'32,32,32');
  GObj.AddTrendLine("Trdline4",C'32,32,32');
  GObj.AddTrendLine("Trdline5",C'32,32,32');
  GObj.AddTrendLine("Trdline6",C'32,32,32');
  GObj.AddTrendLine("Trdline7",C'32,32,32');
  GObj.AddTrendLine("Trdline8",C'32,32,32');
  GObj.AddArrowline("Arrline1",LightSteelBlue);
  GObj.AddArrowline("Arrline2",LightSteelBlue);
  GObj.AddRectangle("Rect1",C'72,72,72');
  GObj.AddRectangle("Rect2",C'72,72,72');
  GObj.AddRectangle("Rect3",C'72,72,72');
  GObj.AddRectangle("Rect4",DarkGray);
  GObj.AddRectangle("Rect5",C'72,72,72');
  }
//---------- Set object coordinate for Trend Line, Arroved Line and Rectangle --
void gr_object_coordinate()
  {
  GObj.MoveGrObject("Trdline1",48,150,48,360);
  GObj.MoveGrObject("Trdline2",176,150,176,360);
  GObj.MoveGrObject("Trdline3",304,150,304,360);
  GObj.MoveGrObject("Trdline4",432,150,432,360);
  GObj.MoveGrObject("Trdline5",42,350,560,350);
  GObj.MoveGrObject("Trdline6",42,300,560,300);
  GObj.MoveGrObject("Trdline7",42,250,560,250);
  GObj.MoveGrObject("Trdline8",42,200,560,200);
  GObj.MoveGrObject("Arrline1",560,150,28,150);
  GObj.MoveGrObject("Arrline2",560,150,560,370);
  GObj.MoveGrObject("Rect1",0,1,208,110);
  GObj.MoveGrObject("Rect2",208,1,416,110);
  GObj.MoveGrObject("Rect3",416,1,624,110);
  GObj.MoveGrObject("Rect4",0,1,624,400);
  GObj.MoveGrObject("Rect5",20,10,195,80);
  }
//+------------------------------------------------------------------+

AllGrObject sınıfının işlevlerine erişim sağlamak için bu sınıfın GObj nesnesini oluşturun. Göstergenin OnInit() işlevinde, gösterge kontrol panelinin görünümünü ve işlevselliğini belirleyen gerekli tüm grafik nesneleri oluşturan gr_object_create() işlevinin çağrısını içerir.

OnCalculate işlevinde MainChart.SetOwnProperty() ve gr_object_coordinate() işlevlerinin çağrılarını ekleyin; böylece üzerine çizilen nesnelerin grafik özellikleri ve koordinatları her yeni tick ile geri yüklenecektir. Bu tür bir geri yükleme, ilk grafikte yeni bir çubuk oluşturulduğunda veya sol fare düğmesi kullanılarak grafik hareket ettirildiğinde veya bir kullanıcı grafik özelliklerini değiştirdiğinde gereklidir. Bu test örneğini derleyip yükledikten sonra kontrol panelinin arayüzlerini göreceğiz; bkz. şek. 1.

Şek. 1. Kontrol panelinin arayüzü. 

Şek. 1. Kontrol panelinin arayüzü.

 Kontrol panelinin grafiğe göre yerleşimini görsel olarak görmek için yukarıdaki örnekte grafik ölçeğinin görüntülenmesini etkinleştirin; bkz. şek. 2.

  Şek. 2. Grafik ölçeği.

Şek. 2. Grafik ölçeği. 

Spektrum Analizörü

Göstergedeki bir spektrumun analizi, giriş dizisinin 1024 derecelendirilmesiyle gerçekleştirilir. Spektrum analizi, hızlı Fourier dönüşümü algoritması kullanılarak gerçekleştirilir. FFT algoritmasını uygulayan işlev www.mql4.com web sitesinin yayınlarından alınmıştır. Hesaplamalar için gerçek zamanlı giriş dizisinin FFT işlevini kullanırız; kodu SpecAnalyzer.mqh dosyasına yerleştirilir. Spektrum analizi için gereken tüm eylemler fft_calc() işlevinde uygulanır. 

void fft_calc()
  {
  int i,k;

  realfastfouriertransform(InpData,ArraySize(InpData),false);          // FFT
  for(i=1;i<ArraySize(Spectrum);i++)
    {
    k=i*2;
    Spectrum[i]=InpData[k]*InpData[k]+InpData[k+1]*InpData[k+1];    
    }
  Spectrum[0]=0.0;                             // Clear constant component level
  }

fft_calc() işlevi çağrıldığında, InpData[] dizisinin analiz edilecek bir giriş dizisi içermesi gerekir. realfastfouriertransform() yürütüldükten sonra, FFT'nin sonucu bu diziye yerleştirilecektir. Ayrıca, spektrum tahminlerinin gerçek ve sanal kısmından her harmonik için modülleme karesi hesaplanır; sonuç, Spectrum[] dizisine yazılır. Spectrum[] dizisindeki öğe indeksi, harmonik sayıya karşılık gelir. Sabit bileşenin hesaplanan değeri göstergede kullanılmadığı için dizinin Spectrum[0] öğesine her zaman sıfır değeri atanır.

InputSource değişkeninin değerine bağlı olarak, InpData[] dizisi test dizileriyle veya harici bir göstergeden elde edilen verilerle doldurulabilir. Giriş verileri get_input_data() işlevinde oluşturulur.

void get_input_data()
  {
  int i;
  
  ArrayInitialize(InpData,0.0);
  switch(InputSource)
    {
    case 0:                                                    // External Data
      if(ExtHandle!=INVALID_HANDLE)
        CopyBuffer(ExtHandle,0,0,ArraySize(InpData),InpData);
      break;
    case 1:                                                    // Test 1. SMA(3)
      for(i=0;i<3;i++)InpData[i]=1;
      break;
    case 2:                                                   // Test 2. SMA(32)
      for(i=0;i<32;i++)InpData[i]=1;
      break;
    case 3:                                                  // Test 3. LWMA(12)
      for(i=0;i<12;i++)InpData[i]=12-i;
      break;
    }
  }

InputSource değeri sıfıra eşitse SAInpData.mq5 göstergesinin sıfır arabelleğinden InpData[] giriş dizisine 1024 değer kopyalanacaktır. Analiz için veriler, göstergenin kendisinde veya ondan diğer göstergeler çağrılarak oluşturulabilir. SAInpData.mq5 göstergesine erişim sağlamak için OnInit() işlevine aşağıdaki satır eklenir; bu, ExtHandle değişkeninin değerini belirler.

int OnInit() 
 {
 button. button. button.

 ExtHandle=iCustom(NULL,0,"SAInpData");  // External indicator Handle

 return(0);
 }

SAInpData.mq5 göstergesi, istemci terminalinin \MQL5\Indicators dizinine yerleştirilmelidir. Bu makaleye örnek olarak eklenmiş SAInpData.mq5 göstergesi, analizöre rastgele bir sıra iletir. SAInpData.mq5 göstergesinin başka bir diziyi analizöre iletmesini sağlamak için kaynak kodunu değiştirin.

get_input_data() işlevleri için bir test dizisi olarak, SMA(3), SMA(32) ve LWMA(12) hareketli ortalamalarının darbe özellikleri oluşturulur. Bir filtrenin darbe özelliklerinin Fourier dönüşümünün, o filtrenin genlik-sıklık özelliklerine karşılık geldiğini dikkate alarak, test dizileri olarak seçersek hareketli ortalamaların genlik-sıklık özelliklerini gözlemleyebiliriz.

Spectrum[] dizisinde saklanan spektrum tahmininin sonucunu normalize etmek ve belirtilen modda görüntülemeye hazırlamak için norm_and_draw() işlevi kullanılır; SpecAnalyzer.mq5 dosyasına bakınız. Seçilen görüntüleme moduna bağlı olarak, bu işlev Y ekseninin metin işaretlemesinin yerini alır.

Giriş dizisinin spektrum tahmininin sonucu, yalnızca grafik biçiminde değil, aynı zamanda metin biçiminde de görüntülenir. Sonuçların metin biçiminde gösterilmesi için “Etiket” türünde beş grafik nesne oluşturulur; bunlar, görüntülenen beş metin satırına karşılık gelir. list_levels() işlevi, bu satırları bilgi ile doldurma işlemini gerçekleştirir. 

void list_levels()
  {
  int m;
  string str;
  
  if(YdBFlag==0) str="%3u    %.5f";                     // If Y-axis mode = Line
  else str="%3u  %6.1f dB";                               // If Y-axis mode = dB
  m=ArraySize(ListArray)-5;
  if(ListPointer<1)ListPointer=1;
  if(ListPointer>m)ListPointer=m;
  GObj.LabelTxt("Label17",StringFormat(str,ListPointer,ListArray[ListPointer]));
  GObj.LabelTxt("Label18",StringFormat(str,ListPointer+1,ListArray[ListPointer+1]));
  GObj.LabelTxt("Label19",StringFormat(str,ListPointer+2,ListArray[ListPointer+2]));
  GObj.LabelTxt("Label20",StringFormat(str,ListPointer+3,ListArray[ListPointer+3]));
  GObj.LabelTxt("Label21",StringFormat(str,ListPointer+4,ListArray[ListPointer+4]));
  }

Satırlar, StringFormat() işlevi kullanılarak biçimlendirilmiş ListArray[] dizisindeki düzeylerin değerlerini görüntüler. Geçerli görüntüleme moduna göre, bu dizi norm_and_draw() işlevi içindeki bilgilerle doldurulur; SpecAnalyzer.mq5 dosyasına bakınız. ListArray[] dizisinin bilgileri, ListPointer değişkeninde saklanan değere eşit dizi indeksinden başlayarak görüntülenir. Çıkış alanının sağında bulunan düğmelere basarak veya giriş alanında gerekli indeksi belirterek ListPointer değişkeninin değerini ve dolayısıyla görüntülenecek satırların başlangıç indeksini değiştirebilirsiniz. Bu düğmelere basmak ve giriş alanındaki değişiklikleri bitirmekle ilgili olaylar, göstergenin OnChartEvent() işlevinde işlenir; SpecAnalyzer.mq5 dosyasına bakınız.

SpecAnalyzer göstergesinin görünümü aşağıdaki şekilde gösterilmiştir.

  Şek. 3. SpecAnalyzer göstergesinin görünümü.

Şek. 3. SpecAnalyzer göstergesinin görünümü.  

Sonuç

Daha önce de belirtildiği gibi, SpecAnalyzer.mq5 göstergesi, eksiksiz bir spektrum analizörünün yalnızca bir prototipidir; makalede grafik nesnelerin kullanımına örnek olarak verilmiştir. Kapsamlı bir gösterge oluşturmak için muhtemelen görünümünü geliştirmeniz, daha işlevsel bir arayüz uygulamanız ve spektrum tahmini algoritmasını iyileştirmeniz gerekecektir.

Gösterge arayüzünü tasarımı için “Bitmap” grafik nesnesini kullanarak, bir grafik düzenleyicide ön kontrol paneli için bir görüntü oluşturarak ve onu kontrol öğelerinin görüntüleneceği bir alt katman olarak kullanarak önemli ölçüde iyileştirebilirsiniz. Bu yaklaşım, değiştirilebilir dış görünümlere sahip göstergeler oluşturmak için kullanılabilir.

Literatür

  1. Yukio Sato. Introduction to Signal Management.
  2. L. Rabiner, B. Gold. Theory and Application of Digital Signal Processing.
  3. S.L. Marple, Jr. Digital Spectral Analysis with Applications.

Dosyalar

  1. SpecAnalyzer.mq5 – Bu makalede açıklanan gösterge.
  2. SpecAnalyzer.mqh – SpecAnalyzer.mq5 için içerme dosyası.
  3. SAInpData.mq5 – Harici verilere erişimin düzenlenmesi için kullanılan gösterge.

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

Ekli dosyalar |
SAInpData.mq5 (3.29 KB)
SpecAnalyzer.mq5 (15.39 KB)
SpecAnalyzer.mqh (20.79 KB)
William Blau'nun MQL5'teki Göstergeleri ve Alım Satım Sistemleri. Bölüm 1: Göstergeler William Blau'nun MQL5'teki Göstergeleri ve Alım Satım Sistemleri. Bölüm 1: Göstergeler
Makalede, William Blau'nun "Momentum, Direction, and Divergence" kitabında açıklanan göstergeler sunulmaktadır. William Blau'nun yaklaşımı, fiyat eğrisindeki dalgalanmaları yaklaşık olarak hızlı ve doğru bir şekilde tahmin etmemize, fiyat hareketleri trendini ve dönüm noktalarını belirlememize ve fiyat gürültüsünü ortadan kaldırmamıza olanak tanır. Aynı zamanda, piyasanın aşırı alım/aşırı satım durumlarını ve bir trendin sona erdiğini ve fiyat hareketinin tersine döndüğünü gösteren sinyalleri de tespit edebiliyoruz.
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.
Önceden tanımlanmış risk ve R/R oranına dayalı etkileşimli yarı otomatik sürükle ve bırak Uzman Danışman (EA) oluşturma Önceden tanımlanmış risk ve R/R oranına dayalı etkileşimli yarı otomatik sürükle ve bırak Uzman Danışman (EA) oluşturma
Bazı yatırımcılar tüm alım-satımları otomatik olarak yürütür ve bazıları birkaç göstergenin çıkışına bağlı olarak otomatik ve manuel alım-satımları karıştırır. Sonraki grubun bir üyesi olarak risk ve ödül seviyelerini doğrudan grafikten dinamik olarak değerlendirmek için etkileşimli bir araca ihtiyacım vardı. Bu makale, önceden tanımlanmış hisse senedi riski ve R/R oranı ile etkileşimli yarı otomatik bir Uzman Danışman (EA) uygulamanın bir yolunu sunacaktır. Uzman Danışman (EA) riski, RR ve lot boyutu parametreleri EA paneli üzerinde çalışma süresi boyunca değiştirilebilir.
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
Yeni MetaTrader 5 istemci terminali ve MQL5 Dili, yatırımcıya görsel bilgi sunmak için yeni fırsatlar sunar. Bu makalede, grafik üzerinde rastgele seçilmiş metin bilgilerinin görüntülenmesini düzenlemeye ilişkin tüm işleri yürüten evrensel ve genişletilebilir bir sınıflar kümesi öneriyoruz. Piyasa İzleme göstergesi örneği sunulmuştur.