Вопрос по динамическому массиву (кусок кода)

 

Всем привет! Ошибка скорее не в самом массиве, а в цикле. Но расскажу по порядку, так как уже голову сломал не могу найти причину косяка в коде.

Суть: Нужно у открывшихся сделок на бай заносить тикеты в динамический массив.

Кусок кода ниже это часть советника, условие если сделок больше на бай чем 1, то срабатывает это условие. Массив к этому условию уже имеет в себе одно значение тикета сделки на бай, в данном случае оно ==1. Когда открывается, новая сделка на бай, то сова начинает сравнивать есть ли такой тикет в массиве, если нет то заносит в массив, после чего выдаёт в журнале весь массив со значениями. В скрине видно, как сову клинет (зацикливает), и значение 0 ячейки массива выдаёт 2 раза, это не нормально. Помогите найти ошибку.

Да и ещё вопрос, когда убираю вот этот Alert ("Начало занесения в архив = ", OrderTicket()); (написал в архив, имел ввиду в массив) то сова вообще не выводит в журнале значения массива, тоже не понятно почему?


// Если одна и больше сделок

  if(CountTradesBuy()>=1)

  {

  

  if(FindBuy()) return;

  if(FindOrderBuy()==true)

  // Выставляем новый ордер

  ticket=OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0,comment,Magic,0,Blue);

  if(ticket<0)

  { Alert(Symbol(),"  Ошибка покупки");  return; }

  RefreshRates();


  Sum = 0; countt=0;  // Вычисляем усредненную цену открытия ордеров

  for(t=0; t<OrdersTotal(); t++)

    if(OrderSelect(t,SELECT_BY_POS))

    if(OrderMagicNumber() == Magic && OrderSymbol() ==Symbol())

    if(OrderType() == OP_BUY) { Sum+=OrderOpenPrice(); countt++; }

  SredTPBuy=NormalizeDouble(Sum/countt+PlusTP*Point, Digits);

    

  for(t=0; t<OrdersTotal(); t++) // Модифицируем ордера, ставим TakeProfit

    if(OrderSelect(t, SELECT_BY_POS))

    if(OrderMagicNumber() == Magic && OrderSymbol() == Symbol())

    if(OrderType() == OP_BUY && SredTPBuy != OrderTakeProfit())

      Result=OrderModify(OrderTicket(),OrderOpenPrice(),0,SredTPBuy,0);

          //Начало работы с массивом

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

           {

            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))

            if(OrderMagicNumber() == Magic && OrderSymbol() == Symbol())

            if(OrderType()==OP_BUY)

               {

                  int Size=ArraySize(MassBuy);

                  for (int m=0; m<Size; m++)

                  

                    if (MassBuy[m]!=OrderTicket()) 

                     Alert ("Начало занесения в архив = ", OrderTicket());   

                           

                             int new_size = ArraySize(MassBuy)+1;

                             ArrayResize(MassBuy,new_size);

                             ArrayFill(MassBuy,new_size-1,1,OrderTicket());

                             for(int g=0;g<ArraySize(MassBuy);g++) printf("MassBuy[%d] = %d",g,MassBuy[g]);            

               }

            }     

   }

}

Файлы:
Screenshot_3.jpg  452 kb
 
Artem Onopin:

Всем привет! Ошибка скорее не в самом массиве, а в цикле. Но расскажу по порядку, так как уже голову сломал не могу найти причину косяка в коде.

Суть: Нужно у открывшихся сделок на бай заносить тикеты в динамический массив.

Кусок кода ниже это часть советника, условие если сделок больше на бай чем 1, то срабатывает это условие. Массив к этому условию уже имеет в себе одно значение тикета сделки на бай, в данном случае оно ==1. Когда открывается, новая сделка на бай, то сова начинает сравнивать есть ли такой тикет в массиве, если нет то заносит в массив, после чего выдаёт в журнале весь массив со значениями. В скрине видно, как сову клинет (зацикливает), и значение 0 ячейки массива выдаёт 2 раза, это не нормально. Помогите найти ошибку.

Да и ещё вопрос, когда убираю вот этот Alert ("Начало занесения в архив = ", OrderTicket()); (написал в архив, имел ввиду в массив) то сова вообще не выводит в журнале значения массива, тоже не понятно почему?

Ошибка сразу в первой строке.

Говоришь "если сделок больше на бай чем 1" а в условии >= больше или равно.

if(CountTradesBuy()>=1)

Дальше даже глядеть не стал. Если будет необходимость можно будет и посмотреть. Но пока такое предложение:

Зачем пересчитывать все ордера после того как очередной ордер открылся? Разве что при запуске советника после выходных или другой причины остановки... Так это надо в OnInit() только один раз.

Почему не заносить тикет в массив непосредственно при открытии ордера?

 
Alexey Viktorov:

Ошибка сразу в первой строке.

Говоришь "если сделок больше на бай чем 1" а в условии >= больше или равно.

Дальше даже глядеть не стал. Если будет необходимость можно будет и посмотреть. Но пока такое предложение:

Зачем пересчитывать все ордера после того как очередной ордер открылся? Разве что при запуске советника после выходных или другой причины остановки... Так это надо в OnInit() только один раз.

Почему не заносить тикет в массив непосредственно при открытии ордера?


Написал не правильно, условие работает, как надо. Сова уже работает больше года. Сейчас решил усовершенствовать, понадобились массивы))

Про пересчёт не понял вопроса, если до массива имеешь ввиду, то мне надо усреднить всю серию ордеров и выставить им общий (один и тоже) ТП

Согласен так будет рациональней, но проблему мне кажется не решит.

 
Artem Onopin:

...

Да и ещё вопрос, когда убираю вот этот Alert ("Начало занесения в архив = ", OrderTicket()); (написал в архив, имел ввиду в массив) то сова вообще не выводит в журнале значения массива, тоже не понятно почему?

...

Никогда не пишите if и for без фигурных скобок, даже если одна строка кода. Составной оператор не отделен фигурными скобками, поэтом при добавлении иди удалении строки кода меняется вся логика. Расставьте фигурные скобки и отформатируйте код - сделайте увеличенные отступы у вложенных циклов и if'ов. Может и сами тогда увидите. 

В той части кода, где выполняется работа с массивом, вообще не наблюдается здравого смысла. 

 
Dmitry Fedoseev:

Никогда не пишите if и for без фигурных скобок, даже если одна строка кода. Составной оператор не отделен фигурными скобками, поэтом при добавлении иди удалении строки кода меняется вся логика. Расставьте фигурные скобки и отформатируйте код - сделайте увеличенные отступы у вложенных циклов и if'ов. Может и сами тогда увидите. 

В той части кода, где выполняется работа с массивом, вообще не наблюдается здравого смысла. 


Замечания понял учту, Спасибо.

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

 
Artem Onopin:

Замечания понял учту, Спасибо.

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

Цикл по ордерам. Выделен очередной ордер, знаем его тикет. Используется дополнительная переменная, пусть будет IsInArray, сначала ей присваивается false, затем проходим по массиву в цикле, если в нем есть тикет выделенного ордера, то присваиваем IsInArray=true и  выскакиваем из цикла. После цикла по массиву, если  IsInArray=false, то добавляем тикет выделенного ордера в массив. 
 
Dmitry Fedoseev:
Цикл по ордерам. Выделен очередной ордер, знаем его тикет. Используется дополнительная переменная, пусть будет IsInArray, сначала ей присваивается false, затем проходим по массиву в цикле, если в нем есть тикет выделенного ордера, то присваиваем IsInArray=true и  выскакиваем из цикла. После цикла по массиву, если  IsInArray=false, то добавляем тикет выделенного ордера в массив. 

Спасибо, пошёл думать))

 
Artem Onopin:

Замечания понял учту, Спасибо.

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

Именно общими фразами и направляют. А написав, даже пример кода, это уже не направление, а шаблон действий. Или лучше сказать кубик лего для программиста...

Artem Onopin:

Написал не правильно, условие работает, как надо. Сова уже работает больше года. Сейчас решил усовершенствовать, понадобились массивы))

Про пересчёт не понял вопроса, если до массива имеешь ввиду, то мне надо усреднить всю серию ордеров и выставить им общий (один и тоже) ТП

Согласен так будет рациональней, но проблему мне кажется не решит.

Пересчёт, я имел в виду перебор всех ордеров. Какой смысл перебирать\пересчитывать все ордера для занесения их в массив, и сразу после этого перебирать только-что заполненный массив

для определения общего ТП??? Может проще перебирая все ордера сразу пересчитать общий уровень ТП, к чему массив тогда?

А если есть желание работать с массивом, то уж надо заполнять его без перебора всех существующих ордеров. Проще завести 2 отдельных массива для Sell и Buy ордеров. И потом с этими массивами работать...

 
Alexey Viktorov:

Именно общими фразами и направляют. А написав, даже пример кода, это уже не направление, а шаблон действий. Или лучше сказать кубик лего для программиста...

Пересчёт, я имел в виду перебор всех ордеров. Какой смысл перебирать\пересчитывать все ордера для занесения их в массив, и сразу после этого перебирать только-что заполненный массив

для определения общего ТП??? Может проще перебирая все ордера сразу пересчитать общий уровень ТП, к чему массив тогда?

А если есть желание работать с массивом, то уж надо заполнять его без перебора всех существующих ордеров. Проще завести 2 отдельных массива для Sell и Buy ордеров. И потом с этими массивами работать...

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


Массив нужен для дальнейшей работы с ним, для отделения локирующих ордеров. Логика с перебором и усреднением работает, конечно 100% я сделал что-то не так, по своей не грамотности, но сейчас меня больше волнуют массивы и работа сними. Постом выше Дмитрий дал логику, сегодня завтра разберусь напишу код выложу, оцените)) 

 

у вас похоже нехватает скобочек {} :-)

после if (MassBuy[m]!=OrderTicket())  точно просится блок охватывающий не только следующие за ним оператор :-)

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

 

можно ещё воспользоваться справкой - в справке плохого не пишут

https://book.mql4.com/ru/build/orders

Учёт ордеров - Создание обычной программы - Учебник по MQL4
Учёт ордеров - Создание обычной программы - Учебник по MQL4
  • book.mql4.com
Учёт ордеров - Создание обычной программы - Учебник по MQL4
Причина обращения: