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

 
Maxim Kuznetsov:

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

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

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


Скобочки, поставил, выше уже об этом писали)) 

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

 
Aleksey Semenov:

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

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


Да, сколько справку не листай, постоянно что-то новое, спасибо))

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

Посмотрите, правильно я ваши слова реализовал? В массив заносит, но в журнале выводит сообщение не останавливаясь, вот ссылка на скрин http://prntscr.com/fnolyz. А так всё верно заносит тикеты ордеров

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();

  

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

      {

         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)

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

               if(OrderType()==OP_BUY)

                  {

                     bool IsInArray=false;

                     int Size=ArraySize(MassBuy);

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

                        {

                         if (MassBuy[t]==OrderTicket())

                           {

                              IsInArray=true;

                              break;

                           }

                        }

                     int new_size = ArraySize(MassBuy)+1;

                     ArrayResize(MassBuy,new_size);

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

                  }

       }

   for(t=0;t<ArraySize(MassBuy);t++)

      {

         printf("MassBuy[%d] = %d",t,MassBuy[t]);

      }


Скриншот
Скриншот
  • prnt.sc
Снято с помощью Lightshot
 

Исправился, выше код конечно хрень полная)))

Но в этой версии вообще не выводит в журнале массив с ордерами, поэтому не понятно занес он их или нет, в чём может быть причина?

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();
  
  
   for (int i=0; i<OrdersTotal(); i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
            if(OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
               if(OrderType()==OP_BUY)
                  {
                     bool IsInArray=false;
                     int Size=ArraySize(MassBuy);
                     for (t=0; t<Size; t++)
                        {
                         if (MassBuy[t]!=OrderTicket())
                           {
                              IsInArray=true;
                              break;
                           }
                        }
                        if (IsInArray==true)
                           {
                              int new_size = ArraySize(MassBuy)+1;
                              ArrayResize(MassBuy,new_size);
                              ArrayFill(MassBuy,new_size-1,1,OrderTicket());
         
                              for(t=0;t<new_size;t++)
                                 {
                                    Alert("MassBuy[%d] = %d",t,MassBuy[t]);
                                 }  
                           }   
                  }
       }
 

Не тот ни другой вариант не верны. Сейчас напишу подробней.

 

В первой варианте вы не проверяете IsInArray=false перед добавлением нового тикета в массив. А во втором случаем вынеси добавление тикета за пределы цикла for  по ордерам. Надо для каждого ордера проверять есть ли его тикет в массиве. 

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();

// здесь надо очистить массив
ArrayResize(MassBuy,0);

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

      {

         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)

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

               if(OrderType()==OP_BUY)

                  {

                     bool IsInArray=false;

                     int Size=ArraySize(MassBuy);

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

                        {

                         if (MassBuy[t]==OrderTicket())

                           {

                              IsInArray=true;

                              break;

                           }

                        }

                        if(!IsInArray){ 
                           int new_size = ArraySize(MassBuy)+1;
                           ArrayResize(MassBuy,new_size);
                           ArrayFill(MassBuy,new_size-1,1,OrderTicket());
                        }

                  }

       }

   for(t=0;t<ArraySize(MassBuy);t++)

      {

         printf("MassBuy[%d] = %d",t,MassBuy[t]);

      }

 
Dmitry Fedoseev:

В первой варианте вы не проверяете IsInArray=false перед добавлением нового тикета в массив. А во втором случаем вынеси добавление тикета за пределы цикла for  по ордерам. Надо для каждого ордера проверять есть ли его тикет в массиве. 


Но он в цикле крутит и крутит вот скрин. http://prntscr.com/fny00s

 
Artem Onopin:

Но он в цикле крутит и крутит вот скрин. http://prntscr.com/fny00s


Потому-что на каждом тике все это делается и вывод через принт делается на каждом тике. Все нормально, так и должно быть. Если конечно не какой-то другой конкретной цели.

 
Dmitry Fedoseev:

Потому-что на каждом тике все это делается и вывод через принт делается на каждом тике. Все нормально, так и должно быть. Если конечно не какой-то другой конкретной цели.


Спасибо за подсказки)) Цель у меня создать 4 массива (разделить по группам ордера) MassBuy[], MassSell[], MassBuyStop[], MassSellStop[] записывать в них номера тикетов. А это всё задумано, только ради того, чтобы MassBuyStop[], MassSellStop[] (локирующие ордера) если станут рыночными ордерами, перекидывать их (при определённом условии) в массивы к рыночным ордерам MassBuy[], MassSell[].  

 
Artem Onopin:

Спасибо за подсказки)) Цель у меня создать 4 массива (разделить по группам ордера) MassBuy[], MassSell[], MassBuyStop[], MassSellStop[] записывать в них номера тикетов. А это всё задумано, только ради того, чтобы MassBuyStop[], MassSellStop[] (локирующие ордера) если станут рыночными ордерами, перекидывать их (при определённом условии) в массивы к рыночным ордерам MassBuy[], MassSell[].  


Сделайте проще. Сразу поле установки отложенного ордера известен его тикет, создайте глобальную переменную с каким-нибудь именем включающим тикет ордера. Например: [ticket]_IsPending. Потом на каждом тике проходить по рыночным и если у него есть эта глобальная переменная, значит этот ордер только что стал рыночным из отложенного, тут выполнить нужные действия и удалить эту глобальную переменную.