Errors, bugs, questions - page 2452

 
A100:

The one that copies the arrays is not by the rules a = b, but by the rules ofArrayCopy( a, b )

You made it up yourself or is it written somewhere?
Let me remind you that this is an implicit assignment operator for structures with dynamic arrays.

 
Sergey Dzyublik:

Did they invent it themselves or is it written somewhere?
Let me remind you, it is the work of implicit assignment operator for structures with dynamic arrays.

It wasn't my idea, it was the Developers'.

        uchar a[], b[]; a = b; //Error: invalid array access
Why is there an error? You wrapped it into a structure and the error disappeared? And why? What fundamentally changed? My answers above
 
Alexey Viktorov:

It is only a question of organising the sequence of actions and events.

You yourself quoted from the manual, which says that consistency is not guaranteed. That is why it is risky.

I've already started to rewrite the code according to Vladimir's advice, but I stumbled over a case when closing is longer than a tick - double counting again (the filter node in counting is very heavy-handed). So far I haven't come up with anything better than stopping before full closing for the sake of compromise with optimization speed.

It's Friday :) Maybe after some rest I'll think of something.

In any case, thanks for the ideas - they will not be lost!

 
A100:

It wasn't my idea, it was the Developers'.

Never understood where it was written, but never mind...
Thanks for the cholivar.

Backed it up with a crutch and ran on:

struct MyArray{
   uchar data[];
   
   void operator=(MyArray &bytes){
      ArrayCopy(this.data, bytes.data);
      ArrayResize(this.data, ArraySize(bytes.data));
   }
};


MyArray GetArray(int i){
   MyArray arr;
   
   if (i%2 == 0){
      ArrayResize(arr.data, 8);
      ArrayInitialize(arr.data, 0x8);
   }else{
      ArrayResize(arr.data, 4);
      ArrayInitialize(arr.data, 0x4);
   }
   return arr;
}


void OnStart(){
   MyArray arr_1 = GetArray(1);
   ArrayPrint(arr_1.data);        // 4 4 4 4
   
   MyArray arr_2 = GetArray(2);
   ArrayPrint(arr_2.data);        // 8 8 8 8 8 8 8 8
   
   arr_2 = arr_1;
   ArrayPrint(arr_2.data);        // 4 4 4 4            
}
 
Igor Zakharov:

You yourself quoted from the manual, which says that consistency is not guaranteed. That is why it is risky.

I have already started to rewrite the code according to Vladimir's advice, but I stumbled over a case when closing is longer than a tick - double counting again (the filter node in counting is very heavy-handed). So far I haven't come up with anything better than stopping before full closing for the sake of compromise with optimization speed.

It's Friday :) Maybe after some rest I'll think of something.

Anyway, thanks for the ideas - they won't go to waste!

I was talking about my own consistency.

According to my observations, it turns out that after OnTick, when transaction occurs, code execution is passed to OnTradeTransaction function without waiting for the next tick. Therefore, there is no difference in processing the closing by its own functions or by OnTradeTransaction. But I prefer working with OnTradeTransaction. The main thing is to correctly arrange the sequence of operations without depending on sequence of transactions coming from the server. And it's important to correctly understand this sequence. Again, according to my own observations, sequence can be broken in transaction type. I.e. TRADE_TRANSACTION_DEAL_ADD may be performed first , and then TRADE_TRANSACTION_HISTORY_ADD, while logically an order should be first added to history and then a transaction.

ps; Then, as I said, by screening TRADE_TRANSACTION_DEAL_ADD transaction you can screen by position opening and by position closing. After all, we are talking about an Expert Advisor for the forex market and an account, right? Therefore, there is no need to recalculate all positions at every sneeze. It is enough to add one if it was opened, or delete one from the counted ones if it was closed.
 
Alexey Viktorov:

of the forex market and the account, right?

Grid :) Yes.

The current logic is as follows: there is a structure that stores all information about each grid: symbol-number of positions-cum-lot-profit and a few other unimportant things... The profit is recalculated by timer, if there are orders (multisymbol robot). But lots and quantity were recalculated in OnTradeTransaction (in case the user "helped").

I wanted to check a case when one grid, for example, is in profit by 100$, and the other one is in loss by 50$ - to close both of them with a profit of 50$ to prevent it from growing.

At the moment I have done so:

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,     // trade transaction structure 
   const MqlTradeRequest&        reqst,     // request structure 
   const MqlTradeResult&         reslt      // response structure 
    )
{
 int index=-1;
 for(index=0;index<symbols_total;index++)
  if(ARRAY[index].symbol==trans.symbol) break; //нашли индекс символа по которому прошла трансакция в массиве структур
 
 if(index>=0) CountOrders(index); //пересчитали элемент
}

So far I addedCountOrders()after closing a couple of grids. For a Strategy Tester, it works. For a real account I will use Vladimir's scheme (with an array of closed tickets).

By the way, pair closing has not justified itself - the drawdown does not considerably decrease, while profit cuts decently.

 
Vladimir Karputov:

I would give up ALL while, Sleep and OnTimer for the task of closing positions. I would do the following: shoot orders to close - exit OnTick, on the next tick check: if positions with needed tickets are still alive - shoot orders to close again and so on in a circle through entry/exit to OnTick.

The logic is as follows: closing of a position is the first priority, so the closing loop is at the very beginning of OnTick. And forming of array of closing tickets can be in any place of OnTick - even in the very end.

Sooner or later, you will end up with the following: you need to close a position, an order to close is sent (MQL5), i.e., an order of the opposite type is sent, since you aren't tracking trading actions in the appropriate handler (or not saving the position state in your EA) and on the next tick an order to close may be in the process of being sent and you will send another order. The result is a position in the opposite direction.

 
Alexey Kozitsyn:

Sooner or later, you will end up with the following: you need to close a position, you send an order to close (MQL5), i.e., you send an order of the opposite type, since you do not track trade actions in the corresponding handler (or do not save the position state in your EA) and on the next tick an order to close may be in the process of being sent, but you send another order. The result is a position in the opposite direction.

For such a case we have:

10036

TRADE_RETCODE_POSITION_CLOSED

Position with the specified POSITION_IDENTIFIER has already been closed

The closing position is sent with the ticket of the position to be closed, so it is unlikely that your described will happen.

 
Sergey Dzyublik:

Never understood where it's written, but never mind...
Thanks for the cholivar.

Backed it up with a crutch and ran on:

Well, it's strange how arrays are copied, but some people even like it...

I've made a more or less adequate wrap over an array and have no problems.

https://www.mql5.com/ru/forum/221917/page26#comment_11233214

 
A100:

It wasn't my idea, it was the Developers'.

I don't recall them ever saying that.

The assignment operator is intended to create an identical copy of an object. That's its purpose. When you equate something to something, you should obviously get a full copy on the left side, not something else. So there's obviously a bug here.

Reason: