Почему они оба сразу не удаляются? смещаются индексы? кк тогда быть подскажите
как вариант - удалять циклом i--
либо скидывать тикеты в массив и потом удалять по тикетам. это работает всегда и на 100% :-)
for(int i = OrdersTotal() - 1; i >= 0 ; i --)
Старые грабли. Цикл сделайте с конца.
for(int i = OrdersTotal() - 1; i >= 0 ; i --)
Так и подумал, поискал на форуме не нашел ответа
спасибо
Была таже проблема, только код другой немного.
А скажите плиз в чём "грабли"?
А скажите плиз в чём "грабли"?
На примере двух ордеров. Индексы 0 и 1. Удаляется ордер с индексом 0. Ордер с индексом 1 становится на его место. Оставшийся ордер переиндексируется, смещается и ему присваивается индекс 0. В цикле следующим берётся ордер с индексом 1, которого уже нет. Вместо него опять ордер с индексом 0, который остаётся неудалённым.
Удалять ордера можно двумя способами:
1. Цикл любой. Внутри цикла удалять ордер с нулевым индексом.
2. Цикл с обратным проходом. Внутри цикла удалять ордер с индексом счётчика цикла.
А скажите плиз в чём "грабли"?
На примере двух ордеров. Индексы 0 и 1. Удаляется ордер с индексом 0. Ордер с индексом 1 становится на его место. Оставшийся ордер переиндексируется, смещается и ему присваивается индекс 0. В цикле следующим берётся ордер с индексом 1, которого уже нет. Вместо него опять ордер с индексом 0, который остаётся неудалённым.
Удалять ордера можно двумя способами:
1. Цикл любой. Внутри цикла удалять ордер с нулевым индексом.
2. Цикл с обратным проходом. Внутри цикла удалять ордер с индексом счётчика цикла.
Можно нарваться не только на реквоты, поэтому лучше обрабатывать ошибки, примерно так:
if(!OrderClose(OrderTicket(), OrderLots(), ClosePrice, slippage, CLR_NONE)) { err = GetLastError(); Error(...параметры...) - функция для обработки ошибок. }И не только после OrderDelete().
А скажите плиз в чём "грабли"?
На примере двух ордеров. Индексы 0 и 1. Удаляется ордер с индексом 0. Ордер с индексом 1 становится на его место. Оставшийся ордер переиндексируется, смещается и ему присваивается индекс 0. В цикле следующим берётся ордер с индексом 1, которого уже нет. Вместо него опять ордер с индексом 0, который остаётся неудалённым.
Удалять ордера можно двумя способами:
1. Цикл любой. Внутри цикла удалять ордер с нулевым индексом.
2. Цикл с обратным проходом. Внутри цикла удалять ордер с индексом счётчика цикла.
А какой размер Sleep лучше использовать? Понятно, что он может быть в разных ДЦ разный, но если как "средняя температура по больнице", то какое значение чаще бывает?
for(int i = 0; i < OrdersTotal(); i ++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (IsStopOrder()) OrderDelete(OrderTicket()); } }
Есть такой код, вроде все правильно, но удаляет почему то только один ордер, хотя на самом деле их два. ф-ия IsStopOrder возвращает истина если ордер OP_BUYSTOP или OP_SELLSTOP. На второй итерации удаляется и второй.
Почему они оба сразу не удаляются? смещаются индексы? кк тогда быть подскажите
Это действительно грабли. Содержание граблей в том, что после удаления первого ордера количество ордеров, определяемое функцией OrdersTotal(), становится меньше на 1, поэтому в заголовке оператора for() меняется предельное значение, и очередная итерация просто не исполняется. Проанализируйте также порядок удаления ордеров. Ведь после удаления любого ордера список ордеров перестраивается, т.е. меняются индексы ордеров в списке. Если их, например, 10, то порядок удаления будет такой: 1, 3, 5.
Вообще, так это не делается. Чтобы правильно удалять ордера, необходимо опеределить их приоритет, т.е. выяснить, какой ордер нужно удалить раньше, а какой позже. Для этого нужно принять во внимание близость ордера к рынку, количество лотов и др. параметры. Возможно, Вам будет интересно почитать статью Учёт ордеров в большой программе .
А Sleep() тут ни при чём.
На примере двух ордеров. Индексы 0 и 1. Удаляется ордер с индексом 0. Ордер с индексом 1 становится на его место. Оставшийся ордер переиндексируется, смещается и ему присваивается индекс 0. В цикле следующим берётся ордер с индексом 1, которого уже нет. Вместо него опять ордер с индексом 0, который остаётся неудалённым.
Удалять ордера можно двумя способами:
1. Цикл любой. Внутри цикла удалять ордер с нулевым индексом.
2. Цикл с обратным проходом. Внутри цикла удалять ордер с индексом счётчика цикла.
Много времени убил на поиски этой темы. Наконец нашел.
Все верно. Но есть уточнение.
Если пользоваться циклом for(i=0;i<OrdersTotal();i++) {OrderSelect(0,...)...}
то все равно удалится только половина ордеров, т.к. кол-во ордеров-то уменьшается.
Поэтому надо сначала в отдельной переменной фиксировать count=OrdersTotal(), а после уже использовать цикл for(i=0;i<count;i++)
Зато второй вариант перебора с конца работает 100%.
А я голову ломал :)
Спасибо.
P.S. Вдогонку дополнение.
Второй вариант предпочтительнее, если надо удалять не все ордера подряд, а лишь те, которые попадают под установленные вами условия.
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Есть такой код, вроде все правильно, но удаляет почему то только один ордер, хотя на самом деле их два. ф-ия IsStopOrder возвращает истина если ордер OP_BUYSTOP или OP_SELLSTOP. На второй итерации удаляется и второй.
Почему они оба сразу не удаляются? смещаются индексы? кк тогда быть подскажите