Самый быстрый и удобный способ передачи больших данных между MT5 и DLL

 

Вроде было похожее обсуждение, но не помню чем закончилось, если вообще закончилось.

Вопрос такой : в скрипте, советнике или индикаторе будет использоваться DLL и хочется, чтобы можно было быстро обменяться с ней достаточно обьемной информацией, например, 100000 баров OHLC или столько же произвольных структур, что-то сделать с ними и получить обратно. Если кто проводил подобные эксперименты, можете подсказать наиболее быстрый и удобный способ передачи подобных данных.

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

Идеи были такими :

1. База данных - недостаток : хочется сделать так, чтобы все умещалось в одну DLL, а потому база скорей всего не подходит

2. Memory Mapping / Socket - недостаток : надо парсить получаемые данные

3. Pipes - преимущество : можно передавать структуры и массивы, недостаток : передача исключительно синхронная и блокирующая остальные процессы, при этом массив структур вроде передавать нельзя, только простые массивы и простые структуры

4. знает ли кто другие способы или может опровергнуть недостатки вышеуказанных методов?

 
Art:

Вроде было похожее обсуждение, но не помню чем закончилось, если вообще закончилось.

Вопрос такой : в скрипте, советнике или индикаторе будет использоваться DLL и хочется, чтобы можно было быстро обменяться с ней достаточно обьемной информацией, например, 100000 баров OHLC или столько же произвольных структур, что-то сделать с ними и получить обратно. Если кто проводил подобные эксперименты, можете подсказать наиболее быстрый и удобный способ передачи подобных данных.

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

Идеи были такими :

1. База данных - недостаток : хочется сделать так, чтобы все умещалось в одну DLL, а потому база скорей всего не подходит

2. Memory Mapping / Socket - недостаток : надо парсить получаемые данные

3. Pipes - преимущество : можно передавать структуры и массивы, недостаток : передача исключительно синхронная и блокирующая остальные процессы, при этом массив структур вроде передавать нельзя, только простые массивы и простые структуры

4. знает ли кто другие способы или может опровергнуть недостатки вышеуказанных методов?

Не заморачиваться и считать всё прямо в mql5.
 
Скорее всего, надуманная проблема. Для автооптимизации из МТ4 доводилось передавать и больше миллиона. Никаких особых тормозов от передачи не наблюдалось, т.к. основные вычисления поедали время и ресурсы куда заметнее. Чтобы не париться с выравниванием, передавал 6 значений (TOHLCV) за раз на 6 входов, на приёмном конце в длл собирал массив собственных расширенных структур.
 

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

https://www.mql5.com/ru/forum/622/page3#comment_45110

Чтобы сделать считывание автоматическим без привязки к конкретной структуре можно использовать ассоциативные массивы :

https://www.mql5.com/ru/code/7047

Еще достаточно жизнеспособно смотрится вариант с БД, но больше педалить надо :

http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

https://www.mql5.com/ru/articles/862

Еще пару ссылок на тему, если кто искать будет :

https://www.mql5.com/en/code/11134

https://www.mql5.com/ru/code/1998

https://www.mql5.com/ru/articles/342

https://www.mql5.com/ru/articles/364

http://www.developerfusion.com/article/84519/mastering-structs-in-c/

http://www.codeproject.com/Articles/138290/Programming-Memory-Mapped-Files-with-the-NET-Frame

P.S. пожелание - очень не хватает метода typeof() в MQL, может кто запедалит :)

 
А зачем в виде строк то? Можно же свечи в виде массива чисел передавать.
Art:

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

https://www.mql5.com/ru/forum/622/page3#comment_45110

Чтобы сделать считывание автоматическим без привязки к конкретной структуре можно использовать ассоциативные массивы :

https://www.mql5.com/ru/code/7047

Еще достаточно жизнеспособно смотрится вариант с БД, но больше педалить надо :

http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

https://www.mql5.com/ru/articles/862

Еще пару ссылок на тему, если кто искать будет :

https://www.mql5.com/en/code/11134

https://www.mql5.com/ru/code/1998

https://www.mql5.com/ru/articles/342

https://www.mql5.com/ru/articles/364

http://www.developerfusion.com/article/84519/mastering-structs-in-c/

http://www.codeproject.com/Articles/138290/Programming-Memory-Mapped-Files-with-the-NET-Frame

P.S. пожелание - очень не хватает метода typeof() в MQL, может кто запедалит :)

 
Alexandre:
Скорее всего, надуманная проблема. Для автооптимизации из МТ4 доводилось передавать и больше миллиона. Никаких особых тормозов от передачи не наблюдалось, т.к. основные вычисления поедали время и ресурсы куда заметнее. Чтобы не париться с выравниванием, передавал 6 значений (TOHLCV) за раз на 6 входов, на приёмном конце в длл собирал массив собственных расширенных структур.

Можно чуть поподробней?  О каких входах идет речь?

Успехов

 
Dmitriy Skub:
А зачем в виде строк то? Можно же свечи в виде массива чисел передавать.

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

если через маппинг, то все равно ведь будет мини-парсинг, например, пишешь в файл строку цен через разделитель "0,90555:0,90444:0,90333", потом при получении и чтении переводишь в массив с помощью StringSplit, так если парсинг все равно будет, то почему бы не передать сразу всю информацию за раз, например :

EURUSD#

0,90555:0,90444:0,90333#

0,90123:0,90456:0,90678#

0,90528:0,90441:0,90785#

или я как-то неправильно понял фразу про "массив чисел"?
 
Vladimir Perervenko:

Можно чуть поподробней?  О каких входах идет речь?

Успехов

Дело было достаточно давно, когда mt4 был без новейших наворотов вроде структур и классов. Готовый пример, к сожалению, не нашёл, поэтому в общих чертах опишу словами.

1) задавал нужное число баров в окне rates_total, обновлял котировки кнопкой home + "обновить" и перезапускал терминал, чтобы новый размер установился;

2) в скрипте ( эксперте, индикаторе ) mql4 назначал двумерный массив размерностью ( rates_total х 6 ) и заполнял его штатной mql4-функцией ArrayCopyRates ( ... );

3) инициализировал длл, передавая ей параметр rates_total, при этом в длл создавался объект - потребитель котировок ( автооптимизатор ) и в нём назначался массив-приёмник из расширенных структур ( TOHLCV + доп. поля ) такого же размера с обязательным контролем границ, т.к. проверить соответствие длин массивов в скрипте mql4 и приёмнике заранее невозможно, поэтому на случай собственных ошибок либо недокачки данных лучше подстраховаться;

4) в скрипте в цикле ( rates_total - 1 ... 0 ) вызывал функцию длл c 6 входами вида BuildRates ( const int64 time_, const double open_, const double high_, const double low_, const double close_, const double volume_ ), которая передавала эти значения аналогичной функции объекта, где и собирался собственно массив-приёмник; дополнительные поля, содержащие разные модели цены ( средняя, средневзвешенная и т.д. ) при сборке либо обнулялись, либо сразу заполнялись по ходу дела;

5) после автооптимизации и сохранения её результатов длл деинициализировалась, при этом ликвидировались массив-приёмник и сам объект.

Как-то так. Помню, что работала такая шняга на передачу/приём данных довольно быстро, если только не пытаться одновременно сбрасывать большие массивы на диск. :) Сейчас, в новом mt4 и в mt5, может быть всё проще. Однако со строками в любом случае связываться не советую - этот способ и раньше был одним из самых медленных, а теперь, с юникодными заморочками, наверняка стал ещё медленнее. :)

Удачи.

 
Artчерез пайпы - да, можно, но к сожалению в MQL пайпы сделанны синхронно, т.е. если отправил что-то на сервер, в DLL, то выполнение скрипта блокируется до тех пор, пока сервер не вернет ответ ... неудобно
   а отдельный поток для отправки в ДЛЛке развернуть не судьба ?
 
Rustamzhan Salidzhanov:  а отдельный поток для отправки в ДЛЛке развернуть не судьба ?

нет, не судьба, что мне это даст, если блочится именно MQL :)

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

я вот пробовал и даже успешно, но неудобно, реализация на C# во вложении, как можно видеть там создается отдельный поток на общение с клиентом в MQL

Файлы:
 
Зачем придумывать извраты если можно передавать массивом голый поток данных? Хоть структурированный, хоть нет.
Причина обращения: