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.
нет, не забыл - ордер выбирается чуть раньше...
и повторный запрос на удаление даётся только если 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 - выходим.. повтора не будет
Именно так и стараюсь делать.
Спасибо за помощь!
Забыли.
Вы не проверили ордер _после_ожидания_. В цикле то кто будет проверять существование ордера?
Абсолютно недостаточно. Только и обязательно OrderSelect перед каждой попыткой совершить торговую операцию.
а что, выделение может "сняться" само собой? т.е. если мы выделили ордер и поспали 10 сек, то надо заново выделять? Или только если производилось какое-то действие с этим ордером?
т.е. вместо этого:
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 ); } } } } }
???
Похоже, Вы совершенно не воспринимаете асинхронность процессов, происходящих в торговом терминале.
Вы выбрали ордер и зафиксировали его для собственного использования. Пока Вы ждете 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); } } } }
Надеюсь, теперь Вы понимаете, что такое:
К счастью, большинство ошибок прибивается прямо на клиенте и не попадают на торговый сервер.
Будем учиться, жаль, что на собственных ошибках, но, слава богу, на демо счетах :)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
из \log:
мой личный:
в истории счёта - написано - отменён в 10:38
билд последний, счёт 14070
Посмотрите, плз.....