Проблема: Не могу найти ошибку :(

 
Доброго времени суток! Господа, прошу помощи..........
По определенным правилам ниже мувинга по low открываются позиции в Buy, выше мувинга по high - позиции в Sell. Эксперт должен закрывать все открытые позиции на покупку при пересечении ценой мувинга по low, и, соответственно, закрывать все позиции на продажу при пересечении ценой мувинга по High.
При тестировании на истории закрываются только первые 3 позиции, стоящие в Buy. Остальные - нет, хотя на графике визуально видно, что они попадают под условие закрытия. (Те 3 позиции, что закрылись, в принципе должны были закрыться примерно по одной цене - при пересечении мувинга и цены...... а они хоть и совпали с мувингом, но закрылись на разных барах и с существенным различием в цене, что тоже странно).
С историей все в порядке, минутки и высшие таймфреймы за тестируемый период все есть (тестирую на днях).
Почему так? Какие могут быть причины? Может что-то в коде не так?
Вот кусок кода, отвечающий за закрытие позиций:
double Bid_old=0; int start() { double MAhigh; double MAlow; //вычисление скользящего среднего по High MAhigh=iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_HIGH,0); //вычисление скользящего среднего по Low MAlow=iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_LOW,0); for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA) { if(OrderType()==OP_BUY) { if(Bid_old<MAlow && Bid>=MAlow && Close[1]<MAhigh) OrderClose(i,1,Bid,3,Ivory); } if(OrderType()==OP_SELL) { if(Bid_old>MAhigh && Bid<=MAhigh && Close[1]>MAhigh) OrderClose(i,1,Ask,3,Ivory); } } } Bid_old=Bid; CheckForOpen(); // вызов функции, отвечающей за открытие позиций }

С уважением, Юлия
 
Это стандартная ситуация с закрытием позиций и проходом от начала позиций.
Проблема в for(int i=0;i<OrdersTotal();i++) - когда позиция номер 0 закрывается, то счетчик позиций i переходит к номеру 1, но массив сделок ужимается и одна сделка пропускается.

В деталях это выглядит так:
1) сделки в начале
позиция тикет сделка 0 #10 BUY 10 USDCHF 1 #11 SELL 1 USDCHF 2 #12 BUY 2 USDCHF


2) закрываем сделку в позиции 0 с тикетом №10, после чего тикет #10 удаляется и массив сделок ужимается
позиция тикет сделка 0 #11 SELL 1 USDCHF 1 #12 BUY 2 USDCHF


3) так как счетчик позиций i увеличивается, то переходим к позиции 1 с тикетом #12, пропуская тикет №11
позиция тикет сделка 0 #11 SELL 1 USDCHF <- перескочили через нее 1 #12 BUY 2 USDCHF <- обрабаты
 
Если пытаться вот таким циклом

for(int i=0;i<OrdersTotal();i++)

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

Как решить проблему правильного прохода по сделкам?
1) после успешного(именно успешного с четкой проверкой результата) закрытия позиции делать коррекцию счетчика i--
2) делать проход с конца for(int i=OrdersTotal()-1;i>=0;i--) - так вообще ничего менять не придется, ужатие массива с конца никак не повлияет на правильный проход
3) предварительно сохранить тикеты сделок в локальный массив, а затем работать только по сохраненным тикетам, но это потенциально опасный способ
Вроде можно еще писать как раньше, но в OrderSelect не i, а 0
 
Тут пока все не закроет,не успокоется... 100% работает!!! :)))
while (OrdersTotal()>0){ OrderSelect(0,SELECT_BY_POS); if (OrderType()==OP_BUY) OrderClose(OrderTicket(),Lots,Bid,3,Green); else if (OrderType()==OP_SELL) OrderClose(OrderTicket(),Lots,Ask,3,Red); }
 
Ronen:
Тут пока все не закроет,не успокоется... 100% работает!!! :)))
А если вдруг попадётся отложенный ордер, то зависание гарантировано ;-) ... Rest in peace expert
 
Ronen:
Тут пока все не закроет,не успокоется... 100% работает!!! :)))
while (OrdersTotal()>0){ OrderSelect(0,SELECT_BY_POS); if (OrderType()==OP_BUY) OrderClose(OrderTicket(),Lots,Bid,3,Green); else if (OrderType()==OP_SELL) OrderClose(OrderTicket(),Lots,Ask,3,Red); }
И сколько объясняем, что так делать нельзя, но все равно появляются безбашенные трейдеры, которые пишут такой код.
Просто нет слов...
 
Renat, если бы свои реальные бабки ставили на советники - сразу перестали бы писать такую чушь. По когтям узнают... :)
 
Ставим точки над i

void CloseBuy() { int slippage=3; for (int i=OrdersTotal()-1; i>=0; i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderType()!=OP_BUY) continue; OrderClose(OrderTicket(),OrderLots(),Bid,slippage); } } void CloseSell() { int slippage=3; for (int i=OrdersTotal()-1; i>=0; i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderType()!=OP_SELL) continue; OrderClose(OrderTicket(),OrderLots(),Ask,slippage); } }

Renat, а не проще добавить в язык MQL4 торговую функцию: "закрыть все ордера" и не мучить ламеров тонкостями асинхронного изменения данных в терминале? А пока такой функции нет, вот её эрзац

void CloseAll() { int slippage=3; for (int i=OrdersTotal()-1; i>=0; i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol()) continue; if (OrderType()==OP_BUY ) OrderClose (OrderTicket(),OrderLots(),Bid,slippage); if (OrderType()==OP_SELL ) OrderClose (OrderTicket(),OrderLots(),Ask,slippage); if (OrderType()==OP_BUYSTOP ) OrderDelete(OrderTicket()); if (OrderType()==OP_SELLSTOP ) OrderDelete(OrderTicket()); if (OrderType()==OP_BUYLIMIT ) OrderDelete(OrderTicket()); if (OrderType()==OP_SELLLIMIT) OrderDelete(OrderTicket()); } }
 
Этих эрзацов куча http://www.alpari-idc.ru/ru/experts/articles/9.html, самый первый был создан где-то год назад на англоязычном форуме.
Причина обращения: