Новая версия платформы MetaTrader 5 build 4755: общие улучшения - страница 19

 

В мобильном МТ5 продолжают исчезать символы из списка при открытии приложения. Уже где-то год это происходит.

Воспроизвести проблему я не могу, происходит рандомно. Две недели назад осталось 2 символа из 30 в списке, сегодня осталось 6 символов из примерно 20 штук.

 

Хочу напомнить разработчикам MetaTrader, что проблема масштабирования индикаторов в отдельном окне до сих пор не решена и мешает использованию некоторых распространенных индикаторов, таких как OBV, A/D и некоторых других.

Это также затрагивает некоторые пользовательские индикаторы.

Похоже, что проблема возникает при работе с диапазоном с отрицательным значением.


I would like to remind the MetaTrader developers, that the scaling issue with indicators on a separate window has still not been resolved, and is preventing the use of some common indicators such as the OBV and A/D and several others.

It also affects some custom indicators as well.

The issue seems to occur when handling a negative valued range.

 

Раньше вызов MQLInfoInteger(MQL_MEMORY_USED) выдавал адекватную оценку, то есть взяв разность между двумя показателями до и после выделения памяти, например, массива в 10 Мб, я видел, что MQL_MEMORY_USED увеличился на 10. Сейчас складывается впечатление, что оптимизатор компилятора переносит операторы выделения каким-то выгодным для себя образом, так что замеры более не позволяют оценивать расход памяти точно по месту в коде. Например:

   Print(MQLInfoInteger(MQL_MEMORY_USED)); // 0
   ArrayResize(data1, Quantity);
   Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2
   ArrayResize(data2, Quantity);
   Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2

Если брать по отдельности, каждый массив по 1 Мб (простого типа), но здесь производится несколько последовательных выделений, и как будто выделение происходит заранее.

Это упрощенный пример. На практике структуры данных посложнее и анализировать их эффективность через данное свойство не получается.

 

Тестер бывает заливает панель с кнопками цветом, сбоит отрисовка. Похоже на то что было раньше, но уже не так сильно.

1) https://www.mql5.com/ru/forum/478178#comment_55386343

2) https://www.mql5.com/ru/forum/478178#comment_55385467




Вариант номер 2:

Вариант номер 3:

Новая версия платформы MetaTrader 5 build 4755: общие улучшения - После обновления платформы MetaTrader 5 мы исправили ошибку в расчете тройного свопа, происшедшую при некоторых сочетаниях условий тестирования.
Новая версия платформы MetaTrader 5 build 4755: общие улучшения - После обновления платформы MetaTrader 5 мы исправили ошибку в расчете тройного свопа, происшедшую при некоторых сочетаниях условий тестирования.
  • 2024.12.13
  • MetaQuotes
  • www.mql5.com
Радиус примагничивания курсора мыши при выделении графических объектов. Надо просто добавить установочные файлы в исключения этого антивирусника и Некоторые проблемы с отрисовкой и срабатыванием контролов тестера. Зависает Play видно по кликам которые сопровождаются желтым кружком. Ползунок пропадает и вместо него выводится Tooltip контрола
 
Stanislav Korotky #:

Раньше вызов MQLInfoInteger(MQL_MEMORY_USED) выдавал адекватную оценку, то есть взяв разность между двумя показателями до и после выделения памяти, например, массива в 10 Мб, я видел, что MQL_MEMORY_USED увеличился на 10. Сейчас складывается впечатление, что оптимизатор компилятора переносит операторы выделения каким-то выгодным для себя образом, так что замеры более не позволяют оценивать расход памяти точно по месту в коде. Например:

Если брать по отдельности, каждый массив по 1 Мб (простого типа), но здесь производится несколько последовательных выделений, и как будто выделение происходит заранее.

Это упрощенный пример. На практике структуры данных посложнее и анализировать их эффективность через данное свойство не получается.

Опубликуйте код для воспроизведения.

Я проверил своим старым кодом, у меня работает нормально.

Да, там нет ArrayResize(). Но раз вы не удосужились написать код для воспроизведения с ArrayResize, то я тем более не хочу тратить на это время.


#define _numOfArrayElements ((int)(1e6 - 16) / sizeof(long))
class OneMegabyteObject // https://www.mql5.com/ru/forum/1111/page3591#comment_55188045
  {
public:
   long arr[_numOfArrayElements];
   OneMegabyteObject(int seed)
     {
      if(seed < 1)
         seed = 1;
      for(int i = _numOfArrayElements - 1; i >= 0; i--)
         arr[i] = seed + (i % seed);
     }
  };

#define _printMemoryUsed(a) Print("#"((string)a)" memory used ", MQLInfoInteger(MQL_MEMORY_USED), " MB")
void OnStart()
  {
   _printMemoryUsed(1);
   OneMegabyteObject* toHeap1 = new OneMegabyteObject(MathRand() % 100);
   _printMemoryUsed(2);
   OneMegabyteObject* toHeap2 = new OneMegabyteObject(MathRand() % 100);
   _printMemoryUsed(3);
   useObjects(toHeap1, toHeap2);
   delete toHeap1;
   delete toHeap2;
  }

// Trying to avoid compiler optimizations
void useObjects(OneMegabyteObject &obj1, OneMegabyteObject &obj2)
  {
   int a = (MathRand() % 9) + 1;
   long result = 0;
   for(int i = _numOfArrayElements - 1; i >= 0; i--)
      result += MathAbs(long(obj1.arr[i] * obj2.arr[i])) % a;
   Print("result = ", result);
  }
 
Vladislav Boyko #:

Опубликуйте код для воспроизведения.

Я проверил своим старым кодом, у меня работает нормально.

Да, там нет ArrayResize(). Но раз вы не удосужились написать код для воспроизведения с ArrayResize, то я тем более не хочу тратить на это время.

Если б было время на выпиливание из общей программы некоего куска, в котором это воспроизводится и при каких условиях, я б так сделал. Поэтому для начала смежный (вероятно связанный) вопрос по памяти - подскажите, почему не совпадает оценочный размер памяти и то, что яко-бы выделяется согласно MQL_MEMORY_USED.

int Quantity = 10000;
int Length = 10;

void GenerateRandomStringList(const string symbols, const int len, const int size, string &result[])
{
   const int n = StringLen(symbols); // alphabet size, unique chars assumed
   const int m = ArraySize(result);
   ArrayResize(result, m + size);
   for(int i = m; i < m + size; ++i)
   {
      StringInit(result[i], len + 1);
      // loop throught all places in the string
      for(int j = 0; j < len; ++j)
      {
         int k = (int)((long)(MathRand() << 16) | MathRand()) % n;
         // append a char (by its index in alphabet) to the string
         StringSetCharacter(result[i], j, symbols[k]);
      }
      // if(i % 100 == 0) Print(i, " ", MQLInfoInteger(MQL_MEMORY_USED));
   }
}

void OnStart()
{
   const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789";
   string messages[];
   int m0 = MQLInfoInteger(MQL_MEMORY_USED);
   GenerateRandomStringList(alphabet, Length, Quantity, messages);
   int m1 = MQLInfoInteger(MQL_MEMORY_USED);
   PrintFormat("%d Mb, %lld bytes", m1 - m0, ((sizeof(short) * (Length + 1) + sizeof(string)) * Quantity)); // 6 Mb, 340000 bytes
}
 
Stanislav Korotky #:
Поэтому для начала смежный (вероятно связанный) вопрос по памяти - подскажите, почему не совпадает оценочный размер памяти и то, что яко-бы выделяется согласно MQL_MEMORY_USED.

Я не большой специалист по памяти и могу ошибаться. На сколько я понимаю, тест ниже показал, что выделено памяти под 2.6 миллиона символов. Если предположить, что один символ занимает 2 байта, то под символы нужно 5.2 мегабайта

int Quantity = 10000;
int Length = 10;

void GenerateRandomStringList(const string symbols, const int len, const int size, string &result[])
{
   const int n = StringLen(symbols); // alphabet size, unique chars assumed
   const int m = ArraySize(result);
   ArrayResize(result, m + size);
   for(int i = m; i < m + size; ++i)
   {
      StringInit(result[i], len + 1);
      // loop throught all places in the string
      for(int j = 0; j < len; ++j)
      {
         int k = (int)((long)(MathRand() << 16) | MathRand()) % n;
         // append a char (by its index in alphabet) to the string
         StringSetCharacter(result[i], j, symbols[k]);
      }
   }
}

void OnStart()
{
   const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789";
   string messages[];
   int m0 = MQLInfoInteger(MQL_MEMORY_USED);
   Print("m0 ", m0);
   GenerateRandomStringList(alphabet, Length, Quantity, messages);
   int m1 = MQLInfoInteger(MQL_MEMORY_USED);
   Print("m1 ", m1);
   ulong totalBuffersSize = 0;
   for(int i = ArraySize(messages) - 1; i >= 0; i--)
      totalBuffersSize += messages[i].BufferSize();
   PrintFormat("%i strings, totalBuffersSize %I64i", ArraySize(messages), totalBuffersSize);
}
 
Vladislav Boyko #:

Я не большой специалист по памяти и могу ошибаться. На сколько я понимаю, тест ниже показал, что выделено памяти под 2.6 миллиона символов. Если предположить, что один символ занимает 2 байта, то под символы нужно 5.2 мегабайта

Значит здесь MQL5 по тихому распределяет под каждую строку 260 символов, хотя его об этом не просят (просят 10+1 для терминального нуля).

 

Когда-то замечал, что MQL5 выделяет под минимальную строку те же 260 символов.

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

Т.е., писать так

string str;
str.Reserve(8192);
str="some string";

смысла нет, размер буфера будет сброшен в дефолт.

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

string str;
str.Reserve(8192);
str+="some string";
...
StringSetLength(str,0);
str+="another string";
 

У меня для EURUSD время последней котировки SYMBOL_TIME 2083 год и так далее, сервер ICMarketsSC-Demo.


А время открытия последнего бара правильное 2025.02.24 11:00. Как такое может быть?