日志中的条目意味着什么

 
当我试图用专家顾问关闭一个交易时,我得到(不是第一次):Ping failed
这是什么,如何处理?
当重新启动MT(关闭条件仍然有效)时,交易成功关闭。

日志中没有错误,文件中的输出,我按字面意思横放了一行,显示OrderSend 工作了,没有错误,但麻烦来了:a)开放列表中的订单仍然存在,b)它在MT重启时关闭,所以它不仅在列表中,而且在现实中。

以防Meta想与Alpari核对日志,账户142605,票据1728130

,我希望仍能得到答案,这不是我第一次发关于这个错误的帖子。
Regards,
Quark
 
谢谢你,我们会研究的。
你能给我发一段从请求开始到收到ping失败的日志吗(检查超时很重要)?这是在真实账户还是模拟账户?
 
<br/ translate="no"> 谢谢,我们会研究的。
你能不能发送一段从提出请求到收到ping失败的日志(检查超时很重要)?这是在真实账户还是模拟账户上?


这是在一个模拟账户上。日志...我关闭并打开了MT,所以 "日志 "标签条目被更新。我下次会复制它,然后重新启动它,感觉需要几天时间,我是说问题的复发。我只能建议从 experts/logs 目录中获取日志。这就是你所想的吗?在账户历史中,该交易对应于以下一行(顺便问一下,为什么在这个标签中没有逐行复制到缓冲区?)1728130 2005.08.31 15:00 买入 0.10 eurusd 1.2223 1.2183 0 2005.08.31 20:07 1.2330 0 107.00 星期五 我在莫斯科,在分析交易时间时可能需要。请注意,专家顾问在晚上8:07关闭交易。事实上,关闭条件是在晚上8:01,但头寸并没有关闭。我关闭和打开MT,在20.07,即立即,在重新启动后的几秒钟内关闭了位置。现在看了看日志(整个日志),但它是147Kb。如果你想要的话,我会附上它,但相信我,这笔交易只有两个条目: 17:00:18 _Friday_Expert EURUSD,H1: open #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 ok ...22:07:24 _Friday_Expert EURUSD,H1: close #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 at price 1.2330 所以似乎没有尝试在20.01














平仓。"算是吧",因为a)"日志 "标签(我没想到MT会重置它)显示了关于ping尝试和失败的说明,b)由于这不是这个EA的第一个问题,看看它从内部看起来如何:

	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只是将文本写到一个文件中。因此,文件中所有适合尝试平仓的条目都出现了,但警报没有被调用,即OrderClose返回了成功完成代码。



 
因此,正如我所承诺的,我一直在等待错误的重复。请注意,这个错误已经出现在另一个EA上,所以它可能不是代码的错误(尽管一切都有可能)。但该专家顾问 "还没有准备好",因为它没有填入所有可能的功能来输出到文件。

在日志中出现了一个错误:ping failed。

也许在ping失败后,你的系统不应该允许OrderSend被执行,那么就会产生一个错误信息

在这种情况下,没有错误信息,只有一条日志记录。程序的行为就像它设法关闭交易一样,只是交易没有关闭。

因此,在日志中:
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 at price 1.2542
2005.09.05 16:01:14 '142605': login (4.00, #27FFBBD7)

顺便说一句,我真的很奇怪为什么sl: 0.0000,我不发送零。

同时,启动功能看起来像这样:

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是一个将字符串输出到文件的函数。 这里有从开始调用的关闭位置函数。正如你所看到的,它尝试平仓5次(我这样做只是为了测试),如果没有错误代码返回(即MT认为该头寸已经关闭),它就在仍然未平仓的订单中寻找具有所需票据的那一个。



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");
	}
}



下面的日志显示,所有5次关闭订单的尝试都失败了(票据没有消失),MT认为该仓位已经关闭。5.9.2005 14:1:29, Signal: none 312758.00000000 - 312754.00000000 >= 4 试图关闭空头头寸,票据:1775545 此票据的订单仍然存在,再次尝试 此票据的订单仍然存在,再次尝试 此票据的订单仍然存在,再次尝试 此票据的订单仍然存在,再次尝试,出售关闭 注意:不要害怕 "信号:无" - 它应该像这样。这是一个开仓的信号。如果满足 "312758.00000000-312754.00000000>=4 "的不等式,则产生平仓的信号, 亲爱的开发者!我非常希望我们能一起解决这个问题。Quark P.S. 像往常一样,重新启动MT,我得到了EA的平仓,没有出现任何问题。



















 
仍在等待开发商的答复。
在我所有的EA中,当试图打开-关闭交易时,增加了将结果写入文件的代码。其结果是令人失望的。大约每次,对所有的EA来说,一次尝试开仓-平仓都是不够的。平均而言,它需要两次(见上面的代码,有一个五次尝试的周期)。有时五次尝试是不够的。同时,MT的工作原理是,如果订单成功打开-关闭,没有错误信息

我使用了 "错误6 "分支中建议的所有信号系统(顺便说一下,有时仍会发生),加上专家顾问的定时器保证每个EA在其专用的10秒内启动,也就是说,EA之间不应该有冲突。

我建议其他开发者在真实的EA中使用下面的代码,以检查你的所有订单是否按照你期望的方式运行。从交易的角度来看,它只是一个普通的OrderSend,周围有输出到一个文件的功能。

无意冒犯,但似乎MT需要对与贸易服务器的互动进行微调。

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

// ------



 
也许你的EA开仓/平仓交易过于频繁。我特意查看了交易历史(我挂了8个EA),我统计了一下一分钟内有多笔交易的次数(不超过10次),都是成功的。的确,EA在1H、4H、D1的条形图上工作,而且到处都插入了超时,但超时只在一个EA的交易之间(事实上我不需要),EA之间没有信号。
然后我需要在模拟账户上找到允许的区间的极限。
 
我现在也有8个EA挂着,都在M5上。
从00:00到12:00
行业 - 141
3个错误("1 "和两个 "6")。

夸克,你能不能把你的EA(在M1上)的最后一个故障版本扔给我,让我在komposterius电子邮件中毁掉?我将再挂8个窗户--看看会发生什么;)
 
你们错过了主要的一点。我没有一分钟的专家。所有的交易都是按时进行的。我没有频繁的交易,最多每小时一次。

专家们等待(使用semaphores)一个队列,此外,魔法数字等于,例如10的EA,等待10 * 10 = 100秒,从一个酒吧的开始,只有这样它才会交易。因此,即使没有信号灯,遇到有魔法11的EA的机会也接近于0。

印象中,如果MT失败一次(ping失败,错误6,等等),他的系统就会出问题,这个EA的后续交易就会失败。

日志的例子(上面显示的代码)。

试图购买,0次尝试失败,错误6
试图购买,尝试1失败,错误129
试图购买,尝试2失败,错误129
试图购买,尝试3次失败,错误129
试图购买,尝试4次失败,错误129
之字形买入错误:4050
2.28000000, 0.02700000, 0.00000000

我们这里有什么?首先出现了一个故障(在日志中--与服务器的连接错误)。然后重试了5次(我的循环中有5次),结果是129 - 错误的价格。下面是价格--很正常。在以这个价格重新启动MT后,订单被成功打开。然后我们得到4050,错误的论据数量。这是来自一个在其他调用中工作正常的函数。错误报告系统显然是失败的。

引述一位专家的话,尽管我怀疑你必须有很多这样的专家,问题才会经常发生。希望编纂者、罗氏和开发者能看看这些代码并提出一些建议。不过,我认为这里是一个MT的问题。

专家。
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);
}

// ------



指标。

#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);
*/



库文件,必须位于专家目录中。

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

// ------

 
你真的让我很感兴趣,夸克 :)
现在是开发商考虑给你的员工找一份工作的时候了,给他们找各种讨厌的东西。
也许是萍水相逢,我没有周期去重试下单,也许我应该在这个时候打电话给刷新,塞进更新鲜的价格。
我迷路了...:)
 
好吧,你终于被吸引住了,夸克:)<br / translate="no">现在是时候让开发人员考虑给你的员工找一个空缺,让你给他们找各种讨厌的东西。
也许是萍水相逢,我没有周期重试下单,也许我需要在这个时候打电话给刷新,塞进更新鲜的价格。
我开始迷路了......:)


好主意...现在可以了...
 
新版本,由罗氏公司投稿。
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();
		}
	}
}