Обсуждение статьи "Передача данных между индикаторами - простое решение наболевшей проблемы"

 

Опубликована статья Передача данных между индикаторами - простое решение наболевшей проблемы:

В статье объясняется, как можно довольно просто создать в терминале MetaTrader программную среду, обеспечивающую средства для доступа к буферам индикаторов из других MQL-программ.

Автор: Алексей

 
Есть очень серьезное предостережение для тех, кто использует частые вызовы DLL функций вида Get/Set.


Ради безопасности системы каждый вызов DLL идет через специальный враппер, что замедляет исполнение. Вызов DLL функции это не банальный call XXXX, а сложная обвязка с маскировкой адресов, контролем за стеком и падениями внутри DLL. В MQL5 сделано так, что если функция внутри DLL испортит стек или крешанется, то выполнение скрипта остановится без падения самого терминала.

Общий совет по использованию DLL функций: старайтесь делать редкие вызовы с большим объемом работы внутри, а не десятки тысяч обращений в секунду с передачей мелких результатов.

 

Интересно. А почему не пойти дальше?

Как заметил Ренат, вызов дешевых функций из dll дорого обходится.

Так почему бы не копировать данные сразу в предоставленный для этого массив?

 
TheXpert:

Интересно. А почему не пойти дальше?

Кому адресуется вопрос - автору или разработчикам?

Если разработчикам, то что именно предлагаете?

 

Нет ли ошибки в функции StringExplode? В текущем виде она не копирует последний компонент строки, если после него (т.е. в конце строки) не стоит разделитель. ИМХО, конец строки должен браться даже в случае, если разделителя нет на конце. Пример: подаем строку "EURUSD,EURJPY" с разделителем ",", и функция сейчас выделяет только EURUSD.

Вот поправленная версия функции, для удобства сделал возврат количества элементов:

int StringExplode(string s, string separator, string &result[])
{
  int i, pos;
  ArrayResize(result, 0);
   
  for(i = 0; ; i++)
  {
    ArrayResize(result, ArraySize(result) + 1);
    pos = StringFind(s, separator);
    if(pos >= 0)
    {
      result[i] = StringSubstr(s, 0, pos);
      s = StringSubstr(s, pos + StringLen(separator));
    }
    else
    {
      result[i] = s;
      i++;
      break;
    }
  }
  
  return(i);
}

 
Renat:
Есть очень серьезное предостережение для тех, кто использует частые вызовы DLL функций вида Get/Set.


Ради безопасности системы каждый вызов DLL идет через специальный враппер, что замедляет исполнение. Вызов DLL функции это не банальный call XXXX, а сложная обвязка с маскировкой адресов, контролем за стеком и падениями внутри DLL. В MQL5 сделано так, что если функция внутри DLL испортит стек или крешанется, то выполнение скрипта остановится без падения самого терминала.

Общий совет по использованию DLL функций: старайтесь делать редкие вызовы с большим объемом работы внутри, а не десятки тысяч обращений в секунду с передачей мелких результатов.

 Кстати, еще одно замечание по поводу множественных вызовов DLL - в процессе тестирования отметил, что при каждом вызове происходят memory leaks по несколько байт 

marketeer:

Нет ли ошибки в функции StringExplode? В текущем виде она не копирует последний компонент строки, если после него (т.е. в конце строки) не стоит разделитель. ИМХО, конец строки должен браться даже в случае, если разделителя нет на конце. Пример: подаем строку "EURUSD,EURJPY" с разделителем ",", и функция сейчас выделяет только EURUSD.

Вот поправленная версия функции, для удобства сделал возврат количества элементов:


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

--------- 

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


 
Renat:

Кому адресуется вопрос - автору или разработчикам?

Если разработчикам, то что именно предлагаете?

Автору. Можно передавать размер массива вместе с ним, тогда можно организовать единовременное копирование массива прямо из памяти в память -- очень дешево и обходит проблемы в MQL4 с поэлементными обращениями. Сейчас куча дел, иначе бы примерчик накатал... Надеюсь, суть понятна.

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

 

Как всё сложно!...

С помщью Ильнура ещё год назад написал библиотеку на MQL4 для работы с памятью. Можно выделять память, двигать указатели, писать и читать, передавать в любые другие программы имя области памяти.

Всё построенно на маппинге. Это существенно проще предлагаемого. 

 
Zhunko:

Как всё сложно!...

С помщью Ильнура ещё год назад написал библиотеку на MQL4 для работы с памятью. Можно выделять память, двигать указатели, писать и читать, передавать в любые другие программы имя области памяти.

Всё построенно на маппинге. Это существенно проще предлагаемого. 

Дело в том, что в предлагаемом подходе не нужно выделять память и двигать указатели. Чтение и запись организуются напрямую в буфер. Это намного проще маппинга.
 
Renat:
Есть очень серьезное предостережение для тех, кто использует частые вызовы DLL функций вида Get/Set.


Ради безопасности системы каждый вызов DLL идет через специальный враппер, что замедляет исполнение. Вызов DLL функции это не банальный call XXXX, а сложная обвязка с маскировкой адресов, контролем за стеком и падениями внутри DLL. В MQL5 сделано так, что если функция внутри DLL испортит стек или крешанется, то выполнение скрипта остановится без падения самого терминала.

Общий совет по использованию DLL функций: старайтесь делать редкие вызовы с большим объемом работы внутри, а не десятки тысяч обращений в секунду с передачей мелких результатов.

Поправка: с 240 билда сняты задержки на вызовах DLL. Теперь они идут практически без задержек как в нативе.
 

Огромное спасибо автору, не хилая библиотека, при грамотном использовании и

"не противоречащим законам генетики скрещиваниям"  можно получить хороший результат.

я например, наконец - то "выдрал" данные с оффлайн графиков, в режиме онлайн))). Платформа MT4.


Ложка дёгтя)) 

Не раз возникали ситуации когда в списке глобальных переменных

висели "старые" по каким то причинам не удаленные. 

Пока не могу выяснить причину этого. 

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