English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Renko grafiği için gösterge

Renko grafiği için gösterge

MetaTrader 5Örnekler | 14 Ocak 2022, 10:28
635 0
Dmitriy Zabudskiy
Dmitriy Zabudskiy

Giriş

Nokta ve Şekil grafiği için Gösterge ve Kagi grafiği için Gösterge makalelerinde Nokta ve Şekil ve "Kagi" gösterge grafiği ilkeleri açıklanmıştır. Renko grafiği oluşturmanın programlama yollarından birini inceleyelim.

"Renko" adı, bir tuğla olan Japonca "renga" kelimesinden türetilmiştir. Renko grafiği, yaratılışı fiyat dalgalanmalarıyla belirlenen bir dizi tuğladan yapılmıştır. Bir fiyat yükseldiğinde, grafiğe bir yukarı tuğla yerleştirilir ve fiyatların düşmesiyle bir aşağı tuğla eklenir. "Renko", Japonca'da "yavaş tempo" anlamına gelir. Renko grafiği, muhtemelen 19. yüzyıl civarında Japonya'da ortaya çıktı. ABD ve Avrupa bunu ilk olarak 1994'te Steeve Nison'ın kitabında yayınlandıktan sonra duydu, Mum Grafiklerin Ötesinde: Yeni Japon Grafik Teknikleri Açıklandı.

Renko grafiği, yukarıda belirtilen çizelgeler gibi zaman çizelgesini yok sayar ve yalnızca fiyat hareketi ile ilgilidir. Nokta ve Şekil grafiğinden farklı olarak, Renko her "tuğlayı" yeni bir sütuna (yeni bir dikey düzlemde) yerleştirir, geri kalanı için ortak bir oluşturma yöntemi vardır: bir "tuğla" boyutu ("nokta", "şekil" ") sabittir, fiyat analizi ve rakam çizgilerinin çekimi benzer şekilde yapılır.

Yani, Renko grafiği bir dizi dikey çubuktur ("tuğlalar"). Trend yönü yukarı olduğunda beyaz (içi boş) tuğlalar, trend aşağı olduğunda siyah (dolu) tuğlalar kullanılır. Yapı, fiyat davranışı ile düzenlenir. Alınan dönemin cari fiyatı, bir önceki tuğlanın (beyaz veya siyah) minimum ve maksimumu ile karşılaştırılır. Menkul değer açılış fiyatından daha yüksek kapanırsa, gövdenin altı açılış fiyatını ve gövdenin üstü kapanış fiyatını temsil eden içi boş (beyaz) bir tuğla çizilir. Menkul değer açılış fiyatının altında kapanırsa, gövdenin üstü açılış fiyatını ve gövdenin altı kapanış fiyatını temsil eden dolu (siyah) bir tuğla çizilir.

Grafiğin ilk tuğlası fiyat davranışına bağlı olarak çizilir, çubuk açılış fiyatı bir önceki tuğlanın maksimum ve minimumu için alınır.

Standart bir Renko grafiği örneği, Şekil 1:

Şek. 1. Standart bir Renko grafiği örneği

Şek. 1. Standart bir Renko grafiği örneği

1. Grafik örneği

Kapanış fiyatına göre standart bir Renko grafiği çizilir. İlk olarak, zaman dilimini ve kutu boyutunu seçin.

Bu örnekte, 30 puntoluk bir kutu boyutuyla EURUSD (H4 zaman dilimi) kullanılmıştır. 03.01.2014 - 31.01.2014 (yaklaşık bir ay) arasındaki Renko grafiğinin sonucu Şekil 2'de gösterilmektedir, solda, belirli bir zaman diliminin grafiği var (burada tuğlaların yatay uzantısını görebilirsiniz), sağda, Renko grafiğinin sonucu var:


Şek.2. EURUSD cinsinden Renko grafiğinin sonucu (H4, kutu 30 puandır) 

Şek.2. EURUSD cinsinden Renko grafiğinin sonucu (H4, kutu 30 puandır)

Grafik ilkesine daha yakından bakalım. Şekil 2'de kırmızı yatay çizgiler, fiyat değişikliklerine göre her bir tuğlanın boyutunu (30 puan), mavi renk ise en ilginç tarihleri göstermektedir.

Grafikte görebileceğiniz gibi 03.01.2014 sonunda bir mum grafik önceden tanımlanmış 1.3591 fiyat aralığının (kırmızı yatay çizgiler) altında 1.3589'da (fiyatla işaretlenmiştir) kapanır, bu da grafikte aşağı yönlü bir tuğla oluşturur.

Bundan sonra fiyat sabittir (1.3561'in altında veya 1.3651'in üzerinde kapanmaz), 20:00 10.01.2014'e kadar açılır (16:00'da oluşturulan mum grafik kapanır) ve 1.3663'ten (fiyatla işaretli) (1.3651 fiyat işaretinin üzerinde) kapanır. Daha sonra fiyat 14.01.2014 20:00 (16:00'da açılan mum grafik kapanır) itibariyle tekrar sabit hale gelir, burada fiyat aralığını aşarak yeni bir tuğla oluşturur ve 1.3684'ten kapanır.

Ardından, fiyatın grafikte düşen aralıkları dört kez geçtiği bir düşüşe tanık oluyorsunuz. 23.01.2014 12:00'de (08:00'de açılan mum grafik kapanır) iki fiyat aralığında yukarı yönlü bir atılım vardır, bu da sırasıyla 1.3639'da kapanarak iki tuğla açar. İlk tuğla açıkça görülebilir, ikincisi uzun bir dikey çizgide çekilir (birinci tuğla ile aynı anda açılması nedeniyle). Daha fazla oluşturma aynı prensiplerde devam ediyor.


2. Renko grafik prensibi

Bu göstergeyi geliştirirken, tüm işlevler mümkün olduğunca bağımsız olarak uygulanmıştır. Ana hedeflerden biri, piyasa analizini daha kolay yürütmek için göstergenin potansiyelini en üst düzeye çıkarmaktı.

Hesaplamalar mevcut zaman dilimi içinde yapılmaz, yani ayarlarda zaman dilimi seçilir ve göstergenin başlatıldığı zaman dilimi ne olursa olsun, kurulum verilerini gösterecektir. Alınan dönem verilerinin ayrı arabellek dizilerine kopyalanması ile elde edilebilir, daha sonra hesaplamalar yapılır ve çıktı arabellek göstergesi doldurulur.

Standart Renko grafiği Kapanış fiyatlarına göre oluşturulur, ancak analizi iyileştirmek için Açık, Yüksek, Düşük değerler kullanılır.

Renko grafiğindeki tuğlalar boyut olarak benzer olduğundan, güçlü fiyat davranışı tarafından yönlendirilen en dinamik piyasa noktalarını bilmek faydalıdır (birkaç tuğlada). Bu amaçla, bir tuğlanın küçük bir dikey gölgeyle temsil edilen (Japon Mum Grafik örneğindeki gibi), seçilen zaman dilimi çubuğunun son tuğla seviyesinde yükselen veya alçalan, (devre dışı bırakılmış) bir göstergesi vardır.

Ana çizelgede ZigZag oluşturma olasılığı, grafik analizini genişletir.

Şekil 3, tam işlevsellikteki göstergeyi temsil eder:

Şekil 3. EURUSD grafiği göstergesi (Günlük, adım 25 puandır)

Şekil 3. EURUSD grafiği göstergesi (Günlük, adım 25 puandır)


3. Göstergenin kodu ve algoritması

Gösterge kodu 900 satırdan oluştuğu için oldukça büyüktür. Daha önce bahsedildiği gibi, maksimum ayrılmış işlevler algoritmanın anlaşılmasını zorlaştırabilir. Önceki makaledeki bazı işlevler temel olarak kullanılacaktır. Bazı yönlerin yanlış anlaşılması durumunda, Kagi grafik yapım göstergesine başvurabilir veya bana e-posta gönderebilirsiniz.

Kodun her işlevi makalede açıklanacaktır. İşlevler yerinde anlatılacaktır.


3.1. Gösterge giriş parametreleri

Renko grafiği, farklı renkteki yukarı ve aşağı tuğlaların aralığıdır. Bu tür bir yapı, bir "Renkli mum grafik" grafiksel yapısında birleştirilmiş yalnızca beş arabellek gerektirir. Kalan dört arabellek, göstergeyi hesaplamak için gereken verileri toplar.

Gruplara ayrılmış giriş parametrelerini (25) alın.

  • adım - bir tuğla boyutu veya adım;
  • type_step - puan veya yüzde olarak adım türü (ikincisi, mevcut fiyata bağlı olarak hesaplanır);
  • magic_numb - grafiksel nesneleri ayırt etmek için gerekli olan ve onları grafikten çıkarmak için kullanılan sihirli bir sayı;
  • levels_number - gösterge penceresinde tuğlaları bölmek için seviyeler (0- seviye yok);
  • levels_color - gösterge penceresindeki seviyelerin rengi;
  • time_frame - grafik oluşturma (analiz edilen dönem) için bir dönem ayarlamak için kullanılır;
  • time_redraw - grafiğin güncelleme zamanı;
  • first_date_start - grafiğin başlatılacağı tarih;
  • type_price - oluşturma için fiyat türleri: Kapat - kapanış fiyatına dayalı standart yöntem; Açık - açılış fiyatı; Yüksek - maksimum fiyatlar ve Düşük - minimum fiyatlar;
  • shadow_print - doğru seçeneği belirlerseniz gölgeler birkaç tuğlanın açılmasına neden olan maksimum veya minimum fiyatı temsil eder;
  • filter_number - grafiğin tersine çevrilmesi için kullanılan tuğla değeri (grafiği tersine çevirmek için gereken tuğla sayısından sorumlu ekstra bir seçenek);
  • zig_zag - ana grafikte ZigZag'ler çizmek için kullanılır (ana grafikte bir analizi kolaylaştıran veya grafiği güncellemek için kullanılan ekstra bir çizim);
  • zig_zag_shadow - maksimum ve minimum fiyatlara göre ZigZag çizmek için kullanılır (uç noktalarda zikzaklar oluşturmak için en yakın maksimum ve minimum fiyatları kullanır);
  • zig_zag_width - ZigZag çizgi genişliği;
  • zig_zag_color_up - ZigZag yukarı doğru çizgi rengi;
  • zig_zag_color_down - ZigZag aşağı doğru çizgi rengi;
  • square_draw - ana grafikte tuğla çizmek için kullanılır (bu modda tuğlaları açan fiyat hareketlerini görebilirsiniz);
  • square_color_up - ana yukarı doğru grafikte tuğla rengi;
  • square_color_down - ana aşağı doğru grafikte tuğla rengi;
  • square_fill - ana grafikte tuğla boyama;
  • square_width - ana grafikte tuğla çizgi genişliği;
  • frame_draw - tuğla çerçeve çizmek için kullanılır (tuğla kenarlıklarını temsil eder, nadiren kullanılan ekstra bir seçenektir);
  • frame_width - tuğla çizgi genişliği;
  • frame_color_up - yukarı tuğla kenarlıkların rengi;
  • frame_color_down - aşağı tuğla kenarlıkların rengi.

Ardından kod, arabellekleri bildirir: beş ana arabellek grafik çizim için kullanılırken, dördü tasarım ve hesaplama verilerini depolamak için kullanılır. Fiyat[] - oluşturma için kullanılan kopyalanan fiyatları depolamak için arabellek, Tarih[] - ana grafikte çizim için kullanılan kopyalanan verileri depolamak için arabellek, Price_high[] ve Price_low[] - ana grafikte ZigZag çizimlerinde uygulanan maksimum ve minimum değerleri depolamak için arabellekler.

Bundan sonra hesaplama arabellek dizileri ve yardımcı işlev değişkenleri bildirilir: func_draw_renko, func_draw_zig_zag, func_draw_renko_main_chart. Bunlar daha sonra açıklanacaktır.

//+------------------------------------------------------------------+
//|                                                         ABCR.mq5 |
//|                                   Azotskiy Aktiniy ICQ:695710750 |
//|                          https://www.mql5.com/ru/users/Aktiniy |
//+------------------------------------------------------------------+
//--- Auto Build Chart Renko
#property copyright "Azotskiy Aktiniy ICQ:695710750"
#property link      "https://www.mql5.com/ru/users/Aktiniy"
#property version   "1.00"
#property description "Auto Build Chart Renko"
#property description "   "
#property description "This indicator used to draw Renko chart in the indicator window, and in the main chart window"
#property indicator_separate_window
#property indicator_buffers 9
#property indicator_plots   1
//--- plot RENKO
#property indicator_label1  "RENKO"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrRed,clrBlue,C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0',C'0,0,0'
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- construction method
enum type_step_renko
  {
   point=0,   // Point
   percent=1, // Percent
  };
//--- type of price
enum type_price_renko
  {
   close=0, // Close
   open=1,  // Open
   high=2,  // High
   low=3,   // Low
  };
//--- input parameters
input double           step=10;                                 // Step
input type_step_renko  type_step=point;                         // Type of step
input long             magic_numb=65758473787389;               // Magic number
input int              levels_number=1000;                      // Number of levels (0-no levels)
input color            levels_color=clrLavender;                // Color of levels
input ENUM_TIMEFRAMES  time_frame=PERIOD_CURRENT;               // Calculation period
input ENUM_TIMEFRAMES  time_redraw=PERIOD_M1;                   // Chart redraw period
input datetime         first_date_start=D'2013.09.13 00:00:00'; // Start date
input type_price_renko type_price=close;                        // Price for construction
input bool             shadow_print=true;                       // Show shadows
input int              filter_number=0;                         // Bricks number needed to reversal
input bool             zig_zag=true;                            // Whether ZigZag should be drawn on the main chart
input bool             zig_zag_shadow=true;                     // Draw ZigZag at highs and lows of the price
input int              zig_zag_width=2;                         // ZigZag line width
input color            zig_zag_color_up=clrBlue;                // ZigZag up line color
input color            zig_zag_color_down=clrRed;               // ZigZag down line color
input bool             square_draw=true;                        // Whether bricks should be drawn on the main chart
input color            square_color_up=clrBlue;                 // Up brick color on the main chart
input color            square_color_down=clrRed;                // Down brick color on the main chart
input bool             square_fill=true;                        // Brick filling on the main chart
input int              square_width=2;                          // Brick line width on the main chart
input bool             frame_draw=true;                         // Whether to draw frames of the bricks
input int              frame_width=2;                           // Brick frame line width
input color            frame_color_up=clrBlue;                  // Up brick frames color
input color            frame_color_down=clrRed;                 // Down brick frames color
//--- indicator buffers
double         RENKO_open[];
double         RENKO_high[];
double         RENKO_low[];
double         RENKO_close[];
double         RENKO_color[];

double         Price[];      // copy price data to the buffer
double         Date[];       // copy data to the buffer
double         Price_high[]; // copy high prices to the buffer
double         Price_low[];  // copy low prices to the buffer
//--- calculation buffer arrays
double         up_price[];    // up brick price
double         down_price[];  // down brick price
char           type_box[];    // brick type (up, down)
datetime       time_box[];    // brick copy time
double         shadow_up[];   // up high price
double         shadow_down[]; // down low price
int            number_id[];   // Index of Price_high and Price_low arrays
//--- calculation global variables
int obj=0;           //variable for storing number of graphics objects
int a=0;             // variable to count bricks
int bars;            // number of bars
datetime date_stop;  // current data
datetime date_start; // start date variable, for calculations
bool date_change;    // variable for storing details about time changes


3.2. Gösterge başlatıcı

Gösterge arabellekleri tek boyutlu dinamik dizilere bağlıdır, adresleme zaman serilerinde olduğu gibi INDICATOR_DATA ve INDICATOR_COLOR_INDEX arabelleklerinde ayarlanır. Geri kalan dinamik dizilerin (Price[], Date[], Price_high[], Price_low[]) adreslemesi, yalnızca veri depolamak için kullanıldıklarından, değişiklik yapılmadan bırakılır.

Grafikte görüntülenmeyen değerler ayarlanır. Ardından göstergeye isim atanır, gösterge doğruluğu ayarlanır ve gösterge penceresinde mevcut sayısal değerlerin görüntülenmesi engellenir.

Bundan sonra date_start değişken değeri (hesaplamaların başlama tarihi) atanır. Değişkene değer atanır, grafik gösterge arabelleği için çok ağır olabileceğinden giriş değeri kullanılmaz. Başlangıç tarihi düzeltilir ve özel ilan edilir. Analiz başlangıç tarihi veya "func_calc_date_start" işlevi, zaman düzeltmelerini gerçekleştirir.

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,RENKO_open,INDICATOR_DATA);
   ArraySetAsSeries(RENKO_open,true);
   SetIndexBuffer(1,RENKO_high,INDICATOR_DATA);
   ArraySetAsSeries(RENKO_high,true);
   SetIndexBuffer(2,RENKO_low,INDICATOR_DATA);
   ArraySetAsSeries(RENKO_low,true);
   SetIndexBuffer(3,RENKO_close,INDICATOR_DATA);
   ArraySetAsSeries(RENKO_close,true);
   SetIndexBuffer(4,RENKO_color,INDICATOR_COLOR_INDEX);
   ArraySetAsSeries(RENKO_color,true);
//---
   SetIndexBuffer(5,Price,INDICATOR_CALCULATIONS);      // initialize price buffer
   SetIndexBuffer(6,Date,INDICATOR_CALCULATIONS);       // initialize data buffer
   SetIndexBuffer(7,Price_high,INDICATOR_CALCULATIONS); // initialize high price
   SetIndexBuffer(8,Price_low,INDICATOR_CALCULATIONS);  // initialize low price
//--- set data which will not be drawn
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- set the indicator appearance
   IndicatorSetString(INDICATOR_SHORTNAME,"ABCR "+IntegerToString(magic_numb)); // indicator name
//--- display accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- prohibit display of the results of the indicator current values
   PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);
//--- assign start date variable value
   date_start=first_date_start;
//---
   return(INIT_SUCCEEDED);
  }

3.3. Analiz başlangıç tarihi hesaplama işlevi

İşlev küçüktür ve esasen bir döngüden oluşur. Yalnızca iki giriş parametresi vardır; başlangıçta ayarlanan başlangıç tarihi ve hesaplama bitiş tarihi (güncel tarih). İşlevde başlangıç tarihi değiştirilir ve cevap olarak görüntülenir.

İşlev gövdesi, alıcı arabellek dizisini ölçmekle başlar (tüm arabellekler, seçilen zaman dilimi çubuklarının sayısına eşit olan aynı boyuta sahiptir). Ardından, seçilen zaman diliminde bir dizi çubuk ölçülür.

Döngü koşulunda, seçilen zaman diliminin çubuk sayısı ve arabellek dizisi boyutu karşılaştırılır. Daha fazla çubuğunuz varsa, yani tümü arabellek dizisine yerleştirilemezse alınan zaman dilimi on gün olarak kısaltılır; bu da analiz başlangıç tarihine on gün eklendiği anlamına gelir. Bu, arabellek dizisi tüm çubuk verilerini içeremeyecek duruma gelene kadar devam eder. İşlev, hesaplanan tarihi verir.

//+------------------------------------------------------------------+
//| Func Calculate Date Start                                        |
//+------------------------------------------------------------------+
datetime func_calc_date_start(datetime input_data_start,// initially start date set
                              datetime data_stop)       // calculation end date (current date)
//---
  {
   int Array_Size=ArraySize(Price);
   int Bars_Size=Bars(_Symbol,time_frame,input_data_start,data_stop);
   for(;Bars_Size>Array_Size;input_data_start+=864000) // 864000 = 10 days
     {
      Bars_Size=Bars(_Symbol,time_frame,input_data_start,data_stop);
     }
   return(input_data_start);
//---
  }

3.4. Veri kopyalama işlevi

İlk olarak, veriler veri kopyalama işlevleriyle (func_copy_price ve func_copy_date) kopyalanır.

Ayarlanan dönem ve zaman diliminin Açılış , Kapanış, Yüksek ve Düşük fiyatlarını dizide kopyalamanıza izin veren fiyat kopyalama işlevini veya func_copy_price'ı ele alalım. Başarılı bir kopyalama durumunda işlev "doğru" değerini verir.

İşlev çağrısının başlangıcında false değeri başlatılır, ardından kopyalanan verinin bir sonuç değişkeni başlatılır ve negatif bir değer atanır. Geçici olarak kopyalanan verileri depolamak için ortak bir price_interim[] dizisi ve kopyalanan verilerin kaydedilmesini önlemek için bar_to_copy değişkeni bildirilir.

Ayrıca işlev, kopyalanan verileri depolamak için önceden bildirilen değişkenleri sıfırlar, zaman dilimindeki çubuk sayısını hesaplar ve seçilen fiyata göre (0-Kapanış, 1-Açılış, 2-Yüksek ve 3-Düşük) ve bir switch beyanına göre, bars_copied değişken fiyatlarına önceden kopyalanan verilerin değerini atar. Bundan sonra, kopyalanacak veri sayısı hesaplanır. Veriler daha önce kopyalanmışsa grafikte değişiklik yapılmasını önlemek için son kopyalanan çubuk bilgileri silinir.

Bir switch, gerekli fiyat verilerini price_interim[] zaman dizisine kopyalar. Bundan sonra, kopyalamanın sonucu kontrol edilir ve bir switch, kopyalanan veri değişkenlerini doldurur.

//+------------------------------------------------------------------+
//| Func Copy Price                                                  |
//+------------------------------------------------------------------+
bool func_copy_price(double &result_array[],
                     ENUM_TIMEFRAMES period,// Timeframe
                     datetime data_start,
                     datetime data_stop,
                     char price_type) // 0-Close, 1-Open, 2-High, 3-Low
  {
//---
   int x=false;        // Variable for answering
   int result_copy=-1; // copied data number
//---
   static double price_interim[]; // Temporal dynamic array for storing copied data
   static int bars_to_copy;       // number of bars to copy
   static int bars_copied_0;      // number of copied bars from Close start date
   static int bars_copied_1;      // number of copied bars from Open start date
   static int bars_copied_2;      // number of copied bars from High start date
   static int bars_copied_3;      // number of copied bars from Low start date
   static int bars_copied;        // number of copied bars from the common variable start date
//--- variables reset due to changes in a start date
   if(date_change==true)
     {
      ZeroMemory(price_interim);
      ZeroMemory(bars_to_copy);
      ZeroMemory(bars_copied_0);
      ZeroMemory(bars_copied_1);
      ZeroMemory(bars_copied_2);
      ZeroMemory(bars_copied_3);
      ZeroMemory(bars_copied);
     }
//--- get an information about the current bars number on the timeframe
   bars_to_copy=Bars(_Symbol,period,data_start,data_stop);
//--- assign a copied function value to a common variable
   switch(price_type)
     {
      case 0:
         //--- Close
         bars_copied=bars_copied_0;
         break;
      case 1:
         //--- Open
         bars_copied=bars_copied_1;
         break;
      case 2:
         //--- High
         bars_copied=bars_copied_2;
         break;
      case 3:
         //--- Low
         bars_copied=bars_copied_3;
         break;
     }
//--- calculate number of bars required to be copied
   bars_to_copy-=bars_copied; 
//--- if it is not the first time the data has been copied
   if(bars_copied!=0) 
     {
      bars_copied--;
      bars_to_copy++;
     }
//--- change the size of the recieving array
   ArrayResize(price_interim,bars_to_copy); 
//--- copy data to the recieving array
   switch(price_type)
     {
      case 0:
         //--- Close
        {
         result_copy=CopyClose(_Symbol,period,0,bars_to_copy,price_interim);
        }
      break;
      case 1:
         //--- Open
        {
         result_copy=CopyOpen(_Symbol,period,0,bars_to_copy,price_interim);
        }
      break;
      case 2:
         //--- High
        {
         result_copy=CopyHigh(_Symbol,period,0,bars_to_copy,price_interim);
        }
      break;
      case 3:
         //--- Low
        {
         result_copy=CopyLow(_Symbol,period,0,bars_to_copy,price_interim);
        }
      break;
     }
//--- check the result of data copying
   if(result_copy!=-1) // if copying to the intermediate array is successful
     {
      ArrayCopy(result_array,price_interim,bars_copied,0,WHOLE_ARRAY); // copy the data from the temporary array to the main one
      x=true;                   // assign the positive answer to the function
      bars_copied+=result_copy; // increase the value of the processed data
     }
//--- return the information about the processed data with one of the copied variables
   switch(price_type)
     {
      case 0:
         //--- Close
         bars_copied_0=bars_copied;
         break;
      case 1:
         //--- Open
         bars_copied_1=bars_copied;
         break;
      case 2:
         //--- High
         bars_copied_2=bars_copied;
         break;
      case 3:
         //--- Low
         bars_copied_3=bars_copied;
         break;
     }
//---
   return(x);
  }

 "func_copy_date" veya tarih kopyalama işlevi. Fonksiyonun kodu yukarıda bahsedilen birime benzer, fark kopyalanan verinin türündedir.

//+------------------------------------------------------------------+
//| Func Copy Date                                                   |
//+------------------------------------------------------------------+
bool func_copy_date(double &result_array[],
                    ENUM_TIMEFRAMES period,// timeframe
                    datetime data_start,
                    datetime data_stop)
  {
//---
   int x=false;                    // variable for answer
   int result_copy=-1;             // number of copied data
   static datetime time_interim[]; // temporaty dynamic array for storing the copied data
   static int bars_to_copy;        // bars number required to be copied
   static int bars_copied;         // copied bars with start date
//--- variables reset due to the start date change
   if(date_change==true)
     {
      ZeroMemory(time_interim);
      ZeroMemory(bars_to_copy);
      ZeroMemory(bars_copied);
     }
//---
   bars_to_copy=Bars(_Symbol,period,data_start,data_stop); // Find out the current number of bars on the time interval
   bars_to_copy-=bars_copied; // Calculate the number of bars to be copied
//---
   if(bars_copied!=0) // If it is not the first time the data has been copied
     {
      bars_copied--;
      bars_to_copy++;
     }
//---
   ArrayResize(time_interim,bars_to_copy); // Change the size of the receiving array
   result_copy=CopyTime(_Symbol,period,0,bars_to_copy,time_interim);
//---
   if(result_copy!=-1) // If copying to the intermediate array is successful
     {
      ArrayCopy(result_array,time_interim,bars_copied,0,WHOLE_ARRAY); // Copy the data from the temporary array to the main one
      x=true; // assign the positive answer to the function
      bars_copied+=result_copy; // Increase the value of the processed data
     }
//---
   return(x);
  }

3.5. Tuğla hesaplama

Gösterge parametrelerinden de görebileceğiniz gibi, bir tuğla boyutu hem puan hem de mevcut fiyatın yüzdesi olarak ayarlanabilir. Puanlar sabit bir değerdir ancak yüzde olarak hesaplamalar nasıl yapılır? Bu amaçla "func_calc_dorstep" tuğla hesaplama işlevi vardır.

Üç giriş parametresi vardır: mevcut fiyat (tuğla boyutu yüzde olarak ise fiyatın yüzdesini hesaplamak için), hesaplama yöntemi (puan veya yüzde) ve adım boyutu (yüzde veya puan olarak olabilen bir değerle ayarlanır).

İşlevin başında cevabın değişkeni çift tür ile başlatılır ve if-else koşul ifadesi ile seçilen hesaplama yöntemine bağlı olarak puanlar atanır. Daha sonra, hesaplamalar integral olmayan değerle sonuçlansa bile değer tamsayısını korumak için yanıt değişkeni int türüne dönüştürülür.

//+------------------------------------------------------------------+
//| Func Calculate Doorstep                                          |
//+------------------------------------------------------------------+
int func_calc_dorstep(double price,      // price
                      char type_doorstep,// step type
                      double doorstep)   // step
  {
   double x=0;          // variable for answer

   if(type_doorstep==0) // If the calculation is to be performed in points
     {
      x=doorstep;
     }

   if(type_doorstep==1) // If the calculation is to be performed in percentage
     {
      x=price/_Point*doorstep/100;
     }

   return((int)x);
  }

3.6. Ana İşlev - Renko Grafiği sınıflandırması

Renko grafiği sınıflandırmasının ana işlevi - "func_draw_renko". Bu işlev, grafiksel arabelleklerden (gösterge arabellekleri) ve hesaplama arabellek dizilerinin doldurulmasından sorumludur. Hesaplama arabellekleri, her bir tuğlanın bilgilerini depolar.

İşlevin girdi parametreleri, fiyatların ve çubukların oluşturma tarihlerinin veri dizileridir. Burada adım türü ve parametresi, ters filtre ve gölge çizim parametresi hakkında bilgi bulabilirsiniz.

İşlev iki kısma ayrılabilir: tuğla hesaplama numarası olan kısım ve hesaplama ve grafik arabellek doldurma bulunan kısım.

İşlevin başlangıcında, arabellekler boş kutuları kapatmak için sıfırlanır. Daha sonra yardımcı değişkenler girilir: adım için "doorstep_now" değişkeni kullanılır (yüzde adımında boyutunu değiştirmek için kullanılır), "point_go" son inşa edilen tuğladan olan mesafe hakkında bilgi depolar, "a" değişkeni tuğla hesaplama için kullanılır, "up_price_calc" ve "down_price_calc" - en son analiz edilen yüksek ve düşük fiyatlar, "type_box_calc" - en son analiz edilen tuğla türü (yukarı veya aşağı).

Her iki işlev parçası da bir döngüden oluşur, ikinci kısım ilkini tamamlar. Süreci ayrıntılı olarak analiz edin.

İlk döngü, kopyalanan tüm değerler üzerinden işlenir, «çubuklar" değeri, bir dizi kopyalanan veriden sorumludur (daha sonra ele alınacak olan bir "func_concolidation" işlevinde hesaplanır). Döngünün devamında, işlev tuğla boyutunun hesaplanmasına başlar. Her çubuğun kapanış fiyatı farklı olduğu için yüzde adımı kullanılıyorsa her çubuk için ayrı ayrı hesaplanmalıdır.

Koşullu if ifadesi fiyatın yönünü kontrol ederken, fiyatın bir veya daha fazla adım mesafesini geçmesi gerekir. Fiyat hareket yönü belirlendikten sonra bir önceki hareketin (son tuğlanın) durumu kontrol edilir. Bu, gösterge parametreleri filtre parametresini (ters çevirme için gerekli tuğla sayısı) içerdiği için yapılır. Tüm koşullar kontrol edildikten sonra döngü başlatılır, tuğlaların mevcut fiyat hareketini temsil ettiği kadar işlenir.

Görüntü çubukları hesaplanır, hesaplama arabellek dizileri boyut olarak değiştirilir ve sıfırlanır. Bundan sonra, ilk birkaç (ilk karşılaştırma sırasında kullanılır) hesaplama dizilerine birincil değerler atanır.

Gösterilen maksimum çubuk sayısı, olası tuğla sayısından azsa, fazladan tuğlalar hesaplanır ve düşük değer ile ilgili mesaj görüntülenir. Bu, grafiğin yanlış görüntülenmesini önlemek için yapılır.

Tuğla sayısı hesaplama değişkeni sıfırlanır ve ana döngü başlar. Önceki döngüden farklı olarak, ana döngü aynı zamanda arabellek dizilerinin hesaplanmasından ve tuğla sayacının sıfırlanmasından da sorumludur.

İşlevin sonunda grafik arabellekleri doldurulur.

//+------------------------------------------------------------------+
//| Func Draw Renko                                                  |
//+------------------------------------------------------------------+
void func_draw_renko(double &price[],   // prices array
                     double &date[],    // date array
                     int number_filter, // bricks number for reversal
                     bool draw_shadow,  // draw shadow
                     char type_doorstep,// step type
                     double doorstep)   // step
  {
//--- arrays reset
//--- drawing buffer arrays
   ZeroMemory(RENKO_close);
   ZeroMemory(RENKO_color);
   ZeroMemory(RENKO_high);
   ZeroMemory(RENKO_low);
   ZeroMemory(RENKO_open);
//--- additional variables
   int doorstep_now; // current step
   int point_go;     // passed points
//--- additional variables for bricks number calculating
   a=0;
   double up_price_calc=price[0];
   double down_price_calc=price[0];
   char type_box_calc=0;

   for(int z=0; z<bars; z++) //---> bricks calculating loop
     {
      //--- calculate step according to the current price
      doorstep_now=func_calc_dorstep(price[z],type_doorstep,doorstep);
      //--- if price rises
      if((price[z]-up_price_calc)/_Point>=doorstep_now)
        {
         //--- calculate points passed
         point_go=int((price[z]-up_price_calc)/_Point);
         //--- prices was rising or unknown price behavour
         if(type_box_calc==1 || type_box_calc==0)
           {
            for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
              {
               //--- add the next brick 
               a++;
               //--- add value of the next brick low price
               down_price_calc=up_price_calc;
               //--- add value of the next brick up price
               up_price_calc=down_price_calc+(doorstep_now*_Point);
               //--- set the brick type (up)
               type_box_calc=1;
              }
           }
         //--- price went down
         if(type_box_calc==-1)
           {
            if((point_go/doorstep_now)>=number_filter)
              {
               for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
                 {
                  //--- add the next brick
                  a++;
                  //--- set the next brick down price
                  down_price_calc=up_price_calc;
                  //--- set the next brick up price
                  up_price_calc=down_price_calc+(doorstep_now*_Point);
                  //--- set the brick type (up)
                  type_box_calc=1;
                 }
              }
           }
        }
      //--- if the price moves downwards
      if((down_price_calc-price[z])/_Point>=doorstep_now)
        {
         //--- calculate the points passed
         point_go=int((down_price_calc-price[z])/_Point);
         //--- if the price went downwards or the direction is unknown
         if(type_box_calc==-1 || type_box_calc==0)
           {
            for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
              {
               //--- add the next brick
               a++;
               //--- set the next brick low price value
               up_price_calc=down_price_calc;
               //--- set the next brick up price value
               down_price_calc=up_price_calc-(doorstep_now*_Point);
               //--- set the britck type (up)
               type_box_calc=-1;
              }
           }
         //--- the price moved upwards
         if(type_box_calc==1)
           {
            if((point_go/doorstep_now)>=number_filter)
              {
               for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
                 {
                  //--- add the next brick
                  a++;
                  //--- set the next brick down price value
                  up_price_calc=down_price_calc;
                  //--- set the next brick up price value
                  down_price_calc=up_price_calc-(doorstep_now*_Point);
                  //--- set the brick type (up)
                  type_box_calc=-1;
                 }
              }
           }
        }
     } //---< bricks calculate loop
//--- calculate the number of display bars
   int b=Bars(_Symbol,PERIOD_CURRENT);
//--- resize arrays
   ArrayResize(up_price,b);
   ArrayResize(down_price,b);
   ArrayResize(type_box,b);
   ArrayResize(time_box,b);
   ArrayResize(shadow_up,b);
   ArrayResize(shadow_down,b);
   ArrayResize(number_id,b);
//--- resize calculation buffers array
   ZeroMemory(up_price);
   ZeroMemory(down_price);
   ZeroMemory(type_box);
   ZeroMemory(time_box);
   ZeroMemory(shadow_up);
   ZeroMemory(shadow_down);
   ZeroMemory(number_id);
//--- fill arrays with the initial values
   up_price[0]=price[0];
   down_price[0]=price[0];
   type_box[0]=0;
//--- calculate odd bricks number
   int l=a-b;
   int turn_cycle=l/(b-1);
   int turn_rest=(int)MathMod(l,(b-1))+2;
   int turn_var=0;
//--- message of partially displayed bricks
   if(a>b)Alert("More bricks than can be placed on the chart, the step is small");

   a=0; //--- reset bricks claculating variable
   for(int z=0; z<bars; z++) //---> Main loop
     {
      //--- calculate the step according to the price
      doorstep_now=func_calc_dorstep(price[z],type_doorstep,doorstep);
      //---if the price moves upwards
      if((price[z]-up_price[a])/_Point>=doorstep_now)
        {
         //--- calculate the points passed
 point_go=int((price[z]-up_price[a])/_Point);
         //--- price moved upwards or its behavour is unknown
         if(type_box[a]==1 || type_box[a]==0)
           {
            for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
              {
               a++; //--- add the next brick
               if((a==b && turn_var<turn_cycle) || (turn_var==turn_cycle && turn_rest==a))
                 {
                  up_price[0]=up_price[a-1];
                  a=1;        // bricks calculator reset
                  turn_var++; // calculator of loops reset
                 }
               //--- the next brick low price value
               down_price[a]=up_price[a-1];
               //--- set the brick up price 
               up_price[a]=down_price[a]+(doorstep_now*_Point);

               //--- set the up shadow value
               if(shadow_print==true) shadow_up[a]=price[z]; //to the upper price level
               else shadow_up[a]=up_price[a];                // to the up price level

               //--- set the low price value(to the brick price level)
               shadow_down[a]=down_price[a];
               //--- value of the brick closing time
               time_box[a]=(datetime)Date[z];
               //--- set the brick type (up)
               type_box[a]=1;
               //--- set the index
               number_id[a]=z;
              }
           }
         //--- the price moved downwards
         if(type_box[a]==-1)
           {
            if((point_go/doorstep_now)>=number_filter)
              {
               for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
                 {
                  a++; //--- add the next brick

                  if((a==b && turn_var<turn_cycle) || (turn_var==turn_cycle && turn_rest==a))
                    {
                     up_price[0]=up_price[a-1];
                     a=1;        // bricks counter reset
                     turn_var++; // loops reset cycle
                    }
                  //--- set the next brick low price value
                  down_price[a]=up_price[a-1];
                  //--- set the next brick up price
                  up_price[a]=down_price[a]+(doorstep_now*_Point);

                  //--- set the up shadow value
                  if(shadow_print==true) shadow_up[a]=price[z]; // at the up price level
                  else shadow_up[a]=up_price[a];                // the brick up price level

                  //--- set of the down price value (the brick price level)
                  shadow_down[a]=down_price[a];
                  //--- set the close time
                  time_box[a]=(datetime)Date[z];
                  //--- set the up brick
                  type_box[a]=1;
                  //--- set index
                  number_id[a]=z;
                 }
              }
           }
        }

      //--- if price moves upwards
      if((down_price[a]-price[z])/_Point>=doorstep_now)
        {
         //--- calculate the points passed
         point_go=int((down_price[a]-price[z])/_Point);
         //--- price moved downwards or the direction is unknown
         if(type_box[a]==-1 || type_box[a]==0)
           {
            for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
              {
               a++; //--- add the next brick
               if((a==b && turn_var<turn_cycle) || (turn_var==turn_cycle && turn_rest==a))
                 {
                  down_price[0]=down_price[a-1];
                  a=1;        // set the bricks counter to zero
                  turn_var++; // reset loop counter
                 }
               //--- set the next brick down price
               up_price[a]=down_price[a-1];
               //--- set the next brick up price
               down_price[a]=up_price[a]-(doorstep_now*_Point);

               //--- set the down shadow value 
               if(shadow_print==true) shadow_down[a]=price[z]; //--- the last lowest price level
               else shadow_down[a]=down_price[a];              //--- low price level

               //--- set the up price value
               shadow_up[a]=up_price[a];
               //--- set the brick close time
               time_box[a]=set the down shadow value];
               //--- set the brick type (down)
               type_box[a]=-1;
               //--- set index
               number_id[a]=z;
              }
           }
         //--- price moved upwards
         if(type_box[a]==1)
           {
            if((point_go/doorstep_now)>=number_filter)
              {
               for(int y=point_go; y>=doorstep_now; y-=doorstep_now)
                 {
                  a++; //--- add the next brick
                  if((a==b && turn_var<turn_cycle) || (turn_var==turn_cycle && turn_rest==a))
                    {
                     down_price[0]=down_price[a-1];
                     a=1;        // reset bricks counter
                     turn_var++; // reset loop counter
                    }

                  up_price[a]=down_price[a-1]; //--- set the next brick down price
                  down_price[a]=up_price[a]-(doorstep_now*_Point); //--- set the up price value

                  //--- set the down shadow value 
                  if(shadow_print==true) shadow_down[a]=price[z]; // at the lowest price level
                  else shadow_down[a]=down_price[a];              // at the down price level

                  //--- set the up price level
                  shadow_up[a]=up_price[a];
                  //--- set the brick close time
                  time_box[a]=(datetime)Date[z];
                  //--- set the brick type (down)
                  type_box[a]=-1;
                  //--- index set
                  number_id[a]=z;
                 }
              }
           }
        }
     } //---< Main loop

//--- fill the draw buffer
   int y=a;
   for(int z=0; z<a; z++)
     {
      if(type_box[y]==1)RENKO_color[z]=0;
      else RENKO_color[z]=1;
      RENKO_open[z]=down_price[y];
      RENKO_close[z]=up_price[y];
      RENKO_high[z]=shadow_up[y];
      RENKO_low[z]=shadow_down[y];
      y--;
     }
  }


3.7. "Trend çizgisi" ve "dikdörtgen" grafiksel nesneleri oluşturma işlevi

"Trend çizgisi" grafiksel nesnesi veya "func_create_trend_line" oluşturma işlevi ve "dikdörtgen" grafiksel nesnesi veya "func_create_square_or_rectangle" oluşturma işlevi, OBJ_RECTANGLE ve OBJ_TREND referansında belirtilen verilere dayanmaktadır. "Renko" grafiğinde grafiksel nesneler oluşturmak ve ana grafik üzerinde "ZigZag" oluşturmak için kullanılırlar.

//+------------------------------------------------------------------+
//| Func Create Trend Line                                           |
//+------------------------------------------------------------------+
void func_create_trend_line(string name,
                            double price1,
                            double price2,
                            datetime time1,
                            datetime time2,
                            int width,
                            color color_line)
  {
   ObjectCreate(0,name,OBJ_TREND,0,time1,price1,time2,price2);
//--- set the line color
   ObjectSetInteger(0,name,OBJPROP_COLOR,color_line);
//--- set the line display style
   ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
//--- set the width of the line
   ObjectSetInteger(0,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or in the (true) background
   ObjectSetInteger(0,name,OBJPROP_BACK,false);
//--- enable (true) or disable (false) the mode of the left line display
   ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,false);
//--- enable (true) or disable (false) the right line display
   ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,false);
  }
//+------------------------------------------------------------------+
//| Func Create Square or Rectangle                                  |
//+------------------------------------------------------------------+
void func_create_square_or_rectangle(string name,
                                     double price1,
                                     double price2,
                                     datetime time1,
                                     datetime time2,
                                     int width,
                                     color color_square,
                                     bool fill)
  {
//--- create rectangle according to the setpoints 
   ObjectCreate(0,name,OBJ_RECTANGLE,0,time1,price1,time2,price2);
//--- set the rectangle color
   ObjectSetInteger(0,name,OBJPROP_COLOR,color_square);
//--- set style of rectangle color
   ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID);
//--- set lines width
   ObjectSetInteger(0,name,OBJPROP_WIDTH,width);
//--- activate (true) or disactivate (false) mode of rectangle colouring
   ObjectSetInteger(0,name,OBJPROP_FILL,fill);
//--- display in the foreground (false) or in the background (true)
   ObjectSetInteger(0,name,OBJPROP_BACK,false);
  }


3.8. Ana grafikteki "Renko" yapısı

Hesaplama ortak arabellek dizilerinin kullanılması nedeniyle, Renko grafiği veya "func_draw_renko_main_chart" işlevi oldukça kompakttır.

Giriş parametreleri şunları içerir: çerçeveleriyle birlikte yukarı ve aşağı tuğla, iki tür çerçeve genişliği (birincisi tuğla için kullanılır, ikincisi bunun çerçevesi için), üç görüntüleme seçeneği ("tuğlalar", renkleri ve çerçeveleri).

İlk olarak, nesnelerin adlarına sahip değişkenler bildirilir, ardından her nesnenin oluşturulan adıyla döngü açılır ve önceki tuğla türüne bağlı olarak "trend çizgisi" ve "dikdörtgen" grafik nesnelerinin işlevi başlatılır. Parametreler, hesaplama arabelleği dizilerinden alınır.

//+------------------------------------------------------------------+
//| Func Draw Renko Main Chart                                       |
//+------------------------------------------------------------------+
void func_draw_renko_main_chart(color color_square_up,
                                color color_square_down,
                                color color_frame_up,
                                color color_frame_down,
                                int width_square,
                                int width_frame,
                                bool square,
                                bool fill,
                                bool frame)
  {
   string name_square;
   string name_frame;

   for(int z=2; z<=a; z++)
     {
      name_square=IntegerToString(magic_numb)+"_Square_"+IntegerToString(z);
      name_frame=IntegerToString(magic_numb)+"_Frame_"+IntegerToString(z);
      if(type_box[z]==1)
        {
         if(square==true)func_create_square_or_rectangle(name_square,up_price[z],down_price[z],time_box[z-1],time_box[z],width_square,color_square_up,fill);
         if(frame==true)func_create_square_or_rectangle(name_frame,up_price[z],down_price[z],time_box[z-1],time_box[z],width_frame,color_frame_up,false);
        }
      if(type_box[z]==-1)
        {
         if(square==true)func_create_square_or_rectangle(name_square,up_price[z],down_price[z],time_box[z-1],time_box[z],width_square,color_square_down,fill);
         if(frame==true)func_create_square_or_rectangle(name_frame,up_price[z],down_price[z],time_box[z-1],time_box[z],width_frame,color_frame_down,false);
        }
     }
  }

3.9. Ana grafikteki "ZigZag" yapısı

Göstergeye bir sonraki ek türü, "ZigZag" grafik işlevi veya "func_draw_zig_zag"dır.

Girdi parametreleri: çizim yolu (maksimum veya minimum fiyatlarda veya grafik noktalarında), çizgi genişliği, yukarı veya aşağı çizgi rengi.

4. resimde "zig_zag_shadow" parametre değişikliği görülmektedir. "True" açıksa gösterge gölge noktalara (minimum ve maksimum fiyatlar) "ZigZag" çizgileri çizer, "false" seçeneğinde "ZigZag" çizgileri "Renko" maksimum ve minimum noktalarına çizilir.


Şek.4. "zig_zag_shadow" parametresinin EURUSD, H1, 10 puan üzerindeki etkisi.

Şek.4. "zig_zag_shadow" parametresinin EURUSD, H1, 10 puan üzerindeki etkisi.

"Trend çizgisi" nesnesini oluşturmak için iki nokta (başlangıç ve bitiş) gereklidir, fiyat parametresi için iki değişken ve tarih parametresi için iki değişken girin. Koşullu ifadeler, ilk tuğla tipine bağlı olarak ilk noktayı ayarlarsa.

Tüm nesneleri oluşturan döngü başlatılır. Gördüğünüz gibi, ilk nokta zaten ayarlandığından döngü ikinci tuğla analizinden başlıyor. Ardından if koşullu ifade, tuğlanın türünü (fiyat davranışı) kontrol eder. Nesne adının değişkeni doldurulur ve hareket değişikliğine bağlı olarak döngü bölünür. Sırayla, çizim yöntemine bağlı olarak iki varyanta ayrılır.

Minimum ve maksimum fiyatlarda görüntüleniyorsa, Price_high[] ve Price_low[] veri dizileri yakın minimum ve maksimum noktaları arar. Arama, yakındaki çubuklarla sınırlandırılmıştır.

Grafik noktalarında sınıflandırılmışsa, veriler arabellek dizilerinden atanır.

"Trend çizgisi" oluşturma işlevi çağrılır. İşlev, "ZigZag"ın analizini ve grafiğini tamamlar.

//+------------------------------------------------------------------+
//| Func Draw Zig Zag                                                |
//+------------------------------------------------------------------+
void func_draw_zig_zag(bool price_shadow,
                       int line_width,
                       color line_color_up,
                       color line_color_down)
  {
   double price_1=0;
   double price_2=0;
   datetime date_1=0;
   datetime date_2=0;

   if(type_box[1]==1)price_1=down_price[1];
   if(type_box[1]==-1)price_1=up_price[1];
   date_1=time_box[1];
   int id=0; //  Low & High array storing variable
   int n=0;  // variable for name forming

   string name_line; //--- variable responsible for the "trend line" name

   for(int z=2; z<=a; z++)
     {
      if(type_box[z]!=type_box[z-1])
        {
         n++;
         name_line=IntegerToString(magic_numb)+"_Line_"+IntegerToString(n);
         if(type_box[z]==1)
           {
            if(price_shadow==true)
              {
               id=number_id[z-1];
               if((id-1)>0 && Price_low[id-1]<Price_low[id])id--;
               if(Price_low[id+1]<Price_low[id])id++;
               price_2=Price_low[id];
               date_2=(datetime)Date[id];
              }
            else
              {
               price_2=down_price[z-1];
               date_2=time_box[z-1];
              }
            func_create_trend_line(name_line,price_1,price_2,date_1,date_2,line_width,line_color_down);
            price_1=price_2;
            date_1=date_2;
           }
         if(type_box[z]==-1)
           {
            if(price_shadow==true)
              {
               id=number_id[z-1];
               if((id-1)>0 && Price_high[id-1]>Price_high[id])id--;
               if(Price_high[id+1]>Price_high[id])id++;
               price_2=Price_high[id];
               date_2=(datetime)Date[id];
              }
            else
              {
               price_2=up_price[z-1];
               date_2=time_box[z-1];
              }
            func_create_trend_line(name_line,price_1,price_2,date_1,date_2,line_width,line_color_up);
            price_1=price_2;
            date_1=date_2;
           }
        }
     }
  }

3.10. Önceden oluşturulmuş grafiksel nesneleri silme

Sihirli sayı, göstergenin nesnelerini belirlemek için kullanılır. Tek bir grafik üzerinde birkaç göstergenin başlatılmasını ve nesneleri silme işlemini basitleştirir.

Sonraki işlev, nesneleri veya "func_delete_objects"i silme işlevidir. Ad (nesnelere bağlı olarak ayarlanır: trend çizgisi veya dikdörtgen) ve nesne sayısı iki giriş parametresidir. İşlev, nesneleri seçer ve önceden atanmış ada sahip nesneleri siler.

//+------------------------------------------------------------------+
//| Func Delete Objects                                              |
//+------------------------------------------------------------------+
void func_delete_objects(string name,
                         int number)
  {
   string name_del;
   for(int x=0; x<=number; x++)
     {
      name_del=name+IntegerToString(x);
      ObjectDelete(0,name_del);
     }
  }

Tüm gösterge nesnelerini silmek için tüm işlevleri birleştiren işlev oluşturuldu.

//+------------------------------------------------------------------+
//| Func All Delete                                                  |
//+------------------------------------------------------------------+
void func_all_delete()
  {
//--- the graphical objects calculating
   obj=ObjectsTotal(0,-1,-1);
//--- all indicator graphical objects deleting
   func_delete_objects(IntegerToString(magic_numb)+"_Line_",obj);
   func_delete_objects(IntegerToString(magic_numb)+"_Square_",obj);
   func_delete_objects(IntegerToString(magic_numb)+"_Frame_",obj);
//--- the chart redrawing
   ChartRedraw(0);
  }


3.11. Seviye oluşturma işlevi

Seviye oluşturma için "func_create_levels" işlevi, gösterge penceresindeki grafiğin görüntülenmesini basitleştirir. Yalnızca iki giriş parametresine sahiptir: oluşturulan seviyelerin sayısı ve renkleri.

İşlevin gövdesinde, görüntülenen seviyelerin sayısını ayarlamak için IndicatorSetInteger kullanılır, ardından her seviye için fiyat ve renk ayarlanır.

//+------------------------------------------------------------------+
//| Func Create Levels                                               |
//+------------------------------------------------------------------+
void func_create_levels(int level_number,
                        color level_color)
  {
//--- set the number of levels in the indicator window
   IndicatorSetInteger(INDICATOR_LEVELS,level_number);
 which brick is taken to draw levels
   int k=0;
   if(a>level_number)k=a-level_number;
//--- set levels prices
   for(int z=0;(z<=level_number && k<=a); z++,k++)
     {
      IndicatorSetDouble(INDICATOR_LEVELVALUE,z,up_price[k]);
      IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,level_color);
     }
  }

3.12. Konsolidasyon işlevi

Tüm işlevleri birleştirmek için "func_consolidation" işlevi oluşturuldu.

İşlev, yürütülen tüm işlevleri çağırır.

//+------------------------------------------------------------------+
//| Func Consolidation                                               |
//+------------------------------------------------------------------+
void func_concolidation()
  {
//--- deleting all the graphical objects of the indicator
   func_all_delete();
//--- the current date
   date_stop=TimeCurrent();
//--- the initial date changing due to the restricted buffer size
   if((bars=Bars(_Symbol,time_frame,date_start,date_stop))>ArraySize(Price))
     {
      date_start=func_calc_date_start(date_start,date_stop);
      Alert("The initial date was changed due to the lack of the chart size");
      date_change=true;
      //--- calculation of bars on the taken timeframe
      bars=Bars(_Symbol,time_frame,date_start,date_stop);
     }
//---
   bool result_copy_price=func_copy_price(Price,time_frame,date_start,date_stop,type_price);
   bool result_copy_date=func_copy_date(Date,time_frame,date_start,date_stop);
//--- change the date parameter
   if(result_copy_price=true && result_copy_date==true)date_change=false;
//---
   if(zig_zag_shadow==true)
     {
      func_copy_price(Price_high,time_frame,date_start,date_stop,2);
      func_copy_price(Price_low,time_frame,date_start,date_stop,3);
     }
//---
   func_draw_renko(Price,Date,filter_number,shadow_print,type_step,step);
   if(zig_zag==true)func_draw_zig_zag(zig_zag_shadow,zig_zag_width,zig_zag_color_up,zig_zag_color_down);
//---
   func_draw_renko_main_chart(square_color_up,square_color_down,frame_color_up,frame_color_down,square_width,frame_width,square_draw,square_fill,frame_draw);
   func_create_levels(levels_number,levels_color);
//--- redraw the chart
   ChartRedraw(0);
  }

3.13. OnCalculate() ve OnChartEvent() işlevleri

OnCalculate() işlevine geçmeden önce, yeni çubuğu analiz eden "func_new_bar" işlevine bir göz atalım.

IsNewBar içinde açıklanan basitleştirilmiş işlevdir.

//+------------------------------------------------------------------+
//| Func New Bar                                                     |
//+------------------------------------------------------------------+
bool func_new_bar(ENUM_TIMEFRAMES period_time)
  {
//---
   static datetime old_times; // array for storing old values
   bool res=false;            // analysis result variable 
   datetime new_time[1];      // new bar time
//---
   int copied=CopyTime(_Symbol,period_time,0,1,new_time); // copy the time of the new bar into the new_time box 
//---
   if(copied>0) // все ок. data have been copied
     {
      if(old_times!=new_time[0])    // if the bar's old time is not equal to new one
        {
         if(old_times!=0) res=true; // if it is not the first launch, true = new bar
         old_times=new_time[0];     // store the bar's time
        }
     }
//---
   return(res);
  }

OnCalculate() işlevi, grafik güncellemesi sırasında yeni bir çubuk oluşturulursa tüm işlevlerin konsolidasyonunu başlatır. 

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   if(func_new_bar(time_redraw)==true)
     {
      func_concolidation();
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

OnChartEvent() işlevi, "C"ye basılarak tüm grafiksel nesneleri siler, "R"ye basılması, grafiğin yeniden çizilmesini (konsolidasyon işlevi) başlatır.

//+------------------------------------------------------------------+
//| OnChartEvent                                                     |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // event ID 
                  const long& lparam,   // long type event parameter
                  const double& dparam, // double type event parameter
                  const string& sparam) // string type event parameter
  {
//--- Keyboard button pressing event
   if(id==CHARTEVENT_KEYDOWN)
     {
      if(lparam==82) //--- "R" key has been pressed
        {
         //--- call of the consolidation function
         func_concolidation();
        }
      if(lparam==67) //--- "C" key has been pressed
        {
         //--- deletion of all objects of the indicator
         func_all_delete();
        }
     }
  }


3.14. OnDeinit() İşlevi

Son olarak, OnDeinit() işlevi. Bu işlev, göstergenin tüm grafiksel nesnelerini silme işlevini başlatır.

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+ 
void OnDeinit(const int reason)
  {
//--- delete all graphical objects of the indicator
   func_all_delete();
  }


4. Uygulamada Renko grafiğini kullanma

Renko grafiği, fiyat hareketleri stratejisine göre oluşturulmuştur.

En popüler stratejiyle başlayalım: yukarı doğru hareket eden tuğla aşağı doğru hareket etmeye başladığında sat ve tersi durumda satın al.

Bu, Şekil 5'te gösterilmiştir:


Şek.5. Standart Renko grafiği (EURUSD H4, 20 puan)

Şek.5. Standart Renko grafiği (EURUSD H4, 20 puan)

Şekil 5, piyasa girişinin altı noktasını (A,B,C,D,E,F) göstermektedir.

"A" noktasında yukarı tuğla, aşağı tuğlaya dönüşür.

(B,C,D) noktalarındaki gibi ters tuğla tek hareketle oluşturulur. Ancak "E" noktasında tek hareketle iki tuğla oluşturuldu, aşağı doğru gölgeler aynı seviyede oluşturuldu.

Bu durumda giriş "E" ve "F" noktaları arasında mümkündür. Başarılı bir giriş değil, fiyat ters yönde hareket ettiğinden, analojik durum "F" noktasında: bir hareketin iki tuğla oluşturduğu yer. Yukarı gölgeler aynı seviyede. Güçlü bir hareket olsa da fiyat yönünü değiştirmiyor.

Bunun anlamı, piyasaya en uygun girişin, tek bir hareketle bir ters tuğla (gölgelere bakın) oluşturulduğu zamandır. Aynı anda iki tuğla oluşturulursa, bu giriş güvenli olmayabilir.

Bu grafikteki "ZigZag" sınıflandırması grafiksel analiz için kullanılabilir. Şekil 6 birkaç örnek göstermektedir: "destek" ve "direnç" çizgileri, "baş ve omuzlar" model ayarı.


Şek.6. Grafiksel analiz (GBPUSD H4, 20 puan)

Şek.6. Grafiksel analiz (GBPUSD H4, 20 puan)

"Eşit uzaklıkta kanal" grafiksel analizi Şekil 7'de gösterilmektedir.

Gösterge, zaman dilimini analiz edecek şekilde ayarlanmıştır ve sınıflandırma, dört saatlik zaman diliminde görüntülenir.

Bu tür ayarlar, aynı anda birkaç zaman diliminde özel takip sinyallerine izin verir; bu, bir göstergenin bir zaman diliminde ve diğerinin ikinci zaman diliminde kullanılabileceği anlamına gelir.


Şek.7. "Eşit uzaklıkta kanal" USDCHF, H4, H1, 20 puandaki ayarların analizi.

Şek.7. "Eşit uzaklıkta kanal" USDCHF, H4, H1, 20 puandaki ayarların analizi.

Şek. 8, bir grafikteki farklı zaman dilimlerinin bir örneğini daha temsil etmektedir.

Zaman grafiği olası kapanış dönüşlerini gösterir, dört saatlik grafik gereksiz sinyalleri siler, günlük grafik eğilim hareketlerinin uzun pozisyon sürelerini onaylar.


Şek.8. GBPUSD, H1, H4 ve D1'deki Renko göstergesi

Şek.8. GBPUSD, H1, H4 ve D1'deki Renko göstergesi

Bir başka gösterge örneği Şekil 9'dadır. Kural diyor ki: En yakın kırmızı tuğlalar arasında, aralarında en az bir mavi tuğla olacak şekilde yukarı doğru bir çizgi oluşturun ve tuğla, çizginin altında oluşturulduktan sonra satış yapın.

Ve tam tersi: en yakın mavi tuğlalar arasında, aralarında en az bir kırmızı tuğla olacak şekilde aşağı doğru bir çizgi oluşturun ve tuğla, çizginin üzerinde oluşturulduktan sonra satış yapın.

Renkler Şekil 9'a göre belirtilmiştir. Şekil 9. Mavi ve kırmızı oklar, çizgi çizme yerlerini ve büyük oklar, satış ve satın alma sinyallerini gösterir.

Şek.9. GBPUSD, H4, 25 puan göstergesi örneği

Şek.9. GBPUSD, H4, 25 puan göstergesi örneği

Sonuç

Renko grafiği, yeni başlayanlar ve profesyonel yatırımcılar için ilginçtir. Aradan uzun yıllar geçmesine rağmen hala piyasalarda kullanılmaktadır.

Bu makalede grafiğe dikkatinizi çekmek ve Renko grafik analizini geliştirmek istedim. Renko grafik yapımının detaylı yöntemini göstermeye çalıştım.

Gösterge için yeni fikirleri ve iyileştirmeleri değerlendirmekten ve belki de bunları gelecekte uygulamaktan memnuniyet duyacağım. Gösterge uygulamasının birkaç yolu vardır, kendi uygulama yöntemlerinizi de bulabilirsiniz.

İlginiz için teşekkürler! Size başarılı alım satımlar ve yeni alım satım stratejisi uygulaması diliyorum.


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

Ekli dosyalar |
abcr.mq5 (77.52 KB)
Bir MQL5 Expert Advisor'dan GSM Modem ile Çalışma Bir MQL5 Expert Advisor'dan GSM Modem ile Çalışma
Şu anda bir alım satım hesabının rahat bir şekilde uzaktan izlenmesi için makul sayıda araç var: mobil terminaller, push bildirimleri, ICQ ile çalışma. Ama hepsi internet bağlantısı gerektiriyor. Bu makale, mobil İnternet olmadığında bile çağrılar ve metin mesajları yoluyla alım satım terminalinizle iletişim halinde kalmanızı sağlayacak bir Expert Advisor oluşturma sürecini açıklamaktadır.
MQL5 Yemek Kitabı - Çok Para Birimli Expert Advisor ve MQL5'te Bekleyen Talimatlarla Çalışma MQL5 Yemek Kitabı - Çok Para Birimli Expert Advisor ve MQL5'te Bekleyen Talimatlarla Çalışma
Bu sefer, bekleyen Satın Al Durdur ve Sat Durdur talimatlarıyla çalışmayı temel alan bir alım satım algoritmasına sahip çok para birimli bir Expert Advisor oluşturacağız. Bu makale şu konuları ele almaktadır: belirli bir zaman aralığında alım satım yapma, bekleyen talimatları verme/değiştirme/silme, son pozisyonun Kar Al veya Zarar Durdur'da kapatılıp kapatılmadığını kontrol etme ve her bir sembol için yatırım geçmişinin kontrolü.
MetaTrader 5'te sürekli vadeli işlem sözleşmeleri MetaTrader 5'te sürekli vadeli işlem sözleşmeleri
Vadeli işlem sözleşmelerinin kısa ömürleri teknik analizlerini karmaşık hale getirir. Kısa grafikleri teknik olarak analiz etmek zordur. Örneğin UX-9.13 Ukrayna Hisse stok endeksinin günlük grafiğindeki çubuk sayısı 100'den fazladır. Bu nedenle, yatırımcı sentetik uzun pozisyonlu vadeli işlem sözleşmeleri oluşturur. Bu makale, MetaTrader 5 terminalinde farklı tarihlere sahip vadeli işlem sözleşmelerinin nasıl birleştirileceğini açıklamaktadır.
MQL5 Cookbook: Fiyat Farklılığını Analiz Etmek İçin Çoklu Sembollü Bir Göstergenin Geliştirilmesi MQL5 Cookbook: Fiyat Farklılığını Analiz Etmek İçin Çoklu Sembollü Bir Göstergenin Geliştirilmesi
Bu yazıda, belirli bir zaman diliminde fiyat farklılaşmasını analiz etmek için çoklu sembollü bir göstergenin geliştirilmesini ele alacağız. Temel konular, çoklu para birimi göstergelerinin programlanmasıyla ilgili bir önceki makalede tartışılmıştı "MQL5 Yemek Kitabı: MQL5'te Çok Sembollü Bir Volatilite Göstergesi Geliştirme". Bu sefer sadece çarpıcı biçimde değiştirilmiş olan yeni özellikler ve işlevler üzerinde duracağız. Çoklu para birimi göstergelerinin programlanmasında yeniyseniz, önce bir önceki makaleyi okumanızı tavsiye ederim.