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

 
Maxim Kuznetsov:

Штатно для обмена данными между советниками, индикаторами, скриптами есть только и исключительно GlobalVariables и файлы

все приведённых 4 пункта это местные "хаки" от безрыбья. Все приведённые 4 пункта используют механизмы не предназначенные для обмена произвольными данными, а тем более массивами данных.

Можно подумать GlobalVariables прямо штатно создавалась для обмена сообщениями. Глупость же сказали. По факту это тот же хак что и любой другой пункт.

 
fxsaber:


...Грубо говоря, полный цикл записи/чтения тиков через ресурс идет со скорость 4 миллиона тиков в секунду.

Чтение/Запись в ресурс осуществляется очень быстро. Но насколько это подходит для такой передачи:

1. Строна А. Событие таймера. Сборка всех значений параметров, которые были изменены на событии и перевод их в строку. Строку переводим в Char, записываем в ресурс. Посылаем сигнал о сообщении стороне Б.

2. Сторона Б. Событие OnChartEvent(), получила сигнал о сообщении, открыла ресурс, прочитала, заполнила ядро параметров новыми значениями, перерисовала нужные элементы.

Что если это событие выполняется постоянно, на частоте таймера?

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

//---------------------------------------------------------------------------------------------------------------------

  • Вариант с EventChartCustom() имеет два недостатка.

  1.  Посылка становится в очередь событий
  2. Посылка не может быть более 127 символов. Следовательно, сообщение в 1000 символов нужно разбивать, а потом снова собирать. И каждая часть сообщения будет стоять в очереди событий.
  • Вариант с передачей через граф. объекты, требует разбития сообщения на пачки по 64-символа, записи их в описание объектов и последующей сборке. Интересно, что этот вариант самый быстрый, но при увеличении длинны строки, его скорость снижается. То есть, каждый вызов ObjectSetString() 3 микросекунды. Но, если строка 1000 символов, то ее нужно разбить по 64 символа, а значит вызвать ObjectSetString() примерно 8 раз. 8*3 = 24 мс. Потом столько же времени собрать строку. Поэтому, если бы строка была в 10000 символов, то однозначно этот метод стал бы приближаться по скорости к методу работы через ресурсы. (Речь о времени сохранения и чтения ресурса + перевода строк в uint и обратно).
Вариант с ресурсом остается не проверенным до конца. Сегодня я проверю его в тестере и будет окончательно ясно, может ли он быть универсальным.
 
Реter Konow:

Что если это событие выполняется постоянно, на частоте таймера?

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

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

Обмен данными между программами

fxsaber, 2018.11.21 13:12

Наверное, обладаете большим количеством времени расписывать столь подробно различные варианты взаимодействий. К сожалению, таким ресурсом не обладаю.

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

 
fxsaber:

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

 

А какие проблемы с юнионом? Пожалуйста, пример:

union UZ{
   double d;
   int i[2];
};

void OnStart(){

   UZ u1;
   UZ u2;
   
   u1.d=12345.678;
   
   ArrayCopy(u2.i,u1.i);
   
   Alert(u2.d);

}
 
Реter Konow:

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

Прочтите предложение про кирпичи.

 
fxsaber:

...

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

Все можно сделать в 10 раз проще и нагляднее. А в статье - черт ногу сломит...


И что толку в этой статье, если Вы сказали, что не проверяли работу с ресурсами в тестере?

 
Реter Konow:

И что толку в этой статье, если Вы сказали, что не проверяли работу с ресурсами в тестере?

Вышел из обсуждения.

 

C этим решением какая то ерунда. Может я что то не верно делаю.

Короче:

Функция StringToCharArray() принимает ТОЛЬКО массив char.

Функция ResourceCreate() принимает ТОЛЬКО массив uint.

Следовательно, нужно промежуточное переписывания содержания массива char (заполненного преобразованной строкой), в массив uint.

 
//+------------------------------------------------------------------+
//|                                                    Tester EA.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //----------------------------------------------
   ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   uchar Arr[];
   uint  Data[];
   //---------------------------
   string price = (string)Bid;
   //---------------------------
   int width = StringToCharArray(price,Arr);
   //---------------------------
   ArrayResize(Data,width);
   //---------------------------
   ArrayCopy(Arr,Data);
   //---------------------------
   if(!ResourceCreate("::Resource",Data,width,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //---------------------------
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+

Индикатор на обычном графике:

//+------------------------------------------------------------------+
//|                                              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
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(25); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   uint Data[50],width,height;
   //-----------------------------
   if(!ResourceReadImage("::Resource",Data,width,height))Print("Failed to read resource!");
   else Print("Resource is readable!");
   //-----------------------------
   
  }
//+------------------------------------------------------------------+