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

 

So have you tried making the variables global?

int izmb=0, izms=0;

void OnTick()
   {
   double LB=0,LS=0;
   int b=0,s=0;
   
   for(int i=0; i<OrdersTotal(); i++)
      {    
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         { 
         if(OrderSymbol()==Symbol())
            { 
            if(OrderType()==OP_BUY)             
               {  
               LB+=OrderLots();
               b++; 
               }                                         
            else if(OrderType()==OP_SELL)        
               {
               LS+=OrderLots();
               s++;
               } 
            }
         }     
      }
   if(izmb!=b || izms!=s)
      { 
      izmb=b;
      izms=s 
           // далее идут условия для открытия ордера.
      }
 
scomoroh:

We wanted to check the conditions for finding an EA entry not every tick, but only when another order is opened or closed by another EA or manually (so that the processor is not overloaded). This is why we need to check if the number of orders corresponds to each tick.

Can we use a static variable ? Will the program work in such a form?

Alternatively, the simplest and easiest condition

OnTrade() is an analog for mt4 with mt5

void OnTrade()
 {
  ... // сюда код, который будет работать только по изменению ситуации по счёту: открытие/закрытие позиций, установка/удаление ордеров
 }

static _OTotal = -1;
static _HTotal = -1;
int OT=OrdersTotal();
int HT=OrdersHistoryTotal();
  if(OT!=_OTotal || HT!=_HTotal) // если изменилось - выполняем
   {
     OnTrade(); // здесь дёргаем текущую ситуацию на счёте и заполняем структуры
     _OTotal=OrdersTotal(); // запомним текущее количество
     _HTotal=OrdersHistoryTotal(); // запомним количество в истории
   }
 
ANDREY:

Thank you for your reply. I understood everything you wrote. But I didn't understand the meaning of what you wrote in terms of my problem.

By horizontal two-dimensional array in my code I mean when there are 2 rows under index 0 or 1 and columns under indexes from 0 to 30. The first dimension is denoted as[0][0],[0][1],[0][2], ...[0][30] The second dimension is denoted as[1][0],[1][1],[1][2], ...[1][30]

By vertical two-dimensional array in my code I mean when there are 31 rows indexed 0 to 30 and 2 columns indexed 0 and 1. The first dimension is denoted as[0][0],[1[0],[2][0], ...[30][0] The second dimension is denoted as[0][1],[1][1],[2][1], ...[30][1]

If you execute my code, the array will fill vertically. And the ArraySort() function will sort the array as it should.

QUESTION Why won 't ArrayFill() function work in this case ? After all, I asked it to fill the first dimension of the array (31 items) with the same values 0.5555.
Thanks for the help.

MQL4 can work with no more than 4-dimensional arrays. Hence, arr[31][31] is an error. An array can be no larger than arr[][4]. And the first dimension is limited not by MQL, but by what, I don't know exactly. Maybe someone can explain.

Function ArrayFill() will work, but we need to understand that the number of elements in the array arr[3][2] will be 6, and we need to write 6 into this function, not 3 by the size of the first dimension.

 

Four-dimensional dimension: arr[][][][] or arr[,,,].

The dimensions of the last three dimensions must be specified in the declaration and fixed. The first dimension can be left unspecified and can be changed later:

int arr[,100,200,500];

In the example of a two-dimensional array, the data in the array are arranged as follows:

int arr[2,5]={0,1,2,3,4,  - в нулевом элементе первого измерения 
              5,6,7,8,9}; - в первом элементе первого измерения

Sort moves the entire horizontal by sorting by the first dimension,

and ArrayFill() fills from one element to another, e.g. from 3 to 8. This results in a mess.

If you want to fill some values in the horizontal by the first dimension, you must control the beginning and the end of filling, knowing how the data is arranged.

For example, the whole ruler of the zero element of the first dimension:

int value=5;
int index=0;
ArrayFill(arr, index*ArrayRange(arr,1), ArrayRange(arr,1), value); 

If only one zero element, then so:

ArrayFill(arr, index*ArrayRange(arr,1), 1, value); 

If many zero elements, then by looping and simple assignment.


I must not have explained it very clearly... Use the printer, print everything in the loop, this way and that, and you'll get the hang of it. You'll learn faster that way.

printf is my friend!

 
Alexey Viktorov:

MQL4 can handle no more than 4-dimensional arrays. Hence, arr[31][31] is an error. An array can be no larger than arr[][4]. And the first dimension is limited not by MQL, but by what, I don't know exactly. Maybe somebody can explain.


And the first dimension( i.e. number of strings) is limited by how many? No more than what number of rows in multidimensional array does MQL4 allow ?

 

I think all four dimensions have a limit:INT_MAX

About the structure.

two-dimensional:

By structure represents a one-dimensional array in which the elements are arranged as follows: first the first row, then the second, then the third.

three dimensional:

In three-dimensional, also. It is a one-dimensional array, where the first rows are one after the other, then the second,.....

Why one-dimensional? Because several cells in a row are allocated for the array in computer memory, so they write everything in them in order: row00+row01+row02+row10+row11....


And it's also possible to add a fourth dimension - stacks of three-dimensional array sheets.

Only the number of rows can be changed in the course of the program. All rows, columns, sheets and stacks are just a convention to understand the structure. The dimensions are not actually in our space, they are just measurements.

As Alexei says:

Alexey Viktorov:

... column ... is ... horizontally because I'm looking at it lying on the couch.........

 
Alexey Viktorov:

Did you noticethe following note

ArrayFill

Multidimensional array when processing with ArrayFill() isrepresented as one-dimensional, for example, array[2][4] is processed as array[8], so when working with this array it's acceptable to specify index of initial element equal to 5. So, call ArrayFill(array, 5, 2, 3.14) for array[2][4] will fill array[1][1] and array[1][2] elements with value 3.14.


Got it all figured out except ArrayFill().

1. When I declare an array double LoY[31][31]; I am essentially creating a table of 31 rows by 31 columns. I have created a two dimensional (rather than four dimensional) array, but have not yet filled it.

2. Next in the code I fill each individual array element with a Bid value. I can fill it with 2 options
a) LoY[31][0]=Bid; - I fill row 31 and the first column of the array with Bid values . And second dimension (column under index 1, is filled with 0 by default, because I don't fill it. So in this variant I havethe first dimension with 31 filled elements and the second dimension with 1.

b) LoY[0][31]=Bid - I fill 31 column and the first row of the array with Bid values. And second dimension (line under index 1, is filled with 0 by default, because I don't fill it. Thus, in this variant, second dimension consists of 31 filled elements, second dimension consists of 1.

ArraySort() sorts the two-dimensional array by the first dimension only. Therefore it will sort option a) , in which the first dimension has 31 rows and will not sort option b), in which the first dimension has only 1 row, because 1 row cannot be sorted.
NowArrayFill() It pulls the two-dimensional array into a single line before it assigns the required values to the elements of the two-dimensional array. That is, it will have to pull my array LoY[31][31] into a single line of size 961 elements. It is a very long string and most of the elements will be unnecessary.

So let's make an array LoY[31][2] (variant a))or LoY[2][31] (variant b))

It is clear howArrayFill() will draw in 1 line in variant b) . The second line will simply join the first one and after the last element of the first line LoY[0][31] the first line of the array in ArrayFill() will continue withLoY[0][32] and will end withLoY[0][62] And the values of the array elements in ArrayFill() will go in the following order from index 0 to 31 the array elements will be filled with price values and from index 32 to the end will be filled with 0 .

QUESTION: How doesArrayFill() draw option a) into 1 line? After all, there are 28 rows in this variant. And if it will be one line, in what order will it contain values of the array elements? And, can I use Print() to print the elements of my two-dimensional array after ArrayFill() converts them into a one-dimensional array? This function itself does not return any value and so Print() does not print it if it is inserted.

Thanks for the help.

 

I messed up a little bit here... I'm ashamed of myself.

array element with a Bid value. I can fill it with 2 options
a) LoY[31][0]=Bid; - I fill row 31 and the first column of the array with Bid values . And second dimension (column under index 1, is filled with 0 by default, because I don't fill it. So in this variant I havethe first dimension with 31 filled elements and the second dimension with 1.

b) LoY[0][31]=Bid - I fill 31 column and the first row of the array with Bid values. And second dimension (line under index 1, is filled with 0 by default, because I don't fill it. Thus, in this variant, second dimension consists of 31 filled elements, second dimension consists of 1.

ArraySort() sorts the two-dimensional array by the first dimension only. Therefore it will sort option a) , in which the first dimension has 31 rows and will not sort option b), in which the first dimension has only 1 row, because 1 row cannot be sorted.
NowArrayFill() It pulls the two-dimensional array into a single line before it assigns the required values to the elements of the two-dimensional array. That is, it will have to pull my array LoY[31][31] into a single line of size 961 elements. It is a very long string and most of the elements will be unnecessary.

So let's make an array LoY[31][2] (variant a))or LoY[2][31] (variant b))

It is clear howArrayFill() will draw in 1 line in variant b) . The second line will simply join the first one and after the last element of the first line LoY[0][31] the first line of the array in ArrayFill() will continue withLoY[0][32] and will end withLoY[0][62] And the values of the array elements in ArrayFill() will go in the following order from index 0 to 31 the array elements will be filled with price values and from index 32 to the end will be filled with 0 .

QUESTION: How doesArrayFill() draw option a) into 1 line? After all, there are 28 rows in this variant. And if it will be one line, in what order will it contain values of the array elements? And, can I use Print() to print the elements of my two-dimensional array after ArrayFill() converts them into a one-dimensional array? This function itself does not return any value, so Print() will not print it if it is inserted in it.

Thank you for your help.

I'm having a hard time understanding you. Maybe this is why I cannot understand it properly. Repeat the question with LoY[5][3] array, i.e. 5 lines and 3 columns.

ArrayFill does not convert the initial array in any way. It only processes the array as if it were a one-dimensional array. The function performs the necessary actions on the array and falls back without affecting the dimensionality.

According to the documentation, theArrayFill(LoY, 3, 6, 12) function will fill only rows with index 1 and 2 in the array LoY with value 12.

LoY[1][0] will be filled with 12.

LoY[1][1] will have value 12.

LoY[1][2] will have the value 12.

LoY[2][0] will have value 12.

LoY[2][1] will have the value 12 .

LoY[2][2] will be set to 12 .

All the others will be left untouched.

Experiment with a small array and numbers that are easy to understand. For example 12 and 8 you will easily notice which is bigger. And 1.123654 and 1.123583 is more complicated

 
Alexey Viktorov:

ArrayFill does not convert the original array in any way. It only processes the array as if it were a one-dimensional array. The function performed the necessary actions on the array and dumped it without disturbing the dimensionality.


This greatly reduced my misunderstanding and increased my understanding. Now I will reanalyse everything I wrote taking into account the newly discovered circumstance....

 
Alexey Viktorov:


According to the documentation, the functionArrayFill(LoY, 3, 6, 12) will only fill the rows with index 1 and 2 in the LoY array with the value 12.

LoY[1][0] will have a value of 12.

LoY[1][1] will have value 12.

LoY[1][2] will have the value 12.

LoY[2][0] will have value 12.

LoY[2][1] will have a value of 12 .

LoY[2][2] will be set to 12 .


QUESTION
How and what values should I enter inArrayFill() if I need to fill the yellow elements of the same array with value 12?

OPTION N 1

OPTION N 2


Thank you for your help.