//+------------------------------------------------------------------+
//| Die MessageBox des EAs mit einer Aufforderung zur Weiterarbeit. |
//| Bei Erreichen einer bestimmten Anzahl einer Verlustserie |
//| warte für die angegebene Balkenzahl und zeige MessageBox mit |
//| einer Aufforderung zur Weiterarbeit. |
//| Zur Prüfung müssen wir Positionen manuell öffnen und mit |
//| mit Verlusten schließen, da der EA seine "Positionen" der |
//| der Einfachheit halber nicht über seine magische Zahl steuert. |
//+------------------------------------------------------------------+
//--- Eingabeparameter
input uint InpMaxLossDeals = 3; // Deals, Maximalverlust
input uint InpInactivityNumBars = 5; // Balkenzahl ohne Aktivität des EAs
//--- globale Variable
bool ExtFirstStart=true; // Flag für Erststart
bool ExtFlag=true; // Flag der "Arbeitserlaubnis" für den EA
uint ExtNumLoss; // Anzahl aufeinanderfolgender Handelsgeschäfte mit Verlust
datetime ExtTimeLastLoss; // Schließzeit der letzten Position mit einem Verlust
//+------------------------------------------------------------------+
//| Expert Initialisierungsfunktion |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Ermitteln der Anzahl aufeinanderfolgender Verlustgeschäfte und des Zeitpunkts des letzten Handelsgeschäfts, das die Position schließt
ExtNumLoss=GetNumLosingTradesInRow(ExtTimeLastLoss);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialisierungsfunktion des Experten |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Tick-Funktion des Experten |
//+------------------------------------------------------------------+
void OnTick()
{
//--- Feststellen, wie viele Balken seit der letzten geschlossenen Verlustposition in der Serie vergangen sind
int bars_remaining=iBarShift(Symbol(),PERIOD_CURRENT,ExtTimeLastLoss);
//--- Wenn das der erste Start ist
if(ExtFirstStart)
{
//--- Wenn nach einer Reihe unrentabler Positionen bereits eine bestimmte Anzahl von Balken verstrichen ist, setze das EA-Operations-Flag
if(bars_remaining>(int)InpInactivityNumBars)
ExtFlag=true;
ExtFirstStart=false;
}
//--- wenn das EA-Operations-Flag deaktiviert ist
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)));
//--- wenn nach einer Reihe von unrentablen Positionen eine bestimmte Anzahl von Balken vergangen ist
if(bars_remaining>(int)InpInactivityNumBars)
{
//--- Fenster der MessageBox mit angegebenen Text und Fenstertitel
//--- das Abfragefenster hat zwei Schaltflächen Yes/No (Ja/Nein) und ein Symbol mit einem Fragezeichen.
//--- die Schaltfläche Yes (Ja) ist standardmäßig ausgewählt.
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);
//--- wenn der Rückgabewert von MessageBox die gedrückte Ja-Taste ist, setze das EA-Operations-Flag
if(mb_id==IDYES)
{
ExtFlag=true;
return;
}
}
//--- ist das EA-Operations-Flag deaktiviert, verlasse OnTick()
return;
}
//--- das EA-Operations-Flag ist gesetzt - der EA funktioniert wie im folgenden Code angegeben
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 Funktion |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
//--- wenn der Transaktionstyp das Hinzufügen einer Transaktion zur Historie ist
if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
{
//--- das Deal-Ticket abrufen und ein Deal aus der Liste mit dem Ticket auswählen
ulong deal_ticket=trans.deal;
if(HistoryDealSelect(deal_ticket))
{
//--- wenn eine Position geschlossen wurde, ermittle die Anzahl der Verlustgeschäfte in Folge und den Zeitpunkt des letzten Handelsgeschäfts
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);
}
}
//--- wenn die Anzahl der Verlustgeschäfte in einer Reihe größer ist als der angegebene Wert und das EA-Operations-Flag aktiviert ist
if(ExtNumLoss>=InpMaxLossDeals && ExtFlag)
{
//--- Fenster der MessageBox mit angegebenen Text und Fenstertitel
//--- das Abfragefenster hat zwei Schaltflächen Yes/No (Ja/Nein) und ein Symbol mit einem Rufzeichen.
//--- die Schaltfläche No (Nein) ist standardmäßig ausgewählt.
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);
//--- wenn in der MessageBox die Schaltfläche No (Nein) gedrückt und zurückgegeben wird, wird das EA-Operastions-Flag deaktiviert
if(mb_id==IDNO)
ExtFlag=false;
}
}
//+------------------------------------------------------------------+
//| Gib die Anzahl der fortlaufenden Verlust-Deals zurück |
//| und den Zeitpunkt der letzten, schließenden Position |
//+------------------------------------------------------------------+
uint GetNumLosingTradesInRow(datetime &time_last_deal)
{
//--- Auswahl der ganzen Historie
if(!HistorySelect(0,TimeCurrent()))
return(0);
//--- Ermitteln des nächsten Handelstickets anhand der Liste der historischen Deals in einer Schleife
uint res=0;
uint total=HistoryDealsTotal();
for(int i=(int)total-1; i>=0; i--)
{
ulong deal_ticket=HistoryDealGetTicket(i);
if(deal_ticket>0)
{
//--- wenn der Deal nicht zum Schließen der Position führt, wechsele zum nächsten
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;
//--- wenn das Ergebnis des Schließens einer Position einen Gewinn ergibt, unterbrich die Schleife
if(!IsClosePositionWithLoss(deal_ticket))
break;
//--- den Zähler der fortlaufenden Verlust-Deals erhöhen
res++;
//--- die maximale Handelszeit einer Variablen zuweisen (suche die letzte)
datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
if(deal_time>time_last_deal)
time_last_deal=deal_time;
}
}
//--- Rückgabe der Anzahl der fortlaufenden Verluste
return(res);
}
//+------------------------------------------------------------------+
//| Rückgabe des Flags für das Schließen einer Position mit Verlust |
//+------------------------------------------------------------------+
bool IsClosePositionWithLoss(const ulong deal_ticket)
{
//--- Ermitteln der Eigenschaften, die den Handelsgewinn beeinflussen
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);
//--- Rückgabe des Flags, das anzeigt, dass der Gesamtwert der erhaltenen Eigenschaften negativ ist
return(profit+comission+swap+fee<0);
}
|