Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 614

 
Vitaly Muzichenko:

Well, you have shown that these are not critical errors.

How the function works, you have answered yourself:


In the tester it's fine. This is how it works in practice.
Files:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
In the tester it's OK. That's how it works in practice.

In this case you need to deal with the code, print( Print(...) ) all values and see where the error comes from

 
Tigerfreerun:
In the tester it's fine. That's how it works in practice.

You just got your answer:

Forum on trading, automated trading systems and trading strategy testing

Any questions from beginners on MQL4, help and discussion on algorithms and codes

Alexey Viktorov, 2018.09.06 21:00

Direction to think about: If the profit is less than zero... how big will the array be during sorting???

And what is the size of the array if there are no orders at all???
Think about what the size of the sortable array a[][2] in the first dimension would be if all profits are NOT greater than zero.
 

Good afternoon, the EA is called "Rollover", but it does not work as planned. It doubles the lot if it closes in minus, but the subsequent closing of the TP for some reason does not allow to return minus trades, which were closed before. Please advise what is wrong, I cannot figure it out. I would like to ask my question in my mailbox.

extern string TimeStart    = "04:00";  //Время начала контрольного периода
extern string TimeEnd      = "09:00";  //Время окончания контрольного периода
extern string TimeCloseOrder = "23:30";//Время в которое происходит закрытие всех ордеров
extern double LOT          = 0.1;
extern int    Magic        = 777;
extern double K_martin     = 2;
extern bool   No_Loss      = true;
int slippage = 3;
double marga,Lot,SL,TP;
int tip,Orders,tipOrders,TradeDey;
//-------------------------------------------------------------------+
int init()
{
   if (Digits==5 || Digits==3) slippage = 30;
}
int start()
{
   datetime Time_Start      = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeStart,     ":00"));
   datetime Time_End        = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeEnd,       ":00"));
   datetime Time_CloseOrder = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeCloseOrder,":00"));

   if (Time_CloseOrder>Time_End) if (CurTime()>=Time_CloseOrder) CLOSEORDERS();

   int tip;
   if (Orders>OrdersTotal()) tip=CloseOrder();
   Orders=OrdersTotal();

   if (ORDERS(0)==0 && tip==0 && (CurTime()<Time_CloseOrder || Time_CloseOrder<=Time_End) && TradeDey!=TimeDay(CurTime()))
   {
      int BarStart = iBarShift(NULL,0,Time_Start,false);
      int BarEnd   = iBarShift(NULL,0,Time_End  ,false);
      double Max_Price=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,BarStart-BarEnd,BarEnd));
      double Min_Price=iLow (NULL,0,iLowest (NULL,0,MODE_LOW, BarStart-BarEnd,BarEnd));
   
      if (TimeCurrent()>Time_End && ObjectFind("bar0"+Time_End)==-1)
      {
         ObjectCreate("bar0"+Time_End, OBJ_RECTANGLE, 0, 0,0, 0,0);
         ObjectSet   ("bar0"+Time_End, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet   ("bar0"+Time_End, OBJPROP_COLOR, Blue);
         ObjectSet   ("bar0"+Time_End, OBJPROP_BACK,  true);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME1 ,Time_Start);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE1,Max_Price);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME2 ,Time_End);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE2,Min_Price);
      }
      
      if (Bid>Max_Price) OrderSend(Symbol(),OP_BUY,LOT,Bid,slippage,Min_Price,
         NormalizeDouble(Ask + Max_Price-Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      if (Bid<Min_Price) OrderSend(Symbol(),OP_SELL,LOT,Bid,slippage,Max_Price,
         NormalizeDouble(Bid - Max_Price+Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      return;
   }
   if (No_Loss) No_Loss();
   if (tip==1 && TradeDey!=TimeDay(CurTime()))
   {
      Lot=Lot*K_martin;
      if (tipOrders==0) OrderSend(Symbol(),OP_SELL,Lot,Bid,slippage,SL,TP,"Nevalyashka",Magic,Blue);
      if (tipOrders==1) OrderSend(Symbol(),OP_BUY ,Lot,Ask,slippage,SL,TP,"Nevalyashka",Magic,Blue);
   }
   return(0);
}
//-------------------------------------------------------------------+
int CloseOrder()
{
   string txt;
   double loss;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
      {
         tipOrders=OrderType();
         Lot=OrderLots();
         loss = MathAbs(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)/Lot/K_martin);
         if (tipOrders==0)
         {
            TP=NormalizeDouble(Bid - loss*Point,Digits);
            SL=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (tipOrders==1)
         {
            SL=NormalizeDouble(Bid - loss*Point,Digits);
            TP=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (OrderClosePrice()==OrderTakeProfit() || OrderProfit()>=0) TradeDey=TimeDay(CurTime());
         if (OrderClosePrice()==OrderStopLoss()) return(1);
      }
   }  
   return(0);
}
//+-----------------------------------------------------------------+
int ORDERS(int tip)
{
   int N_Sell,N_Buy;
   for (int i=0; i<OrdersTotal(); i++)
   {                                               
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
         {
            if (OrderType()==OP_BUY ) N_Buy++;
            if (OrderType()==OP_SELL) N_Sell++;
         }
      }   
   }
if (tip== 0) return(N_Buy+N_Sell);
if (tip== 1) return(N_Buy);
if (tip==-1) return(N_Sell);
}                  
//-------------------------------------------------------------------+
void No_Loss()
{
   int tip;
   double TP,OOP;
   for (int i=OrdersTotal()-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS)==true)
      {
         tip = OrderType();
         if (tip<2 && OrderSymbol()==Symbol())
         {
            if (OrderMagicNumber()!=Magic) continue;
            TP = OrderTakeProfit();
            OOP = OrderOpenPrice();
            if (tip==0) //Bay               
            {  
               if (OrderStopLoss()>OrderOpenPrice()+Ask-Bid) return;
               if ((TP-OOP)/2+OOP<=Bid)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP+Ask-Bid,Digits),TP,0,White);
            }                                         
            if (tip==1) //Sell               
            {                                         
               if (OrderStopLoss()<OrderOpenPrice()-Ask+Bid) return;
               if (OOP-(OOP-TP)/2>=Ask)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP-Ask+Bid,Digits),TP,0,White);
            } 
         }
      }
   }
}
//------------------------------------------------------------------+
void CLOSEORDERS()
{
   bool error;
   int err;
   while (true)
   {  error=true;
      for (int i=OrdersTotal()-1; i>=0; i--)
      {                                               
         if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
         {
            if (OrderSymbol()!=Symbol()||Magic!=OrderMagicNumber()) continue;
            if (OrderType()==OP_BUY)
               error=OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);
            if (OrderType()==OP_SELL)
               error=OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);
         }   
      }
      if (!error) {err++;Sleep(2000);RefreshRates();}
      if (error || err >5) return;
   }
}
//-------------------------------------------------------------------+
 
Tigerfreerun:
I do not really understand what exactly this function does. But, as the author has said, its intended purpose is to cover losing orders with profitable ones between the symbols. I would be glad if you could help me to correct and understand the function
void MaxMinProfit()
{
int i, N, MaxTic, MinTic;
double   MinProf=0, MaxProf=0, OP, g, a[][2];
string MinSym, MaxSym;
ArrayResize(a, 0);
 
for (i=OrdersTotal()-1; i>=0; i--) 
  {    
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
    { 
     if (OrderType()==OP_SELL ||  OrderType()==OP_BUY )
      {
       OP = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
       
      if (MinProf>OP) 
      {
       
          MinProf=OP;
          MinTic=OrderTicket();
          MinSym=OrderSymbol();
          
         }
         
      if (OP>0) 
      {
       
          N++;
            ArrayResize(a, N);
            a[N-1][0]=OP;
            a[N-1][1]=OrderTicket();
          
         }
         
         }
         }
         
         }
         
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);//MODE_ASCEND);
      
      for (i=0; i<Level; i++) 
       {
     
     g+=a[i][0];
     //int ti=a[i-2][1];
     }
         
         
     
     if(MinProf <0 && (g+MinProf)>=ProcMax)
      {
       for (i=0; i<Level; i++) 
       {
       if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
        {
        //Alert(a[i][1]);
         if (OrderType()== OP_BUY)
         {
          OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }
         }
          
          
          
          if (OrderSelect(MinTic, SELECT_BY_TICKET, MODE_TRADES))
        {
         if (OrderType()== OP_BUY)
         {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }}       
return;
}

You don't understand, and I don't want to understand what this function does. You use it. You have chosen it for yourself. How can you use something without understanding what it is for.

I just told you where the error is coming from, for what reason.

One more clarification:

An array is declared. It is highlighted in green. It has zero length in the first dimension. The line in blue is not clear. If you want to reset the size of the array, there is ArrayFree() But even this function will be useless, since the just declared dynamic array has zero length.

2. If there are no orders, the code marked in red will not be executed. Therefore, the array's size will remain zero.

3. Array sorting is provided on every tick. It follows from the code. And what can be sorted in an empty pocket? Unless it's 2 quail eggs...?


And this is the text of the error... What can I say? The developers didn't foresee that someone could try to sort an empty array. They didn't come up with a special message for that.

ArrayFree - Операции с массивами - Справочник MQL4
ArrayFree - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически...
 
Alexey Viktorov:

You don't understand, and I don't want to understand what this function does. You use it. You have chosen it for yourself. How can you use something without understanding what it is for.

I just told you where the error is coming from, for what reason.

One more clarification:

1. an array is declared. It is highlighted in green in the code. It has zero length in the first dimension. The line highlighted in blue is not clear. If we want to reset the size of the array, there is ArrayFree() , but even this function will be useless, since the dynamic array we have just declared has zero length.

2. If there are no orders, the code marked in red will not be executed. Therefore, the array's size will remain zero.

3. Array sorting is provided on every tick. It follows from the code. And what can be sorted in an empty pocket? Unless it's 2 quail eggs...?


And this is the text of the error... What can I say? The developers didn't foresee that someone could try to sort an empty array. They didn't come up with a special message for that.

Alexey, you're wrong. ArrayFree() serves to free up memory from the array when it is no longer needed, which is very rarely needed, and certainly not in this case.

ZeroMemory(a), ArrayInitialize(a,xxx) should be used to zero the array, and ArrayResize(a,xxx) should be used to resize it in the first dimension.

However, this amendment does not affect your reasoning - it is correct.

 
Artyom Trishkin:

Alexey, that's not correct. ArrayFree() is used to free memory from an array when this array is no longer needed, which is very rare, and definitely not in this case.

ZeroMemory(a), ArrayInitialize(a,xxx) should be used to zero the array, and ArrayResize(a,xxx) should be used to resize it in the first dimension.

However, this amendment doesn't affect your reasoning - it's correct.

According to the documentation

ArrayFree .

frees the buffer of any dynamic array and sets the size of the zero dimension to 0.

Maybe I didn't express myself correctly enough and you misunderstood me.
 
Alexey Viktorov:

According to the documentation

Maybe I didn't express myself correctly enough and you misunderstood me.

And further back there:


Note

The use of the ArrayFree() function in scripts and indicators is not necessary very often, as all used memory is immediately released after the script stops operating. In custom indicators, most operations with arrays are accessing indicator buffers, the sizes of which are automatically managed by the executive subsystem of the client terminal.

If a program needs to manage memory independently in complex dynamic conditions, the ArrayFree() function will allow to explicitly and immediately release the memory occupied by an unnecessary dynamic array.


Frees the buffer of any dynamic array and sets the size of the zero dimension to 0

Do you understand? You read the second part and missed the first - important - part? It frees up the memory allocated for the array. It's... gone... The memory space allocated for the array is freed up and can then be occupied by other data. Why, each time you re-enter the function, should memory be reallocated to this array? You are the one that is supposed to free it. All you need to do is to change the size - ArrayResize() or to zero the array - ArrayInitialize(), ZeroMemory(). And memory space for the array will not be released, and it will remain reserved for this array until the program is completed.

 
Artyom Trishkin:

And further back there:


Note

The use of the ArrayFree() function in scripts and indicators is not necessary very often, as all used memory is immediately released upon operation completion. In custom indicators, most operations with arrays are accessing indicator buffers, the sizes of which are automatically managed by the executive subsystem of the client terminal.

If a program needs to manage memory independently in complex dynamic conditions, the ArrayFree() function will allow to explicitly and immediately release the memory occupied by an unnecessary dynamic array.


It frees the buffer of any dynamic array and sets the size of the zero dimension to 0

Do you understand? You've read the second part and missed the first important one, didn't you? It frees up memory allocated for the array. That's all... gone... The memory space allocated for the array is freed up and can be further occupied by other data. Why, each time you re-enter the function, should memory be reallocated to this array? You are the one that is supposed to free it. All you need to do is to change the size - ArrayResize() or to zero the array - ArrayInitialize(), ZeroMemory(). And memory space for the array will not be released, and it will remain reserved for this array until the program is completed.

Ok... And if a local array is declared at each call of a function or, most improbably, on each tick... But the memory for the array is allocated each time the array is defined. Isn't it so? And what difference does it make whether or not memory is freed, but memory is being allocated each time...

My main idea was that you shouldn't do that... and if you do, you'd better do it through ArrayFree().

Here's what's interesting: if a local array is declared each time a function is called, correspondingly, memory is reserved for it each time. And what addresses are used when doing this? The same as when first declaring the array, or what will be used?

 
Denis Danilov:

Good afternoon, the EA is called "Rollover", but it does not work as planned. It doubles the lot if it closes in minus, but the subsequent closing of the TP for some reason does not allow to return minus trades, which were closed before. Please advise what is wrong, I cannot figure it out. I would like to thank in advance all who commented.

Try to check the doubling earlier than the initial lot. Watch the closing by time.

Reason: