Ошибка номер 6 - страница 10

 
[quote
Ваш пример получше будет
[/quote]

Этот пример не работает. Дает ошибки. Не могли бы Вы, как более опытный разработчик, помочь заставить его работать?
С уважением,
Кварк
 

Вопрос: как работает while(!IsStopped()) ? Из хелпа не совсем понятно, я-то думал, это проверка на Allow Live Trading.

это проверка не хотят ли закрыть эксперта извне

Вопрос: эти while и Sleep не будут тормозить систему?

систему тормозить не будут. только отдельно взятого эксперта

Вопрос: будет ли Sleep и семафор корректно обрабатываться в режиме тестирования?

слип в тестировании никак не отрабатывается, просто пропускается. с семафором вопрос сложнее. при тестировании за этот семафор могут конкурировать реально работающие эксперты. при тестировании вообще можно не пользоваться семафорами, так как тестируется только один эксперт - мы не можем организовать одновременное тестирование взаимодействующих экспертов. чтобы исключить работу с семафором при тестировании используйте функцию IsTesting

Еще по логике. Между установкой и снятием семафора, у нас две (максимум) возможности работы с ордерами. Сначала Buy() или Sell() и потом, ниже, CloseOrder(). Не будут ли эти две "активности" конкурировать друг с другом, хоть внутри эксперта, но также, как если бы экспертов было два? Или процесс гарантированно линеен, и пока Buy() не вернется, до CloseOrder() дело не дойдет?

эти активности друг с другом конкурировать не будут, так как торговые операции у нас теперь синхронны, то есть эксперт дожидается завершения торговой операции. "процесс гарантированно линеен"
 
Этот пример не работает. Дает ошибки. Не могли бы Вы, как более опытный разработчик, помочь заставить его работать?

заставлять не буду. подождите пару дней функции GlobalVariableSetOnCondition, тогда все проблемы разграничения доступа будут решены
 
Этот пример не работает. Дает ошибки. Не могли бы Вы, как более опытный разработчик, помочь заставить его работать?

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


Если имеется в виду, что Вы планируете ввести в МТ функцию GlobalVariableSetOnCondition, то не могли бы Вы заранее сказать о ней пару слов?

В том числе и как Вы предлагаете ее использовать в данной ситуации?

Пару дней - считая выходные?
 
Слава, из нашей дискуссии, помимо полезных советов, за которые большое спасибо, я вынес одну идею :) Точнее, предложение. Я уже упоминал о нем, повторюсь.

Не сделать ли Вам в МТ очередь ордеров. То есть, туда можно асинхронно писать требование на работу с позицией, а МТ в отдельной нити это требование обработает, когда будет время, и с гарантией, что никто больше туда не влезет.

Кварк
 
Если имеется в виду, что Вы планируете ввести в МТ функцию GlobalVariableSetOnCondition, то не могли бы Вы заранее сказать о ней пару слов?

В том числе и как Вы предлагаете ее использовать в данной ситуации?

Пару дней - считая выходные?

я уже показывал пример
      if(GlobalVariableSetOnCondition(SemaphoreName, 1.0, 0.0)==true)
        {
         bSemaphored=true;
         break;
        }


если у глобальной переменной значение 0.0, то установить значение в 1.0 и вернуть true. иначе ничего не устанавливать. проверка и изменение значения за один вызов функции.

"пару дней" - это я на всякий случай сказал. сегодня, надеюсь, выложим

 
Не сделать ли Вам в МТ очередь ордеров. То есть, туда можно асинхронно писать требование на работу с позицией, а МТ в отдельной нити это требование обработает, когда будет время, и с гарантией, что никто больше туда не влезет.

очередь ордеров делать не будем
 

я уже показывал пример


Только не сказали, что это такое :) Я думал, функцию предлагается написать мне.


"пару дней" - это я на всякий случай сказал. сегодня, надеюсь, выложим


Спасибо.
 
Дополнительно.

1. В этих 100 постах было приведено несколько багов, найденых при работе над экспертом, и к нему напрямую не относящихся. Например, что эксперты продолжают торговать и после удаления галочки Allow Live Trading. Надеюсь, вы о них не забудете.

2. Ниже ОПЯТЬ привожу код эксперта. Он генерирует ошибки 1, 129, 138. Не могли бы Вы а) рассказать, что такое 138 (реквота), почему она возникает, связана ли она с семафорами, и как ее убрать. б) Почему 129? Цены выводятся вместе с ошибкой, они вроде верны. в) Ну и насчет 1 тоже.

Напомню способ тестирования: 12 минутных окон для 12 валют.

С уважением,
Кварк

double dStopLoss;
int nHoursToHold;

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

int nSlip = 50;

double dLotSize = 0.1;

int nMagic = 0;
int nDigits;

string strTradeSemaphore = "TradeSemaphore";

//////////////////
int init ()
{
	nBars = Bars;

	if(!IsTesting() && !GlobalVariableCheck(strTradeSemaphore)) 
		GlobalVariableSet(strTradeSemaphore, 0.0);
	
	dStopLoss = 110 * Point;
	nHoursToHold = 1;

	nDigits = MarketInfo( Symbol(), MODE_DIGITS );
	
	if(Symbol() == "EURUSD")
		nMagic = 1;
	else if(Symbol() == "EURJPY")
		nMagic = 2;
	else if(Symbol() == "USDCHF")
		nMagic = 3;
	else if(Symbol() == "GBPUSD")
		nMagic = 4;
	else if(Symbol() == "GBPJPY")
		nMagic = 5;
	else if(Symbol() == "GBPCHF")
		nMagic = 6;
	else if(Symbol() == "USDJPY")
		nMagic = 7;
	else if(Symbol() == "AUDUSD")
		nMagic = 8;
	else if(Symbol() == "EURGBP")
		nMagic = 9;
	else if(Symbol() == "USDCAD")
		nMagic = 10;
	else if(Symbol() == "EURCHF")
		nMagic = 11;
	else if(Symbol() == "EURAUD")
		nMagic = 12;
		
	return(0);	
}

// ------

int deinit()
{
	return(0);
}

// ------

int start()
{
	if(Bars < 5)
		return(0);
	
/*	// The previous bar just closed
	bool bIsBarEnd = false;
	if(timePrev != Time[0] + nMagic) 
		bIsBarEnd = true;
	timePrev = Time[0] + nMagic;
*/

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

	// ------
	
	if(!IsTesting())
	{
		while(!IsStopped())
		{
			if(GlobalVariableGet(strTradeSemaphore) == 0.0)
				GlobalVariableSet(strTradeSemaphore, nMagic);

			if(GlobalVariableGet(strTradeSemaphore) == nMagic)
				break;
		
			Sleep(1000);
		}
	}
	
	for(int nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);

		if(OrderMagicNumber() == nMagic)
		{
			if(CurTime() - OrderOpenTime() > (nHoursToHold - 1) * 60 * 60)
			{
				if(OrderType() == OP_BUY)
					OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
				else if(OrderType() == OP_SELL)
					OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
			}
		}
	}

	int nSignal = GetSignal();
	
	if(nSignal == OP_BUY) 
		Buy();
	else if(nSignal == OP_SELL) 
		Sell();

	if(!IsTesting())
		GlobalVariableSet(strTradeSemaphore, 0.0);	
	
	return(0);
}
// ------

void Sell()
{
	if(AccountFreeMargin() < 500)
		return;

	dLotSize = GetLotSize();

	double dNormalizer = MathPow(10, nDigits);
	double dBid = Bid;//MathFloor(Bid * dNormalizer) / dNormalizer; //NormalizeDouble(Bid, nDigits);
	double dStop = Bid + dStopLoss;//MathFloor((Bid + dStopLoss) * dNormalizer) / dNormalizer; //NormalizeDouble(Bid + dStopLoss, nDigits);

	int nResult = OrderSend(Symbol(), OP_SELL, dLotSize, dBid, 
		nSlip, dStop, 0, "Friday", nMagic, 0, OrangeRed);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", sell: " + dBid + ", Stop: " + dStop + ", error: " + nError);
	}
}

// ------

void Buy()
{
	if(AccountFreeMargin() < 500)
		return;

	dLotSize = GetLotSize();

	double dNormalizer = MathPow(10, nDigits);
	double dAsk = Ask;//MathFloor(Ask * dNormalizer) / dNormalizer; //NormalizeDouble(Bid, nDigits);
	double dStop = Ask - dStopLoss;//MathFloor((Ask - dStopLoss) * dNormalizer) / dNormalizer; //NormalizeDouble(Bid + dStopLoss, nDigits);

	int nResult = OrderSend(Symbol(), OP_BUY, dLotSize, dAsk, 
		nSlip, dStop, 0, "Friday", nMagic, 0, Aqua);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", buy: " + dAsk + 
			", Stop: " + dStop + ", error: " + nError);
	}
}
// ------

double GetLotSize()
{
	double dLot = 0.1;
	
	return(dLot);
}

// ------

int GetSignal()
{
	int nSignal;
	if(MathMod(Hour(), 2) == 0)
		nSignal = OP_BUY;
	else
		nSignal = OP_SELL;
		
	return(nSignal);
}
 
ошибка 138 requote может запросто возникнуть. потенциально при 10 работающих экспертах ожидание освобождения семафора может быть 30 секунд и выше. за это время цена запросто может измениться. в этом случае используйте функцию RefreshRates и берите новое значение бид или аск. либо обращайтесь к MarketInfo за новой ценой. 129 - ошибка того же плана, неверная цена - цена слишком далеко уехала и было несколько её изменений за время ожидания. 1 - это вообще не ошибка. она появляется когда идёт попытка модификации ордера теми же значениями, которые уже установлены. странно, что она возникает. у нас она возникает при ручном подтверждении торговли при отказе от сделки