OnTesterInit

Fonksiyon, strateji sınayıcısında optimizasyondan önce gerekli eylemleri gerçekleştirmek için TesterInit olayı meydana geldiğinde uzman danışmanlarda çağrılır. İki fonksiyon tipi vardır.

Sonucu geri göndüren versiyon

int  OnTesterInit(void);

Geri dönüş değeri

int tipi değeri; sıfır, optimizasyon başlamadan önce bir grafikte çalışmakta olan bir uzman danışmanın başarılı bir şekilde başlatılması anlamına gelir.

Gerçekleşim sonucunu geri döndüren OnTesterInit() çağrısı sadece program başlatmasına izin verdiği için değil, ayrıca optimizasyonun erken sonlandırılması durumunda hata kodunu geri döndürdüğünden dolayı kullanım için önerilmektedir. INIT_SUCCEEDED (0) dışındaki herhangi bir değerin geri döndürülmesi bir hata demektir, hiçbir optimizasyon başlatılmaz.

Sonucu geri döndüren versiyon sadece eski kodlarla uyumluluk için bırakılmıştır. Kullanım için önerilmemektedir

void  OnTesterInit(void);

Not

TesterInit olayı uzman danışmanın optimizasyonunun strateji sınayıcısında başlamasından önce oluşturulur. Bu olayda, OnTesterDeInit() veya OnTesterPass() olay yöneticilerine sahip bir uzman danışman otomatik olarak ayrı bir terminal grafiğine yüklenir. Strateji sınayıcısında belirtilen sembol ve zaman aralığına sahiptir.

Böyle bir olay, TesterInit, TesterDeinit ve TesterPass olaylarını alır, ancak Init, Deinit ve NewTick olaylarını almaz. Buna göre, optimizasyon sırasında her bir geçişin sonuçlarını işlemek için gerekli tüm mantık OnTesterInit (), OnTesterDeinit () ve OnTesterPass () yöneticilerinde uygulanmalıdır.

Bir strateji optimizasyonu sırasında her bir geçişin sonucu, FrameAdd () fonksiyonunu kullanan OnTester () yöneticisinden bir çerçeve aracılığıyla geçirilebilir.

OnTesterInit() fonksiyonu, optimizasyon sonuçlarının ileri işlemi için optimizasyonun başlangıcından önce bir uzman danışmanı başlatmak üzere tasarlanmıştır. Her zaman OnTesterDeinit() yöneticisiyle birlikte kullanılır.

OnTesterInit() gerçekleşim süresi sınırlıdır. Eğer aşılırsa, optimizasyonun kendisi iptal edilirken uzman danışman zorla durdurulur. Strateji sınayıcısı günlüğünde bir mesaj görüntülenir:

Tester        OnTesterInit works too long. Tester cannot be initialized.

Örnek OnTick'den alınmıştır. Optimizasyon parametrelerini ayarlamak için OnTesterInit() yöneticisi eklenmiştir:

//+------------------------------------------------------------------+
//|                                          OnTesterInit_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Optimizasyon sırasında girdilerin değerlerini ve "
#property description "sınırlamalarını ayarlayan"
#property description "OnTesterInit() yöneticisine sahip örnek uzman danışman"
 
input double lots=0. 1;       // lot cinsinden hacim
input double kATR=3;          // ATR'de sinyal mum uzunluğu
input int    ATRperiod=20;    // ATR gösterge zaman aralığı
input int    holdbars=8;      // pozisyonu açık tutmak için gereken bar sayısı
input int    slippage=10;     // izin verilebilir kayma miktarı
input bool   revers=false;    // sinyali tersine döndür? 
input ulong  EXPERT_MAGIC=0;  // Uzman danışmanın MagicNumber'ı
//--- ATR gösterge yönetimini depolamak için
int atr_handle;
//--- burada son ATR değerini ve mum bedenini saklayacağız
double last_atr,last_body;
datetime lastbar_timeopen;
double trade_lot;
//--- optimizasyon başlangıç zamanını hatırla
datetime optimization_start;
//--- optimizasyonun bitişinden sonra bir grafikte süreyi görüntülemek için
string report;
//+------------------------------------------------------------------+
//| TesterInit fonksiyonu                                            |
//+------------------------------------------------------------------+
void OnTesterInit()
  {
//--- optimizasyon için girdilerin değerlerini ayarla
   ParameterSetRange("lots",false,0.1,0,0,0);
   ParameterSetRange("kATR",true,3.0,1.0,0.3,7.0);
   ParameterSetRange("ATRperiod",true,10,15,1,30);
   ParameterSetRange("holdbars",true,5,3,1,15);
   ParameterSetRange("slippage",false,10,0,0,0);
   ParameterSetRange("revers",true,false,false,1,true);
   ParameterSetRange("EXPERT_MAGIC",false,123456,0,0,0);
   Print("İlk değerler ve optimizasyon parametre sınırlamaları ayarlandı");
//--- optimizasyon başlangıç zamanını hatırla
   optimization_start=TimeLocal();
   report=StringFormat("%s: optimizasyon %s de başlatıldı",
                       __FUNCTION__,TimeToString(TimeLocal(),TIME_MINUTES|TIME_SECONDS));
//--- mesajları grafikte ve terminal günlüğünde göster
   Print(report);
   Comment(report);
//---   
  }
//+------------------------------------------------------------------+
//| TesterDeinit fonksiyonu                                          |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//--- optimizasyon süresi
   string log_message=StringFormat("%s: optimizasyon %d saniye sürdü",
                                   __FUNCTION__,TimeLocal()-optimization_start);
   PrintFormat(log_message);
   report=report+"\r\n"+log_message;
   Comment(report);
  }
//+------------------------------------------------------------------+
//| Uzman danışman başlatma fonksiyonu                               |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- global değişenleri başlat
   last_atr=0;
   last_body=0;
//--- doğru hacmi ayarla
   double min_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   trade_lot=lots>min_lot? lots:min_lot;   
//--- ATR gösterge yöneticisini oluştur
   atr_handle=iATR(_Symbol,_Period,ATRperiod);
   if(atr_handle==INVALID_HANDLE)
     {
      PrintFormat("%s: iATR oluşturulamadı, hata kodu %d",__FUNCTION__,GetLastError());
      return(INIT_FAILED);
     }
//--- başarılı uzman danışman başlatma
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Uzman danışman tik fonksiyonu                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- alım-satım sinyali
   static int signal=0; // +1 alış sinyali anlamına gelmektedir, -1 satın sinyali anlamına gelmektedir
//--- 'holdbars' bar miktarından daha önce açılmış eski pozisyonları kontrol et ve kapat
   ClosePositionsByBars(holdbars,slippage,EXPERT_MAGIC);
//--- yeni bir barı kontrol et
   if(isNewBar())
     {
      //--- sinyal varlığını kontrol et      
      signal=CheckSignal();
     }
//--- eğer bir netleştirme pozisyonu açıksa, sinyali atla - kapanana kadar bekle
   if(signal!=0 && PositionsTotal()>0 && (ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_NETTING)
     {
      signal=0;
      return// NewTick olay yöneticisinden çık ve yeni bir bar görünene kadar piyasaya girme
     }
//--- bir hedging hesabı için, her bir pozisyon ayrı ayrı tutulur ve kapatılır
   if(signal!=0)
     {
      //--- alış sinyali
      if(signal>0)
        {
         PrintFormat("%s: Alış sinyali! Revers=%s",__FUNCTION__,string(revers));
         if(Buy(trade_lot,slippage,EXPERT_MAGIC))
            signal=0;
        }
      //--- satış sinyali
      if(signal<0)
        {
         PrintFormat("%s: Satış sinyali! Revers=%s",__FUNCTION__,string(revers));
         if(Sell(trade_lot,slippage,EXPERT_MAGIC))
            signal=0;
        }
     }
//--- OnTick fonksiyon sonlandırma
  }
//+------------------------------------------------------------------+
//| Yeni bir alım-satım sinyali kontrol et                           |
//+------------------------------------------------------------------+
int CheckSignal()
  {
//--- 0, sinyal yok anlamına gelmektedir
   int res=0;
//--- sondan bir önceki tam barın ATR değerini elde et (bar indeksi 2'dir)
   double atr_value[1];
   if(CopyBuffer(atr_handle,0,2,1,atr_value)!=-1)
     {
      last_atr=atr_value[0];
      //--- son kapanan barın verilerini bir dizi MqlRates'e ilet
      MqlRates bar[1];
      if(CopyRates(_Symbol,_Period,1,1,bar)!=-1)
        {
         //--- son kapanan barın beden ölçüsünü hesapla
         last_body=bar[0].close-bar[0].open;
         //--- eğer son barın bedeni (index 1 olan bar) bir önceki ATR değerini aşarsa (indeks 2'deki bar), bir alım-satım sinyali alınır
         if(MathAbs(last_body)>kATR*last_atr)
            res=last_body>0?1:-1; // yükselen mum için pozitif değer
        }
      else
         PrintFormat("%s: Son bar elde edilemedi! Error",__FUNCTION__,GetLastError());
     }
   else
      PrintFormat("%s: ATR gösterge değeri alınamadı! Error",__FUNCTION__,GetLastError());
//--- eğer ters alım-satım modu etkinse
   res=revers?-res:res;  // eğer gerekliyse sinyali tersine çevir (1 yerine -1'i geri döndür ve -1 yerine de 1'i geri döndür)
//--- bir alım-satım sinyal değerini geri döndür
   return (res);
  }
//+------------------------------------------------------------------+
//|  Yeni bir bar göründüğünde 'true'yu geri döndür                  |
//+------------------------------------------------------------------+
bool isNewBar(const bool print_log=true)
  {
   static datetime bartime=0; // mevcut barın açılış zamanını sakla
//--- sıfır indeksli barın açılış zamanını elde et
   datetime currbar_time=iTime(_Symbol,_Period,0);
//--- eğer açılış zaman bilgisi değişirse, yeni bir bar gelmiş demektir
   if(bartime!=currbar_time)
     {
      bartime=currbar_time;
      lastbar_timeopen=bartime;
      //--- yeni barın açılış zamanı verilerini günlükte göster      
      if(print_log && !(MQLInfoInteger(MQL_OPTIMIZATION)||MQLInfoInteger(MQL_TESTER)))
        {
         //--- yeni barın açılış zamanı bilgisine sahip bir mesaj göster
         PrintFormat("%s: yeni bar %s %s üzerinde %s de açıldı",__FUNCTION__,_Symbol,
                     StringSubstr(EnumToString(_Period),7),
                     TimeToString(TimeCurrent(),TIME_SECONDS));
         //--- son fiyat(tik) hakkındaki verileri elde et
         MqlTick last_tick;
         if(!SymbolInfoTick(Symbol(),last_tick))
            Print("SymbolInfoTick() başarısız oldu, hata = ",GetLastError());
         //--- son fiyat zamanını milisaniye olarak kadar göster
         PrintFormat("Son fiyat %s.%03d taydı",
                     TimeToString(last_tick.time,TIME_SECONDS),last_tick.time_msc%1000);
        }
      //--- yeni bir bar var
      return (true);
     }
//--- yeni bir bar yok
   return (false);
  }
//+------------------------------------------------------------------+
//| Belirtilen hacimle, piyasa fiyatından alış yap                   |
//+------------------------------------------------------------------+
bool Buy(double volume,ulong deviation=10,ulong  magicnumber=0)
  {
//--- piyasa fiyatından alış yap
   return (MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber));
  }
//+------------------------------------------------------------------+
//| Belirtilen hacimle, piyasa fiyatından satış yap                  |
//+------------------------------------------------------------------+
bool Sell(double volume,ulong deviation=10,ulong  magicnumber=0)
  {
//--- piyasa fiyatından alış yap
   return (MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber));
  }
//+------------------------------------------------------------------+
//| Bar sayısı ile hesaplanan açık tutma süresine göre pozisyonu kapat             
//+------------------------------------------------------------------+
void ClosePositionsByBars(int holdtimebars,ulong deviation=10,ulong  magicnumber=0)
  {
   int total=PositionsTotal(); // açık pozisyonların sayısı   
//--- tüm açık pozisyonları ara
   for(int i=total-1; i>=0; i--)
     {
      //--- pozisyon parametreleri
      ulong  position_ticket=PositionGetTicket(i);                                      // pozisyon bileti
      string position_symbol=PositionGetString(POSITION_SYMBOL);                        // sembol 
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                  // pozisyon MagicNumber'ı
      datetime position_open=(datetime)PositionGetInteger(POSITION_TIME);               // pozisyon açılış zamanı
      int bars=iBarShift(_Symbol,PERIOD_CURRENT,position_open)+1;                       // kaç bar önce pozisyon açıldı
 
      //--- eğer bir pozisyonun ömrü, MagicNumber ve sembol eşleşirken, halihazırda fazlaysa
      if(bars>holdtimebars && magic==magicnumber && position_symbol==_Symbol)
        {
         int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);           // ondalık basamak sayısı
         double volume=PositionGetDouble(POSITION_VOLUME);                              // pozisyon hacmi
         ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // pozisyon türü
         string str_type=StringSubstr(EnumToString(type),14);
         StringToLower(str_type); // doğru mesaj formatı için metin kutusunu küçült
         PrintFormat(" #%I64u %s %s %.2f pozisyonunu kapat",
                     position_ticket,position_symbol,str_type,volume);
         //--- emir türünü belirle ve alım-satım isteğini gönder
         if(type==POSITION_TYPE_BUY)
            MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber,position_ticket);
         else
            MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber,position_ticket);
        }
     }
  }
//+------------------------------------------------------------------+
//| Bir alım-satım isteği hazırla ve gönder                          |
//+------------------------------------------------------------------+
bool MarketOrder(ENUM_ORDER_TYPE type,double volume,ulong slip,ulong magicnumber,ulong pos_ticket=0)
  {
//--- yapıların bildirimi ve başlatımı
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   double price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
   if(type==ORDER_TYPE_BUY)
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
//--- istek parametreleri
   request.action   =TRADE_ACTION_DEAL;                     // İşlem türü
   request.position =pos_ticket;                            // kapanıyorsa, pozisyon bileti
   request.symbol   =Symbol();                              // sembol
   request.volume   =volume;                                // hacim 
   request.type     =type;                                  // emir türü
   request.price    =price;                                 // alım-satım fiyatı
   request.deviation=slip;                                  // fiyattan izin verilen sapma
   request.magic    =magicnumber;                           // emir MagicNumber'ı
//--- bir istek gönder
   if(!OrderSend(request,result))
     {
      //--- başarısızlık verilerini görüntüle
      PrintFormat("OrderSend %s %s %.2f %.5f de hata %d",
                  request.symbol,EnumToString(type),volume,request.price,GetLastError());
      return (false);
     }
//--- başarılı operasyonu bildir
   PrintFormat("retcode=%u  işlem=%I64u  emir=%I64u",result.retcode,result.deal,result.order);
   return (true);
  }

Ayrıca bakınız

Alım-satım stratejilerini sınama, Optimizasyon sonuçlarıyla çalışma, OnTesterDeinit, OnTesterPass, ParameterGetRange, ParameterSetRange