Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1919

 
MrBrooklin #:

Спасибо за подсказку, Алексей! Сначала подожду ответ в этой ветке, но уж если будет тишина, вот тогда обращусь в тему Ошибки, баги, вопросы.

С уважением, Владимир.

В этой ветке вряд ли Вы дождётесь ответов от разработчиков. Нашли ошибку - убедились, что это действительно ошибка - сообщили в озвученную Алексеем ветку. Не нужно ожидать действий модераторов по этому поводу - мы тоже люди, и у нас тоже бывает времени нет.

 
Artyom Trishkin #:

В этой ветке вряд ли Вы дождётесь ответов от разработчиков. Нашли ошибку - убедились, что это действительно ошибка - сообщили в озвученную Алексеем ветку. Не нужно ожидать действий модераторов по этому поводу - мы тоже люди, и у нас тоже бывает времени нет.

Здравствуйте, Артём!

Всё понятно.

С уважением, Владимир.

 

Доброе время суток!!!!

Вот две функции сеточного советника первая функция калькуляция профита с учетом частичного закрытия убыточных ордеров

//+----------------------------------------------------------------------------+
//| Калькуляция сетки ордеров                                                  |
//+----------------------------------------------------------------------------+
bool CalculiteProfit()
  {
   double oProfit=0,oLoss=0,percent;
   int i;
   nOrd=0;
   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic || OrderType()>OP_SELL)
         continue;
      if(OrderProfit()>=0)
         oProfit += OrderProfit();
      else
        {
         oLoss+=OrderProfit();
         Ord_ticket[nOrd]=OrderTicket();
         Ord_lot[nOrd]=OrderLots();
         nOrd++;
        }
     }
   oLoss = MathAbs(oLoss+GetOrderSwap()+GetOrderCommission());
   if(oLoss>0)
      percent=oProfit/oLoss*100;
   else
      percent=100;
   if(percent<MinPercentForClose) //MinPercentForClose переменная из настроек 
      return(false);
   for(i=0; i<nOrd; i++)
     {
      Ord_lot[i]=(MathCeil((Ord_lot[i]*RowLots)*percent)/100)/RowLots;
     }
   return(true);
  }

Вторая функция закрытия ордеров причем закрытия части убыточных ордеров 

//+----------------------------------------------------------------------------+
//| Закрытие сетки ордеров при заданной команде с учетом части ордеров         |
//+----------------------------------------------------------------------------+
void ClosseAll()
  {
   int i,j,tkt;

   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic)
         continue;
      tkt=OrderTicket();
      RefreshRates();
      if(OrderProfit()>=0)
        {
         if(OrderType() == OP_BUY)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, slip))
               Print("Не удалось закрыть ордера на покупку!");
           }
         else
            if(OrderType() == OP_SELL)
              {
               if(!OrderClose(OrderTicket(), OrderLots(), Ask, slip))
                  Print("Не удалось закрыть ордер на продажу!");
              }
        }
      else
         for(j=0; j<nOrd; j++)
            if(tkt==Ord_ticket[j])
              {
               if(OrderLots()<Ord_lot[j])
                  Ord_lot[j]=OrderLots();
               Ord_lot[j]=NRL(Ord_lot[j]);
               if(OrderType() == OP_BUY)
                 {
                  if(!OrderClose(OrderTicket(), Ord_lot[j], Bid, slip))
                     Print("Не удалось закрыть ордера на покупку!");
                 }
               else
                  if(OrderType() == OP_SELL)
                    {
                     if(!OrderClose(OrderTicket(), Ord_lot[j], Ask, slip))
                        Print("Не удалось закрыть ордер на продажу!");
                    }
               break;
              }
     }
  }

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

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

Если да то помогите её написать  

Спасибо

 
EVGENII SHELIPOV #:

Доброе время суток!!!! 

Если да то помогите её написать  

Время сейчас не доброе.

Ты имеешь ввиду за тебя написать? 

 
Andrey Sokolov #:

Время сейчас не доброе.

Ты имеешь ввиду за тебя написать? 

Не рвите себя Александр

 

заблудился в элементарщине:

как мне организовать перебор поз для трала - сонаправленных, почему то тралит одну позу, т.е. не перебирает... МТ5

for (i=0; i<PositionsTotal(); i++)   
     if (a_position.Select(_Symbol))       
     if (PositionSelect(_Symbol)) if(Symbol()==PositionGetSymbol(i))  
     if (Magic==PositionGetInteger(POSITION_MAGIC))  
   //  magic = myposition.Magic();   
      {
         //  ------------   перевод в бу  BUY   ------------    
         //if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 
         if (a_position.PositionType() == POSITION_TYPE_BUY)
          if (NLb_fun > 0)
            {
                Print(" перевод в безубыток BUY, _SL = ", _SL, " POSITION_PRICE_OPEN: ",
                     NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits),
                     " NLb_fun = ", NormalizeDouble(NLb_fun,_Digits));
               Modify = true;
 if(Modify)
              {
               Print(" серия рыночных позиций BUY назначена к переводу в безубыток, текущией позы POSITION_PRICE_OPEN = ",
               NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits)," тикет = ",PositionGetInteger(POSITION_TICKET));
                
               trade.PositionModify(_Symbol,SymbolInfoDouble(_Symbol, SYMBOL_BID) - 50*_Point,PositionGetDouble(POSITION_TP));
               Print(" Перенос в бу стоп лосса позиции Buy № ",  PositionGetInteger(POSITION_TICKET));
    ...
           } // к if(Modify)
        }    // к if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 

...

можно просто участок кода как перебор позы для трала при HEDGE позиций рыночных - спс.

вопрос решил! Спс, в очередной раз Владимиру Карпутову!!!

с его тралом!

https://www.mql5.com/ru/code/17263

ключевая фишка смотреть в цикле по индексу и модифицировать вариантом с тикетом!!!

//--- при таком методе мы будет сюда попадать на каждом тике.
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
           {
            //--- TrailingStop -> подтягивание StopLoss у ПРИБЫЛЬНОЙ позиции
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               //--- когда у позиции ещё нет StopLoss
               if(m_position.StopLoss()==0)
                 {
                  //--- пока StopLoss равен 0.0, TrailingStep не учитываем
                  if(m_symbol.Bid()-ExtTrailingStop>m_position.PriceOpen())
                    {
                     //--- модификация позиции
                     m_trade.PositionModify(m_position.Ticket(),m_position.PriceOpen(),0.0);
                    }
                 } 
TrailingStop
TrailingStop
  • www.mql5.com
Пример советника с реализацией Trailing Stop.
 

 Простенькая задачка: нужно выпихнуть из массива ArrayJ все элементы, совпадающие по индексу и значению с элементами массива ArrayI:

int OnInit()
  {
   int CommonArray[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13};
   int ArrayI[20]=   {0, 0, 0, 0, 0, 0, 0, 8, 9, 10,  0, 12, 13, 13, 13, 13,  0,  0, 13,  0};
   int ArrayJ[];

   for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayResize(ArrayJ,j+1);
      ArrayJ[j]=CommonArray[j];
   }

   ArrayPrint(ArrayI);
   ArrayPrint(ArrayJ);

   for(int i=0; i<ArraySize(ArrayI); i++)
      if(ArrayI[i])
         for(int j=0; j<ArraySize(ArrayJ); j++)
            if(ArrayI[i]==ArrayJ[j])
               ArrayRemove(ArrayJ,j,1);

   ArrayPrint(ArrayJ);
//---
   return(INIT_SUCCEEDED);
  }

 Выделена ключевая строка. Результат:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7 11

ожидалось:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7          11                13 13    13

 ArrayJ динамический, с ним как будто что-то не так... но статический мне и не нужен.

 Сломал себе весь ум. ЧЯДНТ? Или неужто это аналог старой песни:

https://www.mql5.com/ru/forum/1111/page3141#comment_27152680

и

https://www.mql5.com/ru/forum/1111/page3142#comment_27371998

про именованные константы?

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2022.01.28
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 
x572intraday #:

 Простенькая задачка: нужно выпихнуть из массива ArrayJ все элементы, совпадающие по индексу и значению с элементами массива ArrayI:

 Выделена ключевая строка. Результат:

ожидалось:

 ArrayJ динамический, с ним как будто что-то не так... но статический мне и не нужен.

1. ArrayResize лучше вынести за цикл

ArrayResize(ArrayJ,ArraySize(ArrayI));
for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayJ[j]=CommonArray[j];
   }

2. ArrayRemove не делает элемент массива "пустым", а "сдвигает" последующие элементы на его место. Отсюда нарушается соответствие элементов в последующих индексах.

 
JRandomTrader #:

1. ArrayResize лучше вынести за цикл

2. ArrayRemove не делает элемент массива "пустым", а "сдвигает" последующие элементы на его место. Отсюда нарушается соответствие элементов в последующих индексах.

 Про 2 вопросов нет, это я для наглядности интервалы расставил. Помимо этого, в Справке сказано про статический массив: "Если функция используется для массива фиксированного размера, то сам размер массива не меняется: при этом происходит физическое копирование оставшегося "хвоста" в позицию start." В примере из Справки тоже используется массив фиксированного размера, а у меня динамический.

 Касательно 1. За цикл вынести нет возможности, так как в реальной задаче неизвестен заранее ни размер ArrayJ, ни ArrayI, а у CommonArray тем паче свой размер — они все не совпадают.

 Есть у меня ещё пример, где выпихивание элементов не обрывается на полпути, как в приведённом примере:

int OBJTFVArray[]={1, 2, 3, 4, 5, 6, 10, 12, 1520, 30, 16385, 16386, 16387, 16388, 16390, 16392, 16396, 16408, 32769, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160};
int PArray[20]={0, 0, 0, 0, 0, 00, 16390, 16392, 163960, 32769, 49153, 49153, 49153, 49153, 0, 0, 49153, 0};
int PArray_[];

int OnInit()
  {
   for(int p_=0; p_<ArraySize(PArray); p_++)
   {
      ArrayResize(PArray_,p_+1);
      PArray_[p_]=OBJTFVArray[p_+8];
   }

   ArrayPrint(PArray);
   ArrayPrint(PArray_);

   for(int p=0; p<ArraySize(PArray); p++)
      if(PArray[p])
         for(int p_=0; p_<ArraySize(PArray_); p_++)
            if(PArray[p]==PArray_[p_])
               ArrayRemove(PArray_,p_,1);

   ArrayPrint(PArray_);

   return(INIT_SUCCEEDED);
  }

Результат годный:

 0     0     0     0     0     0     0 16390 16392 16396     0 32769 49153 49153 49153 49153     0     0 49153     0
15    20    30 16385 16386 16387 16388 16390 16392 16396 16408 32769 49153 49154 49155 49156 49157 49158 49159 49160
15    20    30 16385 16386 16387 16388                   16408             49154 49155 49156 49157 49158 49159 49160

но нужно, чтобы тот вариант работал. Затык, видимо, случается, если в хвосте справа идут подряд элементы с одним и тем же значением (см. предыдущий пост) — а это уже похоже на проблему, на которую я ссылался выше.

 
x572intraday #:

 Про 2 вопросов нет, это я для наглядности интервалы расставил. Помимо этого, в Справке сказано про статический массив: "Если функция используется для массива фиксированного размера, то сам размер массива не меняется: при этом происходит физическое копирование оставшегося "хвоста" в позицию start." В примере из Справки тоже используется массив фиксированного размера, а у меня динамический.

 Касательно 1. За цикл вынести нет возможности, так как в реальной задаче неизвестен заранее ни размер ArrayJ, ни ArrayI, а у CommonArray тем паче свой размер — они все не совпадают.

 Есть у меня ещё пример, где выпихивание элементов не обрывается на полпути, как в приведённом примере:

Результат годный:

но мне надо, чтобы тот вариант работал. Затык, видимо, случается, если в хвосте справа идут подряд элементы с одним и тем же значением (см. предыдущий пост) — а это уже похоже на проблему, на которую я ссылался выше.

1. За цикл вынести можно и нужно, так, как я показал. Если только размер ArrayI не меняется по ходу цикла.

2. Далее что-то типа того

int k=0; // объявляем до цикла - чтобы использовать после
for(int i=0; i<ArraySize(ArrayI); i++) // после предыдущего кода (1) размеры ArrayI и ArrayJ равны
  if(ArrayI[i]!=ArrayJ[i])
    {
     ArrayJ[k++]=ArrayI[i];
    }
ArrayResize(ArrayJ,k);
Причина обращения: