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

 

Так Вы пробовали сделать переменные глобальными?

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:

Тут была такая задумка, чтобы условия по поиску входа советника проверялись не каждый тик, а только, если  открывается или закрывается очередной ордер другим советником или в ручную (чтобы не было лишней нагрузки на процессор) . Поэтому и нужна проверка соответствия количества ордеров с каждым тиком.

Можно ли использовать статистическую переменную -  static?  Будет ли программа в таком виде рабочей?

Как вариант, самое простое и лёгкое условие

OnTrade() - это аналог для мт4 с мт5

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:

Спасибо за ответ. Понял все что Вы написали. Но не понял смысла написанного с точки зрения моей проблемы.

Под горизонтальным двумерным массивом в моем коде  я имею в виду когда есть 2 строки под индексом 0 или 1 и столбцы под индексами от 0 до 30. Первое измерение обозначается как  [0] [0], [0] [1], [0] [2], ...[0] [30] Второе измерение обозначается как  [1] [0], [1] [1], [1] [2], ...[1] [30] 

Под вертикальным  двумерным массивом в моем коде  я имею в виду когда есть 31 строка под индексами от  0 до 30 и  2 столбца под индексами  0 и 1. Первое измерение обозначается как  [0] [0], [1 [0], [2] [0], ...[30] [0] Второе измерение обозначается как  [0] [1], [1] [1], [2] [1], ...[30] [1] 

Если исполнить мой код то массив заполнится по вертикали. И функция  ArraySort() будет сортировать массив как ей и положено.

ВОПРОС Почему при этом функция  ArrayFill() работать не будет? Ведь я попросил ее что бы она на двадцатой минуте заполнила первое измерение массива (31 элемент) одинаковыми значениями 0.5555.
Спасибо за помощь.

MQL4 может работать не более чем с 4х-мерными массивами. Следовательно arr[31][31] это ошибка. Массив может быть не больше чем arr[][4]. При этом первое измерение ограничено не MQL, а чем, я точно не знаю. Может кто-то объяснит.

Функция ArrayFill() работать будет, только надо понимать, что количество элементов в массиве arr[3][2] будет 6 и в эту функцию надо писать 6, а не 3 по размеру первого измерения.

 

Четырёхмерное измерение: arr[][][][] или arr[,,,].

При этом размеры трёх последних измерений должны быть указаны при объявлении, и закреплены жестко. А первый можно не указывать и изменять в дальнейшем:

int arr[,100,200,500];

на примере двухмерного массива данные в массиве располагаются так:

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

Cортировка двигает всю горизонталь сортируя по первому измерению,

а ArrayFill() заполняет от одного элемента до другого, например от 3 до 8. Получается каша.

Если Вы хотите заполнять какие-то значения в горизонтали по первому измерению, то должны сами контролировать начало и конец заполнения, зная как располагаются данные.

Например, вся линейка нулевого элемента первого измерения:

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

Если только одного нулевого, тогда так:

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

Если много нулевых элементов, тогда циклом и простым присвоением. 


Многабукав, наверное, непонятно объяснил... Пользуйтесь принтом, печатайте всё что находится в цикле, и так и сяк, и придёт осознание. Так быстрее научитесь.

принтф - мой друг!

 
Alexey Viktorov:

MQL4 может работать не более чем с 4х-мерными массивами. Следовательно arr[31][31] это ошибка. Массив может быть не больше чем arr[][4]. При этом первое измерение ограничено не MQL, а чем, я точно не знаю. Может кто-то объяснит.


А первое измерение( то есть, количество строк) ограничено каким количеством? Не более какого количества строк в многомерном массиве разрешает  MQL4 ?

 

думаю, у всех четырёх измерений ограничение: INT_MAX

Про структуру.

двухмерный:

по своей структуре представляет одномерный массив, в котором элементы располагаются так: сначала первая строка, затем вторая, затем третья.

трехмерный:

в трехмерном, также. Это одномерный массив, где сначала строки первого листа друг за другом, затем второго,....

Почему одномерный? Потому, что под массив в памяти компьютера выделяется несколько ячеек подряд, вот и пишут в них всё по порядку: строка00+строка01+строка02+строка10+строка11....


И есть ещё возможность добавить четвёртое измерение - пачки листов трехмерных массивов.

По ходу программы изменять можно только количество строк. Все строки, столбики, листы и пачки - это условность, для понимания структуры. На самом деле измерения не находятся в нашем пространстве, это просто измерения.

Как говорит Алексей:

Alexey Viktorov:

  столбец   расположен … горизонтально, потому, что я смотрю на это лёжа на диване………

 
Alexey Viktorov:

Вы обратили внимание на примечание

ArrayFill

Многомерный массив при обработке функцией ArrayFill() представляется одномерным, например, массив array[2][4] обрабатывается как array[8], поэтому при работе с этим массивом допустимо указать индекс начального элемента равным 5. Таким образом, вызов ArrayFill(array, 5, 2, 3.14) для массива array[2][4] заполнит значением 3.14 элементы массива array[1][1] и array[1][2].


Разобрался со всем кроме  ArrayFill() .

1. Когда я объявляю массив  double LoY[31][31]; я по сути создаю таблицу размером 31 строка на 31 столбец. Я создал двухмерный (а не четырехмерный) массив, но еще не заполнил его.

2. Далее в коде  я заполняю каждый отдельно взятый элемент массива значением Bid. Я могу заполнить его  при помощи 2 вариантов
         а) LoY[31][0]=Bid; - заполняю 31 строку и первый столбец  массива значениями Bid . А второе измерение(столбец под индексом 1, по умолчанию заполнено 0, потому что я его не  заполняю. Таким образом в этом варианте  первое измерение  у меня состоит из 31 заполненного элемента, а второе из 1.

         б)  LoY[0][31]=Bid  - заполняю 31 столбец  и первую строку  массива значениями Bid . А второе измерение(строка под индексом 1, по    умолчанию заполнено 0, потому что я его не  заполняю.  Таким образом в этом варианте  второе измерение  у меня состоит из 31 заполненного элемента, а второе из 1.

    ArraySort()  сортирует двумерный массив только по первому измерению. Следовательно она будет сортировать вариант а) , в котором в первом измерении 31 строка и не будет сортировать вариант б) в котором в первом измерении только 1 строка , потому что 1 строку сортировать невозможно. 
Теперь     ArrayFill()    Она перед тем как присвоить нужным элементам  двумерного массива нужные значения, вытягивает двумерный массив в одну строку. То есть она должна будет вытянуть мой массив  LoY[31][31] в одну строку размером 961 элемент. Это очень длинная строка и большинство элементов будут лишними. 

Поэтому сделаем массив  LoY[31][2](вариант а))или  LoY[2][31] (вариант б))

 Понятно как    ArrayFill()    вытянет в 1 строку вариант б) . Вторая строка просто присоединится к первой и после последнего элемента первой строки    LoY[0][31]  первая строка массива в   ArrayFill()    продолжиться с   LoY[0][32] и закончится   LoY[0][62] И значения элементов массива в функции  ArrayFill() будут идти в следующем порядке с нулевого индекса по 31 элементы массива будут заполнены значениями цены, а с 32 индекса и до конца будут заполнены 0.  

ВОПРОС. А как  ArrayFill() вытянет в 1 строку вариант а)? Ведь в этом варианте 28 строк. И если это будет одна строка то в каком порядке в ней будут идти значения элементов массива? И можно ли при помощи Print() вывести элементы моего двумерного  массива после того как  ArrayFill() преобразует их в одномерный массив? Сама эта функция никакого значения не возвращает и поэтому  Print() ее не печатает, если ее вставить в нее.

Спасибо за помощь.

 

Что-то я тут намудрил… аж стыдно

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

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

Alexey Viktorov, 2021.03.18 20:42

MQL4 может работать не более чем с 4х-мерными массивами. Следовательно arr[31][31] это ошибка. Массив может быть не больше чем arr[][4]. При этом первое измерение ограничено не MQL, а чем, я точно не знаю. Может кто-то объяснит.

Функция ArrayFill() работать будет, только надо понимать, что количество элементов в массиве arr[3][2] будет 6 и в эту функцию надо писать 6, а не 3 по размеру первого измерения.

может не сильно трезв был¿

ANDREY:

Разобрался со всем кроме  ArrayFill() .

1. Когда я объявляю массив  double LoY[31][31]; я по сути создаю таблицу размером 31 строка на 31 столбец. Я создал двухмерный (а не четырехмерный) массив, но еще не заполнил его.

2. Далее в коде  я заполняю каждый отдельно взятый элемент массива значением Bid. Я могу заполнить его  при помощи 2 вариантов
         а) LoY[31][0]=Bid; - заполняю 31 строку и первый столбец  массива значениями Bid . А второе измерение(столбец под индексом 1, по умолчанию заполнено 0, потому что я его не  заполняю. Таким образом в этом варианте  первое измерение  у меня состоит из 31 заполненного элемента, а второе из 1.

         б)  LoY[0][31]=Bid  - заполняю 31 столбец  и первую строку  массива значениями Bid . А второе измерение(строка под индексом 1, по    умолчанию заполнено 0, потому что я его не  заполняю.  Таким образом в этом варианте  второе измерение  у меня состоит из 31 заполненного элемента, а второе из 1.

    ArraySort()  сортирует двумерный массив только по первому измерению. Следовательно она будет сортировать вариант а) , в котором в первом измерении 31 строка и не будет сортировать вариант б) в котором в первом измерении только 1 строка , потому что 1 строку сортировать невозможно. 
Теперь     ArrayFill()    Она перед тем как присвоить нужным элементам  двумерного массива нужные значения, вытягивает двумерный массив в одну строку. То есть она должна будет вытянуть мой массив  LoY[31][31] в одну строку размером 961 элемент. Это очень длинная строка и большинство элементов будут лишними. 

Поэтому сделаем массив  LoY[31][2](вариант а))или  LoY[2][31] (вариант б))

 Понятно как    ArrayFill()    вытянет в 1 строку вариант б) . Вторая строка просто присоединится к первой и после последнего элемента первой строки    LoY[0][31]  первая строка массива в   ArrayFill()    продолжиться с   LoY[0][32] и закончится   LoY[0][62] И значения элементов массива в функции  ArrayFill() будут идти в следующем порядке с нулевого индекса по 31 элементы массива будут заполнены значениями цены, а с 32 индекса и до конца будут заполнены 0.  

ВОПРОС. А как  ArrayFill() вытянет в 1 строку вариант а)? Ведь в этом варианте 28 строк. И если это будет одна строка то в каком порядке в ней будут идти значения элементов массива? И можно ли при помощи Print() вывести элементы моего двумерного  массива после того как  ArrayFill() преобразует их в одномерный массив? Сама эта функция никакого значения не возвращает и поэтому  Print() ее не печатает, если ее вставить в нее.

Спасибо за помощь.

Что-то сложно вас понять. Может по этому толком объяснить не получается. Повторите вопрос с массивом LoY[5][3] то-есть 5 строк и 3 столбца.

ArrayFill никак не преобразует исходный массив. Только обработка массива происходит так будто-бы туда сунули одномерный массив. Функция произвела необходимые действия с массивом и отвалила не нарушая размерность.

Согласно документации функция ArrayFill(LoY, 3, 6, 12) заполнит в массиве LoY только строки с индексом 1 и 2 значением 12.

LoY[1][0] будет иметь значение 12.

LoY[1][1] будет иметь значение 12.

LoY[1][2] будет иметь значение 12.

LoY[2][0] будет иметь значение 12.

LoY[2][1] будет иметь значение 12.

LoY[2][2] будет иметь значение 12.

Все остальные останутся не тронутыми.

Поэкспериментируйте с небольшим массивом и числами которые легко понимать. Например 12 и 8 вы легко заметите что больше. А 1.123654 и 1.123583 сложней

 
Alexey Viktorov:

ArrayFill никак не преобразует исходный массив. Только обработка массива происходит так будто-бы туда сунули одномерный массив. Функция произвела необходимые действия с массивом и отвалила не нарушая размерность.


Это значительно уменьшило мое недопонимание и увеличило понимание. Сейчас по новому проанализирую все что написал с учетом вновь открывшегося обстоятельства....

 
Alexey Viktorov:


Согласно документации функция ArrayFill(LoY, 3, 6, 12) заполнит в массиве LoY только строки с индексом 1 и 2 значением 12.

LoY[1][0] будет иметь значение 12.

LoY[1][1] будет иметь значение 12.

LoY[1][2] будет иметь значение 12.

LoY[2][0] будет иметь значение 12.

LoY[2][1] будет иметь значение 12.

LoY[2][2] будет иметь значение 12.


ВОПРОС
Как и какие значения нужно ввести в   ArrayFill(), если значением 12 мне нужно заполнить желтые элементы этого же массива?

ВАРИАНТ N 1

ВАРИАНТ N 2


 

Спасибо за помощь
   
Причина обращения: