//+------------------------------------------------------------------+ //| 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); } |