//+------------------------------------------------------------------ //| Events.mq4 | //| Copyright © 2006, komposter | //| mailto:komposterius@mail.ru | //+------------------------------------------------------------------ #property copyright "Copyright © 2006, komposter" #property link "mailto:komposterius@mail.ru" // das Array eröffneter Positionen beim vorherigen Tick int pre_OrdersArray[][2]; // [Zahl der Positionen][№ Ticketnummer, Positionstyp] // Ereignisvariable int eventBuyClosed_SL = 0, eventBuyClosed_TP = 0; int eventSellClosed_SL = 0, eventSellClosed_TP = 0; int eventBuyLimitDeleted_Exp = 0, eventBuyStopDeleted_Exp = 0; int eventSellLimitDeleted_Exp = 0, eventSellStopDeleted_Exp = 0; int eventBuyLimitOpened = 0, eventBuyStopOpened = 0; int eventSellLimitOpened = 0, eventSellStopOpened = 0; void CheckEvents( int magic = 0 ) { // die Flagge des ersten Starts static bool first = true; // der Code des letzten Fehlers int _GetLastError = 0; // die Gesamtzahl der Positionen int _OrdersTotal = OrdersTotal(); // die Anzahl der Positionen, die den Kriterien entsprechen (das laufende Symbol und die angegebene MagicNumber), // beim laufenden Tick int now_OrdersTotal = 0; // Anzahl der Positionen, die den Kriterien entsprechen, beim vorherigen Tick static int pre_OrdersTotal = 0; // das Array eröffneter Positionen beim vorherigen Tick int now_OrdersArray[][2]; // [№ in der Liste][№ Ticketnummer, Positionstyp] // die laufende Nummer der Position im Array now_OrdersArray (für Suche) int now_CurOrder = 0; // die laufende Nummer der Position im Array pre_OrdersArray (für Suche) int pre_CurOrder = 0; // das Array, wo geschlossene Positionen jeden Typs gespeichert werden int now_ClosedOrdersArray[6][3]; // [Ordertyp][Schließungstyp] // Array, wo ausgelöste Pending Orders gespeichert werden int now_OpenedPendingOrders[4]; // [Ordertyp] // vorläufige Flaggen bool OrderClosed = true, PendingOrderOpened = false; // temporäre Variablen int ticket = 0, type = -1, close_type = -1; //Ereignisvariablen auf Null setzen eventBuyClosed_SL = 0; eventBuyClosed_TP = 0; eventSellClosed_SL = 0; eventSellClosed_TP = 0; eventBuyLimitDeleted_Exp = 0; eventBuyStopDeleted_Exp = 0; eventSellLimitDeleted_Exp = 0; eventSellStopDeleted_Exp = 0; eventBuyLimitOpened = 0; eventBuyStopOpened = 0; eventSellLimitOpened = 0; eventSellStopOpened = 0; // die Größe des Arrays eröffneter Positionen entsprechend der aktuellen Anzahl ändern ArrayResize( now_OrdersArray, MathMax( _OrdersTotal, 1 ) ); // das Array auf Null setzen ArrayInitialize( now_OrdersArray, 0.0 ); // die Arrays geschlossener Positionen und Pending Orders auf Null setzen ArrayInitialize( now_ClosedOrdersArray, 0.0 ); ArrayInitialize( now_OpenedPendingOrders, 0.0 ); //+------------------------------------------------------------------ //| In allen Positionen suchen und nur diejenigen ins Array schreiben, die //| den Kriterien entsprechen //+------------------------------------------------------------------ for ( int z = _OrdersTotal - 1; z >= 0; z -- ) { if ( !OrderSelect( z, SELECT_BY_POS ) ) { _GetLastError = GetLastError(); Print( "OrderSelect( ", z, ", SELECT_BY_POS ) - Error #", _GetLastError ); continue; } // die Zahl der Orders auf dem laufenden Symbol und der Orders mit der angegebenen MagicNumber zählen if ( OrderMagicNumber() == magic && OrderSymbol() == Symbol() ) { now_OrdersArray[now_OrdersTotal][0] = OrderTicket(); now_OrdersArray[now_OrdersTotal][1] = OrderType(); now_OrdersTotal ++; } } // die Größe des Arrays eröffneter Positionen hinsichtlich der Zahl der Positionen, die den Kriterien entsprechen. ArrayResize( now_OrdersArray, MathMax( now_OrdersTotal, 1 ) ); //+------------------------------------------------------------------ //| in der der Liste der Positionen beim vorherigen Tick suchen und geschlossene Positionen sowie ausgelöste //| Pending Orders zählen //+------------------------------------------------------------------ for ( pre_CurOrder = 0; pre_CurOrder < pre_OrdersTotal; pre_CurOrder ++ ) { // das Ticket und den Ordertyp speichern ticket = pre_OrdersArray[pre_CurOrder][0]; type = pre_OrdersArray[pre_CurOrder][1]; // annehmen, wenn dies eine Position war, wurde sie geschlossen, OrderClosed = true; // annehmen, wenn dies eine Pending Order war, wurde sie nicht ausgelöst PendingOrderOpened = false; // in allen Positionen der laufenden Liste eröffneter Positionen suchen for ( now_CurOrder = 0; now_CurOrder < now_OrdersTotal; now_CurOrder ++ ) { // wenn es eine Position mit dem Ticket in der Liste gibt, if ( ticket == now_OrdersArray[now_CurOrder][0] ) { // bedeutet das, dass die Position nicht geschlossen wurde (die Order wurde nicht gelöscht) OrderClosed = false; // wenn sich ihr Typ geändert hat, if ( type != now_OrdersArray[now_CurOrder][1] ) { // war das eine Pending Order, und sie wurde ausgelöst PendingOrderOpened = true; } break; } } // wenn eine Position geschlossen wurde (die Order wurde gelöscht), if ( OrderClosed ) { // diese wählen if ( !OrderSelect( ticket, SELECT_BY_TICKET ) ) { _GetLastError = GetLastError(); Print( "OrderSelect( ", ticket, ", SELECT_BY_TICKET ) - Error #", _GetLastError ); continue; } // und feststellen, WIE die Position geschlossen (die Order gelöscht) wurde: if ( type < 2 ) { // Buy und Sell: 0 - manuell, 1 - SL, 2 - TP close_type = 0; if ( StringFind( OrderComment(), "[sl]" ) >= 0 ) close_type = 1; if ( StringFind( OrderComment(), "[tp]" ) >= 0 ) close_type = 2; } else { // Pending Orders: 0 - manuell, 1 - Verfall close_type = 0; if ( StringFind( OrderComment(), "expiration" ) >= 0 ) close_type = 1; } // ins Array geschlossener Orders schreiben, die Order vom Typ type // wurde unter close_type Bedingungen geschlossen now_ClosedOrdersArray[type][close_type] ++; continue; } // wenn eine Pending Order ausgelöst wurde, if ( PendingOrderOpened ) { // ins Array ausgelöster Orders schreiben, die Order vom Typ type wurde ausgelöst now_OpenedPendingOrders[type-2] ++; continue; } } //+------------------------------------------------------------------ //| Alle notwendigen Informationen wurden gesammelt - den Variablen der Ereignisse entsprechende Werte zuordnen //+------------------------------------------------------------------ // wenn dies nicht der erste Start des Experten ist, if ( !first ) { // in allen Elementen des Arrays ausgelöster Pending Orders suchen for ( type = 2; type < 6; type ++ ) { // wenn dieses Element nicht leer ist (eine Order diesen Typs wurde ausgelöst), den Variablenwert ändern if ( now_OpenedPendingOrders[type-2] > 0 ) SetOpenEvent( type ); } // in allen Elementen des Arrays geschlossener Positionen suchen for ( type = 0; type < 6; type ++ ) { for ( close_type = 0; close_type < 3; close_type ++ ) { // wenn das Element nicht leer ist (die Position wurde geschlossen), den Variablenwert ändern if ( now_ClosedOrdersArray[type][close_type] > 0 ) SetCloseEvent( type, close_type ); } } } else { first = false; } //---- das Array laufender Positionen in das Array vorheriger Positionen speichern ArrayResize( pre_OrdersArray, MathMax( now_OrdersTotal, 1 ) ); for ( now_CurOrder = 0; now_CurOrder < now_OrdersTotal; now_CurOrder ++ ) { pre_OrdersArray[now_CurOrder][0] = now_OrdersArray[now_CurOrder][0]; pre_OrdersArray[now_CurOrder][1] = now_OrdersArray[now_CurOrder][1]; } pre_OrdersTotal = now_OrdersTotal; } void SetOpenEvent( int SetOpenEvent_type ) { switch ( SetOpenEvent_type ) { case OP_BUYLIMIT: eventBuyLimitOpened ++; return(0); case OP_BUYSTOP: eventBuyStopOpened ++; return(0); case OP_SELLLIMIT: eventSellLimitOpened ++; return(0); case OP_SELLSTOP: eventSellStopOpened ++; return(0); } } void SetCloseEvent( int SetCloseEvent_type, int SetCloseEvent_close_type ) { switch ( SetCloseEvent_type ) { case OP_BUY: { if ( SetCloseEvent_close_type == 1 ) eventBuyClosed_SL ++; if ( SetCloseEvent_close_type == 2 ) eventBuyClosed_TP ++; return(0); } case OP_SELL: { if ( SetCloseEvent_close_type == 1 ) eventSellClosed_SL ++; if ( SetCloseEvent_close_type == 2 ) eventSellClosed_TP ++; return(0); } case OP_BUYLIMIT: { if ( SetCloseEvent_close_type == 1 ) eventBuyLimitDeleted_Exp ++; return(0); } case OP_BUYSTOP: { if ( SetCloseEvent_close_type == 1 ) eventBuyStopDeleted_Exp ++; return(0); } case OP_SELLLIMIT: { if ( SetCloseEvent_close_type == 1 ) eventSellLimitDeleted_Exp ++; return(0); } case OP_SELLSTOP: { if ( SetCloseEvent_close_type == 1 ) eventSellStopDeleted_Exp ++; return(0); } } }