Информация к размышлению - типа ошибка...

 
лог из experts\log:
11:36:11 trade_lib EURUSD,M15: order #240336 sell stop placed ok
11:38:24 error_lib EURUSD,M15: loaded successfully
11:38:24 error_input EURUSD,M15: loaded successfully
11:38:24 info_input EURUSD,M15: loaded successfully
11:38:36 trade_lib EURUSD,M15: unknown ticket 240336 for OrderDelete function
11:38:47 trade_lib EURUSD,M15: unknown ticket 240336 for OrderDelete function



из \log:

11:36:11 '14070': pending order sell stop 1.00 GBPUSD at 1.8931 sl: 1.8952 tp: 0.0000
11:36:11 '14070': request accepted by server
11:36:11 '14070': request in process
11:36:11 '14070': order open : #240336 sell stop 1.00 GBPUSD at 1.8931 sl: 1.8952 tp: 0.0000
11:38:24 '14070': delete pending order #240336 sell stop 1.00 GBPUSD at 1.8931 sl: 1.8952 tp: 0.0000
11:38:24 '14070': delete pending order #240336 sell stop 1.00 GBPUSD at 1.8931 sl: 1.8952 tp: 0.0000 failed [Off quotes]


мой личный:

Expert log ( 11:38:24 )
GBPUSD - есть ордер, установленный этим экспертом:
№ 240336 - SellStop
Open Price = 1.8931, Bid = 1.8950

Expert log ( 11:38:24 )
Сигнал изменился
Необходимо удалить ордер...

Expert log ( 11:38:24 )
Удаляем ордер № 240336, SellStop...

Expert log ( 11:38:24 )
Ошибка при удалении ордера!!!
Эксперт ожидает 5 минут...
GetLastError = 136
Off quotes

Expert log ( 11:38:36 )
Удаляем ордер № 240336, SellStop...

Expert log ( 11:38:36 )
Ошибка при удалении ордера!!!
Эксперт ожидает 5 минут...
GetLastError = 4108
invalid ticket

Expert log ( 11:38:47 )
Удаляем ордер № 240336, SellStop...

Expert log ( 11:38:47 )
Ошибка при удалении ордера!!!
Эксперт ожидает 5 минут...
GetLastError = 4108
invalid ticket



в истории счёта - написано - отменён в 10:38

билд последний, счёт 14070
Посмотрите, плз.....

 
Можете привести полный код? Возможно ошибка у нас, но все равно надо посмотреть последовательность вызываемых операций.
 
Можете привести полный код? Возможно ошибка у нас, но все равно надо посмотреть последовательность вызываемых операций.

Renat, у меня советник торгует уже недели 2, такой ошибки не было... А код состоит из библиотек 10, всё сложно =)
именно удаление ордера происходит следующим образом:
				log_trade ();
				info_trade ( "Expert log 1", "Сигнал изменился" );
				info_trade ( "Expert log 2", "Необходимо удалить ордер..." );
				info_trade ( "Expert log 3", "" );
				info_trade ( "Expert log 4", "" );

				for ( x = 1; x <= 3; x ++ )
				{
					orderdelete = _OrderDelete ( OrderTicket() );
					if ( orderdelete > 0 )
					{ Sleep(10000); return(0); }
					else
					{ Sleep(10000); }
				}


ф-ция _OrderDelete:

/////////////////////////////////////////////////////////////////////////////////
/**/ int _OrderDelete ( int _OrderTicket )
/////////////////////////////////////////////////////////////////////////////////
// Стандартная ф-ция OrderDelete + вывод информации.
// При успешном выполнении возвращает "1", при ошибке возвращает "-1"
/////////////////////////////////////////////////////////////////////////////////
{
	OrderSelect ( _OrderTicket, SELECT_BY_TICKET );
	string _OrderType_str = _OrderType_str ( OrderType() );
	log_trade ();
	info_trade ( "Expert log 1", "Удаляем ордер № " + _OrderTicket + ", " + _OrderType_str + "..." );
	info_trade ( "Expert log 2", "" );
	info_trade ( "Expert log 3", "" );
	info_trade ( "Expert log 4", "" );
	int order = OrderDelete( _OrderTicket );
	if ( order > 0 )
	{
		log_trade ();
		info_trade ( "Expert log 2", "Удалён успешно..." );
		Sleep(10000);
		return(1);
	}
	else
	{
		int error_code = GetLastError();
		log_trade_warning ( );
		info_trade_warning ( "Expert log 1", "Ошибка при удалении ордера!!!"  );
		Processing_Error ( error_code );
		return(-1);
	}
}


все ф-ции log_..., info_.... - это вывод информации и запись в свой лог-файл.
Processing_Error просто даёт описание ошибки и отправляет на почту уведомление. "ожидает 5 минут" - пока нету...

Множество ордеров уже были удалены, т.е. врядли это моя ошибка....

 
кстати, хотел спросить.... когда "сбрасывается" выделенный ордер/позиция? т.е. когда с них снимается выделение - только при удалении/модификации/закрытии?
 
for ( x = 1; x <= 3; x ++ )
  {
   orderdelete = _OrderDelete ( OrderTicket() );
   Sleep(10000);
  }


Вы совершенно забыли вызвать OrderSelect (с обязательной проверкой результата операции!) перед обращением к данным ордера. Получилось так: заснули на 10 сек, а поток как ни в чем не бывало - пошли повторять операцию, используя старый непроверенный номер тикета!

Подход должен быть очень четкий и однозначный: проверять все и всегда, писать код, который явно все перепроверяет перед операцией. Это о программировании, а не только об MQL.

 
Вы совершенно забыли вызвать OrderSelect

нет, не забыл - ордер выбирается чуть раньше...
и повторный запрос на удаление даётся только если orderdelete <= 0 :
				for ( x = 1; x <= 3; x ++ )
				{
					orderdelete = _OrderDelete ( OrderTicket() );
					[b]if ( orderdelete > 0 )
					{ Sleep(10000); return(0); }[/b]
					else
					{ Sleep(10000); }
				}


с обязательной проверкой результата операции!

будет достаточно if ( OrderTicket() > 0 ) .... ???
пошли повторять операцию

если orderdelete > 0 - выходим.. повтора не будет
Подход должен быть очень четкий и однозначный: проверять все и всегда, писать код, который явно все перепроверяет перед операцией. Это о программировании, а не только об MQL.

Именно так и стараюсь делать.
Спасибо за помощь!

 
нет, не забыл - ордер выбирается чуть раньше...

Забыли.
Получилось так: заснули на 10 сек, а поток как ни в чем не бывало - пошли повторять операцию, используя старый непроверенный номер тикета!

Вы не проверили ордер _после_ожидания_. В цикле то кто будет проверять существование ордера?

будет достаточно if ( OrderTicket() > 0 ) ....

Абсолютно недостаточно. Только и обязательно OrderSelect перед каждой попыткой совершить торговую операцию.
 
Забыли

Вы не проверили ордер _после_ожидания_. В цикле то кто будет проверять существование ордера?


а что, выделение может "сняться" само собой? т.е. если мы выделили ордер и поспали 10 сек, то надо заново выделять? Или только если производилось какое-то действие с этим ордером?

Абсолютно недостаточно. Только и обязательно OrderSelect перед каждой попыткой совершить торговую операцию


т.е. вместо этого:
for ( int z = 0; z <= OrdersTotal()-1; z ++ )
{
	OrderSelect( z, SELECT_BY_POS );
	if ( OrderMagicNumber() == _MagicNumber )
	{
		if ( .......... )
		{
			for ( x = 1; x <= 3; x ++ )
			{
				orderdelete = _OrderDelete ( OrderTicket() );
				if ( orderdelete > 0 )
				{ Sleep(10000); return(0); }
				else
				{ Sleep(10000); }
			}
		}
	}
}



должно быть это:

for ( int z = 0; z <= OrdersTotal()-1; z ++ )
{
	OrderSelect( z, SELECT_BY_POS );
	if ( OrderMagicNumber() == _MagicNumber )
	{
		if ( .......... )
		{
			for ( x = 1; x <= 3; x ++ )
			{
				orderdelete = _OrderDelete ( OrderTicket() );
				if ( orderdelete > 0 )
				{ Sleep(10000); return(0); }
				else
				{ Sleep(10000); OrderSelect( z, SELECT_BY_POS ); }
			}
		}
	}
}



???

 
а что, выделение может "сняться" само собой? т.е. если мы выделили ордер и поспали 10 сек, то надо заново выделять? Или только если производилось какое-то действие с этим ордером?

Похоже, Вы совершенно не воспринимаете асинхронность процессов, происходящих в торговом терминале.
Вы выбрали ордер и зафиксировали его для собственного использования. Пока Вы ждете N секунд, реально ордер может из базы исчезнуть, ну а Вы будете пользоваться его сохраненной копией. Вот именно поэтому надо перед использованием делать SelectOrder с обязательной проверкой результата.

должно быть это:

Опять неверно. Я же явно писал "проверять результат операции OrderSelect".

Должно быть:

for ( int z = 0; z < OrdersTotal(); z ++ )
  {
   if(OrderSelect(z,SELECT_BY_POS)==false) break;
   //--- ордер есть, теперь проверим - он обязательно должен быть отложенным
   if(OrderType()>OP_SELL)
     if(OrderMagicNumber() == _MagicNumber)  // и совпадать код
       {
        int ticket=OrderTicket();    // сохраним обязательно тикет!
        if( .......... )
	  {
	   for( x = 0; x <3; x ++ )
	     {
              if(OrderSelect(ticket,SELECT_BY_TICKET)==false) break;
              //--- пробуем удалить ордер (код удаления сомнителен)
              if(_OrderDelete(ticket)>0) { Sleep(10000); return(0); }
	      Sleep(10000);
             }
          }
       }
   }


Надеюсь, теперь Вы понимаете, что такое:

Подход должен быть очень четкий и однозначный: проверять все и всегда, писать код, который явно все перепроверяет перед операцией. Это о программировании, а не только об MQL.

 
Похоже, скоро торговые серверы захлестнет волна транзакций от изумительных экспертов :-)
К счастью, большинство ошибок прибивается прямо на клиенте и не попадают на торговый сервер.
 
Renat, спасибо за разьяснения...
Будем учиться, жаль, что на собственных ошибках, но, слава богу, на демо счетах :)
Причина обращения: