Особенности языка mql5, тонкости и приёмы работы - страница 101

 
fxsaber:

Результат

Да, не учел внутреннюю работу Sleep, которая на моем компе занимает где-то 4 мс

По хорошему более точной альтернативой  Sleep (кому важна точность :)) является

void sleep(int m)
  {
   if(m>0) Sleep(int(0.995*m+0.5)-1);
  }

не гарантирую точность коэффициента 0.995. Подбирал для своего компьютера. Возможно и для всех подойдет.

Файлы:
TestSleep.mq5  1 kb
 
fxsaber:

Честно говоря, даже не знаю, что это обозначает и где в MQL5 можно с этим столкнуться.

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

https://en.wikipedia.org/wiki/Interrupt
Interrupt - Wikipedia
Interrupt - Wikipedia
  • en.wikipedia.org
This article is about computer interrupts. For the study of the effect of disruptions on job performance, see Interruption science. For other uses, see Interruption. In system programming, an interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the...
 

Помимо файлов и глобальных переменных есть еще один способ передачи инфы между программами

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

Библиотеки: TradeTransactions

fxsaber, 2018.09.20 16:23

// Пример хранения/обмена данными через Ресурсы внутри Терминала
#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/ru/code/22166

void OnStart()
{  
  const RESOURCEDATA<int> ResourceINT("::int"); // Ресурс для обмена int-ами. const - как доказательство, что ничего не пишется в объект класса
  
  int ArrayINT[] = {1, 2, 3};
  int Num = 5;
  
  ResourceINT = ArrayINT;  // Ресурс хранит массив.
  ResourceINT += Num;      // Добавили в ресурс еще значение.
  ResourceINT += ArrayINT; // Добавили массив.
  
  int ArrayINT2[];  
  ResourceINT.Get(ArrayINT2); // Считали данные из ресурса.
  ArrayPrint(ArrayINT2);      // Вывели: 1 2 3 5 1 2 3

  ResourceINT.Free();                // Удалили данные из ресурса
  Print(ResourceINT.Get(ArrayINT2)); // Убедились, что данных нет: 0

  const RESOURCEDATA<MqlTick> ResourceTicks("::Ticks"); // Ресурс для обмена тиками. const - как доказательство, что ничего не пишется в объект класса
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
    for (int i = 0; i < 3; i++)
      ResourceTicks += Tick; // Добавили в ресурс тики

  MqlTick Ticks[];
  ResourceTicks.Get(Ticks); // Считали данные из ресурса.
  ArrayPrint(Ticks);        // Вывели.
  
  // Это полное имя ресурса для обращения из другой программы
  const string NameOut = StringSubstr(MQLInfoString(MQL_PROGRAM_PATH), StringLen(TerminalInfoString(TERMINAL_PATH)) + 5) + "::Ticks";  
  Print(NameOut); // Вывели полное имя ресурса.
  
  const RESOURCEDATA<MqlTick> Resource(NameOut); // Ресурс для доступа к данным (read-only) из другой программы
  
  MqlTick TicksOut[];
  Resource.Get(TicksOut); // Считали данные из ресурса.
  ArrayPrint(TicksOut);   // Вывели.
  
  Resource.Free();   // Не получится повлиять на данные read-only-ресурса.
  Print(_LastError); // ERR_INVALID_PARAMETER - Ошибочный параметр при вызове системной функции.
}
 
fxsaber:

Помимо файлов и глобальных переменных есть еще один способ передачи инфы между программами

Речь же идет о программах в рамках одного запущенного терминала?

 
Nikolai Semko:

Речь же идет о программах в рамках одного запущенного терминала?

Да. Поэтому и упомянуты глобальные переменные.

А между Терминалами стал использовать такой способ.
 
fxsaber:

Да. Поэтому и упомянуты глобальные переменные.

А между Терминалами стал использовать такой способ.

Да, это реально круто!
Очень классная находка использование RAM дисков вместо SSD. 

 
fxsaber:

Да. Поэтому и упомянуты глобальные переменные.

А между Терминалами стал использовать такой способ.

Я давно для себя использую такой легкий полухакерский способ с использованием user32.dll. Но массивы тиков таким образом не передашь.  

Давно его придумал еще на заре осваивания MQL4. Более короткого решения нигде не встречал.  Конечно он кривоват с точки зрения нормальной организации обмена, но работает шустро (не исключено, что быстрее всех существующих решений) и исправно и меня во всем устраивает, поэтому больше мозги не напрягал.

Ктоме того такой способ не требует дополнительных действий. 

Смысл в том, что для всей Винды есть общая для всех переменная типа string - имя главного окна Windows. Все ее могут менять и все ее видят.

Файлы:
 
Nikolai Semko:

Я давно для себя использую такой легкий полухакерский способ с использованием user32.dll. Но массивы тиков таким образом не передашь.  

Если через dll, то есть универсальное решение для всех типов данных.

 
Nikolai Semko:

но работает шустро (не исключено, что быстрее всех существующих решений)

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

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

 
fxsaber:

Если через dll, то есть универсальное решение для всех типов данных.

Я ж не спорю. Ваше решение действительно универсальнее. 
Но лично мне мост между терминалами нужен только для передачи текущего тика.

Мой вариант просто попроще для понимания в силу примитивности  и чуть работает быстрее. Замерял в сравнении с вашим - быстрее где-то в 1.5- 2 раза. Чтение при передачи одного тика 90 микросекунд против 160 микросекунд.

Файлы: