Was der Logbucheintrag bedeutet

 
Wenn ich versuche, einen Handel mit einem Expert Advisor zu schließen, erhalte ich (nicht zum ersten Mal) die Meldung: Ping failed
Was ist das und wie kann ich damit umgehen?
Beim Neustart von MT (die Abschlussbedingung ist noch gültig) wird das Geschäft erfolgreich abgeschlossen.

Es gibt keine Fehler im Protokoll, die Ausgabe in der Datei, die ich buchstäblich über eine Zeile, zeigt, dass OrderSend WORKED, kein Fehler, aber hier ist das Problem: a) der Auftrag in der Liste der offenen blieb und b) es geschlossen auf Neustart von MT, so war es nicht nur in der Liste, sondern auch in der Realität.

Nur für den Fall, dass Meta die Logs mit Alpari abgleichen möchte, Konto 142605, Ticket 1728130

Ich hoffe, noch eine Antwort zu bekommen, dies ist nicht mein erster Beitrag über diesen Fehler.
Mit freundlichen Grüßen,
Quark
 
Vielen Dank, wir werden uns das ansehen.
Können Sie mir ein Stück des Protokolls vom Moment der Anfrage bis zum Moment, in dem der Ping fehlgeschlagen ist, schicken (es ist wichtig, Timeouts zu überprüfen)? Und ist dies auf einem echten oder einem Demo-Konto?
 
<br/ translate="no"> Danke, wir werden uns das ansehen.
Können Sie einen Teil des Protokolls vom Zeitpunkt der Anfrage bis zum Empfang des fehlgeschlagenen Ping senden (es ist wichtig, Timeouts zu überprüfen)? Und ist dies auf einem echten oder einem Demokonto?


Dies ist ein Demokonto. Log... Ich habe das MT geschlossen und wieder geöffnet, so dass der Eintrag auf der Registerkarte "Log" aktualisiert wurde. Ich werde es das nächste Mal kopieren, dann neu starten, es fühlt sich an, als ob es ein paar Tage dauern wird, ich meine ein Wiederauftreten des Problems. Ich kann nur ein Protokoll aus dem Verzeichnis experts\logs vorschlagen. Ist es das, was Sie im Sinn hatten?

In der Kontohistorie entspricht diese Transaktion der folgenden Zeile (warum gibt es in dieser Registerkarte übrigens keine zeilenweise Kopie in den Puffer?):
1728130 2005.08.31 15:00 buy 0.10 eurusd 1.2223 1.2183 0 2005.08.31 20:07 1.2330 0 107.00 Freitag

Ich bin in Moskau, kann es in der Analyse der Handelszeiten benötigt werden.

Beachten Sie, dass der Expert Advisor den Handel um 20:07 Uhr geschlossen hat. In Wirklichkeit war die Schließungsbedingung um 20:01 Uhr, aber die Position wurde nicht geschlossen. Ich schloss und öffnete MT, und bei 20,07, d.h. sofort, innerhalb von Sekunden nach dem Neustart der Position geschlossen.

Jetzt habe ich mir das Protokoll angesehen (das ganze Protokoll), aber es ist 147Kb groß. Ich werde es anhängen, wenn Sie wollen, aber glauben Sie mir, es gibt nur zwei Einträge für dieses Geschäft:

17:00:18 _Friday_Expert EURUSD,H1: open #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 ok
...
22:07:24 _Freitag_Experte EURUSD,H1: close #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 at price 1.2330

Es scheint also keinen Versuch zu geben , die Position bei 20.01 zu schließen. "Irgendwie", weil a) die Registerkarte "Log" (ich hatte nicht erwartet, dass MT sie zurücksetzt) eine Notiz über den Ping-Versuch und den Fehlschlag zeigte und b) da dies nicht das erste Problem mit diesem EA ist, sehen Sie sich an, wie es von innen aussieht:

	for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);

		if(OrderMagicNumber() == nMagic)
		{
SaveComment("\r\n\t" + MathFloor(CurTime() / 3600) + " - " +
	MathFloor(OrderOpenTime() / 3600) + " >= " + nHoursToHold);

			int nCurHour = TimeHour(CurTime());
			int nOrderOpenHour = TimeHour(OrderOpenTime());
			if(nOrderOpenHour > nCurHour)
				nCurHour += 24;
			
			// if(MathFloor(CurTime() / 3600) - MathFloor(OrderOpenTime() / 3600) >= nHoursToHold)
			if(nCurHour - nOrderOpenHour >= nHoursToHold) 
			{
				if(OrderType() == OP_BUY)
				{
					CloseBuy("Friday");
SaveComment(", nbuy closed"); 
				}
				else if(OrderType() == OP_SELL)
				{
					CloseSell("Friday");
SaveComment(", sell closed");
				}
			}
		}
	}

...


void CloseBuy(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket);
	
	int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
		
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + ", error: " + nError);
	}
		
}

// ------

void CloseSell(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket);
	
	int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + ", error: " + nError);
	}

}
// ------



SaveComment schreibt nur Text in eine Datei.
So erschienen alle Einträge in der Datei, die für die versuchte Schließung der Position geeignet waren, aber der Alarm wurde nicht aufgerufen, d.h. OrderClose gab den Code für den erfolgreichen Abschluss zurück.


 
Ich habe also, wie versprochen, auf Fehlerwiederholungen gewartet. Beachten Sie sofort, dass dieser Fehler bereits auf einem anderen EA erschienen war, so ist es wahrscheinlich nicht der Code (obwohl alles sein kann). Aber dieser Expert Advisor war "nicht fertig", in dem Sinne, dass er nicht mit allen möglichen Funktionen zur Ausgabe in die Datei gefüllt war.

Im Protokoll steht ein Fehler: ping failed.

Vielleicht sollte Ihr System nach einem fehlgeschlagenen Ping die Ausführung von OrderSend nicht zulassen, dann würde eine Fehlermeldung generiert werden.

In diesem Fall gibt es keine Fehlermeldung, sondern nur einen Protokolleintrag. Das Programm verhält sich so, als hätte es den Handel geschlossen, nur wird der Handel nicht geschlossen.

Also, im Log:
2005.09.05 16:01:35 TradeContext: ping failed
2005.09.05 16:01:35 TradeContext: ping error
2005.09.05 16:01:14 '142605': close order #1775545 sell 0.10 EURUSD at 1.2535 sl: 0.0000 tp: 0.0000 zum Preis von 1.2542
2005.09.05 16:01:14 '142605': login (4.00, #27FFBBD7)

Übrigens, ich frage mich wirklich, warum sl: 0.0000, ich sende keine Null.

Gleichzeitig sieht die Startfunktion wie folgt aus:

int start()
{
	if(Bars < 5)
		return(0);
	
	Report("Friday", nMagic, bReportDone);

	// ------
	
	if(!IsBarEnd())
		return(0);
		
	CheckTradeSemaphore();
	
	// ------
	
	if(bUseMm == true)
	{
		dProfit = 0;
		
		for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++)
		{
			OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY);
			if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL)
			{
				dProfit += OrderProfit();
			}
		}
	}

	int nSignal = GetSignal();

SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
switch(nSignal)
{
	case -1: SaveComment(", Signal: none"); break;
	case OP_BUY: SaveComment(", Signal: buy"); break;
	case OP_SELL: SaveComment(", Signal: sell"); break;
	default: SaveComment(", Signal: ????"); break;
}

	for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);

		if(OrderMagicNumber() == nMagic)
		{
SaveComment("\r\n\t" + MathFloor(CurTime() / 3600) + " - " +
	MathFloor(OrderOpenTime() / 3600) + " >= " + nHoursToHold);

			int nCurHour = TimeHour(CurTime());
			int nOrderOpenHour = TimeHour(OrderOpenTime());
			if(nOrderOpenHour > nCurHour)
				nCurHour += 24;
			
			// if(MathFloor(CurTime() / 3600) - MathFloor(OrderOpenTime() / 3600) >= nHoursToHold)
			if(nCurHour - nOrderOpenHour >= nHoursToHold) 
			{
				if(OrderType() == OP_BUY)
				{
					CloseBuy("Friday");
SaveComment(", buy closed"); 
				}
				else if(OrderType() == OP_SELL)
				{
					CloseSell("Friday");
SaveComment(", sell closed");
				}
			}
		}
	}

 	int nNumOfOpenedOrders = 0;
	for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
		if(OrderMagicNumber() == nMagic)
			nNumOfOpenedOrders++;
	}

	if(nNumOfOpenedOrders == 0)
	{
		if(nSignal == OP_BUY) 
		{
SaveComment("\r\n\tAsk: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit);
			Buy("Friday");
SaveComment("\r\n\tbuy opened");
		}
		else if(nSignal == OP_SELL) 
		{
SaveComment("\r\n\tBid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit);
			Sell("Friday");
SaveComment("\r\n\tsell opened");
		}
	}
SaveComment("\r\n");

	// ------
	
//	ModifyOrders();
	
	// ------
	
	if(!IsTesting())
		GlobalVariableSet(strTradeSemaphore, 0.0);	

	// ------
		
	return(0);
}



SaveComment ist eine Funktion zur Ausgabe der Zeichenkette in eine Datei.

Hier ist die Funktion zum Schließen der Position, die von Anfang an aufgerufen wird. Wie Sie sehen können, wird 5 Mal versucht, die Position zu schließen (ich habe das nur zu Testzwecken gemacht), und wenn kein Fehlercode zurückgegeben wird (d.h. MT denkt, dass die Position geschlossen ist), sucht es unter den noch offenen Aufträgen nach demjenigen, der das erforderliche Ticket hat.

void CloseSell(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket);
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
	}
}



Das unten stehende Protokoll zeigt, dass alle 5 Versuche, einen Auftrag zu schließen, fehlgeschlagen sind (das Ticket ist nicht verschwunden), wobei MT davon ausgeht, dass die Position geschlossen ist.


5.9.2005 14:1:29, Signal: none
312758.00000000 - 312754.00000000 >= 4
Versuch, Short-Position zu schließen, Ticket: 1775545
Order mit diesem Ticket immer noch vorhanden, erneuter Versuch
Order mit diesem Ticket immer noch vorhanden, erneuter Versuch
Order mit diesem Ticket immer noch vorhanden, erneuter Versuch
Order mit diesem Ticket immer noch vorhanden, erneuter Versuch, Verkauf geschlossen

Hinweis: haben Sie keine Angst vor "Signal: none" - es sollte so sein. Dies ist ein Signal zum Eröffnen einer neuen Position. Das Signal zum Schließen einer Position wird erzeugt, wenn die Ungleichung "312758.00000000 - 312754.00000000 >= 4" erfüllt ist,


Liebe Entwickler!
Ich hoffe sehr, dass wir dieses Problem gemeinsam lösen werden.

Quark

P.S. Wie immer, wenn ich MT neu starte, wird die Position von EA geschlossen, ohne k.l. Probleme.

 
Ich warte immer noch auf eine Antwort von den Entwicklern.
Code hinzugefügt, der die Ergebnisse in eine Datei schreibt, wenn ich versuche, ein Geschäft in allen meinen EAs zu öffnen oder zu schließen. Das Ergebnis ist enttäuschend. Ungefähr jedes Mal, für alle EAs, ist ein Versuch, einen Auftrag zu öffnen und zu schließen, nicht genug. Im Durchschnitt braucht es zwei (siehe Code oben, es gibt einen Zyklus von fünf Versuchen). Manchmal sind fünf Versuche nicht genug. Gleichzeitig arbeitet MT so, als ob der Auftrag erfolgreich geöffnet - geschlossen wird, es werden keine Fehlermeldungen ausgegeben.

Alle Semaphoren, die im Zweig "Fehler Nummer 6" vorgeschlagen wurden (was übrigens immer noch manchmal vorkommt), verwende ich, und der Timer der Expert Advisors garantiert, dass jeder EA in den ihm zugewiesenen 10 Sekunden startet, d.h. es sollte keine Konflikte zwischen EAs geben.

Ich schlage vor, dass andere Entwickler den unten stehenden Code in Live-EAs verwenden, um zu prüfen, ob alle Ihre Aufträge so funktionieren, wie Sie es erwarten. Vom Standpunkt des Handels aus gesehen handelt es sich um einen normalen OrderSend, der von Funktionen zur Ausgabe in eine Datei umgeben ist.

Nichts für ungut, aber es scheint, dass MT die Interaktion mit dem Handelsserver noch optimieren muss.

double GetLotSize(double dInitFraction = 0.1, double dProfitFraction = 0.1)
{
	double dLot = 0.1;
	
	if(bUseMm)
	{
		dLot  = (dInitFraction * dInitAmount + dProfitFraction * dProfit) / 1000;

		dLot = MathFloor(dLot * 10) / 10;
	
		if(dLot < 0.1)
			dLot = 0.1;
	}
	
	return(dLot);
}

// ------

void Sell(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Bid - dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment("Trying to sell, attempt " + nTry + "\r\n");
		
		nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 
			dTp, strExpertName, nMagic, 0, OrangeRed);
		
		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
			SaveComment(" failed, error " + GetLastError() + "\r\n");
	}	
	
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
		SaveComment(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
	}
}

// ------

void Buy(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Ask + dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment("Trying to buy, attempt " + nTry);
		
		nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, 
			dTp, strExpertName, nMagic, 0, Aqua);

		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
			SaveComment(" failed, error " + GetLastError() + "\r\n");
	}	

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);

		SaveComment(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);
	}
}

// ------

void CloseBuy(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket);
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
		
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
	}
}

// ------

void CloseSell(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket);
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
	}
}

// ------

void SaveComment(string strComment)
{
	if(!IsTesting())
	{
		int hFile = FileOpen("__test_" + strExpert + "_" + Symbol() + ".txt", 
			FILE_BIN | FILE_READ | FILE_WRITE, '\t');	
	
		FileSeek(hFile, 0, SEEK_END);
		FileWriteString(hFile, strComment, StringLen(strComment));
		// FileFlush(hFile);
	
		FileClose(hFile);
	}
}

// ------



 
Vielleicht öffnen/schließen Ihre EAs die Trades zu oft. Ich ging speziell durch die Geschichte der Geschäfte (ich habe 8 EAs hängen) und ich habe eine Anzahl von Zeiten, wenn es mehr als eine Transaktion in einer Minute (nicht mehr als 10), alle von ihnen sind erfolgreich. Es ist wahr, EAs arbeiten auf Bar Eröffnungen auf 1H, 4H, D1 und Timeouts sind überall eingefügt, aber Timeouts nur zwischen Geschäften von einem EA (in der Tat ich brauche sie nicht), keine Semaphoren zwischen EAs.
Dann müssen wir die Grenze des erlaubten Intervalls auf dem Demokonto finden.
 
Ich habe auch 8 EAs hängen im Moment, alle auf M5.
Von 00:00 bis 12:00
Berufe - 141
3 Fehler ("1" und zwei "6").

Quark, können Sie werfen mich in komposterius E-Mail ru die letzte glitchy Version Ihres EA (die auf M1 ist)? Ich werde noch 8 weitere Fenster aufhängen - mal sehen, was passiert ;)
 
Ihr überseht den Hauptpunkt. Ich habe KEINE Minutenexperten. Der gesamte Handel erfolgt nach Zeitplan. Ich habe KEINE häufigen Handelsgeschäfte, höchstens eines pro Stunde.

Experten warten (unter Verwendung von Semaphoren) auf eine Warteschlange, außerdem wartet der EA mit der magischen Zahl 10 z.B. 10 * 10 = 100 Sekunden ab dem Beginn eines Balkens, und erst dann wird gehandelt. Daher ist die Wahrscheinlichkeit, einen EA mit Magic 11 anzutreffen, auch ohne Semaphoren nahe bei 0.

Der Eindruck ist, dass, wenn MT einmal fehlschlägt (Ping fehlgeschlagen, Fehler 6, etc.) etwas schief geht in seinem System und nachfolgende Trades dieser EA fehlschlagen.

Beispiel eines Protokolls (Code siehe oben):

Versuch zu kaufen, Versuch 0 fehlgeschlagen, Fehler 6
Versuch zu kaufen, Versuch 1 fehlgeschlagen, Fehler 129
Versuch zu kaufen, Versuch 2 fehlgeschlagen, Fehler 129
Versuch zu kaufen, Versuch 3 fehlgeschlagen, Fehler 129
Versuch zu kaufen, Versuch 4 fehlgeschlagen, Fehler 129
Zickzack-Kauffehler: 4050
2.28000000, 0.02700000, 0.00000000

Was haben wir hier? Zuerst gab es einen Fehler (im Protokoll - Verbindungsfehler mit dem Server). Dann ergeben 5 Wiederholungen (ich habe 5 in meiner Schleife) 129 - falscher Preis. Unten ist der Preis - ganz normal. Nach dem Neustart von MT zu diesem Preis wurde der Auftrag erfolgreich eröffnet. Dann erhalten wir 4050, die falsche Anzahl von Argumenten. Dies ist eine Funktion, die auch bei anderen Aufrufen gut funktioniert. Das Fehlermeldesystem hat eindeutig versagt.

Ich zitiere einen Experten, obwohl ich vermute, dass man viele davon haben muss, damit das Problem häufig auftritt. Hoffentlich sehen sich der Kompostierer, Roche und die Entwickler den Code an und geben einen Rat. Dennoch denke ich, dass es sich hier um MT handelt.

Experte:
extern double dZigzagSize;
extern int nMa1;
extern int nMa2;
extern int nBuySell;

// ------

double dTrailingStop;
double dStopLoss;
double dTakeProfit;

bool bUseMm = false;

string strExpert = "Zigzag";

// ------

#include "mylib.mq4"

// ------

int init ()
{
	nBars = 0;//Bars;
	if(!IsTesting() && !GlobalVariableCheck(strTradeSemaphore))
		GlobalVariableSet(strTradeSemaphore, 0.0);

	// ------

	if(IsTesting() && nMa1 >= nMa2)
		return(-1);

	if(Symbol() == "EURUSD" && Period() == 60)
	{
		if(!IsTesting())
		{
			dZigzagSize = 210; 					// 210,60,108,3: 2397, 614
			nMa1 = 48;							// 210,48,120,1: 2016, 332
			nMa2 = 120;

			nBuySell = 1;
		}

		nMagic = 23;
	}
	else if(Symbol() == "EURJPY" && Period() == 60)
	{
		if(!IsTesting())
		{										// 240,24,132,1: 1987, 387
			dZigzagSize = 240; 					
			nMa1 = 24;							
			nMa2 = 132;

			nBuySell = 3;
		}										
												
		nMagic = 2;
	}
	else if(Symbol() == "USDCHF" && Period() == 60)
	{
		if(!IsTesting())
		{										// 260,36,204,2: 2219, 262
			dZigzagSize = 260; 					
			nMa1 = 36;							 
			nMa2 = 204;
			
			nBuySell = 2;
		}										
												

		nMagic = 3;
	}
	else if(Symbol() == "GBPUSD" && Period() == 60)
	{
		if(!IsTesting())
		{										// 270,48,84,3: 5515, 679
			dZigzagSize = 270; 					
			nMa1 = 48;							
			nMa2 = 84;							
			
			nBuySell = 3;
		}										

		nMagic = 4;
	}
	else if(Symbol() == "GBPCHF" && Period() == 60)
	{
		if(!IsTesting())
		{										// 270,96,108,1: 2854,292
			dZigzagSize = 270; 					
			nMa1 = 96;							
			nMa2 = 108;

			nBuySell = 1;
		}				
						
		nMagic = 5;
	}
	else if(Symbol() == "USDCAD" && Period() == 60)
	{
		if(!IsTesting())
		{										// 220,60,300: 1906, 213
			dZigzagSize = 220; 					
			nMa1 = 60;							  
			nMa2 = 300;

			nBuySell = 2;
		}				
						
		nMagic = 7;
	}
	else if(Symbol() == "EURAUD" && Period() == 60)
	{
		if(!IsTesting())
		{										// 210,24,36,3: 3921, 545
			dZigzagSize = 230; 					// 230,24,60,3: 3397, 453
			nMa1 = 24;							// 230,24,132,3: 2819, 292 
			nMa2 = 60;
			
			nBuySell = 3;
		}			

		nMagic = 9;
	}
	
	dStopLoss = dZigzagSize * Point;
	dTrailingStop = dZigzagSize * Point;
	
	dTakeProfit = 0;
	
	return(0);
}
//////////////////
int deinit()
{
	if(!IsTesting())
		GlobalVariableSetOnCondition(strTradeSemaphore, 0.0, nMagic);
	return(0);
}
////////////////////
int start()
{
	if(Bars < MathMax(nMa1, nMa2))
		return(0);

	if(IsTesting() && nMa1 >= nMa2)
		return(0);

	Report("Zigzag", nMagic, bReportDone);

	// ------

	if(!IsBarEnd())
		return(0);

	CheckTradeSemaphore();

	// ------

	int nSignal = 0;
	double dMa1;
	double dMa2;
	
	nSignal = iCustom(NULL, 0, "_Zigzag_Ind", dZigzagSize, 0, 1);
		
	dMa1 = iMA(NULL, 0, nMa1, 0, MODE_EMA, PRICE_CLOSE, 1);
	dMa2 = iMA(NULL, 0, nMa2, 0, MODE_EMA, PRICE_CLOSE, 1);

	if(bUseMm == true)
	{
		dProfit = 0;
		
		for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++)
		{
			OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY);
			if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL)
			{
				dProfit += OrderProfit();
			}
		}   
 	}

	for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
		if(OrderMagicNumber() == nMagic)
		{
			int nMode = OrderType(); 
	
			if(nMode == OP_BUY && nSignal == 1)
			{
				CloseBuy("Zigzag");
				break;
			}
			else if(nMode == OP_SELL && nSignal == -1)
			{		
				CloseSell("Zigzag");
				break;					
	    	}
		}
	}

 	int nNumOfOpenedOrders = 0;
	for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
		if(OrderMagicNumber() == nMagic)
			nNumOfOpenedOrders++;
	}

	if(!nNumOfOpenedOrders)
	{
		if(nSignal == -1 && dMa1 >= dMa2)
		{
			if(nBuySell == 1 || nBuySell == 3)
				Buy("Zigzag");
		}
		else if((nSignal == 1 && dMa1 <= dMa2))
		{
			if(nBuySell == 2 || nBuySell == 3)
				Sell("Zigzag");
		}
	}

	// ------
	
	ModifyOrders();	
	
	// ------
	
	if(!IsTesting())
		GlobalVariableSet(strTradeSemaphore, 0.0);	

	// ------

	return(0);
}

// ------



Indikator:

#property copyright "Quark"
#property link      ""

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_minimum -1
#property indicator_maximum 1

// indicator parameters
extern int nMinMaxPoints = 50;

// indicator buffers
double arrExtMapBuffer[];

int nExtCountedBars = 0;

int nLastMinMaxBar;
int nLastMinMaxType;

double dLastMin, dLastMax;

////////////////////////
int init()
{
	string strIndicatorShortName;

	// drawing settings
	SetIndexStyle(0, DRAW_HISTOGRAM);
	SetIndexShift(0, 0);
	SetIndexEmptyValue(0,0.0);
		
	IndicatorDigits(4);
		
	strIndicatorShortName = "Zigzag(" + nMinMaxPoints + ")";  
	IndicatorShortName(strIndicatorShortName);

	// indicator buffers mapping
	SetIndexBuffer(0, arrExtMapBuffer);

	dLastMin = Low[Bars - 1];
	dLastMax = High[Bars - 1];

	nLastMinMaxBar = Bars - 1;
	nLastMinMaxType = 0;

	int nPos = Bars - 1;
	int nLastPos = nPos;

	while(nPos >= 0)	// Looking for a first min or max
	{
		if(dLastMax <= High[nPos])
		{
			dLastMax = High[nPos];
			nLastMinMaxBar = nPos;
		}

		if(dLastMin >= Low[nPos])
		{
			dLastMin = Low[nPos];
			nLastMinMaxBar = nPos;
		}

		if(Low[nPos] < dLastMax - nMinMaxPoints * Point)	// Maximum found
		{
			nLastMinMaxType = 1;
			dLastMin = Low[nPos];
			dLastMax = High[nPos];
			nLastMinMaxBar = nPos;
		
			break;
		}
		else if(High[nPos] > dLastMin + nMinMaxPoints * Point)	// Minimum found
		{
			nLastMinMaxType = -1;
			dLastMax = High[nPos];
			dLastMin = Low[nPos];
			nLastMinMaxBar = nPos;
			
			break;			
		}

		nPos--;
	}

	return(0);
}
////////////////////
int start()
{
	nExtCountedBars = IndicatorCounted();
	if(nExtCountedBars < 0) 
		return(-1);

	// last counted bar will be recounted
	if(nExtCountedBars > 0) 
		nExtCountedBars--;

	Zigzag();  

	return(0);
}
///////////////////
void Zigzag()
{
	int nPos = Bars - nExtCountedBars - 2;

	while(nPos > 0)
	{
		arrExtMapBuffer[nPos] = 0.0;
		
		double dLastMaxTmp = dLastMax;
		double dLastMinTmp = dLastMin;
		
		if(nLastMinMaxType != 1)	// Expecting maximum
		{
			if(dLastMax <= High[nPos])
			{
				dLastMax = High[nPos];
				nLastMinMaxBar = nPos;
			}
			
			if(Low[nPos] < dLastMax - nMinMaxPoints * Point)	// Maximum found
			{
				if(High[nPos] - Low[nPos] <= nMinMaxPoints * Point)
				{
					arrExtMapBuffer[nPos] = 1;//High[nLastMinMaxBar];
					nLastMinMaxType = 1;
					dLastMin = Low[nPos];
					dLastMax = High[nPos];
					nLastMinMaxBar = nPos;
				}
				else
				{
					arrExtMapBuffer[nPos] = 0;
					arrExtMapBuffer[nPos + 1] = 0;
					dLastMax = dLastMaxTmp;
					dLastMin = dLastMinTmp;
				}
			}
		}
		
		if(nLastMinMaxType != -1)	// Expecting minimum
		{
			if(dLastMin >= Low[nPos])
			{
				dLastMin = Low[nPos];
				nLastMinMaxBar = nPos;
			}
			
			if(High[nPos] > dLastMin + nMinMaxPoints * Point)	// Maximum found
			{
				if(High[nPos] - Low[nPos] <= nMinMaxPoints * Point)
				{
					arrExtMapBuffer[nPos] = -1;//Low[nLastMinMaxBar];
					nLastMinMaxType = -1;
					dLastMax = High[nPos];
					dLastMin = Low[nPos];
					nLastMinMaxBar = nPos;
				}
				else
				{
					arrExtMapBuffer[nPos] = 0;
					arrExtMapBuffer[nPos + 1] = 0;
					dLastMax = dLastMaxTmp;
					dLastMin = dLastMinTmp;
				}
			}
		}

		nPos--;
	}
}
///////////////////
/*

if(IsTesting())
{
	FileDelete("__zigzag_test.txt"); 
	hFile = FileOpen("__zigzag_test.txt", FILE_BIN | FILE_WRITE, '\t');	
}

void SaveComment(string strComment)
{
	if(IsTesting())
	{
		FileWriteString(hFile, strComment, StringLen(strComment));
	}
}

if(IsTesting())
	FileClose(hFile);
*/



Bibliotheksdatei, muss im Verzeichnis Expert liegen:

double dTp = 0;

//double dStop;

datetime timePrev = 0;
int nBars;
int nDelaySeconds = 10;

int nSlip = 5;

double dProfit = 0;
double dInitAmount = 1000;
double dLotSize = 0.1;

int nMagic = 0;
bool bReportDone = false;

string strTradeSemaphore = "TradeSemaphore";

// ------

void Report(string strFileName, int nMagic, bool& bReportDone)
{
	if(IsTesting())
		return;
	if(Hour() == 0 && Minute() >= nMagic / 2 && IsTesting() == false)
	{
		if(bReportDone == false)
		{
			int hFile = FileOpen(strFileName + "_" + Symbol() + "_" + Period() + ".rpt", 
				FILE_BIN | FILE_WRITE, ',');
			
			string str = "CloseDateTime,Buy,Sell\r\n";
			FileWriteString(hFile, str, StringLen(str)); 

			for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++)
			{
				OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY);	
				if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL && OrderSymbol() == Symbol())
				{
					str = TimeToStr(OrderCloseTime(), TIME_DATE|TIME_MINUTES);
					
					if(OrderType() == OP_BUY)
						str = str + "," + OrderProfit() + ",0";
					else
						str = str + ",0," + OrderProfit();
					
					str = str + "\r\n";
					
					FileWriteString(hFile, str, StringLen(str));
				}
			}			

			FileFlush(hFile); 
			FileClose(hFile); 
			
			bReportDone = true;
		}
	}
	else if(Hour() != 0)
		bReportDone = false;
}

// ------

double GetLotSize(double dInitFraction = 0.1, double dProfitFraction = 0.1)
{
	double dLot = 0.1;
	
	if(bUseMm)
	{
		dLot  = (dInitFraction * dInitAmount + dProfitFraction * dProfit) / 1000;

		dLot = MathFloor(dLot * 10) / 10;
	
		if(dLot < 0.1)
			dLot = 0.1;
	}
	
	return(dLot);
}

// ------

void Sell(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Bid - dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		SaveComment(" Trying to sell, attempt " + nTry + "\r\n");
		SaveComment("Ask: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n");
		
		nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 
			dTp, strExpertName, nMagic, 0, OrangeRed);
		
		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
			SaveComment(" failed, error " + GetLastError() + "\r\n");
	}	
	
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
		SaveComment(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
	}
}

// ------

void Buy(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Ask + dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		SaveComment(" Trying to buy, attempt " + nTry + "\r\n");
		SaveComment("Bid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit);
		
		nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, 
			dTp, strExpertName, nMagic, 0, Aqua);

		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
			SaveComment(" failed, error " + GetLastError() + "\r\n");
	}	

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);

		SaveComment(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);
	}
}

// ------

void ModifyOrders()
{
	for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
		if(OrderMagicNumber() == nMagic)
		{
			if(OrderType() == OP_BUY)
			{
				if(OrderStopLoss() < Bid - dTrailingStop - 5 * Point)
				{
					OrderModify(OrderTicket(), OrderOpenPrice(), 
						Bid - dTrailingStop, OrderTakeProfit(), 0, Aqua);

					break;
				}
			}
			
			if(OrderType() == OP_SELL)
			{
				if(OrderStopLoss() > Ask + dTrailingStop + 5 * Point)
				{
					OrderModify(OrderTicket(), OrderOpenPrice(), 
						Ask + dTrailingStop, OrderTakeProfit(), 0, OrangeRed);

					break;
				}
			}
		}
	}
}

// ------
/*
void ModifyOrders(double dTrailingConvergence = 1)
{
	for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);
		if(OrderMagicNumber() == nMagic)
		{
			if(dTrailingConvergence != 1)
			{
				dStop *= dTrailingConvergence;
				dStop = NormalizeDouble(dStop, MarketInfo(Symbol(), MODE_DIGITS));
				if(dStop < 10 * Point)
					dStop = 10 * Point;			
			}

			if(OrderType() == OP_BUY)
			{
				if(OrderStopLoss() < Bid - dStop - 5 * Point)
				{
					OrderModify(OrderTicket(), OrderOpenPrice(), 
						Bid - dStop, OrderTakeProfit(), 0, Aqua);

					break;
				}
			}
			
			if(OrderType() == OP_SELL)
			{
				if(OrderStopLoss() > Ask + dStop + 5 * Point)
				{
					OrderModify(OrderTicket(), OrderOpenPrice(), 
						Ask + dStop, OrderTakeProfit(), 0, OrangeRed);

					break;
				}
			}
		}
	}
}
*/
// ------

bool IsBarEnd()
{
	bool bIsBarEnd = false;
	if(nBars != Bars)
	{
		if(IsTesting() || (!IsTesting() && CurTime() > Time[0] + nMagic * nDelaySeconds))
		{
			bIsBarEnd = true;
			nBars = Bars;
		}
	}
	
	return(bIsBarEnd);
}

// ------

void CheckTradeSemaphore()
{
	if(!IsTesting())
	{
//		int n = 1;
		while(!IsStopped())
		{
			GlobalVariableSetOnCondition(strTradeSemaphore, nMagic, 0.0);
//			if(GlobalVariableGet(strTradeSemaphore) == 0.0)
//				GlobalVariableSet(strTradeSemaphore, nMagic);

			if(GlobalVariableGet(strTradeSemaphore) == nMagic)
				break;

//			Comment(GlobalVariableGet(strTradeSemaphore) + ": " + n);
//			n++;
		
			Sleep(1000);
		}
	
		RefreshRates();
	}
}

// ------
/*
void CloseBuy(string strExpertName)
{
	int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + nError);
	}
}

// ------

void CloseSell(string strExpertName)
{
	int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert("Noc_1 close: " + nError);
	}
}
*/
// ------

void CloseBuy(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket + "\r\n");
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
		
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
	}
}

// ------

void CloseSell(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket + "\r\n");
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
	}
}

// ------

void SaveComment(string strComment)
{
	if(!IsTesting())
	{
		int hFile = FileOpen("__test_" + strExpert + "_" + Symbol() + ".txt", 
			FILE_BIN | FILE_READ | FILE_WRITE, '\t');	
	
		FileSeek(hFile, 0, SEEK_END);
		FileWriteString(hFile, strComment, StringLen(strComment));
		// FileFlush(hFile);
	
		FileClose(hFile);
	}
}

// ------

 
Du hast mich wirklich neugierig gemacht, Quark :)
Es ist an der Zeit, dass die Entwickler über einen Job für Sie als Mitarbeiter nachdenken, um alle möglichen Gemeinheiten zu finden.
Vielleicht liegt es am Ping, ich habe keine Zyklen, um Bestellungen zu wiederholen, vielleicht sollte ich an dieser Stelle Refresh anrufen und frischere Preise einstecken.
Ich verliere mich ...:)
 
Nun, du hast es endlich geschafft, Quark :)<br / translate="no"> Es wird Zeit, dass die Entwickler über eine freie Stelle für dich als Mitarbeiter nachdenken, damit sie alle möglichen Gemeinheiten finden.
Vielleicht liegt es am Ping, ich habe keine Zyklen, um Bestellungen zu wiederholen, vielleicht muss ich an dieser Stelle Refresh anrufen und frischere Preise einstecken.
Ich verliere mich ...:)


Gute Idee... Wird jetzt gemacht...
 
Eine neue Ausgabe, mit einem Pitch von Roche:
void Sell(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Bid - dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		SaveComment(" Trying to sell, attempt " + nTry + "\r\n");
		SaveComment("Ask: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n");
		
		nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 
			dTp, strExpertName, nMagic, 0, OrangeRed);
		
		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
		{
			SaveComment(" failed, error " + GetLastError() + "\r\n");
			RefreshRates();
		}
	}	
	
	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
		SaveComment(strExpertName + " sell error: " + nError + "\r\n" +
			Bid + ", " + dStopLoss + ", " + dTp);
	}
}

// ------

void Buy(string strExpertName)
{
	dLotSize = GetLotSize();
	
	if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500)
		return;

	double dTp;
	if(dTakeProfit == 0)
		dTp = 0;
	else
		dTp = Ask + dTakeProfit;

	int nResult;
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		SaveComment(" Trying to buy, attempt " + nTry + "\r\n");
		SaveComment("Bid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit);
		
		nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, 
			dTp, strExpertName, nMagic, 0, Aqua);

		if(nResult != -1)
		{
			SaveComment(" successfull\r\n");
			break;
		}
		else
		{
			SaveComment(" failed, error " + GetLastError() + "\r\n");
			RefreshRates();
		}
	}	

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);

		SaveComment(strExpertName + " buy error: " + nError + "\r\n" +
			Ask + ", " + dStopLoss + ", " + dTp);
	}
}


void CloseBuy(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket + "\r\n");
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
		
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
			SaveComment(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
		{
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
			RefreshRates();
		}
	}
}

// ------

void CloseSell(string strExpertName)
{
	int nTicket = OrderTicket();
	SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket + "\r\n");
	
	for(int nTry = 0; nTry < 5; nTry++)
	{
		SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
		if(nResult == -1)
		{
			int nError = GetLastError();
			Alert(strExpertName + ", error: " + nError);
			SaveComment(strExpertName + ", error: " + nError);
		}
		
		bool bClosed = true;
		for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--)
		{
			OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES);
			if(OrderTicket() == nTicket)
			{
				bClosed = false;
				break;
			}
		}
		
		if(bClosed == true)
		{
			SaveComment("\r\n\tNo more orders with this ticket No");
			break;
		}
		else
		{
			SaveComment("\r\n\tOrder with this ticket still present, trying again");
			RefreshRates();
		}
	}
}