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

 
Dmitry Fedoseev:

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


Хорошо подумаю над этим вариантом, звучит проще чем массивы между собой сравнивать.

 
Artem Onopin:

Хорошо подумаю над этим вариантом, звучит проще чем массивы между собой сравнивать.


Проще и быстрее работать будет. 

Если с массивами, то надо на каждом тике прокручивать цикл по ордерам и для каждого ордера цикл по массиву. А с глобальными переменными только цикл по ордерам.

 
добрый день.

все гораздо проще чем кажется. я не буду вдаваться в подробности и расписывать все что тут писали другие авторы. приведу пример изначального вашего кода и его реализацию без ошибок.в коде указаны исправления.
это ваш код.

// Если одна и больше сделок
   if(CountTradesBuy()>0)
     {
      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]);
                 }
        }
     }

а это переделанный с учетом ошибок и модифицирован для лучшего быстродействия.

if(CountTradesBuy()>0)
     {
      if(FindBuy()) return;
      if(FindOrderBuy())
         ticket=OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0,comment,Magic,0,Blue);
      else return;
      if(ticket<0)
        { Alert(Symbol(),"  Ошибка покупки");  return; }
      RefreshRates();
      Sum=0;
      countt=0; // эта переменная должна быть double при работе с ордерами разного объема
      for(t=0; t<OrdersTotal(); t++)
        {
         if(!OrderSelect(t,SELECT_BY_POS))continue;//такое выполнение алгоритма гораздо быстрее вашего
         if(OrderMagicNumber()!=Magic)continue;
         if(OrderSymbol()!=_Symbol)continue;
         if(OrderType()!=OP_BUY) continue;
         Sum+=OrderOpenPrice()*OrderLots();
         countt+=OrderLots();
        }
      if(countt<MarketInfo(_Symbol,MODE_MINLOT))return;//выходим если нет ордеров

      SredTPBuy=NormalizeDouble(Sum/countt+PlusTP*Point,Digits);
      for(t=0; t<OrdersTotal(); t++)
        {
         if(!OrderSelect(t,SELECT_BY_POS))continue;
         if(OrderMagicNumber()!=Magic)continue;
         if(OrderSymbol()!=_Symbol)continue;
         if(OrderType()!=OP_BUY) continue;
         /*
         if(SredTPBuy!=OrderTakeProfit())ТАКАЯ ПРОВЕРКА С ЧИСЛАМИ DOUBLE НЕ ВЕРНА
         */
         if(MathAbs(SredTPBuy-OrderTakeProfit())>=_Point)//правильная проверка на соответствие условию
            Result=OrderModify(OrderTicket(),OrderOpenPrice(),0,SredTPBuy,0);
        }
      //если нам нужны ордера только в рынке обнуляем массив
      ArrayResize(MassBuy,0);
      //если мы ведем общую статистику по всем ордерам которые были открыты в бай обнулять не нужно
      for(int i=0; i<OrdersTotal(); i++)
        {
         if(!OrderSelect(i,SELECT_BY_POS))continue;
         if(OrderMagicNumber()!=Magic)continue;
         if(OrderSymbol()!=_Symbol)continue;
         if(OrderType()!=OP_BUY) continue;

         int Size=ArraySize(MassBuy);
         bool fl=false;//флаг присутствия ордера в массиве
         if(Size>0)//проверяем наличие ордера если у нас в массиве присутствует уже какой то ордер
            for(int m=0; m<Size && !fl; m++)
              {
               if(MassBuy[m]!=OrderTicket())continue;
               fl=true;
              }
         if(fl)continue;//если ордер есть в базе переходим к другому ордеру без добавления в массив
         //Alert("Начало занесения в архив = ",OrderTicket());//будет выводить при добавлении каждого ордера, не советую, лучше закоментировать
         ArrayResize(MassBuy,Size+1);
         MassBuy[Size]=OrderTicket();
         printf("MassBuy[%d] = %d",Size,MassBuy[Size]);//будет выводить только при добавлении ордера в массив
         //если вы ведете общую статистику ордеров то как понимаете будет выводить после добавления ордера всего 1 раз 
         //если вы ведете статистику ордеров в рынке и обнуляете массив перед его заполнением будет выводить при каждом цикле обновления массива
         //а это значит при установке нового ордера BUY будет выводиться весь массив
         //для проверки работы алгоритма возможно это и нужно а вот для работы в реале явно лишнее
        }
     }

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

с уважением.

 
Andrey Kisselyov:
добрый день.

все гораздо проще чем кажется. я не буду вдаваться в подробности и расписывать все что тут писали другие авторы. приведу пример изначального вашего кода и его реализацию без ошибок.в коде указаны исправления.
это ваш код.

а это переделанный с учетом ошибок и модифицирован для лучшего быстродействия.

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

с уважением.


Спасибо, постараюсь понять и внедрит))