MQL5'te Tik Göstergeleri Oluşturma
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
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz