English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5'te Tik Göstergeleri Oluşturma

MQL5'te Tik Göstergeleri Oluşturma

MetaTrader 5Göstergeler | 9 Aralık 2021, 10:45
198 0
Denis Zyatkevich
Denis Zyatkevich

Giriş

Alım satımda, fiyat değişikliklerinin ayrıntılı resmini görmek için mümkün olduğunca fazla bilgiye sahip olunması istenir. Tik grafiğini kullanabilirsiniz. MQL5'te bir tik grafiği oluşturmaya çalışalım.

Bu makalede iki göstergenin oluşturulması açıklanmaktadır: bir tik fiyat grafiği ve belirli sayıda tik işareti içeren mumları çizen "Tik Mumları" grafiği. Dikkate alınan göstergelerin her biri, istemci terminali yeniden başlatıldıktan sonra göstergenin verilerinin oluşturulması için alınan fiyat değerlerini dosyaya yazar (bu veriler diğer programlar tarafından da kullanılabilir).

Tik Göstergesi Oluşturma

MQL5'te tik verilerini grafikte çizen bir gösterge yazalım. Böyle bir göstergenin bir örneği Şekil 1'de sunulmuştur:

Şekil 1. Tik grafiği örneği

Gösterge iki satır çizmektedir: Teklif ve Satış fiyatları. Her birinin çizimi göstergenin seçeneklerinde kapatılabilir.

Gösterge, aracıdan alınan geçerli sembolün fiyatlarını aşağıdaki biçimde bir metin dosyasına kaydeder: Sunucu süresi, Teklif fiyatı ve Satış fiyatı:

2010.03.26 19:43:02 1.33955 1.33968

Dosya adı finansal enstrüman adına karşılık gelir (örneğin, EURUSD.txt). Dosyalar aşağıdaki yolda bulunur: MT5_Folder\MQL5\Files. Bir dosya ve dosya adı öneki için ek dizin göstergenin seçeneklerinde belirtilebilir (aynı sembole sahip grafiklere eklenmiş birkaç gösterge varsa yararlı olabilir).

Bir gösterge oluşturmak için MetaTrader 5 istemci terminalini başlatın ve F4 tuşuna basarak MetaQuotes Dil Düzenleyicisini başlatın. Bir programın kodunu yazmaya başlayalım.

Göstergenin fiyat grafiğinin altında ayrı bir pencerede çizilmesi gerektiğini belirteceğiz:

// indicator in a separate window
#property indicator_separate_window

İki gösterge satırı (sırasıyla Teklif ve Satış fiyatları) çizilmelidir, bu nedenle iki grafik çizimi kullanmalıyız:

// two graphic plots are used: for Bid and Ask lines
#property indicator_plots 2

Grafikte çizilecek verileri içeren iki gösterge tamponunu belirtmeliyiz:

// two indicator's buffers
#property indicator_buffers 2

Göstergenin her satırı için DRAW_LINE (çizgi) çizim türünü, STYLE_SOLID (düz çizgi) çizim stilini ve "Teklif" ve "Satış" metin etiketlerini tanımlayalım:

// drawing type of a Bid line
#property indicator_type1 DRAW_LINE
// drawing color of a Bid line
#property indicator_color1 Red
// drawing style of a Bid line
#property indicator_style1 STYLE_SOLID
// text label of a Bid line
#property indicator_label1 "Bid"
// drawing type of an Ask line
#property indicator_type2 DRAW_LINE
// drawing color of an Ask line
#property indicator_color2 Blue
// drawing style of an Ask line
#property indicator_style2 STYLE_SOLID
// text label of an Ask line
#property indicator_label2 "Ask"

 Göstergenin seçenekler menüsünde değerleri kullanıcı tarafından değiştirilebilen giriş değişkenlerini belirtelim.

// the BidLineEnable indicates showing of a Bid line
input bool BidLineEnable=true; // Show Bid Line
// the AskLineEnable indicates showing of an Ask line
input bool AskLineEnable=true; // Show Ask Line
// the path_prefix defines a path and file name prefix
input string path_prefix=""; // FileName Prefix

BidLineEnable  ve AskLineEnable  değişkenleri, göstergede Teklif ve Satış satırlarının gösterilmesini etkinleştirmenize ve devre dışı bırakmanıza olanak tanır. path_prefix değişkeni, dosya adından önce bulunan dosya adı önekini belirtmenizi sağlar. Bu değişkeni kullanarak, bir alt dizinin yolunu da belirtebilirsiniz, örneğin path_prefix = "MyBroker/test_" ise, dosyaların yolu aşağıdaki gibi olacaktır: "MetaTrader5_Folder\MQL5\Files\MyBroker", "EURUSD" sembolü için dosya adı "test_EURUSD.txt" olacaktır.

Global seviyede, göstergenin çeşitli fonksiyonlarında kullanılacak değişkenleri bildirelim, bu değişkenlerin değerleri göstergenin çağrıları arasında kaydedilir:

// the tick_stored variable is a number of served quotes
int ticks_stored;
// the BidBuffer[] and AskBuffer[] arrays - are indicator's buffers
double BidBuffer[],AskBuffer[];

tick_stored değişkeni, kullanılabilir teklif sayısını depolamak için kullanılır. BidBuffer[] ve AskBuffer[], gösterge tamponları olarak kullanılan dinamik dizilerdir, grafikte Teklif ve Satış satırları olarak çizilen fiyat verileri bu tamponlarda depolanır.

OnInit fonksiyonu, BidBuffer[] ve AskBuffer[]  dizilerinin çizim için verileri içerdiğini gösterir. Sıfıra eşit gösterge tamponu değerlerine sahip verilerin grafikte çizilmemesi gerektiğini belirtelim.

void OnInit()
  {
   // the BidBuffer[] is an indicator buffer
   SetIndexBuffer(0,BidBuffer,INDICATOR_DATA);
   // the AskBuffer[] is an indicator buffer
   SetIndexBuffer(1,AskBuffer,INDICATOR_DATA);
   // setting EMPTY_VALUE for a Bid line
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   // setting EMPTY_VALUE for an Ask line
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
  }

Şimdi OnCalculate fonksiyonunu oluşturuyoruz ve fonksiyon çağrıldığında fonksiyona geçirilen tüm parametreleri listeleyeceğiz: 

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[])

Değişkenleri bildirelim:

// the file_handle variable is a file handle
// the BidPosition and AskPosition - are positions of Bid and Ask prices in the string;
// the line_string_len is a length of a string, read from the file, i is a loop counter;
int file_handle,BidPosition,AskPosition,line_string_len,i;
// the last_price_bid is the last Bid quote
double last_price_bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
// the last_price_ask is the last Ask quote
double last_price_ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
// the filename is a name of a file, the file_buffer is a string, 
// used as a buffer for reading and writing of string data
string filename,file_buffer;

Bir tamsayı türündeki file_handle değişkeni, dosyanın tanıtıcısını dosya işlemlerinde depolamak için kullanılacaktır, BidPosition ve AskPosition dizedeki Teklif ve Satış fiyatlarının başlangıç pozisyonlarının depolanmasını sağlamak için kullanılacaktır, line_string_len dize uzunluğu için kullanılacaktır, dosyadan okunacaktır, i değişkeni döngü sayacı olarak kullanılacaktır. Son alınan Teklif ve Satış fiyatlarının değerleri last_price_bid ve last_price_ask değişkenlerinde depolanır. Dosya adı dizesi değişkeni dosya adını depolamak için kullanılır, file_buffer dosyaya okuma ve yazma için kullanılan bir dizedir.

Dosya adı path_prefix değişkeninden, finansal enstrümanın adından ve ".txt" dosya uzantısından oluşturulur. StringConcatenate fonksiyonunun kullanımı, bellekte daha hızlı ve daha ekonomik çalıştığı için, ekleme operatörünü kullanarak dizelerin birleştirilmesine göre daha fazla tercih edilir.

// File name formation from the path_prefix variable, name
// of financial instrument and ".Txt" symbols
StringConcatenate(filename,path_prefix,Symbol(),".txt");

Dosyayı, daha sonra kullanım için FileOpen fonksiyonunu kullanarak açıyoruz:

// Opening a file for reading and writing, codepage ANSI, shared reading mode
file_handle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_ANSI|FILE_SHARE_READ);

Verileri okuyup dosyaya yazacağımız için FILE_READ ve FILE_WRITE bayraklarını kullanıyoruz. FILE_ANSI bayrağı, ANSI kod sayfasının kullanılacağını gösterir (varsayılan Unicode'dur), FILE_SHARE_READ bayrağı, paylaşılan erişimin çalışırken diğer uygulamalar tarafından okunmasına izin verildiği anlamına gelir.

Göstergenin ilk başlatılışında herhangi bir veri yoktur (veya grafik dönemi değiştirilmiştir):

 // At first execution of OnCalculate function, we are reading the quotes from a file
 if(prev_calculated==0)
  {
   // Reading the first line from the file and determine the length of a string
   line_string_len=StringLen(FileReadString(file_handle))+2;
   // if file is large (contains more quotes than rates_total/2)
   if(FileSize(file_handle)>(ulong)line_string_len*rates_total/2)
     {
      // Setting file pointer to read the latest rates_total/2 quotes
      FileSeek(file_handle,-line_string_len*rates_total/2,SEEK_END);
      // Moving file pointer to the beginning of the next line
      FileReadString(file_handle);
     }
   // if file size is small
   else
     {
      // Moving file pointer at the beginning of a file
      FileSeek(file_handle,0,SEEK_SET);
     }
   // Reset the counter of stored quotes
   ticks_stored=0;
   // Reading until the end of the file
   while(FileIsEnding(file_handle)==false)
    {
      // Reading a string from the file
      file_buffer=FileReadString(file_handle);
      // Processing of string if its length is larger than 6 characters
      if(StringLen(file_buffer)>6)
        {
         // Finding the start position of Bid price in the line
         BidPosition=StringFind(file_buffer," ",StringFind(file_buffer," ")+1)+1;
         // Finding the start position of Ask price in the line
         AskPosition=StringFind(file_buffer," ",BidPosition)+1;
         // If the Bid line should be plotted, adding this value to BidBuffer[] array
         if(BidLineEnable) 
         BidBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,BidPosition,AskPosition-BidPosition-1));
         // If the Ask line should be plotted, adding this value to AskBuffer[] array
         if(AskLineEnable) 
         AskBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,AskPosition));
         // Increasing the counter of stored quotes
         ticks_stored++;
        }
     }
  }

Dosyadan okunması gereken teklif sayısını grafikteki birkaç çubuğun yarısıyla sınırlayacağız. Birincil olarak, dosyadan dizeyi okuyoruz ve uzunluğunu belirliyoruz. Bir satırın sonunda, 10 ve 13 kodlarına ("yeni satır" ve "satır başı") sahip iki ek karakter vardır, bu nedenle satır uzunluğunu 2 artırmamız gerekir.

Dosyanın kalan satırlarının ortalama uzunluğunun aynı olduğunu varsayıyoruz. Dosya uzunluğu rates_total/2 sayısındaki bir satır uzunluğundaki üründen büyükse (yani, dosya rates_total/2'den daha fazla teklif içeriyorsa), yalnızca rates_total/2 son tekliflerini okuyacağız. Bunu yapmak için, dosya işaretçisini rates_total/2 ile bir dize uzunluğunun ürününe eşit uzaklığa ayarlıyoruz (dosyanın sonundan) ve dosya işaretçisini bir satırın başına hizalamak için dosyadan bir satır okuyoruz.

if operatörünü kullanarak iki değeri karşılaştırdığımızı unutmayın, farklı türlere sahiptirler: dosya uzunluğu ulong türüdür, sağ taraftaki ifade int türüne sahiptir. Bu nedenle, sağ taraftaki ifadenin ulong türüne açık tiplenmesini gerçekleştiriyoruz.

Dosya rates_total/2'den daha az teklif içeriyorsa, dosya işaretçisini dosyanın başına taşırız. 

Teklif sayacını sıfır olarak ayarlıyoruz ve bir dosyanın sonuna ulaşana kadar satırları bir dosyadan okuyoruz. Dize işleme, uzunluğu altı karakterden büyük olan dizeler için gerçekleştirilir, aralarında tarih, saat, teklif ve satış ve ayırıcılar için bir karakter içeren minimum dize uzunluğudur. Bir dizeden Teklif ve Satış değerlerini ayıklıyoruz, ilgili satırın çizilmesi gerekiyorsa dosyadan okuyoruz ve teklif sayacını artırıyoruz.

Veriler daha önce okunduysa, dosya işaretçisini FileSeek fonksiyonunu kullanarak dosyanın sonuna taşırız (yeni veriler dosyaya yazılır). StringConcatenate fonksiyonunu kullanarak, FileWrite fonksiyonu kullanılarak bir dosyaya yazılacak dizeyi oluştururuz. İlgili satırın çizilmesi ve teklifler sayacının artırılması gerekiyorsa, BidBuffer[] ve AskBuffer[], dizilerine Teklif ve Satış fiyatlarının yeni değerlerini ekleriz.

  // If the data have been read before
else
  {
   // Moving file pointer at the end of the file
   FileSeek(file_handle,0,SEEK_END);
   // Forming a string, that should be written to the file
   StringConcatenate(file_buffer,TimeCurrent()," ",DoubleToString(last_price_bid,_Digits)," ",DoubleToString(last_price_ask,_Digits));
   // Writing a string to the file
   FileWrite(file_handle,file_buffer);
   // If the Bid line should be plotted, adding the last Bid price to the BidBuffer[] array
   if(BidLineEnable) BidBuffer[ticks_stored]=last_price_bid;
   // If the Ask line should be plotted, adding the last Ask price to the AskBuffer[] array
   if(AskLineEnable) AskBuffer[ticks_stored]=last_price_ask;
   // Increasing the quotes counter
   ticks_stored++;
  }

Verileri neden OnInit fonksiyonunun içindeki bir dosyadan okumadığınızı sorabilirsiniz? Bunun nedeni şunlardır: BidBuffer[] ve AskBuffer[] dinamik dizilerinin uzunluğu tanımlanmamıştır, bu, OnCalculate fonksiyonu çağrıldığında belirtilir.

Önceden açılmış dosyayı kapatırız.

// Closing the file
FileClose(file_handle);

Teklif sayacı, dosyadan okunduktan sonra veya BidBuffer[] ve AskBuffer[] dizilerine eklemeden sonra grafikteki çubuk sayısına eşit veya daha büyük olacaksa, eski tekliflerin yarısı kaldırılır ve kalanlar yerlerinde taşınır.

// If number of quotes is more or equal than number of bars in the chart
if(ticks_stored>=rates_total)
  {
   // Removing the first tick_stored/2 quotes and shifting remaining quotes
   for(i=ticks_stored/2;i<ticks_stored;i++)
     {
      // If the Bid line should be plotted, shifting the values of BidBuffer[] array on tick_stored/2
      if(BidLineEnable) BidBuffer[i-ticks_stored/2]=BidBuffer[i];
      // If the Ask line should be plotted, shifting the values of AskBuffer[] array on tick_stored/2
      if(AskLineEnable) AskBuffer[i-ticks_stored/2]=AskBuffer[i];
     }
   // Changing the value of a counter
   ticks_stored-=ticks_stored/2;
  }

Gösterge tamponlarının BidBuffer[] ve AskBuffer[] dizileri zaman serisi değildir, bu nedenle son öğe ticks_stored-1 değerine eşit indekse sahiptir, son grafik çubuğu rates_total-1 değerine eşit indekse sahiptir. Bunları aynı seviyede birleştirmek için PlotIndexSetInteger fonksiyonunu kullanarak göstergenin satırını kaydıralım:

// Shifting the Bid line to align with the price chart
PlotIndexSetInteger(0,PLOT_SHIFT,rates_total-ticks_stored);
// Shifting the Ask line to align with the price chart
PlotIndexSetInteger(1,PLOT_SHIFT,rates_total-ticks_stored);

Son alınan fiyatların değerleri bunları pencerenin sol üst köşesinde göstermek için rates_total-1 ile eşit indekse sahip BidBuffer[] ve AskBuffer[] öğelerine depolanır (ilgili satırlar çizilmiş olmalıdır).

// If the Bid line should be plotted, placing the value to the last element 
// of BidBuffer [] array to show the last Bid price in the indicator's window  
if(BidLineEnable) BidBuffer[rates_total-1]=last_price_bid;
// If the Ask line should be plotted, placing the value to the last element 
// of AskBuffer [] array to show the last Ask price in the indicator's window
if(AskLineEnable) AskBuffer[rates_total-1]=last_price_ask;

OnCalculate fonksiyonunun yürütülmesi, rates_total döndürülerek tamamlanır (sıfırdan farklı herhangi bir sayı döndürebilirsiniz), fonksiyonun kodu süslü parantezle sona erer.

// Return from OnCalculate(), return a value, different from zero   
return(rates_total);
}

Tick göstergesi yazıldı. Göstergenin tam kaynak kodu, makalenin sonunda bulunan bağlantıdan indirilebilir.

"Tik Mumları" Göstergesi Oluşturma

Şimdi sözde “tik mumlarını” çizen bir göstergeyi yazalım. Her mumun belirtilen zaman dilimine karşılık geldiği geleneksel mum grafiğinin aksine, "Tik Mumları" grafiği farklı bir yapıya sahiptir: her mum, aracıdan (eş hacimde mumlar) alınan önceden tanımlanmış bir dizi tike sahiptir. Bu gösterge Şekil 2'de gösterildiği gibi görünür:


Şekil 2. "Tik Mumları" göstergesi

"Tik Mumları" göstergesinin yanı sıra yukarıda düşünülen tik göstergesi, gelen tüm teklifleri dosyaya yazar. Veri biçimi ve dosya konumu ayrıntıları aynıdır. Dosya yolu, ad öneki, mum için tik sayısı ve bir fiyatın türü (Teklif veya Satış) göstergenin seçeneklerinde belirtilebilir.

Bir gösterge oluşturmak için MetaTrader 5 istemci terminalini başlatın ve F4 tuşuna basarak MetaQuotes Dil Düzenleyicisini başlatın.

Bunun ayrı bir pencerede çizilmesi gerektiğini belirtelim:

// Indicator is plotted in a separate window
#property indicator_separate_window

Göstergenin tek bir grafik çizimi vardır: renkli mumlar.

// One graphic plot is used, color candles
#property indicator_plots 1

Renkli mumların gösterilmesi ve her mum için fiyatın fiyat veri değerlerinin (açılış, yüksek, düşük ve kapanış) değerlerinin depolanması için dört tampona ihtiyacımız vardır. Ayrıca mumların renk indekslerini depolamak için bir tampona daha ihtiyacımız var.

// We need 4 buffers for OHLC prices and one - for the index of color
#property indicator_buffers 5

Çizim türünü belirtelim: DRAW_COLOR_CANDLES - renkli mumlar.

// Specifying the drawing type - color candles
#property indicator_type1 DRAW_COLOR_CANDLES

Mumlar için kullanılacak renkleri belirtelim:

// Specifying the colors for the candles
#property indicator_color1 Gray,Red,Green

Aşağıdaki değerlerden birini içeren numaralandırma türünün price_types öğesini oluşturalım: Teklif veya Satış:

/ / Declaration of the enumeration
enum price_types
  (
   Bid,
   Ask
  )

Göstergenin seçenekler menüsünden kullanıcı tarafından değiştirilebilen giriş parametrelerini belirtiyoruz:

// The ticks_in_candle input variable specifies the number of ticks,
// corresponding to one candle
input int ticks_in_candle=16; //Tick Count in Candles
// The applied_price input variable of price_types type indicates 
// the type of the data, that is used in the indicator: Bid or Ask prices.
input price_types applied_price=0; // Price
// The path_prefix input variable specifies the path and prefix to the file name
input string path_prefix=""; // FileName Prefix

ticks_in_candle değişkeni, bir muma karşılık gelen tik sayısını belirtir. applied_price değişkeni, mumların yapımı için kullanılan bir fiyatın türünü gösterir: Teklif veya Satış. Geçmiş tiklerin verileri için dosyanın dizin ve dosya adı öneki path_prefix değişkeninde belirtilebilir.

Gösterge çağrıları arasında kaydedilmesi gereken değerlere sahip değişkenler global seviyede bildirilir.

// The ticks_stored variable contains the number of stored quotes
int ticks_stored;
// The TicksBuffer [] array is used to store the incoming prices
// The OpenBuffer [], HighBuffer [], LowBuffer [] and CloseBuffer [] arrays
// are used to store the OHLC prices of the candles
// The ColorIndexBuffer [] array is used to store the index of color candles
double TicksBuffer[],OpenBuffer[],HighBuffer[],LowBuffer[],CloseBuffer[],ColorIndexBuffer[];

ticks_stored değişkeni, kullanılabilir teklif sayısını depolamak için kullanılır. TicksBuffer[] dizisi alınan tekliflerin depolanması için kullanılır, OpenBuffer[], HighBuffer[], LowBuffer[] ve CloseBuffer[] dizileri, grafikte çizilecek mum fiyatlarının (açılış, en yüksek, en düşük ve kapanış) depolanması için kullanılır. ColorIndexBuffer[] dizisi mumların renk dizininin depolanması için kullanılır.

OnInit fonksiyonu OpenBuffer[], HighBuffer[], LowBuffer[] ve CloseBuffer[] dizilerinin gösterge tamponu olarak kullanıldığını, ColorIndexBuffer[] dizisinin mumların renk indeksini içerdiğini, TicksBuffer[] dizisinin ara hesaplamalar için kullanıldığını gösterir:

void OnInit()
  {
   // The OpenBuffer[] array is an indicator buffer
   SetIndexBuffer(0,OpenBuffer,INDICATOR_DATA);
   // The HighBuffer[] array is an indicator buffer
   SetIndexBuffer(1,HighBuffer,INDICATOR_DATA);
   // The LowBuffer[] array is an indicator buffer
   SetIndexBuffer(2,LowBuffer,INDICATOR_DATA);
   // The CloseBuffer[] array is an indicator buffer
   SetIndexBuffer(3,CloseBuffer,INDICATOR_DATA);
   // The ColorIndexBuffer[] array is the buffer of the color index
   SetIndexBuffer(4,ColorIndexBuffer,INDICATOR_COLOR_INDEX);
   // The TicksBuffer[] array is used for intermediate calculations
   SetIndexBuffer(5,TicksBuffer,INDICATOR_CALCULATIONS);

Sonra, OpenBuffer[], HighBuffer[], LowBuffer[], CloseBuffer[] ve ColorIndexBuffer[] dizilerini zaman serisi olarak belirtiyoruz (yani en son veriler 0 indeksine sahiptir):

   // The indexation of OpenBuffer[] array as timeseries
   ArraySetAsSeries(OpenBuffer,true);
   // The indexation of HighBuffer[] array as timeseries
   ArraySetAsSeries(HighBuffer,true);
   // The indexation of LowBuffer[] array as timeseries
   ArraySetAsSeries(LowBuffer,true);
   // The indexation of CloseBuffer[] array as timeseries
   ArraySetAsSeries(CloseBuffer,true);
   // The indexation of the ColorIndexBuffer [] array as timeseries
   ArraySetAsSeries(ColorIndexBuffer,true);

0'a eşit gösterge tamponlarının değerleri grafiğe çizilmemelidir:

   // The null values of Open prices (0th graphic plot) should not be plotted
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   // The null values of High prices (1st graphic plot) should not be plotted
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
   // The null values of Low prices (2nd graphic plot) should not be plotted
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0);
   // The null values of Close prices (3rd graphic plot) should not be plotted
   PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0);

OnInit fonksiyonunun yazımı tamamlandı, fonksiyonu süslü parantez kullanarak kapatıyoruz.

OnCalculate fonksiyonunu yazmanın zamanı geldi. Fonksiyona geçirilen tüm parametreleri belirtelim:

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[])
  {

OnInit fonksiyonunda kullanılacak değişkenleri bildiririz.

// the file_handle variable is a file handle
// the BidPosition and AskPosition - are positions of Bid and Ask prices in the string;
// the line_string_len is a length of a string, read from the file, 
// CandleNumber - number of candle, for which the prices OHLC are determined,
// i - loop counter;
int file_handle,BidPosition,AskPosition,line_string_len,CandleNumber,i;
// The last_price_bid variable is the recent received Bid price
double last_price_bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
// The last_price_ask variable is the recent received Ask price
double last_price_ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
// the filename is a name of a file, the file_buffer is a string, 
// used as a buffer for reading and writing of string data
string filename,file_buffer;

Tamsayı türündeki file_handle değişkeni dosya işlemlerinde dosyanın tanıtıcısını depolamak için kullanılır, BidPosition ve AskPosition dizedeki Teklif ve Satış fiyatlarının başlangıç pozisyonlarının depolanmasını sağlamak için kullanılır, line_string_len bir dize uzunluğudur, bir dosyadan okunur, CandleNumber hesaplanan mumun indeksidir, i değişkeni döngü sayacı olarak kullanılır.

Son alınan Teklif ve Satış fiyatları double türündeki last_price_bid  ve last_price_ask  değişkenlerinde depolanır. Bir dize türündeki dosya adı değişkeni bir dosya adı depolaması için kullanılır, file_buffer dosya işlemlerinde kullanılan bir dizedir.

Göstergenin tamponları olan OpenBuffer[], HighBuffer[], LowBuffer[], CloseBuffer[] ve ColorIndexBuffer[] dizilerinin aksine, TicksBuffer[] dizisinin boyutu otomatik olarak ayarlanmaz, bu nedenle TicksBuffer[] dizisinin boyutunu OpenBuffer[], HighBuffer[], LowBuffer[], CloseBuffer[] ve ColorIndexBuffer[] dizilerinin boyutuyla aynı şekilde ayarlayalım:

// Setting the size of TicksBuffer[] array
ArrayResize(TicksBuffer,ArraySize(CloseBuffer));

Dosya adını path_prefix değişkeninden, finansal enstrümanın adından ve ".txt" uzantısından hazırlayın:

// File name formation from the path_prefix variable, name
// of financial instrument and ".Txt" symbols
StringConcatenate(filename,path_prefix,Symbol(),".txt");

Dosyayı önceki gösterge için yukarıda açıklanan parametrelerle açalım.

// Opening a file for reading and writing, codepage ANSI, shared reading mode
file_handle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_ANSI|FILE_SHARE_READ);

OnCalculate fonksiyonu ilk kez çağrılırsa ve TicksBuffer[]  dizisinde herhangi bir veri yoksa, bunları dosyadan okuruz:

if(prev_calculated==0)
  {
   // Reading the first line from the file and determine the length of a string
   line_string_len=StringLen(FileReadString(file_handle))+2;
   // if file is large (contains more quotes than rates_total/2)
   if(FileSize(file_handle)>(ulong)line_string_len*rates_total/2)
     {
      // Setting file pointer to read the latest rates_total/2 quotes
      FileSeek(file_handle,-line_string_len*rates_total/2,SEEK_END);
      // Moving file pointer to the beginning of the next line
      FileReadString(file_handle);
     }
   // if file size is small
   else
     {
      // Moving file pointer at the beginning of a file
      FileSeek(file_handle,0,SEEK_SET);
     }
   // Reset the counter of stored quotes
   ticks_stored=0;
   // Reading until the end of the file
   while(FileIsEnding(file_handle)==false)
     {
      // Reading a string from thefile
      file_buffer=FileReadString(file_handle);
      // Processing of string if its length is larger than 6 characters
      if(StringLen(file_buffer)>6)
        {
         // Finding the start position of Bid price in the line
         BidPosition=StringFind(file_buffer," ",StringFind(file_buffer," ")+1)+1;
          //Finding the start position of Ask price in the line
         AskPosition=StringFind(file_buffer," ",BidPosition)+1;
         // If the Bid prices are used, adding the Bid price to TicksBuffer[] array
         if(applied_price==0)
         TicksBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,BidPosition,AskPosition-BidPosition-1));
         // If the Ask prices are used, adding the Ask price to TicksBuffer[] array
         if(applied_price==1)
         TicksBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,AskPosition));
         // Increasing the counter of stored quotes
         ticks_stored++;
        }
     }
  }

Dosyadan tekliflerin okunması yukarıda daha ayrıntılı olarak açıklanmıştır, önceki göstergeyle aynıdır.

Teklifler daha önce TicksBuffer[] dizisine okunduysa, dosyaya yeni fiyat değerleri yazarız, TicksBuffer[] dizisine yeni bir fiyat yerleştiririz ve teklif sayacını artırırız:

// If the data have been read before
else
  {
   // Moving file pointer at the end of the file
   FileSeek(file_handle,0,SEEK_END);
   // Forming a string, that should be written to the file
   StringConcatenate(file_buffer,TimeCurrent()," ",DoubleToString(last_price_bid,_Digits)," ",DoubleToString(last_price_ask,_Digits));
   // Writing a string to the file
   FileWrite(file_handle,file_buffer);
   // If the Bid prices are used, adding the last Bid price to TicksBuffer[] array
   if(applied_price==0) TicksBuffer[ticks_stored]=last_price_bid;
   // If the Ask prices are used, adding the last Ask price to TicksBuffer[] array
   if(applied_price==1) TicksBuffer[ticks_stored]=last_price_ask;
   // Increasing the quotes counter
   ticks_stored++;
  }

Dosyanın kapanışı:

// Closing the file
FileClose(file_handle);

Depolanan teklif sayısı fiyat grafiğindeki çubuk sayısına ulaştıysa veya daha fazla olursa, en eski verilerin yarısını kaldırır ve kalan verileri kaydırırız:

// If number of quotes is more or equal than number of bars in the chart
if(ticks_stored>=rates_total)
  {
   // Removing the first tick_stored/2 quotes and shifting remaining quotes
   for(i=ticks_stored/2;i<ticks_stored;i++)
     {
      // Shifting the data to the beginning in the TicksBuffer[] array on tick_stored/2
      TicksBuffer[i-ticks_stored/2]=TicksBuffer[i];
     }
   // Changing the quotes counter
   ticks_stored-=ticks_stored/2;
  }

Her mum için OHLC değerlerini hesaplayalım ve bu değerleri ilgili gösterge tamponlarına yerleştirelim:

   // We assign the CandleNumber with a number of invalid candle
   CandleNumber=-1;
   // Search for all the price data available for candle formation
   for(i=0;i<ticks_stored;i++)
     {
      // If this candle is forming already
      if(CandleNumber==(int)(MathFloor((ticks_stored-1)/ticks_in_candle)-MathFloor(i/ticks_in_candle)))
        {
         // The current quote is still closing price of the current candle
         CloseBuffer[CandleNumber]=TicksBuffer[i];
         // If the current price is greater than the highest price of the current candle,
          // it will be a new highest price of the candle
         if(TicksBuffer[i]>HighBuffer[CandleNumber]) HighBuffer[CandleNumber]=TicksBuffer[i];
         // If the current price is lower than the lowest price of the current candle, 
          // it will be a new lowest price of the candle
         if(TicksBuffer[i]<LowBuffer[CandleNumber]) LowBuffer[CandleNumber]=TicksBuffer[i];
         // If the candle is bullish, it will have a color with index 2 (green)
         if(CloseBuffer[CandleNumber]>OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=2;
         // If the candle is bearish, it will have a color with index 1 (red)
         if(CloseBuffer[CandleNumber]<OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=1;
         // If the opening and closing prices are equal, then the candle will have a color with index 0 (grey)
         if(CloseBuffer[CandleNumber]==OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=0;
        }
      // If this candle hasn't benn calculated yet
      else
        {
         // Let's determine the index of a candle
         CandleNumber=(int)(MathFloor((ticks_stored-1)/ticks_in_candle)-MathFloor(i/ticks_in_candle));
         // The current quote will be the opening price of a candle
         OpenBuffer[CandleNumber]=TicksBuffer[i];
         // The current quote will be the highest price of a candle
         HighBuffer[CandleNumber]=TicksBuffer[i];
         // The current quote will be the lowest price of a candle
         LowBuffer[CandleNumber]=TicksBuffer[i];
         // The current quote will be the closing price of a candle
         CloseBuffer[CandleNumber]=TicksBuffer[i];
         // The candle will have a color with index 0 (gray)
         ColorIndexBuffer[CandleNumber]=0;
        }
     }

OnCalculate fonksiyonunun yürütülmesi sıfır olmayan bir değerin döndürülmesiyle tamamlanır, bu da TicksBuffer[] dizisinin zaten verilere sahip olduğu ve fonksiyonun sonraki çağrısında bunları okumasının gerekmediği anlamına gelir. Kapanış süslü parantezini fonksiyonun sonuna yerleştiririz.

 // Return from OnCalculate(), return a value, different from zero   
 return(rates_total);
}

Makalenin sonunda, göstergenin tam kaynak kodunu indirmek için kullanılabilecek bir bağlantı vardır.

Sonuç

Bu yazıda, iki tik göstergesinin oluşturulmasını değerlendirdik: tik grafiği göstergesi ve "tik mumları" göstergesi.

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

Ekli dosyalar |
tickindicator.mq5 (8.28 KB)
MetaTrader 5 ile Yeni Fırsatlar MetaTrader 5 ile Yeni Fırsatlar
MetaTrader 4, dünyanın her yerinden yatırımcılar arasında popülerliğini kazandı ve daha fazlasının istenemeyeceği düşünülüyordu. Yüksek işlem hızı, kararlılığı, gösterge yazmak için çok çeşitli olanaklar, Uzman Danışmanlar (EA) ve bilgi işlem sistemleri ve yüzün üzerinde farklı aracı arasından seçim yapma becerisi ile terminal kendini diğerlerinden büyük ölçüde ayırdı. Ancak zaman sabit durmuyor ve kendimizi MetaTrade 4 veya MetaTrade 5 seçimiyle karşı karşıya buluyoruz. Bu makalemizde, 5. nesil terminalin mevcut lehimize olan temel farklarını anlatacağız.
MQL5'teki Çizim Stilleri MQL5'teki Çizim Stilleri
MQL4'te 6 çizim stili ve MQL5'te 18 çizim stili vardır. Bu nedenle, MQL5'in çizim stillerini tanıtmak için bir makale yazmaya değer olabilir. Bu yazıda MQL5'teki çizim stillerinin detaylarını ele alacağız. Ek olarak, bu çizim stillerinin nasıl kullanılacağını göstermek için bir gösterge oluşturacağız ve çizimi iyileştireceğiz.
Yeni Başlayanlar için MQL5’te Uzman Danışman Yazmak İçin Adım Adım Açıklamalı Kılavuz Yeni Başlayanlar için MQL5’te Uzman Danışman Yazmak İçin Adım Adım Açıklamalı Kılavuz
MQL5’te Uzman Danışmanların programlanması basittir ve kolayca öğrenilebilir. Bu adım adım açıklamalı kılavuzda geliştirilmiş bir alım satım stratejisine dayanarak basit bir Uzman Danışman yazmak için gereken temel adımları göreceksiniz. Uzman Danışmanın yapısı, yerleşik teknik talimatlar ve alım satım fonksiyonları, Hata Ayıklama modunun ayrıntıları ve Strateji Test Cihazının kullanımı açıklanmaktadır.
MQL5'te göstergeler nasıl çağrılır MQL5'te göstergeler nasıl çağrılır
MQL programlama dilinin yeni versiyonuyla birlikte, yalnızca göstergelerle ilgilenme yaklaşımı değişmedi, aynı zamanda göstergelerin nasıl oluşturulacağının da yeni yolları var. Ayrıca, göstergenin tamponlarıyla çalışma esnekliğine sahipsiniz - artık istediğiniz indeksleme yönünü belirleyebilir ve tam olarak istediğiniz kadar gösterge değeri alabilirsiniz. Bu makale, göstergeleri çağırmanın ve göstergenin tamponundan veri almanın temel yöntemlerini açıklar.