Семафор - он сильно нужен? - страница 2

 
что сложного в том, что IsTradeAllowed предупреждает Вас о том, что все попытки торговых операций будут отклонены? причём ещё на стороне клиента. мы не будем переименовывать эту функцию по историческим причинам.
 
что сложного в том, что IsTradeAllowed предупреждает Вас о том, что все попытки торговых операций будут отклонены? причём ещё на стороне клиента. мы не будем переименовывать эту функцию по историческим причинам.

Абсолютно ничего сложного. И историческое значение этой функции я менять не прошу.
Пусть она возвращает значение флага, как и в третьей версии, и эта функциональность вполне согласуется с ее названием.
Мне же надо знать в реальном времени, свободен или занят торговый поток. Не разрешена ли торговля, а могу ли я торговать, когда она разрешена. Я же привел пример, когда IsTradeAllowed работает некорректно. Что в этом-то сложного?
 
подумаем
 

На самом деле, нужно как-то различать TradeAllowed, то есть разрешено ли торговать вообще, и TradeContextBusy, то есть открыт или занят торговый канал в текущий момент времени в реалтайм.


Почему МЫ должны это делать. Пусть терминал сам выстраивает ордера в очередь. Но это так, к слову.

Я первый :))) по совету Славы (и по его коду) ввел семафоры. Они помогают СЛАБО. По крайней мере, от кластера ошибок, любовно окрещенных трейдерами "ошибка номер 6". Вот окончательный код.

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

int deinit()
{
	if(!IsTesting())
		GlobalVariableSetOnCondition(strTradeSemaphore, 0.0, nMagic);
		
	return(0);
}

int start()
{
...
	if(!IsBarEnd())
		return(0);

	CheckTradeSemaphore();
...

	if(!IsTesting())
		GlobalVariableSet(strTradeSemaphore, 0.0);	

	// ------

	return(0);
}

string strTradeSemaphore = "TradeSemaphore";

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())
	{
		while(!IsStopped())
		{
			GlobalVariableSetOnCondition(strTradeSemaphore, nMagic, 0.0);

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

			Sleep(1000);
		}
	
		RefreshRates();
	}
}



Помогает сочетание (см. код выше) таймаута и семафора. Ошибок становится меньше, просто за счет увеличения числа попыток (см. код ниже :) и пауз между ними.

void Sell(string strExpertName)
{
	dLotSize = 0.1;//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("\r\n" + Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds());
		SaveComment(" Trying to sell, attempt " + nTry + "\r\n");
		SaveComment("\r\nAsk: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n");
		
		nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 
			dTp, strExpertName, nMagic, 0, OrangeRed);
		
		Sleep(10000);
		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);
	}
}



Как видно, функция будет пытаться продать 5 раз, и только если все 5 попыток провалятся, начнет выдавать алерты.

 
Но это, конечно, обходы... Надо бы сделать ПРИНУДИТЕЛЬНУЮ ДЕИНИЦИАЛИЗАЦИЮ при выключении терминала и добавить в UninitializeReason( ) REASON_TERMINALSHUTDOWN. Проблем быть не должно.
В deinit эксперта делаем проверку UninitializeReason( ), и если она говорит, что терминал закрывается, обнуляем всё что можно =)))


Я в свое время предлагал скрип startup, исполняемый МТ при перезапуске.
Причина обращения: