Questions from Beginners MQL4 MT4 MetaTrader 4 - page 247

 
Valeriy Yastremskiy #:

Insert the code correctly, alt S or by icon, hint code.

Why do you need aSaveTick array?

You are only using 2 array elements. Replace them with global or static variables if you declare them in a function.

It's not sensible to use an array for 2 variables.

And you seem to call arrays before theFindTick() function is called, where the size of the SaveTick array is set. And there is an overrun of the array.

Thank you. Got it.
Can you tell me what the error is, it seems to me the function is not counting correctly


***
 
makssub #:

Thank you. Got it.
Can you tell me what the error is, it seems to me the function is not counting correctly


Insert the code correctly, it's the 13th box on top of the answer window.

And you can write in words what the function does line by line.

It certainly doesn't look correct.

I do not understand where and how the Tick variable is assigned to the order ticket. And there is no need to check for the magic number and order type according to the following condition
_magic < 0 || OrderMagicNumber() == _magic
If the function is called with a magic number less than zero or the magic number equals the number of the selected order, we will request the point size and if it is equal to zero we will look for an empty value in the order symbol... and so on.

Oh, and remember, the order select fills in the data structure of the order and stores it. And only after the next order select with a different order number or ticket will the data in this structure change.

I.e., OrderSend does not fill the order data structure, but returns the order ticket or minus 1. And the order structure is only filled in by OrderSelect. And then the data of this order can be obtained from this structure.

 
Valeriy Yastremskiy #:

Insert the code correctly, it's the 13th box at the top of the answer window.

And you can write in words what the function does line by line.

It seems to be wrong of course.

And it's not clear where and how the Tick variable is assigned to the order ticket. And there is no need to check for the magic number and order type according to the following condition
_magic < 0 || OrderMagicNumber() == _magic
If the function is called with a magic number less than zero or the magic number equals the number of the selected order, we will request the point size and if it is equal to zero we will look for an empty value in the order symbol... and so on.

Oh, and remember, the order select fills in the data structure of the order and stores it. And only after the next order select with a different order number or ticket will the data in this structure change.

I.e., OrderSend does not fill the order data structure, but returns the order ticket or minus 1. And the order structure is only filled in by OrderSelect. And then from this structure we can get the data of this order.

int FindTicket()
   {
   int oldticket;
   int tick=0;
   ticket=0;
   
   
   for(int cnt = OrdersTotal ()-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
            oldticket = OrderTicket();
            if (oldticket > ticket)
               {
               ticket = oldticket;
               tick = OrderTicket();
               }
            }
         }
      }
   return(tick); 
   }              
int TickF = FindTicket();
int CalculateProfitHistory() 
{
  double _point;
  int    i, _ototal = OrdersHistoryTotal(), _profit=0;
  for   (i = 0; i < OrdersHistoryTotal(); i++) 
  {
    if (OrderSelect(TickF, SELECT_BY_TICKET, MODE_HISTORY)) 
    {
      if (OrderSymbol() == Symbol())
      {
        if (OrderMagicNumber() == Magic) 
        {
           _point = MarketInfo(OrderSymbol(), MODE_POINT);
           if (_point == 0) 
           {
              if (StringFind(OrderSymbol(), "") < 0) 
                 _point = 0.0001; 
              else _point = 0.01;
           }   
           if (OrderType() == OP_BUY) 
           {
              _profit += int((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/_point);
           }
           if (OrderType()==OP_SELL) 
           {
              _profit += int((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/_point);
           }
         }
      }
    }
  }
  return(_profit);
}

In the first function, we find the required order ticket and the second function should calculate the profit of all orders closed after that ticket. The profit of those orders that were before it is of no interest to me. But the second one does not calculate it correctly. When an order is opened these 2 functions are called and therefore it should be equal to 0, but it is not.
PS took your advice, gave up arrays)
12th box above)

 
makssub #:

In the first function, I find the ticket of the required order, and the second function should calculate the profit of all orders closed after this ticket. I am not interested in the profit of the ones before it.
PS took your advice, I refused arrays)
the 12th square from above)

The first function finds the ticket with the highest number, if tickets increase with numbers))) On the next iteration of the loop, the ticket of the next highest numbered order is compared with the ticket of the previous order. The order select fills the order structure, and OrderTicket retrieves the ticket value from this structure.

Write or read for yourself what each line of code does.

In the second function, OrderSelect will fill the order structure with the same ticket data)

 
Valeriy Yastremskiy #:

The first function finds the ticket with the highest number, if the tickets increase with numbers))) At the next iteration of the loop, the ticket of the next highest numbered order is compared to the ticket of the previous order. The order select fills the order structure, and OrderTicket retrieves the ticket value from this structure.

Write or read for yourself what each line of code does.

In the second function, OrderSelect will fill the order structure with the same ticket data)

Spelled it out, but it seems to be bad with logic regarding this language. Can you tell me how to determine the ticket of the last open order?

How do I calculate the profit of all the closed orders following it?

 
makssub #:

Spelled it out, but it seems to be bad with logic in relation to this language. Can you tell me how to determine the ticket of the last open order?

How do I calculate the profit of all the closed orders following it?

By the time of opening of an order. It should be the largest.) And we should not use the order number. Or we have to store in our base the order numbers, tickets, state of orders and open/close time.

 if(OrderSelect(Ticket, SELECT_BY_TICKET)==true) // Если выбор рыночного ордера произошел успешно
        {
         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт           {
            
            //           Alert("Наш рыночный ордер жив, Модифицируем его если нужно ");
            if(Tral_Stop!=0 || Tral_Profit!=0)
          {     ModifyTral(); }
            return;
           }
         if(OrderCloseTime()!=0)              // Если наш рыночный ордер закрылся
         {
Alert("Our market order has closed. The Adviser's work is completed ",
                  " Swap = ", OrderSwap(), " Commission = ", OrderCommission(),"Profit/loss = ",OrderProfit());
         // ..... // получаем профит и считаем общий профит например
         }

And it is better to remember the logic to the end. It is easier then. It is better to start with necessary data, and there should be enough data for a decision)

We have open time of orders (not pending). We have their tickets. We have an open price, SL and TP of each market order. And there is a time of order closing. And after the order is closed, the Profit field is filled in.

This is the data we need to create the logic out of these fields.

The phrase "closed orders following the last open order" is not defined at all. They can go by number, by ticket and by time.

 
Valeriy Yastremskiy #:

By the opening time of the order. It should be the largest)

You write it correctly, but the code looks a bit complicated )))))

I would do it the way you put it:

int GetTicketLastOpenOrder()
{
   int ticket = -1;
   datetime t = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL && OrderOpenTime() > t)
      {
         ticket = OrderTicket();
         t = OrderOpenTime();
      }
   }
   return(ticket);
}


ZS: OrderSelect() by ticket number will take much longer to execute than a simple search by open orders

 
Igor Makanu #:

You write it correctly, but the code is a bit convoluted ))))

Just write it the way you want:


S : OrderSelect() by ticket number will take much longer to execute than a simple enumeration of open orders

Thanks Igor, it's just when they don't understand the essence, the right code for something does not convey the essence, so I ask to put not complicated algorithms into words))))

 
Valeriy Yastremskiy #:

By the opening time of the order. It should be the biggest) And only not by order number, and often ticketing is not helpful either. Or memorise order numbers, tickets, order status and open/close times in your database.

And it is better to remember the logic up to the end. It is easier then. It is better to start with necessary data, and there should be enough data for a decision)

We have open time of orders (not pending). We have their tickets. We have an open price, SL and TP of each market order. And there is a time of order closing. And after the order is closed, the Profit field is filled in.

This is the data we need to create the logic out of these fields.

The phrase "closed orders following the last open order" is not defined at all. They can go by number, by ticket and by time.

Thank you very much for your replies. I have implemented some of your suggestions.
I have written a function that finds the right tick.
Wrote a function that counts the profit of all closed orders after the desired order tick of the selected function. All I have to do now is to correct it according to your recommendations and add a check by time etc.

tpl = NormalizeDouble(Bid - ProfitLock*Point, Digits);
            ticket = OrderSend (Symbol(), OP_SELL, lastlot, Bid, Slippage, 0, tpl, "",Magic, 0, Red);


double CalculateProfitHistory()
{
double order=0,op=0;
int cnt=0;
datetime time=0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
      if(OrderSelect(Tick,SELECT_BY_TICKET,MODE_HISTORY))
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
            
            
            op += OrderProfit();
            order +=op;
            cnt++;
            
         }
      }
      }
   return(order);
  }

The only thing that confuses me now is that it does not calculate it correctly. If TP comes out 0.02 as a result of the test, it calculates and writes 0.1300 in Comment. Can you tell me what's wrong with it?

 
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2021.09.02
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
Reason: