Мой подход. Ядро - Движок. - страница 124

 
Andrey Barinov:

Потому что надо вместо OrderOpenPrice поставить OrderOpenTime()

Точно. Перепутал. :)

 
Реter Konow:

Должен признать, что результаты теста меня немного удивили.

Вот именно поэтому я и хотел, чтобы ты сделал все сам, а не давать готовых решений, которые что о стенку горохом.
А представляешь, Петр, есть еще такая фича, как указатель на функцию, благодаря которой можно организовывать вызовы функций, просто беря эти указатели из массива таких указателей. Думаю, в твоей задачи тебе это бы очень пригодилось. Только вот беда - снова с классами нужно связываться. 
 
Nikolai Semko:
Вот именно поэтому я и хотел, чтобы ты сделал все сам, а не давать готовых решений, которые что о стенку горохом.
А представляешь, Петр, есть еще такая фича, как указатель на функцию, благодаря которой можно организовывать вызовы функций, просто беря эти указатели из массива таких указателей. Думаю, в твоей задачи тебе это бы очень пригодилось. Только вот беда - снова с классами нужно связываться. 

Я слышал об указателях на функции. Однако, у меня очень мало функций. Именно из за этого, нет пространства и необходимости применения ООП. 

У меня иная концепция разработки. Я считаю, что работа целостных много-функциональных блоков эффективнее, чем больших комплексов маленьких функций.

Переспективнее, с точки зрения развития механизмов.

Такое у меня мнение...

Больших блоков у меня несколько. Чтобы применить ООП, их нужно разбить на маленькие функции, организовать в классы, а потом, использовать указатели и прочие вещи.

Но у меня не получится это сделать. Просто по тому, что я мыслю иначе.

Концепция ООП не совпадает с особенностями моего мышления, и я не могу в нем развернуться. В этом причина.

 
Nikolai Semko:

Заметь, Николай, что в вопросе программного развития, у меня нет проблем. Все развивается очень быстро. 

При этом, механизмы работают нормально. 

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

Я попробую проверить скорость и нагрузку на процессор в тестовом советнике и выложу результат.

Если он будет хорошим, перестрою связь между движом и советником, сделав ее на ресурсах.

 

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

Однако, похоже их размер объявляется только внутри юниона и потом не меняется. 

Я попробывал изменить размер массива сhar из юниона, через ArrayResize, но эффекта нет.

Похоже, размер массива сhar должен быть установлен заранее. И он должен быть максимальным.


Вот код:

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[4];
   uint    Uint[1];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(1000);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand();
   if(q > 10000)q = 10000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Меняем размер массива из Char[] юниона. 
   //-------------------------------------------------------
   ArrayResize(u.Char,StrSize);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   //StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //
   //-------------------------------------------------------
   Print("StrSize  ",StrSize," Размер u.Char  ",ArraySize(u.Char));
  }
//+------------------------------------------------------------------+
 

Теперь однозначно понятно, что размер массива char в юнионе, должен быть заранее известен. Потому что  ArrayResize(u.Char, StrSize) не меняет его.

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

 

Хорошая новость. Все работает хорошо.

Строка записывается в ресурс и читается другим советником на другом графике.

Нагрузки на процессор нет. Нагрузку дает только вызов Алерта печатающего строку.

Вот код советников:

1. Советник формирующий строку и записывающий ее в ресурс.

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(16);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand(),width,height;
   if(q > 1000)q = 1000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //Cохраняем строку переведенную в байты в ресурсе.
   //-------------------------------------------------------
   if(!ResourceCreate("::Resource",u.Uint,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //-------------------------------------------------------
  }
//+------------------------------------------------------------------+
 

Советник читающий строку из ресурса на другом графике:

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(16); 
   
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"\\Experts\\TEST_2.ex4::Resource"))Print("Resource is not connected!");
   else Print("Resource connected!");
//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Char_Uint u;   
   uint width,height;
   //string Message; 
   //-----------------------------
   if(!ResourceReadImage("\\Experts\\TEST_2.ex4::Resource",u.Uint,width,height))Print("Failed to read resource!  ",GetLastError());
   //-----------------------------
   string String = CharArrayToString(u.Char);
   //-----------------------------
   Alert("  String  ",String);
   //-----------------------------
  }
//+------------------------------------------------------------------+


Буду использовать ресурсы для связи. Единственный недостаток - нужно устанавливать максимальный размер массива char в юнионе. Зато, не нужно думать о размерах строки и количестве MT-объектов.

Этот метод более медленный, чем метод связи через MT-объекты, но вполне подходящий.

 
Реter Konow:

У вас интересная теория, хотя она не совсем соответствуем результатам моих опытов, которые я сейчас выложу ниже.

Как показала проверка, именно инициализация массива пикселей нагружает процессор больше всего.

Проверьте тестовый советник ниже.

Перечитал задачу:

Vasiliy Sokolov:

Петр, вот задание. Сделай панель, отображающую текущие открытие ордера в МТ4. Полную копию системной панели делать не надо, отобрази максимально простую таблицу с базовыми свойствами открытых ордеров: цена открытия, направление, профит. Остальное на твое усмотрение. Главное, что бы при закрытии ордера, его отображение в твоей таблице также исчезало. И наоборот, при открытии нового ордера, он появлялся бы в этой таблице.

Здесь видны две необходимых операции перерисовки при изменении таблицы на экране: 1. при закрытии сделки и 2. при открытии сделки. Зачем перерисовывать пикселы в остальное время?

Вы решаете какую-то другую задачу?

 
Vladimir:

Перечитал задачу:

Vasiliy Sokolov:

Здесь видны две необходимых операции перерисовки при изменении таблицы на экране: 1. при закрытии сделки и 2. при открытии сделки. Зачем перерисовывать пикселы в остальное время?

Вы решаете какую-то другую задачу?

Так они перерисовываются именно так, как вы сказали.

А нагрузка на процессор возникает при анимации  :

Здесь происходит постоянная переинициализация значений в массиве пикселей. Каждый 16 миллесекунд. Это нагружает процессор до 40%.

Я пытался понять, что именно нагружает. Думал, сохранение ресурса или его чтение. Оказалось, что именно переинициализация массива в цикле рисования.


Также оказалось, что постоянный вызов ObjectSetInteger(0,"MT object",OBJPROP_SELECTED,1); (Каждый 16 миллесекунд) тоже нагружает процессор. Примерно на 10%. 

Этот вызов я использую для сообщения другому советнику, что ему нужно прочитать ресурс с данными анимации.

В сумме, получается +~50% нагрузки на процессор при анимации.

Причина обращения: