Veri Erişiminin Düzenlenmesi

Bu bölümde fiyat verilerinin (zaman-serileri) istenmesi, elde edilmesi ve depolanması ile ilgili sorular üzerinde durulacaktır.

Verinin Alım-Satım Sunucusundan Alınması

Fiyat verileri MetaTrader 5 terminalinde kullanılabilir duruma gelmeden önce alınıp işlenmelidir. Verilerin alınması için MetaTrader 5 alım-satım sunucusu ile bağlantı sağlanmalıdır. Terminalin isteğiyle birlikte, veriler dakikalık bloklar halinde paketlenmiş olarak alınır.

Veri için kullanılan sunucu referansının mekanizması, isteğin yapılma şeklinden (kullanıcı tarafından çizelgenin kaydırılmasıyla veya bir MQL5 programı kullanılarak) bağımsızdır.

Ara Verilerin Depolanması

Sunucudan alınan veriler otomatik olarak açılır ve HCC (ara) biçiminde saklanır. Her sembolün verileri ayrı klasörlere konulur: terminal_dizini\bases\sunucu_ismi\history\sembol_ismi. Örneğin, MetaQuotes-Demo sunucusundan alınan EURUSD verisi, terminal_dizini\bases\MetaQuotes-Demo\history\EURUSD\ konumunda saklanır.

Veriler, .hcc uzantılı dosyalara yazılırlar. Her bir dosya, bir senelik aralığı içerecek şekilde, dakikalık verilerden oluşur. Örneğin, EURUSD klasörü içinde 2009.hcc şeklinde isimlendirilmiş bir dosya, EURUSD sembolünün 2009 yılı için dakikalık verilerini içerecektir. Bu veriler tüm zaman-aralıkları için gereken fiyat verilerinin hazırlanması amacıyla kullanılırlar ve doğrudan kullanım için tasarlanmamışlardır.

Gerekli Zaman-aralığı Verilerinin Ara Verilerden Elde Edilmesi

HCC ara dosyaları, istenen zaman-aralığı verilerinin HC biçiminde kurulması amacıyla veri kaynağı şeklinde kullanılırlar. HC biçimli veriler, hızlı erişim için maksimal şekilde hazırlanmış zaman-serileridir. Bir çizelgenin veya bir MQL5 programının isteği üzerine oluşturulurlar. Verinin hacmi, çizelgede yer alabilecek maksimum çubuk sayısını ("Max bars in charts" parametresinin değerini) geçmemelidir. Veri, daha sonraki kullanımlar için hc uzantılı dosyalarda saklanır.

Kaynak tasarrufu amacıyla, zaman-aralığının verileri sadece gerektiğinde RAM üzerine kaydedilir. Uzun bir süre çağrılmazlarsa, RAM üzerinden silinip bir dosyaya kaydedilirler. Her bir zaman-aralığı için gereken veri, diğer zaman-aralıkları için de hazır olup olmadığına bakılmaksızın hazırlanır. Verilerin biçimlendirilmesine ve erişilmesine dair kurallar, her zaman-aralığı için aynıdır. Yani, HCC dosyasında saklanan veri biriminin "bir dakikalık" olması, HCC dosyasının varlığı, M1 zaman-aralığı verisinin HC biçiminde var olacağı anlamına gelmez

Sunucudan yeni verilerin alınmasıyla, tüm zaman-aralıklarındaki HC biçimli fiyat verileri otomatik olarak güncellenir. Bu durum, verileri arka-planda hesaplama için kullanan göstergelerin yeniden çizilmesine yol açar.

"Max bars in chart" Parametresi

"Max bars in charts" parametresi; çizelgeler, göstergeler ve MQL5 programları için kullanılabilir olan çubukların sayısını kısıtlar. Bu, tüm zaman aralıkları için geçerlidir ve her şeyden önce bilgisayar kaynaklarını korumak amacıyla tasarlanmıştır.

Bu parametre için büyük bir değer ayarlandığında, küçük zaman-aralıklarında kullanılan fiyat verileri için derin bir geçmiş mevcutsa, zaman-serilerinin ve gösterge tamponlarının depolanması için kullanılacak bellek miktarının yüzlerce megabayt olabileceği hatırlanmalıdır; bu durumda müşteri terminali için kullanılan RAM sınırlamalarına ulaşabilir (32-bit MS Windows uygulamaları için 2Gb).

"Max bars in charts" parametresinin değiştirilmesi, terminalin yeniden başlatılmasıyla etkinleşir. Bu parametrenin değiştirilmesi, ek veriler için otomatik olarak sunucuya başvurulmasına veya zaman serileri için ek çubukların şekillenmesine yol açmaz. Çizelgenin verilerin olmadığı bölüme kaydırılması veya bir MQL5 programının verileri istemesi durumunda, veriler sunucudan istenir ve zaman-serileri yeni kısıtlamalar doğrultusunda yeniden şekillenir.

Sunucudan istenecek veri miktarı, "Max bars in charts" parametresi göz önüne alınarak, zaman-aralığı için istenen çubuk sayısına karşılık gelecektir. Bu parametreyle ayarlanan sınırlama katı bir sınırlama değildir; bazı durumlarda bir zaman-aralığındaki mevcut çubukların sayısı, mevcut parametre değerini birazcık aşabilir.

Veri mevcudiyeti

Bir verinin HCC biçimindeki varlığı (HC biçiminde kullanılması için hazırlanmış olsa bile), bu verinin bir çizelge üzerinde gösterildiğini veya bir MQL5 programında kullanıldığını göstermez

Fiyat verilerine veya bir MQL5 programından gösterge değerlerine erişim gerçekleştirirken, verilerin belli bir andaki mevcudiyeti garanti edilmez. Kaynakların korunması amacıyla, MetaTrader 5 içerisinde MQL5 programı için gereken verinin tam bir kopyası depolanmaz; sadece terminalin veri tabanına doğrudan erişim sağlanır.

Tüm zaman-aralıklarındaki fiyat geçmişleri HCC ara biçimi temelinde kurulur ve sunucudan yapılacak her veri güncellemesi, tüm zaman-aralıklarının da güncellenmesine ve göstergelerin yeniden hesaplanmasına yol açar. Bunun bir sonucu olarak, veri erişimi - az önce mevcut olsa bile - bloke edilebilir.

Terminal Verilerinin Sunucu Verileri ile Senkronizasyonu #

MQL5 programı herhangi bir sembolün/zaman-aralığının verisini çağırabileceği için, gerekli zaman-serilerinin, terminalde henüz hazırlanmamış olması veya gerekli fiyat verilerinin alım-satım sunucusu ile senkronize edilmemiş olması mümkündür. Bu durumda ortaya çıkacak gecikme anını tahmin edebilmek zordur.

Gecikme döngülerini kullanan algoritmalar en iyi çözümü vermezler. Bu durumun tek istisnası scriptlerdir; scriptler olay işleyicilerine sahip olmadıklarından alternatif bir algoritma seçenekleri yoktur. Özel göstergeler için benzer algoritmalar kesinlikle önerilmez, çünkü bu çeşit döngüler, mevcut göstergelerin hesaplama süreçlerinin ve sembole dair diğer fiyat-verisi işlemlerinin sonlandırılmasına yol açar.

Uzman Danışmanlar ve göstergeler için olay işleme modelinin kullanılması daha iyi olacaktır. OnTick() veya OnCalculate() olayının işlenmesi sırasında, gereken zaman-serisi için veri alınamazsa, işleyicinin bir sonraki çağrısı sırasındaki erişim durumuna dayanarak, olay işleyicisinden çıkılmalıdır.

Geçmiş Verilerinin Eklenmesi için bir Script Örneği

Alım-satım sunucusundan, seçilen sembolün geçmiş verisini almak için bir isteği uygulayan bir script örneği. Bu script, seçilen sembolün bir çizelgesi üzerinde çalıştırılmak için düşünülmüştür. Zaman-aralığının bir önemi yoktur; yukarıda da bahsedildiği gibi, fiyat verileri sunucudan bir-dakikalık paketler şeklinde indirilir ve istenen zaman-aralıkları bu paket verilerden hesaplanır.

Veri alımına dair her eylemi ayrı bir fonksiyon şeklinde yazalım, CheckLoadHistory(symbol, timeframe, start_date):

int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date)
  {
  }

CheckLoadHistory() fonksiyonu, herhangi bir programdan (Uzman Danışman, script veya gösterge) çağrılabilecek evrensel bir fonksiyon olarak tasarlanmıştır; üç giriş parametresine ihtiyaç duyar: sembol ismi, periyot ve (istenilen fiyat geçmişinin başlangıcını belirtmek için) başlangıç tarihi.

Eksik veriyi istemeden önce fonksiyon kodundaki gerekli yerleri dolduralım. Öncelikle sembol isminin ve periyot değerinin doğruluğundan emin olalım:

   if(symbol==NULL || symbol==""symbol=Symbol();
   if(period==PERIOD_CURRENT)     period=Period();

Ardından, sembolün Piyasa gözlemi Penceresinde yer aldığını doğrulayalım, yani sunucuya istek gönderdiğimizde sembolün geçmişi mevcut olsun. Piyasa Gözleminde böyle bir sembol bulunmuyorsa, SymbolSelect() fonksiyonunu kullanarak ekleyelim.

   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT))
     {
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOLreturn(-1);
      SymbolSelect(symbol,true);
     }

Şimdi, istenen sembol/periyot çifti için mevcut geçmişin başlangıç tarihini almalıyız. CheckLoadHistory() fonksiyonuna geçirilen startdate giriş parametresinin değeri, mevcut geçmiş içerisinde yer alıyor olabilir; bu durumda sunucudan veri isteği gereksiz olacaktır. Seçilen sembol/periyot için, mevcut olan ilk tarihi öğrenmek amacıyla, SeriesInfoInteger() fonksiyonu, SERIES_FIRSTDATE şekillendiricisi ile birlikte kullanılır.

   SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date);
   if(first_date>0 && first_date<=start_date) return(1);

Bir sonraki önemli adım, fonksiyonun çağrılacağı programın tipinin kontrol edilmesidir. Aynı periyoda sahip gösterge zaman-serilerinin güncellenmesi için yapılan isteklerin sakıncalı olacağını not ediniz. Bu tip güncellemeler, göstergenin çalışmakta olduğu iş parçacığı üzerinde gerçekleştirilir. Bu nedenle, bir çakışma gerçekleşmesi yüksek olasılıktır. Bunu kontrol etmek için MQL5InfoInteger() fonksiyonunu MQL5_PROGRAM_TYPE şekillendiricisi ile kullanın.

   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol)
      return(-4);

Eğer tüm kontroller başarıyla gerçekleştirilmişse, alım-satım sunucusuna başvurmadan son bir deneme yapalım. İlk önce, HCC biçimli mevcut dakikalık veriler için başlangıç tarihini öğrenelim. Bu değeri SeriesInfoInteger() fonksiyonunu SERIES_TERMINAL_FIRSTDATE şekillendiricisi ile kullanarak alırız ve yine start_date parametresinin değeriyle karşılaştırırız.

   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date))
     {
      //--- zaman-serilerinin kurulabileceği veri mevcut
      if(first_date>0)
        {
         //--- zaman-serilerini kurmaya zorla
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times);
         //--- tarihi kontrol et
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
            if(first_date>0 && first_date<=start_date) return(2);
        }
     }

Tüm kontrollerden sonra uygulama iş parçacığı hala CheckLoadHistory() fonksiyonunun gövdesinde yer alıyorsa, eksik veri, alım-satım sunucusundan istenmelidir. Bunun için önce, "Max bars in chart" değerine TerminalInfoInteger() fonksiyonu ile dönüş yapalım:

  int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);

Bu veri fazladan veri istemememiz için gereklidir. Ardından, sembolün geçmişinin alım-satım sunucusunda bulunan ilk tarihini (regardless of the period), SERIES_SERVER_FIRSTDATE şekillendiricisi ile SeriesInfoInteger() fonksiyonunu kullanarak öğrenmeliyiz.

   datetime first_server_date=0;
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped())
      Sleep(5);

İsteğin asenkron bir işlem olması nedeniyle, fonksiyon, bir döngü içerisinde (first_server_date değişkeni bir değer alana kadar) beş milisaniyelik gecikme ile çağrılır veya döngü işlemi kullanıcı tarafından sonlandırılır; bu durumda IsStopped() fonksiyonu, true dönüşü yapacaktır. Alım-satım sunucusundan alacağımız veriler için geçerli bir değer belirleyelim.

   if(first_server_date>start_date) start_date=first_server_date;
   if(first_date>0 && first_date<first_server_date)
      Print("Uyarı: ilk sunucu tarihi ",first_server_date,,
symbol," için serinin ilk tarihiyle uyumlu değil ",first_date);

Sunucudaki başlangıç tarihinin (first_server_date), sembolün HCC biçimindeki başlangıç tarihinden (first_date ) düşük olması durumunda, karşılık gelen giriş bültene çıktılanır.

Artık, eksik fiyat verisini alım-satım sunucusundan istemek için hazırız. İsteği bir döngü şeklinde gerçekleştir, söz konusu döngünün gövdesini doldurmaya başla:

   while(!IsStopped())
     {
      //1. yeniden kurulan zaman-serisi ile HHC biçimindeki ara verinin senkronizasyonu için bekle
      //2. söz konusu zaman-serisindeki mevcut çubuk sayısını al 
      //    çubuk sayısı, "Max_bars_in_chart" paraetresinden büyükse, çıkabiliriz, iş bitti
      //3. yeniden kurulan zaman-serisinin first_date başlangıç tarihini al ve start_date değeriyle karşılaştır
      //    first_date değeri, start_date değerinden küçükse çıkabiliriz, iş bitti
      //4. sunucudan, geçmişin yeni bir parçasını iste - 'bars' numaralı son çubuktan başlayarak 100 çubuk
     }

İlk üçü, zaten bilinen araçlarla uygulanır.

   while(!IsStopped())
     {
      //--- 1.zaman-serisi yeniden kurulanan kadar bekle
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped())
         Sleep(5);
      //--- 2.kaç çubuğumuz var öğren
      int bars=Bars(symbol,period);
      if(bars>0)
        {
         //--- çubuklar, çizelgeye çizilebilecek miktardan fazla, çık
         if(bars>=max_bars) return(-2); 
         //--- 3. zaman-serisindeki mevcut başlangıç tarihine dönüş yap
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
            // başlangıç tarihi, istenenden daha önceye denk geliyor, görev tamamlandı
            if(first_date>0 && first_date<=start_date) return(0);
        }
      //4. Geçmişin yeni bir parçasını iste - 'bars' numaralı son çubuktan başlayarak 100 çubuk
     }

son dördüncü nokta kaldı (geçmiş isteği). Sunucuya doğrudan başvuramayız ama HCC içindeki geçmiş yetersiz ise herhangi bir Copy-fonksiyonu ile sunucuya istek gönderme işlemini otomatik olarak başlatabiliriz. first_date değişkeni içindeki başlangıç tarihi, istek uygulama derecesi için basit ve doğal bir kriter olduğundan, kullanılabilecek en kolay yol CopyTime() fonksiyonudur.

Zaman-serilerinden veri kopyalayan fonksiyonlar çağrıldığında, start parametresinin (kopyalamanın başlayacağı çubuk numarası) hiç bir zaman mevcut terminal geçmişinin dışında olmaması gerektiği not edilmelidir. Sadece 100 çubuğa sahipseniz, 500 numaralı çubuktan başlayarak 300 çubuk kopyalamayı denenmenin hiç bir anlamı olmaz. Böyle bir istek, hatalı olarak değerlendirilecek ve işlenmeyecektir, yani alım-satım sunucusundan fazladan veri yüklenmeyecektir.

Bu yüzden bars indisli çubuktan başlayarak 100 çubuk kopyalarız. Bu, eksik verilerin alım-satım sunucusundan düzgünce yüklenmesini sağlayacaktır. Aslında, sunucu fazladan veriler gönderir, böylece 100 çubuktan fazla yüklenecektir.

   int copied=CopyTime(symbol,period,bars,100,times);

Kopyalama işleminden sonra, kopyalanan elemanların sayısını kontrol etmeliyiz. Girişim başarısız olursa, copied değeri null olacak ve fail_cnt sayacının değeri bir artırılacaktır. 100 başarısız denemeden sonra, fonksiyonun işlemi sonlandırılacaktır.

int fail_cnt=0;
... 
   int copied=CopyTime(symbol,period,bars,100,times);
   if(copied>0)
     {
      //--- veriyi kontrol et
      if(times[0]<=start_date)  return(0);  // kopyalanan veri daha küçük, hazır
      if(bars+copied>=max_bars) return(-2); // çubuklar çizelgeye çizilebilecek olandan fazla, hazır
      fail_cnt=0;
     }
   else
     {
      //--- 100'den az denemede başarı
      fail_cnt++;
      if(fail_cnt>=100) return(-5);
      Sleep(10);
     }
 

Böylece, hem çalışmanın her anındaki mevcut durum doğru şekilde işlenir, hem de CheckLoadHistory() fonksiyonunun çağrısından sonra, ek bilgiler için işlenebilecek olan sonlandırma koduna dönüş yapılır. Örneğin, bu yol:

   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate);
   switch(res)
     {
      case -1 : Print("Bilinmeyen sembol ",InpLoadedSymbol);                  break;
      case -2 : Print("Çizelgeye çizilebilecek olandan daha fazla istenen çubuk var"); break;
      case -3 : Print("Uygulama kullanıcı tarafından durduruldu");           break;
      case -4 : Print("Gösterge, kendi verisini yüklememeli");               break;
      case -5 : Print("Yükleme başarısız");                                  break;
      case  0 : Print("Tüm veriler yüklendi");                               break;
      case  1 : Print("Zaman-serisindeki zaten yüklü olan veriler yeterli"); break;
      case  2 : Print("Zaman-serisi, terminaldeki mevcut verilerden kuruldu"); break;
      default : Print("Uygulama sonucu başarısız");
     }

Fonksiyonun bütün kodu, herhangi bir veriye yapılan erişimin doğru şekilde düzenlenmesini ve istek sonuçlarının işlenmesini gösteren bir script örneğinde bulunabilir.

Code:

//+------------------------------------------------------------------+
//|                                              TestLoadHistory.mq5 |
//|                         Copyright 2000-2024, MetaQuotes Ltd. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.02"
#property script_show_inputs
//--- giriş parametreleri
input string          InpLoadedSymbol="NZDUSD";   // Yüklenecek sembol
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1;  // Yüklenecek periyot
input datetime        InpStartDate=D'2006.01.01'; // Başlangıç tarihi
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("Yüklemeyi başlat",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"tarihinden itibaren",InpStartDate);
//---
   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate);
   switch(res)
     {
      case -1 : Print("Bilinmeyen sembol ",InpLoadedSymbol);             break;
      case -2 : Print("Çizelgeye çizilebilecek olandan daha fazla istenen çubuk var"); break;
      case -3 : Print("Program durduruldu");                        break;
      case -4 : Print("Gösterge, kendi verisini yüklememeli");      break;
      case -5 : Print("Yükleme başarısız");                                break;
      case  0 : Print("Yükleme başarılı");                                  break;
      case  1 : Print("Önceden yüklenmiş");                          break;
      case  2 : Print("Önceden yüklenmiş ve kurulmuş");                break;
      default : Print("Bilinmeyen sonuç");
     }
//---
   datetime first_date;
   SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date);
   int bars=Bars(InpLoadedSymbol,InpLoadedPeriod);
   Print("İlk tarih ",first_date," - ",bars," çubuk");
//---
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date)
  {
   datetime first_date=0;
   datetime times[100];
//--- sembol ve periyodu kontrol et
   if(symbol==NULL || symbol==""symbol=Symbol();
   if(period==PERIOD_CURRENT)     period=Period();
//--- sembol Piyasa Gözleminde seçili mi kontrol et
   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT))
     {
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOLreturn(-1);
      SymbolSelect(symbol,true);
     }
//--- veri mevcut mu kontrol et
   SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date);
   if(first_date>0 && first_date<=start_date) return(1);
//--- bu bir gösterge ise kendi verisini yüklemesini isteme
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol)
      return(-4);
//--- ikinci deneme
   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date))
     {
      //--- zaman-serilerinin kurulabileceği veri mevcut
      if(first_date>0)
        {
         //--- zaman-serilerini kurmaya zorla
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times);
         //--- tarihi kontrol et
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
            if(first_date>0 && first_date<=start_date) return(2);
        }
     }
//--- terminal seçeneklerinden "max bars in chart"
   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);
//--- sembol geçmişinin bilgisini yükle
   datetime first_server_date=0;
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped())
      Sleep(5);
//--- yükleme için başlangıç tarihini düzelt
   if(first_server_date>start_date) start_date=first_server_date;
   if(first_date>0 && first_date<first_server_date)
      Print("Uyarı: ilk sunucu tarihi ",first_server_date,,symbol,
            " için serinin ilk tarihiyle uyumlu değil ",first_date);
//--- veriyi adım adım yükle
   int fail_cnt=0;
   while(!IsStopped())
     {
      //--- zaman-serisinin kurulması için bekle
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped())
         Sleep(5);
      //--- kurulan çubukları iste
      int bars=Bars(symbol,period);
      if(bars>0)
        {
         if(bars>=max_bars) return(-2);
         //--- ilk tarihi iste
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
            if(first_date>0 && first_date<=start_date) return(0);
        }
      //--- bir sonraki kısmın kopyalanması, verinin yüklenmesi için zorlar
      int copied=CopyTime(symbol,period,bars,100,times);
      if(copied>0)
        {
         //--- veriyi kontrol et
         if(times[0]<=start_date)  return(0);
         if(bars+copied>=max_bars) return(-2);
         fail_cnt=0;
        }
      else
        {
         //--- 100'den az denemede başarı
         fail_cnt++;
         if(fail_cnt>=100) return(-5);
         Sleep(10);
        }
     }
//--- durduruldu
   return(-3);
  }
//+------------------------------------------------------------------+
//| Periyodun string tipli değerine dönüş yapar                      |
//+------------------------------------------------------------------+
string GetPeriodName(ENUM_TIMEFRAMES period)
  {
   if(period==PERIOD_CURRENTperiod=Period();
//---
   switch(period)
     {
      case PERIOD_M1:  return("M1");
      case PERIOD_M2:  return("M2");
      case PERIOD_M3:  return("M3");
      case PERIOD_M4:  return("M4");
      case PERIOD_M5:  return("M5");
      case PERIOD_M6:  return("M6");
      case PERIOD_M10return("M10");
      case PERIOD_M12return("M12");
      case PERIOD_M15return("M15");
      case PERIOD_M20return("M20");
      case PERIOD_M30return("M30");
      case PERIOD_H1:  return("H1");
      case PERIOD_H2:  return("H2");
      case PERIOD_H3:  return("H3");
      case PERIOD_H4:  return("H4");
      case PERIOD_H6:  return("H6");
      case PERIOD_H8:  return("H8");
      case PERIOD_H12return("H12");
      case PERIOD_D1:  return("Daily");
      case PERIOD_W1:  return("Weekly");
      case PERIOD_MN1return("Monthly");
     }
//---
   return("bilinmeyen periyot");
  }