//+------------------------------------------------------------------+
//| EA, belirtilen sayıda kârsız işlem serisine ulaşıldığında ileri |
//| çalışma talebini içeren bir MessageBox penceresi görüntüler. |
//| Belirtilen sayıda çubuk için beklenir ve çalışmaya devam etme |
//| isteğini içeren bir MessageBox penceresi görüntülenir. |
//| EA, basitlik için sihirli sayı ile kendi "pozisyonlarını" |
//| kontrol etmediğinden, kontrol etmek amacıyla |
//| zararla birkaç pozisyonu manuel olarak açıp kapatmamız gerekir. |
//+------------------------------------------------------------------+
//--- girdi parametreleri
input uint InpMaxLossDeals = 3; // Maksimum zararla kapanan işlem sayısı
input uint InpInactivityNumBars = 5; // Uzman Danışmanın faaliyetsiz kaldığı çubuk sayısı
//--- global değişkenler
bool ExtFirstStart=true; // İlk başlatma bayrağı
bool ExtFlag=true; // Uzman Danışmanın çalışmasına izin vermek için bayrak
uint ExtNumLoss; // Ardışık kârsız işlem sayısı
datetime ExtTimeLastLoss; // Zarardaki bir pozisyonu kapatmak için son işlemin zamanı
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- ardışık zararla kapanan işlem sayısını ve pozisyonu kapatmak için son işlemin zamanını al
ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- serideki son zararla kapanan pozisyondan bu yana kaç çubuk geçtiğini belirle
int bars_remaining=iBarShift(Symbol(),PERIOD_CURRENT,ExtTimeLastLoss);
//--- eğer bu ilk başlatma ise
if(ExtFirstStart)
{
//--- kârsız pozisyon serisinden sonra belirtilen sayıda çubuk geçtiyse, Uzman Danışmanın çalışma bayrağını ayarla
if(bars_remaining>(int)InpInactivityNumBars)
ExtFlag=true;
ExtFirstStart=false;
}
//--- Uzman Danışmanın çalışma bayrağı devre dışı ise
if(!ExtFlag)
{
Comment(StringFormat("The advisor is stopped for %d bars. Num Loss positions: %u, Time last loss: %s",
(InpInactivityNumBars-bars_remaining),ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS)));
//--- kârsız pozisyon serisinden sonra belirli sayıda çubuk geçtiyse
if(bars_remaining>(int)InpInactivityNumBars)
{
//--- belirtilen metin ve pencere başlığı ile bir MessageBox penceresi görüntüle
//--- talep penceresinde Yes/No düğmesi ve soru işaretli bir simge bulunur.
//--- Yes düğmesi varsayılan olarak seçilir.
string mb_text="The specified number of bars of EA inactivity have passed.\n Continue its work?";
string mb_caption="Please note";
int mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1);
//--- MessageBox'tan geri dönen kod basılmış Yes düğmesiyse, Uzman Danışmanın çalışma bayrağını ayarla
if(mb_id==IDYES)
{
ExtFlag=true;
return;
}
}
//--- Uzman Danışmanın çalışma bayrağı devre dışı, OnTick() fonksiyonundan çık
return;
}
//--- Uzman Danışmanın çalışma bayrağı ayarlandı - Uzman Danışman aşağıdaki kodda belirtildiği gibi çalışır
Comment(StringFormat("The advisor is working. Num Loss positions: %u, Time last loss: %s, Elapsed Bars: %d",
ExtNumLoss,TimeToString(ExtTimeLastLoss,TIME_DATE|TIME_MINUTES|TIME_SECONDS),bars_remaining));
}
//+------------------------------------------------------------------+
//| TradeTransaction fonksiyonu |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
//--- işlem türü geçmişe bir işlem eklemek ise
if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
{
//--- bir işlem fişi al ve listeden fişe göre bir işlem seç
ulong deal_ticket=trans.deal;
if(HistoryDealSelect(deal_ticket))
{
//--- bu bir piyasadan çıkış işlemi ise, ardışık zararla kapanan işlem sayısını ve son işlemin zamanını al
ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
if(entry==DEAL_ENTRY_OUT || entry==DEAL_ENTRY_INOUT || entry==DEAL_ENTRY_OUT_BY)
ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
}
}
//--- ardışık zararla kapanan işlem sayısı belirtilen değerden fazlaysa ve Uzman Danışmanın çalışma bayrağı etkinse
if(ExtNumLoss>=InpMaxLossDeals && ExtFlag)
{
//--- belirtilen metin ve pencere başlığı ile bir MessageBox penceresi görüntüle
//--- talep penceresinde Yes/No düğmesi ve ünlem işaretli bir simge bulunur.
//--- No düğmesi varsayılan olarak seçilir.
string mb_text="The number of losing trades has reached the specified maximum. The advisor is stopped.\n Continue its work?";
string mb_caption="Attention!";
int mb_id=MessageBox(mb_text,mb_caption,MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
//--- MessageBox'tan geri dönen kod basılmış No düğmesiyse, Uzman Danışmanın çalışma bayrağını devre dışı bırak
if(mb_id==IDNO)
ExtFlag=false;
}
}
//+------------------------------------------------------------------+
//| Ardışık kârsız işlem sayısını ve zarardaki bir pozisyonu |
//| kapatmak için son işlemin zamanını geri döndür |
//+------------------------------------------------------------------+
uint GetNumLosingTradesInRow(datetime &time_last_deal)
{
//--- tüm geçmişi seç
if(!HistorySelect(0,TimeCurrent()))
return(0);
//--- bir döngü içerisinde geçmiş işlemlerin listesine göre bir sonraki işlem fişini al
uint res=0;
uint total=HistoryDealsTotal();
for(int i=(int)total-1; i>=0; i--)
{
ulong deal_ticket=HistoryDealGetTicket(i);
if(deal_ticket>0)
{
//--- eğer işlem pozisyondan çıkmak için değilse, bir sonrakine geç
ENUM_DEAL_ENTRY entry=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
if(entry!=DEAL_ENTRY_OUT && entry!=DEAL_ENTRY_OUT_BY && entry!=DEAL_ENTRY_INOUT)
continue;
//--- bir pozisyonu kapatmanın sonucunda kâr varsa, döngüyü kes
if(!IsClosePositionWithLoss(deal_ticket))
break;
//--- ardışık zararla kapanan işlem sayacını artır
res++;
//--- en büyük işlem zamanını bir değişkene yaz (sonuncuyu ara)
datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
if(deal_time>time_last_deal)
time_last_deal=deal_time;
}
}
//--- ardışık zarar sayısını geri döndür
return(res);
}
//+------------------------------------------------------------------+
//| Bir pozisyonu zararla kapatma bayrağını geri döndür |
//+------------------------------------------------------------------+
bool IsClosePositionWithLoss(const ulong deal_ticket)
{
//--- işlemden elde edilen kârı etkileyen özelliklerin değerlerini al
double profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
double comission=HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
double swap=HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
double fee=HistoryDealGetDouble(deal_ticket,DEAL_FEE);
//--- özelliklerin toplam değerinin negatif olduğunu belirten bayrağı geri döndür
return(profit+comission+swap+fee<0);
}
|