English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
MetaTrader 5'de Sınamanın Temelleri

MetaTrader 5'de Sınamanın Temelleri

MetaTrader 5Sınayıcı | 9 Aralık 2021, 11:24
132 0
MetaQuotes
MetaQuotes

Neden Strateji Sınama Aracına İhtiyacımız Var?

Otomatikalım-satım fikri, bir alım-satım robotunun haftanın 7 günü 24 saat aralıksız çalışabilmesinden kaynaklanmaktadır. Robotlar yorulmaz, şüpheye düşmez ve korkmaz, tüm psikolojik problemlerden uzaktır. Sadece alım-satım kurallarının belirlenmesi ve bir algoritmada uygulanması yeterlidir ve robot, yorulmadan çalışmak için hazırdır. Ama ilk önce, şu iki koşulun sağlandığından emin olmanız gerekir:

  • Uzman Danışman, alım satım sisteminin kurallarına bağlı olarak alım satım işlemleri gerçekleştirir;
  • Uzman Danışman içinde uygulanan alım-satım stratejisi, geçmiş veri üzerinde karlılık gösterir.

Bu iki sorunun cevabını alabilmek için, MetaTrader 5 müşteri terminaline eklenmiş olan Strategy Sınama aracına ihtiyaç duyarız.


Tik Oluşturma Modları

Uzman Danışman, MQL5 dilinde yazılan ve her seferinde bazı harici olaylara yanıt olarak çalışan bir programdır. Uzman danışman (EA), her ön-tanımlı olay için karşılık gelen bir fonksiyon (olay işleyici) içerir.

NewTick olayı (fiyat değişimi) bir Uzman Danışman (EA) için ana olaydır, bu nedenle, Uzman Danışmanı sınayabilmek için bir tik dizisine gereksinim duyarız. MetaTrader 5 müşteri terminalinin Strateji Sınama aracında uygulanan 3 adet tik oluşturma modu bulunmaktadır:

  • Her tik
  • 1 dakikalık çubuklarla OHLC fiyatları (1 Minute OHLC)
  • Sadece açılış fiyatları

En temel ve en detaylı olanı "Her tik" (Every tick) modudur, diğer iki mod ise temel modun basitleştirilmiş halidir, ve "Her tik" moduyla karşılaştırmalı olarak açıklanacaklardır. Aralarındaki farkı anlamak amacıyla üç modun tamamını düşünün.


"Her tik"

Finansal enstrümanlara dair tarihsel fiyat verileri, dakikalık çubuklar şeklinde paketlenmiş olarak sunucudan MetaTrader 5 istemci terminaline aktarılır. İsteklerin yapılmasına ve istenen zaman aralığının yapımına dair detaylı bilgiyi, MQL5 Referans dosyasının Veri Erişiminin Düzenlenmesi bölümünde bulabilirsiniz.

Fiyat geçmişinin en küçük elemanı dakikalık çubuktur, bundan dört fiyat değerine dair verilerialabilirsiniz:

  • Open - dakikalık çubuğun açılış fiyatı;
  • High - dakikalık çubuk içinde gerçekleşmiş en yüksek fiyat değeri;
  • Low - dakikalık çubuk içinde gerçekleşmiş en düşük fiyat değeri;
  • Close - çubuğun kapanış fiyatı.

Yeni dakikanın çubuğu, yeni dakikanın başlamasıyla (toplam saniye sayısının 0 olmasıyla) değil, en az bir puanlık bir fiyat değişimini içeren yeni bir tikin gelmesiyle açılır. Aşağıdaki resim, yeni işlem haftasının 2011.01.10 00:00 açılış zamanına sahip ilk bir dakikalık çubuğunu göstermektedir. Cuma ve Pazartesi günleri arasındaki fiyat boşluğu, kurların gelen haberlere bağlı olarak, hafta-sonu da dalgalanmaları nedeniyle sık karşılaşılan bir durumdur.

Şekil 1. Cuma ve Pazartesi arasındaki fiyat boşluğu

Bu çubuğun 10 Ocak 2011 günü 00 saatinde ve 00 dakikasında başladığını biliyoruz, ama saniye hakkında hiç bir bilgimiz yok. 00:00:12'de , 00:00:36'da (yeni günün başlangıcından 12 veya 36 saniye sonra) veya o dakika içerisindeki herhangi bir anda açılmış olabilir. Ama EURUSD Open (açılış) fiyatının, açılış anında 1,28940 olduğunu bilebiliriz.

Ayrıca söz konusu dakikalık çubuğun kapanış fiyatına karşılık gelen tikin, saniye içerisindeki geliş anını tam olarak bilmiyoruz. Sadece bir şey biliyoruz : bir dakikalık çubuğun son Close (kapanış) fiyatını. Bu dakika için fiyat 1,28958 seviyesinde. High ve Low fiyatlarının oluşma anlarını da bilmiyoruz ama maksimum ve minimum fiyatların sırasıyla 1,28958 ve 1,28940 seviyelerinde olduğunu biliyoruz.

Alım satım stratejisini sınamak amacıyla, Uzman Danışmanın çalışmasını simüle edebileceğimiz, tiklerden oluşan bir diziye ihtiyaç duyarız. Bu şekilde, her bir dakikalık çubuk için, fiyatın kesinlikle uğramış olduğu 4 kontrol noktasını biliriz. Bir çubuğun 4 tik içerdiğini biliyorsak, bu bilgi bir sınama gerçekleştirmek için yeterli olacaktır, diğer taraftan tik hacmi genellikle 4’ün üzerindedir.

İşte bu nedenle, Open, High, Low, ve Close fiyatlarının arasında, ek kontrol noktaları oluşturulması gerekir. "Her tik" tik oluşturma modunun temel ilkeleri MetaTrader 5 Terminalinin Strateji Sınama Aracının Tik Oluşturma Algoritması kısmında açıklanmıştır, aşağıdaki şekilde temsil edilmektedir.

Şekil 2. Tik oluşturma algoritması

"Her tik" modunda sınama yapılırken, Uzman Danışmanın (EA) OnTick() fonksiyonu her kontrol noktasında çağrılacaktır. Her kontrol noktası, oluşturulan diziden gelen bir tiktir. Uzman Danışman, simüle edilen tik zamanını ve fiyatını çevrimiçi çalışmalarda olduğu gibi alacaktır.

Önemli: "Her tik", en doğru sonuç veren sınama modudur ama aynı zamanda en çok zaman harcayandır. Alım satım stratejilerinin büyük çoğunluğu için, başlangıç olarak diğer iki sınama modundan birinin kullanımı, genellikle yeterlidir.


"1 Dakikalık OHLC"

"Her tik" modu, üç sınama modu arasında en doğru olanıdır ama aynı zamanda en yavaşıdır. OnTick() işleyicisinin çalışması her tikte gerçekleşir ve tik hacmi oldukça büyük olabilir. Çubuk içindeki minimal fiyat hareketlerinin önem taşımadığı bir strateji için, daha hızlı ve daha kaba bir simülasyon modu bulunmaktadır: "1 dakikalık OHLC".

"1 dakikalık OHLC" modunda, tik dizisi sadece dakikalık çubukların OHLC fiyatlarından oluşur; oluşturulan kontrol noktalarının sayısı ve de sınama süresi anlamlı ölçüde azaltılmıştır. OnTick () fonksiyonu, dakikalık çubukların OHLC fiyatlarından oluşan tüm kontrol noktalarında çalıştırılır.

Açılış, Yüksek, Düşük ve Kapanış fiyatlarının arasında ek tiklerin oluşturulmasının reddedilmesi; Açılış fiyatının belirlendiği andan itibaren, fiyatların geliştirilmesinde katı bir determinizm görüntüsü ortaya çıkaracaktır. Bu, test edilen bakiyenin yukarı yönlü grafiğini gösteren bir "Sınama Kasesi", oluşturulmasını mümkün kılar.

Böyle bir Kase örneği, Kod Tabanı - Grr-al linkinde bulunabilir.

Şekil 3. Grr-al Uzman Danışmanı, OHLC fiyatlarının özelliklerini kullanır

Resimde bu Uzman Danışmanın etkileyici grafiği gözükmektedir. Nasıl elde edildi? Bir dakikalık çubuk için 4 ayrı fiyat biliyoruz ve yine biliyoruz ki Açılış fiyatı bunların ilkiyken Kapanış fiyatı ise sonuncusu. Bunların arasında Yüksek ve Düşük fiyatlarımız var ve bunların oluşma sıraları belirsiz, ama Yüksek fiyatın Açılış fiyatından büyük veya ona eşit olduğunu (ve Düşük fiyatın Açılış fiyatından küçük veya ona eşit olduğunu) biliyoruz.

Açılış fiyatının alınma zamanını belirlemek ve ardından Yüksek veya Düşük fiyatın ondan önce gelip gelmediğini belirlemek üzere bir sonraki tik işaretini analiz etmek için yeterlidir. Eğer fiyat Açılış fiyatının altındaysa, bu Düşük fiyattır ve bu tikte alım yaparız, bir sonraki tik, Yüksek fiyata karşılık gelir; burada alış pozisyonunu kapatır ve satış için yeni pozisyon açarız. Bir sonraki (son) tik, Kapanış fiyatıdır ve burada da satış pozisyonunu kapatırız. 

Açılıştan sonra aldığımız tik açılış fiyatından büyükse, bu işlem dizisini ters yönde uygularız. Bu "hile" modunda bir dakikalık çubuğu işleyin, ardından bir sonraki için bekleyin.

Böyle bir Uzman Danışmanı geçmiş veriyle sınarken her şey düzgün gider, ama bir kez çevrimiçi çalıştırdığımızda, asıl gerçek ortaya çıkar; bakiye çizgisi istikrarlıdır, ama aşağı doğru yönelmiştir. Bu numarayı ortaya çıkarmak için, Uzman Danışmanı "Her Tik" modunda çalıştırmamız gerekir.

Not: Bir uzman Danışmanın test sonuçları, kaba sınama modlarında ("1 dakikalık OHLC" ve "Sadece Açılış Fiyatları") çok iyi görünüyorsa "Her Tik" modunda da Sınama gerçekleştirdiğinizden emin olun.


"Sadece Açılış Fiyatları"

Bu modda tikler, sınama için seçilen zaman aralığında OHLC fiyatlarının temelinde oluşturulur. Uzman Danışmanın OnTick() fonksiyonu, sadece çubuğun başlangıcındaki Açılış fiyatında çalışır. Bu özellik nedeniyle, stop (durdurma) seviyeleri ve bekleyen emirler, belirtilenden farklı bir fiyat ile tetiklenebilir (özellikle test sırasında büyük periyotlar kullanılıyorsa). Bunun yerine Uzman Danışman için hızlı bir ön değerlendirme testi yapabilme olanağımız bulunmaktadır.

W1 ve MN1 periyotları, "Sadece Açılış Fiyatları" modu için birer istisnadır: Bu periyotlar için tikler, haftalık veya aylık değil, günlük OHLC fiyatları ile oluşturulur.

EURUSD H1 sembolünde, "Sadece Açılış Fiyatları" modunda bir Uzman Danışmanı test ettiğimizi düşünelim. Bu durumda tiklerin (kontrol noktalarının) toplam sayısı, sınamanın yapıldığı zaman aralığındaki bir saatlik çubukların sayısının 4 katı olacaktır. Ama OnTick() işleyicisi, sadece bir saatlik çubuğun açılışında çağrılacaktır. Doğru sınama için istenen kontroller, tiklerin geri kalanı (Uzman Danışmandan "gizlenenler") üzerinde gerçekleşir.
  • Marjin (teminat) gerekliliklerinin hesaplanması;
  • Zarar Durdur ve Kâr Al seviyelerinin tetiklenmesi;
  • Bekleyen emirlerin tetiklenmesi;
  • Zaman aşımına uğramış bekleyen emirlerin kaldırılması.

Herhangi bir açık pozisyon veya bekleyen emir yoksa, gizli tiklerin üzerinde bu kontrolleri gerçekleştirmemiz gerekmez ve ciddi bir hız artışı sağlanabilir. "Sadece Açılış Fiyatları" modu, işlemleri sadece açılış fiyatından gerçekleştiren ve StopLoss, TakeProfit ve bekleyen emir kullanmayan stratejiler için oldukça uygundur. Bu tip stratejiler için gereken test geçerliliği korunur.

Standart paketteki Uzman Danışmanlardan, her modda test edilebilecek olan Moving Average Uzman Danışmanını örnek olarak alalım. Bu Uzman Danışmanın mantığı, tüm kararların çubuğun açılışında verilmesi, işlemlerin hemen uygulanması ve bekleyen emir kullanılmaması üzerine kuruludur.

Bu uzman için EURUSD H1 sembolünde, 2010.01.09 ile 2010.31.12 aralığında bir test düzenleyip sonuç grafiklerini karşılaştıralım. Aşağıdaki resim, üç modun her biri için test raporundaki bakiye grafiğini göstermektedir.


Şekil 4. Standart paketteki Moving Average.mq5 uzmanının test grafiği test moduna bağımlı değildir (yakınlaştırmak için görüntüye tıklayın)

Sizin de görebileceğiniz gibi, farklı modlardaki tüm grafikler, standart paketteki Moving Average uzmanı için aynıdır.

"Sadece Açılış Fiyatları" modunda bir takım kısıtlamalar bulunmaktadır:

  • Rastgele Gecikme yürütme modunu kullanamazsınız.
  • Test edilen Uzman Danışman için, sınama/optimizasyon için kullanılandan daha küçük bir timeframe zaman aralığı verisine erişemezsiniz. Örneğin, sınamayı/optimizasyonu H1 periyodu üzerinde gerçekleştirirseniz, H2, H3, H4 vb. periyotların verilerine erişebilirsiniz, ama M30, M20, M10 vb. verilerine erişemezsiniz. Ayrıca, erişilmek istenen daha yüksek zaman aralıkları, sınama için kullanılan zaman aralığının katı olmalıdır. Örneğin, M20 üzerinde bir sınama gerçekleştiriyorsanız, M30 verisine erişemezsiniz, ama H1 verisine erişmeniz mümkündür. Bu kısıtlamalar, sınama sürecinde oluşturulan çubukların katı olmayan veya onlardan daha düşük periyotlu çubuklardan veri alınmasının imkansız oluşu ile ilişkilidir.
  • Diğer zaman aralıklarının verilerindeki erişim kısıtlamaları, verileri Uzman Danışman tarafından kullanılan diğer sembollere de uygulanır. Bu durumda, her bir sembol için yapılacak kısıtlama, sınama/optimizasyon sırasında erişilen ilk zaman aralığına bağlı olacaktır. EURUSD H1 üzerinde yapılan bir sınama sırasında, Uzman Danışmanın GBPUSD M20 verisine erişim sağladığını düşünün. Bu durumda Uzman Danışman, EURUSD H1, H2 vb. verilerine de, GBPUSD M20, H1, H2 vb. verilerine eriştiği gibi erişebilecektir.

Not: "Sadece Açılış Fiyatları" modu, en kısa test süresine sahiptir fakat tüm alım-satım stratejileri için uygun değildir. İstenen sınama modunu, alım-satım stratejisinin karakteristiklerine göre seçin. 

Tik oluşturma bölümünü sonuca bağlamak amacıyla; EURUSD sembolü ve M15 periyodu için, 2011.01.11 21:00:00 - 2011.01.11 21:30:00 aralığında, farklı tik oluşturma modlarının görsel karşılaştırmasını inceleyelim.

Tikler, WriteTicksFromTester.mq5 Uzman Danışmanı kullanılarak farklı dosyalara yazılmışlardır ve bu dosya isimlerinin sonları filenamEveryTick, filenameOHLC ve filenameOpenPrice giriş parametreleri ile belirlenmiştir.

Şekil 5. WriteTicksFromTester Uzman Danışmanı için tiklerin başlangıç ve bitiş tarihlerini belirleyebiliriz (start ve end değişkenleri)

Üç tik dizisini içeren üç dosyayı almak için, Uzman Danışman, karşılık gelen üç ayrı modda ("Her tik", "1 dakikalık OHLC" ve "Sadece Açılış Fiyatları") tekil olarak (üç defa) çalıştırılır. Ardından, bu üç dosyadaki veriler TicksFromTester.mq5 göstergesi ile çizelge üzerinde görüntülenir. Gösterge kodları bu yazıya eklenmiştir.


Şekil 6. MetaTrader 5 terminalinin Strateji Sınama aracında, üç farklı moddaki tik dizisi

Varsayılan olarak, MQL5 dilindeki tüm dosya işlemleri, "dosya güvenlik ortamı" (sandbox) içinde gerçekleştirilir; sınama sırasında Uzman Danışman, sadece kendi "dosya güvenlik ortamına" erişebilir. Göstergenin ve Uzman Danışmanın sınama sırasında aynı klasördeki dosyalarla çalışabilmesi için, FILE_COMMON bayrağını kullandık. Uzman Danışmandan bir kod örneği:

//--- open the file
   file=FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON,";");
//--- check file handle
   if(file==INVALID_HANDLE)
     {
      PrintFormat("Error in opening of file %s for writing. Error code=%d",filename,GetLastError());
      return;
     }
   else
     {
      PrintFormat("The file will be created in %s folder",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
     }

Gösterge içindeki veriyi okumak için de yine FILE_COMMON bayrağını kullandık. Bu, gerekli dosyaları bir klasörden diğerine, el yordamıyla taşımaktan kaçınmamızı sağladı.

//--- open the file
   int file=FileOpen(fname,FILE_READ|FILE_CSV|FILE_COMMON,";");
//--- check file handle
   if(file==INVALID_HANDLE)
     {
      PrintFormat("Error in open of file %s for reading. Error code=%d",fname,GetLastError());
      return;
     }
   else
     {
      PrintFormat("File will be opened from %s",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
     }


Spread simülasyonu

Bid ve Ask fiyatları arasındaki fark, spread olarak adlandırılır. Sınama sırasında spread modellenmez; geçmiş veriden alınır. Geçmiş verideki spread değeri sıfıra eşit veya sıfırdan küçükse, istenen geçmiş verinin zamanına karşılık gelen spread değeri, sınama birimi tarafından kullanılır.

Strateji Sınama Aracında spread her zaman kayan noktalı şekilde düşünülür. Bu SymbolInfoInteger (symbol, SYMBOL_SPREAD_FLOAT) çağrısının her zaman 'true' dönüşü yapmasından kaynaklanır.

Ayrıca, tarihsel veriler, tik değerlerini ve alım satım hacimlerini de içerirler. Verileri depolamak ve almak için, özel MqlRates yapısını kullanırız:

struct MqlRates
  {
   datetime time;         // opening bar time
   double   open;         // opening price Open
   double   high;         // the highest price High
   double   low;          // the lowest price Low
   double   close;        // the closing price Close
   long     tick_volume;  // the tick volume
   int      spread;       // spread
   long     real_volume;  // market volume 
  };


Müşteri Terminalinin Global Değişkenleri

Sınama sırasında, müşteri terminalinin global değişkenleri de ayrıca simüle edilir, ama bunlar, terminalin F3 tuşu kullanılarak görülebilecek mevcut global değişkenleri ile ilişkili değildirler. Yani, sınama sırasındaki terminalin global değişkenleri ile ilgili tüm işlemler, müşteri terminalinin dışında (sınama biriminde) yer alırlar.


Sınama sırasında göstergelerin hesaplanması

Gerçek zamanlı modda, gösterge değerleri ​her tikte hesaplanır. Strateji Sınama Aracı, göstergelerin hesaplanması için maliyet bakımından verimli bir model yürütür; göstergeler sadece Uzman Danışman çalışmadan hemen önce yeniden hesaplanırlar. Yani göstergenin yeniden hesaplanması; OnTick(), OnTrade() ve OnTimer() fonksiyonlarının çağrılarından önce gerçekleşir.

Belirli bir olay işleyicinin içinde gösterge için bir çağrı olup olmaması önemli değildir; tanıtıcı değerleri iCustom() veya IndicatorCreate() oluşturulan göstergeler, olay işleyicinin çağrılmasından önce yeniden hesaplanırlar.

Sonuç olarak, "Her tik" modunda sınama yapılırken, göstergelerin hesaplanması OnTick() fonksiyonunun çağrısından önce gerçekleşir.

Uzman Danışman içinde EventSetTimer() fonksiyonu kullanılarak bir zamanlayıcı etkinleştirilmişse, göstergeler OnTimer() işleyicisinin çağrılmasından önce hesaplanacaktır. Bu sebeple, optimal olmayan bir yolla yazılmış göstergelerin kullanımı ile, sınama süresi büyük oranda artabilir.


Sınama sırasında Geçmiş Verinin Yüklenmesi

Sınanan sembolün geçmişi, sınama süreci başlamadan önce terminal tarafından, alım satım sunucusundan yüklenerek senkronize edilir. Terminal, sembolün mevcut olan bütün geçmişini, bir daha istememek amacıyla ilk seferinde yükler. Bundan sonra sadece yeni veriler yüklenir.

Test birimi, sınanan sembolün geçmişini sınama başladıktan hemen sonra müşteri terminalinden alır. Test sürecinde diğer enstrümanların verileri de kullanılıyorsa (çok dövizli bir Uzman Danışman gibi), sınama birimi, verinin çağrılmasıyla birlikte müşteri terminalinden gereken veriyi ister. Geçmiş verisi terminalde mevcutsa, hemen sınama birimine aktarılır. Eğer veriler mevcut değilse, terminal verileri sunucudan ister ve yükler, ardından test birimine aktarır.

Ek enstrümanların verilerine, alım satım işlemleri için çapraz kurları hesaplamak amacıyla da ihtiyaç duyulur. Örneğin, EURCHF üzerinde USD karşıt döviz birimi ile bir sınama gerçekleştirirken, ilk alım satım işlemini gerçekleştirmeden önce, sınama birimi EURUSD ve USDCHF sembollerinin geçmişini müşteri terminalinden ister; ama strateji bu sembollerin doğrudan kullanımını içermez.

Çok dövizli bir stratejiyi sınamadan önce, gereken tüm geçmiş verilerinin müşteri terminaline yüklenmesi önerilir. Bu, sınama/optimizasyon sırasında, istenen verinin yüklenmesinin yol açabileceği gecikmelerin önlenmesine yardımcı olur. Geçmişi, uygun çizelgeyi açıp, onu geçmiş başlangıcına kadar kaydırarak da yükleyebilirsiniz. Terminale zorla veri yüklemeye dair bir örnek de, MQL5 Referansının Veri Erişiminin Düzenlenmesi bölümünde yer almaktadır.

Sınama birimi sınanan sembolün geçmişini terminalden istediğinde, terminal geçmişi sunucudan sadece bir kere yükler. Geçmiş, trafiği azaltmak için paketlenmiş şekilde yüklenir.
Sınama birimleri, geçmişi terminalden paketlenmiş olarak alır. Bir sonraki sınamada, sınama aracı veriyi terminalden yüklemez; istenen veri, sınayıcının bir önceki çalışmasından zaten mevcuttur.


Çok Para Birimli Sınama

Strateji Sınama Aracı, çoklu sembollerle alım satım yapan stratejileri sınamamıza imkan tanır. Önceki platformlarda sınama işlemi sadece tek sembol için gerçekleştirildiğinden, bunlar sıklıkla çok para birimli Uzman Danışmanlar olarak isimlendirilir. MetaTrader 5 terminalinin Strateji Sınama Aracı içinde, alım satım stratejilerini mevcut tüm semboller için modelleyebiliriz.

Sınama aracı, kullanılan sembollerin geçmiş verilerini verinin çağrılmasıyla birlikte müşteri terminalinden (alım satım sunucusundan değil!) otomatik olarak yükler.

Sınama birimi, sınama başlangıcında sadece göstergenin hesaplanması için gereken eksik verileri indirir (geçmiş verileri sağlamak için küçük bir farkla). D1 ve daha düşük zaman aralıkları için, indirilen minimum geçmiş hacmi bir yıldır.

Yani, 2010.11.01 - 2010.12.01 aralığında M15 periyoduyla (1 aylık aralıkta 15 dakikalık çubuklarla) bir sınama gerçekleştiriyorsak, terminal 2010 yılının tamamı için aracın geçmişini isteyecektir. Haftalık zaman aralığı içinse, yaklaşık iki yıla denk gelen (bir yıl 52 hafta içerir)100 çubukluk geçmiş yüklenir. Aylık zaman aralığında sınama gerçekleştirmek için, sınama birimi 8 yıllık geçmiş verisi isteyecektir (12 ay x 8 yıl = 96 ay).

Yeterli sayıda çubuk yoksa, sınama işleminden önce gereken çubuk rezervini sağlamak amacıyla, başlangıç tarihi otomatik olarak geçmişten bugüne kaydırılacaktır.

Test sırasında, semboller hakkında bilgi edinebileceğiniz Piyasa Gözlemi" de simüle edilir.

Ön tanımlı olarak, sınama başlangıcında Strateji Sınama aracındaki "Piyasa Gözlemi" içinde sadece bir sembol bulunur; bu, sınamanın yapılacağı semboldür. Tüm gerekli semboller, başvurulduğunda Strateji Sınama Aracının (terminalin değil!) "Piyasa Gözlemine" bağlanırlar.  

Çok para birimli bir Uzman Danışmanı sınamaya başlamadan önce, istenilen sembolün terminalin "Piyasa Gözlemi"nden seçilmesi ve istenen verinin yüklenmesi gerekir. "Yabancı" bir sembolün ilk çağrısı sırasında sembolün geçmişi, terminal ve sınama birimi arasında senkronize edilir. "Yabancı" sembol, sınama işleminin yapıldığı sembolden farklı olan semboldür.

"Başka" bir sembolün verilerine, şu durumlarda başvuru yapılır:

"Başka" bir sembol ilk defa çağrıldığında, sınama süreci durdurulur ve sembolün/periyodun geçmişi terminalden sınama birimine aktarılır. Bu sembol için gereken tik dizisi de aynı zamanda oluşturulur.

Seçilen tik oluşturma moduna göre, her bir sembol için ayrı tik dizileri oluşturulur. Ayrıca, SymbolSelect() fonksiyonunu OnInit() işleyicisi içinde kullanarak, sembolün geçmişini açık yolla isteyebilirsiniz; geçmişin yüklenmesi işlemi, Uzman Danışmanın sınanmasına başlamadan hemen önce gerçekleştirilir.

Bu şekilde, MetaTrader 5 müşteri terminali içinde çok para birimli bir sınama gerçekleştirmek için ayrı bir çabaya ihtiyaç olmaz. Sadece, uygun sembollerin çizelgelerini müşteri terminalinde açmanız yeterlidir. İstenen veriyi içeren geçmiş, istenen tüm semboller için, alım satım sunucusundan otomatik olarak indirilecektir.


Strateji Sınama Aracında Zamanın Simülasyonu

Sınama sırasında yerel zaman TimeLocal() her zaman TimeTradeServer() sunucu zamanına eşittir. Dolayısıyla, sunucu zamanı daima GMT'ye karşılık gelen zamana eşit olacaktır - TimeGMT(). Bu sebeple, tüm bu fonksiyonlar sınama sırasında aynı zamanı gösterecektir.

Strateji Sınama Aracında GMT zamanı, yerel zaman ve sunucu zamanı arasında fark olmaması, sunucu bağlantısının kurulmaması ihtimaline karşı kasıtlı olarak yapılmıştır. Sınama sonuçları, bağlantı olup olmadığına bakılmaksızın her zaman aynı olmalıdır. Sunucu zamanı hakkındaki bilgi yerel olarak depolanmaz ve sunucudan alınır.

 

Strateji Sınama Aracında OnTimer() Fonksiyonu

MQL5 zamanlayıcı olaylarının işlenmesine izin verir. OnTimer() işleyicisinin çağrısı, sınama modundan bağımsızdır.

"Sadece açılış fiyatları" modunda H4 periyodu için bir sınama gerçekleştirildiğini ve uzman danışmanın saniyelik çağrılar yapan bir zamanlayıcıya sahip olduğunu düşünelim; bu durumda, H4 çubuğunun her açılış anında OnTick() işleyicisi bir defa, OnTimer() işleyicisi ise 14400 defa (3600 saniye * 4 saat) çağrılacaktır. Bu miktar Uzman Danışmanın sınama süresi ve çalışma mantığına bağlı olarak aratacaktır.

Sınama süresinin zamanlayıcı frekansına olan bağımlılığını ölçmek için, alım satım işlemi içermeyen basit bir Uzman Danışman oluşturulmuştur.

//--- input parameters
input int      timer=1;              // timer value, sec
input bool     timer_switch_on=true; // timer on
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- run the timer if  timer_switch_on==true
   if(timer_switch_on)
     {
      EventSetTimer(timer);
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- stop the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
// take no actions, the body of the handler is empty
  }
//+------------------------------------------------------------------+

Test süresi ölçümleri, zamanlayıcı parametresininfarklı değerlerinde (Zamanlayıcı olayının periyodikliği) alınmıştır. Elde edilen veriye göre, sınama süresini Zamanlayıcı periyodunun bir fonksiyonu olarak çizdik.

Şekil 7. Zamanlayıcı periyodunun bir fonksiyonu olarak sınama süresi

Grafikten de görebileceğiniz gibi, EventSetTimer(Timer) fonksiyonunun başlatılması sırasında zamanlayıcı parametresi ne kadar küçükse, OnTimer() işleyicisinin çağrıları arasındaki periyot (Periyot) o kadar küçük ve sınama süresi T de o kadar fazladır.


Strateji Sınama Aracında Sleep() Fonksiyonu

Grafik üzerinde çalışırken Sleep() fonksiyonu, Uzman Danışmana veya betiğe, mql5 programının çalışmasını bir süreliğine durdurma imkanı sağlar. Bu, o an hazır olmayan bir veri istemeniz durumunda ve veri hazır olana kadar beklemeniz gerekiyorsa kullanışlıdır. Sleep() fonksiyonunun detaylı kullanımına dair bir örnek Veri erişiminin düzenlenmesi bölümünde bulunabilir.

Sınama süreci, Sleep() çağrısıyla duraklamaz. Sleep() fonksiyonunu çağırdığınızda, oluşturulan tikler belirtilen gecikme içinde yürütülmeye devam eder; bu da bekleyen emirlerin ve durdurma emirlerinin tetiklenmesiyle sonuçlanabilir. Sleep() çağrısının ardından, Strateji Sınama aracında simüle edilen zaman, Sleep fonksiyonunun parametresinde belirtilen aralık kadar artırılır.

Sleep() fonksiyonunun çalıştırılması sonucunda, Strateji Sınama Aracındaki mevcut zaman sınama periyodunun ötesine geçiyorsa; "Sınama sırasında sonsuz Sleep döngüsü tespit edildi" şeklinde bir hata mesajı alırsınız. Bu hata mesajını almışsanız, test sonuçları reddedilmez, tüm hesaplamalar tam hacmiyle (işlemlerin sayısı, azalma vs.) gerçekleştirilir ve test sonuçları terminale aktarılır.

Sınama süresi, sınama aralığının boyutunu aşacağından, Sleep() fonksiyonu OnDeinit() içerisinde çalışmayacaktır.

Şekil 7. Sleep() fonksiyonunun, MetaTrader 5 terminalinin Strateji Sınama Aracındaki kullanımına dair bir şema

Şekil 8. Sleep() fonksiyonunun, MetaTrader 5 terminalinin Strateji Sınama Aracındaki kullanımına dair bir şema


Matematiksel Hesaplamalardaki Optimizasyon Problemleri için Strateji Sınama Aracının Kullanılması

MetaTrader 5 terminalindeki sınama aracı, sadece alım satım stratejileri için değil, aynı zamanda matematiksel hesaplamalar için de kullanılabilir. Bunu kullanmak için "Matematiksel hesaplamalar" modunu seçmeniz gerekmektedir:

Bu durumda, yalnızca üç fonksiyon çağrılır: OnInit(), OnTester(), OnDeinit(). "Matematiksel hesaplamalar" modunda Strateji Sınama Aracı herhangi bir tik oluşturmayacak ve geçmişi yüklemeyecektir.

Strateji sınama aracı, başlangıç tarihini bitiş tarihinden büyük yazmış olsanız bile "Matematiksel hesaplamalar" modunda çalışır.

Sınama aracını matematiksel problemleri çözmek için kullanırken, tikler oluşturulmayacak ve geçmiş yüklenmeyecektir.

MetaTrader 5 Strateji Sınama Aracında çözmek için tipik bir matematiksel problem, çok değişkenli bir fonksiyonun ekstremumunun aranmasıdır.

Bunun için şu koşullar sağlanmalıdır:

  • Fonksiyon değerinin hesaplama işlemleri OnTester() fonksiyonu içine yerleştirilmelidir;
  • Fonksiyonun parametreleri, Uzman Danışmanın giriş parametreleri olarak belirlenmelidir;

Uzman Danışmanı derleyin ve "Strateji Sınama Aracı" penceresini açın. "Giriş parametreleri" sekmesinde, istenen giriş parametrelerini seçin ve her bir fonksiyon değişkeni için başlangıç, durdurma ve adım değerlerini belirleyerek, parametre değerleri setini tanımlayın.

Optimizasyon tipini seçin: "Yavaş, tam algoritma" (parametre uzayının tamamının aranması) veya "Hızlı, genetik tabanlı algoritma". Fonksiyonun ekstremum değerini basitçe aramak için, hızlı optimizasyonun seçilmesi daha iyi olacaktır; ama bütün parametre kümesi içinarama gerçekleştirmek istiyorsanız, o zaman en iyisi yavaş optimizasyondur.

"Matematiksel hesaplamalar" modunu seçin ve "Başlat" düğmesine basarak optimizasyon prosedürünü çalıştırın. Optimizasyon sırasında Strateji Sınama Aracının, fonksiyonun maksimum değerini arayacağını unutmayın. Eğer yerel minimum değerini bulmak istiyorsanız, hesaplanan fonksiyonun değerini OnTester fonksiyonu içinde ters çevirin:

return(1/function_value);

Fonksiyon değerinin sıfıra eşit olmamasına dikkat edilmelidir, aksi durumda sıfıra bölmeden kaynaklanan bir kritik hata alırız.

Bununla birlikte bir yol daha bulunmaktadır; bu yöntem daha uygundur ve optimizasyon sonuçlarında bozulmaya yol açmaz, bu makalenin okuyucuları tarafından önerilmiştir:

return(-function_value);

Bu seçenekte fonksiyon değerinin sıfıra eşit olup olmadığının kontrol edilmesi gerekmez, 3 boyutlu bir temsilde optimizasyon yüzeyi aynı şekle sahiptir ve orijinal fonksiyonun yansımasıdır.

Örnek olarak sink() fonksiyonunu kullanalım:

Bu fonksiyonun ekstremumunu bulmak için gereken Uzman Danışman kodu OnTester() fonksiyonunun içine yerleştirilir:

//+------------------------------------------------------------------+
//|                                                         Sink.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input double   x=-3.0; // start=-3, step=0.05, stop=3
input double   y=-3.0; // start=-3, step=0.05, stop=3
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double sink=MathSin(x*x+y*y);
//---
   return(sink);
  }
//+------------------------------------------------------------------+
Bir optimizasyon gerçekleştirin ve optimizasyon sonuçlarını 2B grafik şeklinde görün.

Şekil 9. sink (x*x+y*y) tam optimizasyon sonuçları 2 boyutlu grafik şeklinde işlev görür

Verilen parametre değerleri (x, y) ne kadar iyiyse, renk de o kadar canlı olacaktır. sink() formülünden beklendiği gibi, fonksiyonun değerleri (0,0)merkezinin etrafında konsantrik daireler şeklindedir. sink() fonksiyonunun tek bir global ekstremuma sahip olmadığı, 3 boyutlu grafikten görülebilir:

Sink fonksiyonunun 3B Grafiği


"Sadece Açılış fiyatları" modunda Çubukların Senkronizasyonu

MetaTrader 5 müşteri terminalindeki sınama aracı, "çok para birimli" Uzman Danışmanları kontrol etmemizi sağlar. Çok para birimli bir Uzman Danışman, iki veya daha çok sembol üzerinden alım satım gerçekleştiren bir Uzman Danışmandır.

Birden çok sembol üzerinden alım satım yapan stratejilerin sınanması, sınama aracına birkaç ek teknik gereksinim yükler:

  • Bu semboller için tiklerin oluşturulması;
  • Bu semboller içingösterge değerlerinin hesaplanması ;
  • Bu semboller için marjin (teminat) gereksinimlerinin hesaplanması;
  • Oluşturulan tik dizilerinin tüm alım satım sembolleri için senkronize edilmesi.

Strateji sınama aracı, her bir enstrüman için seçilen alım satım moduna göre bir tik dizisini oluşturur ve yürütür. Aynı zamanda, diğer sembollerde nasıl açıldığından bağımsız olarak her bir sembol için yeni bir çubuk açılır. Yani, çok para birimli Uzman Danışmanların sınanması sırasında, bir enstrüman için yeni çubuğun çoktan açıldığı, diğeri içinse henüz açılmadığı bir durumla karşılaşılabilir (bu durum sıklıkla yaşanır). Böylece, sınama içindeki her şey gerçekte olduğu gibi olur.

Sınama aracında geçmişin özgün simülasyonu, "Her tik" ve "1 dakikalık OHLC" test modları seçildiği sürece herhangi bir sorun ortaya çıkarmaz. Bu modlarda, farklı sembollerden çubukların senkronizasyonu gerçekleşene kadar bekleyebilmek adına bir mum için yeterli tik işareti oluşturulur. Peki alım satım enstrümanlarının senkronizasyonu bu kadar gerekliyse, çok para birimli stratejileri "Sadece açılış fiyatları" modunda nasıl sınayabiliriz? Bu modda Uzman Danışman sadece açılış zamanına denk gelen tek bir tik üzerinde çağrılır.

Bunu bir örnek üzerinde göstereceğiz: EURUSD üzerinde bir uzman danışmanı test ediyorsak ve EURUSD üzerinde yeni bir saatlik mum açılmışsa, "Sadece açılış fiyatları" modunda sınama yaparak bu olayı kolayca anlayabiliriz; Yeni Tik olayı, sınama periyodunun üzerindeki çubuk açılış zamanına denk gelecektir. Amam yeni çubuğun Uzman Danışmanda kullanılan USDJPY sembolü üzerinde de açılacağı kesin değildir.

Normal koşullar altında, OnTick() fonksiyonunun işlemini tamamlamak ve bir sonraki tik ile birlikte USDJPY sembolü üzerinde yeni bir çubuğun oluşup oluşmadığını kontrol etmek yeterlidir. Ama "Sadece açılış fiyatları" modunda bir sınama gerçekleştirirken başka bir tik olmayacaktır; bu yüzden bu modun çok para birimli Uzman Danışmanların sınanması için uygun olmadığı düşünülebilir. Ama öyle değildir; MetaTrader 5 içindeki sınama aracının gerçek hayattaki gibi davrandığını unutmamanız gerekir. Sleep() fonksiyonunu kullanarak, diğer semboller için yeni çubuklar açılana kadar bekleyebilirsiniz!

Synchronize_Bars_Use_Sleep.mq5 Uzman Danışmanının kodu, "Sadece açılış fiyatları" modunda çubukların senkronizasyonunun bir örneğini göstermektedir:

//+------------------------------------------------------------------+
//|                                   Synchronize_Bars_Use_Sleep.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input string   other_symbol="USDJPY";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- check symbol
   if(_Symbol==other_symbol)
     {
      PrintFormat("You have to specify the other symbol in input parameters or select other symbol in Strategy Tester!");
      //--- forced stop testing
      return(-1);
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- static variable, used for storage of last bar time
   static datetime last_bar_time=0;
//--- sync flag
   static bool synchonized=false;

//--- if static variable isn't initialized
   if(last_bar_time==0)
     {
      //--- it's first call, save bar time and exit
      last_bar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE);
      PrintFormat("The last_bar_time variable is initialized with value %s",TimeToString(last_bar_time));
     }

//--- get open time of the last bar of chart symbol
   datetime curr_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
//--- if times aren't equal
   if(curr_time!=last_bar_time)
     {
      //--- save open bar time to the static variable
      last_bar_time=curr_time;
      //--- not synchronized
      synchonized=false;
      //--- print message
      PrintFormat("A new bar has appeared on symbol %s at %s",_Symbol,TimeToString(TimeCurrent()));
     }
//--- open time of the other symbol's bar
   datetime other_time;

//--- loop until the open time of other symbol become equal to curr_time
   while(!(curr_time==(other_time=(datetime)SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_DATE)) && !synchonized))
     {
      PrintFormat("Waiting 5 seconds..");
      //--- wait 5 seconds and call SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_DATE)
      Sleep(5000);
     }
//--- bars are synchronized
   synchonized=true;
   PrintFormat("Open bar time of the chart symbol %s: is %s",_Symbol,TimeToString(last_bar_time));
   PrintFormat("Open bar time of the symbol %s: is %s",other_symbol,TimeToString(other_time));
//--- TimeCurrent() is not useful, use TimeTradeServer()
   Print("The bars are synchronized at ",TimeToString(TimeTradeServer(),TIME_SECONDS));
  }
//+------------------------------------------------------------------+

Uzman Danışmanın son satırına dikkat edin; bu satırda senkronizasyonun gerçekleştirildiği mevcut zaman görüntülenmektedir:

   Print("The bars synchronized at ",TimeToString(TimeTradeServer(),TIME_SECONDS));

Mevcut zamanı görüntülemek için TimeCurrent() fonksiyonunun yerine TimeTradeServer() fonksiyonunu kullandık. TimeCurrent() fonksiyonu, Sleep() çağrısından sonra değişmeyen son tik zamanına dönüş yapar. Bu Uzman Danışmanı "Sadece açılış fiyatları" modunda çalıştırdığınızda, çubukların senkronizasyonuna dair bir mesaj görürsünüz.


Son tik zamanı yerine mevcut sunucu zamanını almanız gerekiyorsa, TimeCurrent() yerine TimeTradeServer() fonksiyonunu kullanın.

Çubukların senkronizasyonu için bir yol daha mevcuttur: Zamanlayıcı kullanımı. Bu tip bir Uzman Danışman örneği (Synchronize_Bars_Use_OnTimer.mq5) bu makaleye eklenmiştir.


Sınama aracı içinde IndicatorRelease() Fonksiyonu

Tekil bir sınama tamamladıktan sonra, otomatik olarak aracın bir grafiği açılır. Bu grafikte, tamamlanan sözleşmeler ve Uzman Danışmanda kullanılan göstergeler yer alır. Bu, giriş çıkış noktalarını görsel olarak analiz etmenize ve bunları gösterge değerleriyle karşılaştırmanızaolanak sağlar.  

Not: Sınama işleminden sonra açılan grafikte görüntülenen göstergeler, sınamanın tamamlanmasından sonra yeniden hesaplanır. Bu göstergeler Uzman Danışman İçerisinde kullanılmış olsa bile.

Ama bazı durumlarda, programcı hangi göstergelerin alım satım algoritmalarına dahil olduğunu gizlemek isteyebilir. Örneğin, Uzman Danışmanın kodu, kaynak kodu sağlanmadan yürütülebilir bir dosya olarak kiralanır veya satılır. Bu amaç için, IndicatorRelease() fonksiyonunun kullanımı uygundur.

Eğer terminal tarafından, directory/profiles/templates konumundan tester.tpl isimli bir şablon ayarlanırsa, bu şablon açılan grafiğe uygulanacaktır. Bu şablonun yokluğu durumunda ise, varsayılan şablon uygulanacaktır (default.tpl).

Aslında IndicatorRelease() fonksiyonu asıl olarak, artık gerekmediğinde göstergenin hesaplama kısmını serbest bırakmak üzere tasarlanmıştır. Bunun amacı, bellek ve CPU kaynaklarını korumaktır, çünkü her yeni tik ile gösterge hesaplanması için yeniden çağrılır. İkinci bir amaç ise, tekil bir sınamadan sonra göstergenin sınama grafiğinde görüntülenmesini engellemektir.

Sınama işleminden sonra göstergenin grafik üzerinde görüntülenmesini engellemek için, IndicatorRelease() fonksiyonunu, gösterge tanıtıcısı ile OnDeinit() işleyicisinin içinde çağırın. OnDeinit() fonksiyonu her zaman sınama tamamlandıktan sonra ve sınama grafiği gösterilmeden önce çalışır.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   bool hidden=IndicatorRelease(handle_ind);
   if(hidden) Print("IndicatorRelease() successfully completed");
   else Print("IndicatorRelease() returned false. Error code ",GetLastError());
  }
Sınama işleminden sonra göstergenin grafik üzerinde görüntülenmesini engellemek için IndicatorRelease() fonksiyonunu OnDeinit() işleyicisinin içerisinde çağırın.


Sınama Aracında Olay İşleme

MetaTrader 5 sınama aracında geçmiş verisi ile sınamaya konu olması açısından OnTick() işleyicisinin Uzman Danışman içindeki varlığı zorunlu değildir. Bir Uzman Danışmanın aşağıdaki işleyicilerden en az birini içermesi yeterlidir:

  • OnTick() - Gelen yeni tik olayının işleyicisi;
  • OnTrade() - Alım satım olayının işleyicisi;
  • OnTimer() - Zamanlayıcıdan gelen sinyal olaylarının işleyicisi;
  • OnChartEvent() - Müşteri olayları için bir işleyici.

Bir Uzman Danışmanı sınarken OnChartEvent() fonksiyonunu kullanarak özel olayları işleyebiliriz, ama bu fonksiyon göstergelerde sınama aracı içinde çağrılamaz. Gösterge OnChartEvent() olay işleyicisini içeriyorsa ve gösterge sınanan Uzman Danışmanda kullanılıyor olsa bile, gösterge herhangi bir özel olay almayacaktır.

Sınama sırasında, göstergeler EventChartCustom() fonksiyonu ile özel olaylar oluşturabilirler ve Uzman Danışman bu olayı OnChartEvent() içerisinde işleyebilir.


Sınama Birimleri

MetaTrader 5 müşteri terminalinde sınama, sınama birimleri kullanılarak gerçekleştirilir. Yerel birimler, otomatik olarak oluşturulup devreye sokulurlar. Yerel birimlerin sayısı bilgisayardaki çekirdek sayısına karşılık gelir.

Her sınama birimi, müşteri terminalinden bağımsız olarak global değişkenlerin kendisine has kopyasına sahiptir. Burada terminal, görevleri yerel veya uzak birimlere dağıtan bir sevk merkezi gibidir. Birim Uzman Danışmanın sınanması görevini tamamladıktan sonra, verilen parametrelerle birlikte, sonuçları terminale verir. Tek bir sınama için tek bir birim kullanılır.

Birim, terminalden alınan geçmiş verisini, enstrümanların isimlerine göre ayrı klasörlere kopyalar; örneğin, EURUSD geçmişi, EURUSD isimli bir klasöre kaydedilir. Enstrümanların geçmişleri kaynaklarına göre de ayrılır. Geçmiş verilerinin depolanması şu şekilde gözükür:

tester_catalog\Agent-IPaddress-Port\bases\name_source\history\symbol_name

Örneğin, MetaQuotes-Demo sunucusundan alınan EURUSD geçmişi, tester_catalog\Agent-127.0.0.1-3000\bases\MetaQuotes-Demo\EURUSD klasörüne kaydedilebilir.

Yerel birim, sınamanın tamamlanmasının ardından bekleme moduna geçer ve yeni bir görev için 5 dakika boyunca bekler, böylece bir sonraki çağrıda zaman harcanmaz. Bekleme süresinin bitmesiyle, Yerel birim kapanır ve CPU belleğinden kaldırılır.

Kullanıcı tarafından (İptal et düğmesi ile) veya müşteri terminalinin kapatılması sonucunda sınama sürecinin erken tamamlanması durumunda, Tüm birimler hemen işlemlerini durdurur ve bellekten kaldırılır.


Terminal ve Sınama Birimi arasında Veri Değişimi

Bir sınama gerçekleştirdiğinizde, müşteri terminali, birime gönderilmek üzere bir dizi parametre bloku hazırlar:
  • Sınama için giriş parametreleri (simülasyon modu, test aralığı, enstrümanlar, optimizasyon kriteri, vb.)
  • "Piyasa Gözlemi" içinden seçilen sembollerin listesi
  • Sınanacak sembolün özellikleri (sözleşme büyüklüğü, piyasadan StopLoss ve Takeprofit değerlerini ayarlamak için izin verilen marjinler, vb.)
  • Sınanan Uzman Danışman vegiriş parametrelerinin değerleri
  • Ek dosyalar hakkında bilgi (kütüphaneler, göstergeler, veri dosyaları - # property tester_ ...)

    tester_indicator

    dizgi

    "indicator_name.ex5" biçiminde bir özel göstergenin ismi. Sınama gerektiren özel göstergeler, iCustom() fonksiyonunun çağrısıyla otomatik olarak tanımlanırlar (karşılık gelen parametre, bir sabit dizgi ile ayarlanmışsa). Tüm diğer durumlar için (IndicatorCreate() fonksiyonunun kullanımı veya gösterge ismini ayarlayan parametrenin sabit olmayan bir dizgi ile verilmesi) bu özellik istenir

    tester_file

    dizgi

    Sınama aracı için, uzantısı belirtilmiş şekilde, çift tırnak içinde (bir sabit dizgi olarak) dosya adı. Belirlenen dosya, sınama aracına aktarılacak. Test edilecek girdi dosyaları, gerekli olanlar mevcutsa her zaman belirtilmelidir.

    tester_library

    dizgi

    Çift tırnak içinde, uzantılı olarak kütüphane adı. Bir kütüphane dll veya ex5 uzantılarına sahip olabilir. Sınama gerektiren kütüphaneler otomatik olarak tanımlanırlar. Ama, kütüphanelerden herhangi biri, bir özel gösterge tarafından kullanılıyorsa bu özellik gereklidir

Her parametre bloku için, MD5-hash biçiminde bir dijital imza oluşturulur; bunlar birime gönderilir. MD5-hash, her küme için benzersizdir; büyüklüğü hesaplandığı bilgiden kat kat daha küçüktür.

Birim, blokların hash değerlerini alır ve onları zaten elinde olanlarla karşılaştırır. Verilen parametrenin parmak izi, birimin elinde yoksa veya alınan hash değeri birim içerisinde olandan farklıysa, birim bu parametre blokunu kabul eder. Bu, terminal ile sınama birimi arasındaki trafiği azaltır.

Sınama işlemi bittikten sonra birim, tüm sonuçları terminale döndürür. Bu sonuçlar, "Test Sonuçları" ve "Optimizasyon Sonuçları" isimli sekmelerde gösterilir:Alınan kâr, sözleşmelerin sayısı, Sharpe katsayısı, OnTester() fonksiyonunun sonucu, vb.

Optimizasyon sırasında terminal, sınama görevlerini küçük paketler halinde birimlere dağıtır, her paket birkaç görev içerir (her görev, bir giriş parametreleri kümesiyle tekil bir sınma anlamına gelir). Bu, terminal ve birim arasındaki değişim süresini azaltır.

Birimler, güvenlik nedeniyle, terminalden alınan EX5 dosyalarını hiçbir zaman sabit diske kaydetmez; bu yüzden, birimin çalıştığı bilgisayar, gönderilen veriyi kullanamaz. Tüm diğer dosyalar (DLL dosyaları da dahil olmak üzere) güvenlik ortamı (sandbox) içinde tutulur. DLL kullanan Uzman Danışmanları uzak birimlerde sınayamazsınız.

Sınama sonuçları, gerektiğinde hızlı bir şekilde ulaşabilmek amacıyla, terminal tarafından özel bir önbellekte toplanır (sonuç önbelleği). Terminal her parametre kümesi için bir önceki çalışmadan gelen mevcut sonuçları, yeniden işlenmesini önlemek amacıyla sonuç önbelleği içinde kontrol eder. Söz konusu parametre kümesine dair bir sonuç bulunamamışsa; görev, işlenmesi için birime verilir.

Terminal ve sınama birimi arasındaki tüm trafik şifrelenmiştir.


Tüm Müşteri Terminallerinin Ortak Klasörünün Kullanılması

Tüm sınama birimleri, birbirlerinden ve terminalden izole edilmiştir: her birim, günlüğünün kaydedildiği kendine has bir klasöre sahiptir. Bunun yanında, tüm dosya işlemleri agent_name/MQL5/Files klasöründe gerçekleşir. Ama, tüm müşteri terminallerinin ortak klasörünü kullanarak, yerel birimler ve terminal arasında bir etkileşim sağlayabiliriz. Bunun için, dosya açılışı kısmında FILE_COMMON bayrağını belirtmeniz gerekir:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- the shared folder for all of the client terminals
   common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- draw out the name of this folder
   PrintFormat("Open the file in the shared folder of the client terminals %s", common_folder);
//--- open a file in the shared folder (indicated by FILE_COMMON flag)
   handle=FileOpen(filename,FILE_WRITE|FILE_READ|FILE_COMMON);
   ... further actions
//---
   return(0);
  }


DLL Dosyalarının Kullanımı

Optimizasyonu hızlandırmak için sadece yerel değil, aynı zamanda uzak birimleri de kullanabiliriz. Bu durumda, uzak birimler için bazı kısıtlamalar bulunmaktadır. Öncelikle uzak birimler, Print() fonksiyonunun çalıştırılmasından doğan sonuçları ve pozisyon açıp kapama mesajlarını günlüklerinde göstermezler. Hatalı yazılmış Uzman Danışmanların, uzak birimin bulunduğu bilgisayarı mesajlarla çöplüğe çevirmemesi için, günlük içinde sadece gereken minimum bilgiler görüntülenir.

İkinci bir kısıtlama da şudur: Uzman Danışmanların sınanması sırasında DLL kullanımına izin verilmez. Güvenlik nedeniyle, uzak birimler üzerinde DLL çağrılarına kesinlikle izin verilmez. Yerel birimlerde ise sınanmış Uzman Danışmanın DLL kullanmasına sadece uygun "DLL kullanımına izin ver" seçeneğiyle izin verilir.

Şekil 10. Mql5-programları için "DLL kullanımına izin ver" seçeneği

Not: DLL çağrılarına izin verilmesini gerektiren Uzman Danışmanlardan alınanları (komut dosyaları, göstergeler) kullanırken, terminalin ayarlarında bu seçeneğe izin vermekle üstlendiğiniz risklerin farkında olmalısınız. Bu risk, sınama veya bir grafik üzerinde çalıştırma olsun, Uzman Danışmanın ne için kullanılacağıyla alakalı değildir.


Sonuç

Makale, MetaTrader 5 müşteri terminalinde Uzman Danışmanların sınanması konusunda hızlı bir şekilde ustalaşmanıza yardımcı olacak temel bilgilerle ilgilidir:

  • Üç tik oluşturma modu;
  • Sınama sırasında gösterge değerlerininhesaplanması;
  • Çok para birimli sınama;
  • Sınama sırasında zamanın simülasyonu;
  • Strateji Sınama Aracında OnTimer(), OnSleep() ve IndicatorRelease() fonksiyonlarının çalışması;
  • DLL çağrıları sırasında sınama birimlerinin çalışması;
  • Tüm müşteri terminalleri için paylaşılan klasörü kullanma;
  • "Sadece Açılış fiyatları" modunda çubukların senkronizasyonu;
  • Olay İşleme.

Müşteri terminalinin Strateji Sınama Aracının ana görevi, MQL5 programlayıcısının minimum çabasıyla verilerin gerekli doğruluğunu sağlamaktır. Geliştiriciler, yalnızca ticaret stratejinizi geçmiş veriler üzerinde sınamak için kodunuzu yeniden yazmak zorunda kalmamanız adına çok çaba harcadı. Sınamanın temellerini bilmek yeterlidir ve doğru yazılmış bir Uzman Danışman, sınama aracında ve grafikteki çevrimiçi modda eşit şekilde çalışacaktır.


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

MQL5'te Kaynak Kullanımı MQL5'te Kaynak Kullanımı
MQL5 programları sadece rutin hesaplamaları otomatikleştirmekle kalmaz, aynı zamanda tam özellikli bir grafik ortam yaratabilir. Gerçekten etkileşimli kontroller oluşturmaya yönelik fonksiyonlar, artık neredeyse klasik programlama dillerinde olduğu kadar zenginler. MQL5'te tam teşekküllü bir bağımsız program yazmak istiyorsanız, kaynakları içinde kullanın. Kaynakları olan programların bakımı ve dağıtımı kolaydır.
MetaTrader 5 Alım Satım Olayları MetaTrader 5 Alım Satım Olayları
Bir alım satım hesabının mevcut durumunun izlenmesi, açık pozisyonların ve emirlerin kontrol edilmesini gerektirir. Bir alım satım sinyali bir yatırım haline gelmeden önce, müşteri terminalinden alım satım sunucusuna bir istek olarak gönderilmeli ve işlenmeyi bekleyen emir kuyruğuna yerleştirilmelidir. Alım satım sunucusundan gelen bir isteği kabul etmek, süresi dolduğunda silmek veya bir anlaşma yürütmek - tüm bu eylemlerin ardından alım satım etkinlikleri gelir ve alım satım sunucusu, terminali onlar hakkında bilgilendirir.
MQL5 Sihirbazı: Yeni Sürüm MQL5 Sihirbazı: Yeni Sürüm
Bu makale, güncellenmiş MQL5 Sihirbazı'nda bulunan yeni özelliklerin açıklamalarını içerir. Değiştirilmiş sinyal mimarisi, çeşitli piyasa modellerinin kombinasyonuna dayalı alım satım robotları oluşturmayı mümkün kılar. Makalede yer alan örnek, bir Uzman Danışmanın etkileşimli şekilde oluşturulma prosedürünü açıklamaktadır.
MetaTrader 5 Emirler, Pozisyonlar ve Yatırımlar MetaTrader 5 Emirler, Pozisyonlar ve Yatırımlar
Güçlü bir alım satım robotu oluşturmak, MetaTrader 5 alım satım sisteminin mekanizmalarını anlamadan yapılamaz. Müşteri terminali, alım satım sunucusundan pozisyonlar, emirler ve yatırımlar hakkında bilgi alır. Bu verileri MQL5 kullanarak düzgün bir şekilde kullanmak için MQL5 programı ve müşteri terminali arasındaki etkileşimin iyi anlaşılması gerekir.