Español Português
preview
Моделирование рынка (Часть 17): Сокеты (XI)

Моделирование рынка (Часть 17): Сокеты (XI)

MetaTrader 5Тестер |
53 1
Daniel Jose
Daniel Jose

Введение

В двух предыдущих статьях мы объяснили, как подготовить Excel для взаимодействия с MetaTrader 5. В частности, в предыдущей статье, Моделирование рынка (Часть 16): Сокеты (X) мы объяснили, как написать код на VBA. Это необходимо для корректного взаимодействия Excel с сервером, который написан на Python, даже если вам кажется, что такое взаимодействие не вызовет никаких проблем.

В этом коротком разделе, где мы объяснили, что такое сокеты, мы показали, что при неправильном использовании Excel могут возникнуть проблемы. Это происходит при использовании сервера в Python. Однако, как уже показали в двух предыдущих статьях, правильное написание кода на VBA решает любые проблемы взаимодействия между Excel и Python и обеспечивает их идеальное согласованное функционирование. Но осталось сделать ещё одну необходимую вещь для полного завершения реализации. Указанное должно реализовываться в разделе, посвященном MetaTrader 5, где нам предстоит принять несколько решений.


Планирование перед внедрением

Главное решение, которое необходимо принять, — это какой язык программирования будем использовать для реализации той части, которая будет работать на MetaTrader 5. Я говорю об этом, потому что мы можем делать это и с помощью Python, и с использованием самого MQL5. Оба языка позволят нам делать большую часть, если не всё, что мы захотим. Однако, если мы выберем Python, мы столкнемся с ограничением: будучи скриптом, его необходимо разместить на графике. Напротив, если мы используем MQL5, мы можем применить метод или модель, которые лучше подходят для выполнения поставленной задачи.

Но если мы собираемся использовать MQL5, мы можем ориентировать решение на сервис. Иными словами, в отличие от Python, для работы которого требуется открытый график, MQL5 позволяет использовать сервис для связи с Excel. Данный подход имеет ряд преимуществ, которые я могу подтвердить.

Главное преимущество заключается в том, что сервис независим и может взаимодействовать с графиком, практически полностью контролируя MetaTrader 5 или даже не взаимодействуя с ним вообще. При использовании сервиса мы можем открывать и закрывать график, добавлять в него элементы, изменять запущенные процессы и так далее. Но самое главное, поскольку сервис работает вне графика, его можно использовать, даже если MetaTrader 5 используется для целей, не связанных напрямую с рынком.

Да, MetaTrader 5 можно использовать не только для торговли активами. Возможно, мы объясним это в другой раз, но только если посчитаю это действительно интересным для демонстрации. Хорошо, договорились. Мы будем использовать MQL5 и сделаем так, чтобы часть кода, которая будет выполняться в MetaTrader 5, работала как сервис. Давайте теперь перейдем к реализации.


Реализация

Реализация той части кода, которая будет работать в MetaTrader 5, не представляет сложности. Однако есть несколько моментов, которые нужно учитывать. Это необходимо для того, чтобы вы смогли заставить систему работать. Запомните одну важную вещь: будет запущена не одна программа. В реальности нам придётся запускать три программы одновременно. Важно реализовать и построить каждую из них так, чтобы они могли взаимодействовать и общаться одна с другой, и чтобы каждая из них понимала, что пытается или хочет сделать другая. Поэтому очень важно тестировать систему постепенно, шаг за шагом.

Сначала создадим код на Python, который будет выполнять роль сервера. Далее создадим и протестируем код VBA, который будет работать в Excel. И только тогда, когда Excel эффективно сможет взаимодействовать с сервером на Python и отдавать ему команды, следует переходить к этому этапу в MetaTrader 5.

Поэтому мой совет пользователям, которые хотят создать или реализовать подобную систему и не имеют большого опыта работы с несколькими программами одновременно, — действовать постепенно. Не пытайтесь внедрить всё сразу. Сначала нужно составить план, а затем постепенно продвигаться вперед. Итак, давайте взглянем на исходный код, который можно просмотреть полностью ниже:

01. //+------------------------------------------------------------------+
02. #property service
03. #property copyright "Daniel Jose"
04. #property version   "1.00"
05. //+------------------------------------------------------------------+
06. input string   user01 = "127.0.0.1";    //Address Server
07. input int      user02 = 9090;           //Port Server
08. //+------------------------------------------------------------------+
09. #define def_SizeBuff     2048
10. //+------------------------------------------------------------------+
11. void OnStart()
12. {
13.     bool tab;
14.     int sock;
15.     uint len, id, iMem;
16.     char buff[], ArrMem[];
17.     string szMsg, szCmd, szRet;
18.     
19.     sock = INVALID_HANDLE;
20.     ArrayResize(ArrMem, def_SizeBuff);
21.     while (!IsStopped())
22.     {
23.         Print("Trying to connect...");
24.         while (!IsStopped())
25.         {
26.             if (sock != INVALID_HANDLE)
27.                 SocketClose(sock);
28.             if ((sock = SocketCreate()) != INVALID_HANDLE)
29.                 if (SocketConnect(sock, user01, user02, 1000))
30.                     break;
31.                 else
32.                     Sleep(500);
33.         }
34.         if (!IsStopped())
35.         {
36.             szMsg = "<MT5 with Excel>:MT5";
37.             len = StringToCharArray(szMsg, buff) - 1;
38.             SocketSend(sock, buff, len);
39.             Print("Excel is online...");
40.         }
41.         ArrayInitialize(ArrMem, 0);
42.         iMem = 0;
43.         while (!IsStopped() && SocketIsConnected(sock))
44.         {
45.             szCmd = szRet = "";
46.             id = 0;
47.             do
48.             {
49.                 len = SocketIsReadable(sock);
50.                 len = ((iMem + len) < def_SizeBuff ? len : def_SizeBuff - iMem);
51.                 if (SocketRead(sock, buff, len, 500) > 0)
52.                     ArrayInsert(ArrMem, buff, iMem);
53.                 for (int c0 = 0; (ArrMem[c0] != 0) && (c0 < def_SizeBuff); c0++) switch (ArrMem[c0])
54.                 {
55.                     case '[':
56.                         id = 1;
57.                     case ';':
58.                         if ((SymbolExist(szMsg, tab)) && (id < 2))
59.                             szRet += StringFormat("%f%s", iClose(szMsg, PERIOD_D1, 0), (ArrMem[c0] == ';' ? ";" : ""));
60.                         szMsg = "";
61.                         break;
62.                     case ']':
63.                         id = 2;
64.                         iMem = 0;
65.                         break;
66.                     default:
67.                         switch (id)
68.                         {
69.                             case 0:
70.                                 szMsg += StringFormat("%c", ArrMem[c0]);
71.                                 break;
72.                             case 1:
73.                                 szCmd += StringFormat("%c", ArrMem[c0]);
74.                                 break;
75.                             case 2:
76.                                 for (iMem = 0; (ArrMem[c0 + iMem] != 0) && ((c0 + iMem) < def_SizeBuff); iMem++);
77.                                 ArrayCopy(ArrMem, ArrMem, 0, c0, iMem);
78.                                 break;
79.                     }
80.                 }
81.             }while (SocketIsConnected(sock) && (!IsStopped()) && (id != 2));
82.             if (!IsStopped() && SocketIsConnected(sock))
83.             {            
84.                 if (szCmd != "")
85.                 {
86.                     Print(szCmd, "<CMD<");
87.                     szRet = "N/D";
88.                 }
89.                 len = StringToCharArray(szRet, buff) - (szCmd != "" ? 1 : 0);
90.                 SocketSend(sock, buff, len);
91.             }
92.         }
93.     }
94.     if (sock != INVALID_HANDLE)
95.         SocketClose(sock);
96.     ArrayFree(ArrMem);
97.     Print("Shutting down...");
98. }
99. //+------------------------------------------------------------------+

Код на языке MQL5

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

Хорошо, давайте начнем разбираться, что делает данный код. Но чтобы у вас было больше энтузиазма и внимания, давайте посмотрим, что происходит, когда всё функционирует. Именно это можно увидеть ниже. Для начала понаблюдаем за тем, что происходит в Excel. Помните, что во время создания данной анимации сервис уже работал в MetaTrader 5, что вы можете увидеть в другой анимации.

При наблюдении за сообщением MetaTrader 5 в Excel во время выполнения операций можно было заметить следующие действия:

Интересно, не так ли? Следует помнить, что эти два приложения, Excel и MetaTrader 5, могут быть установлены на разных компьютерах, и даже в этом случае мы получим тот же результат. Теперь, когда у вас пробудилось любопытство, давайте посмотрим, как этот код работает в MQL5, так как остальные части мы уже объяснили в предыдущих статьях.


Разбор кода на MQL5

Во второй строке мы указываем, что код будет представлять собой сервис. Если бы данной строки не было, этот же код представлял бы собой скрипт. В предыдущих статьях мы уже объясняли разницу между сервисом и скриптом. Но если у вас есть какие-либо сомнения, помните: сервис не связан напрямую с графиком. В отличие от этого, скрипт связан с графиком. Однако код сервиса и код скрипта будут практически идентичны. Единственное различие между ними заключается именно в строке 02.

Следующее, что нужно понять, это именно строки 06 и 07. Они используются для того, чтобы при запуске исполняемого файла в MetaTrader 5 пользователь мог передать ему некоторые параметры. Именно эти параметры и нуждаются в корректировке. То есть, адрес, по которому запущен Python-сервер, и его порт.

Прошу заметить следующее: нужно указывать не место запуска Excel, а место запуска сервера Python. Подобные вещи могут вызывать путаницу. Но помните: сервер Python никоим образом не встроен в Excel и может находиться на другом компьютере. Но Excel должен знать, как найти этот сервер. Для лучшего понимания обратитесь к предыдущей статье, где мы объяснили ту часть кода, которая будет существовать в Excel и написана на VBA.

После завершения начальной (и базовой) части мы переходим к строке 11, где и начинается основная часть кода. Между строками 13 и 17 объявлены некоторые переменные, которые будут использоваться в этом конкретном коде. Теперь перейдём к той части, которая поначалу может показаться немного запутанной, но позже всё станет совершенно ясно. Обратите внимание, что в строке 19 инициализировали одну из переменных. Причина в том, что весь код полностью заключен в одном большом цикле. Данный цикл начинается в строке 21 и продолжается до строки 93, поэтому единственный способ его завершить — это вручную остановить сервис или закрыть MetaTrader 5.

Чтобы узнать, в каком состоянии находится наше соединение с сервером, мы выведем несколько сообщений в окно сообщений MetaTrader 5, как вы уже было показано в анимации выше. Первое сообщение выведено в строке 23. В нем мы просто указываем, что клиент (то есть MetaTrader 5) пытается подключиться. Это происходит так, потому что в строке 24 мы попадаем в бесконечный цикл. Данный цикл бесконечен, потому что он завершается только тогда, когда завершается программа.

«Но подождите секунду. Идея встраивания бесконечного цикла в другой цикл не имеет смысла. Зачем это делать?» Будьте спокойны, дорогие читатели. Цикл в строке 24 бесконечен, но он завершается в очень конкретный момент. Однако, поскольку переменная, которая содержит сокет, может уже содержать какое-либо значение, нам сначала необходимо освободить старый сокет. Проверка и выполнение данной операции производится в строке 26, а освобождение происходит в строке 27. Поэтому важно, чтобы строка 19 существовала. Если бы мы не настроили переменную, которая указывает на отсутствие соединения, мы бы засомневались при выполнении этого освобождения в строке 27.

Поэтому мы договорились, что это будет сделано именно так. Если соединение существовало, оно будет разорвано. Если не существовало, мы ничего не делаем. Однако в строке 28 мы попытались создать сокет. Скорее всего, это принесет успех. Но назначение сокета не обязательно означает, что соединение установлено. Следовательно, если нам не удастся подключиться к серверу в строке 29, то выполнится строка 32. Это создаст небольшую паузу, чтобы мы могли попытаться снова.

Однако, и вот в чем суть проблемы с бесконечным циклом в строке 24, если нам не удастся подключиться к серверу, нам будет назначен сокет. В данном случае мы должны вернуть его операционной системе. Итак, давайте возвращаемся к проверке строки 26. На этот раз, однако, проверка пройдет успешно, и будет выполнена строка 27, которая освободит назначенный сокет. И мы повторяем данный процесс назначения и освобождения сокета до тех пор, пока нам не удастся установить соединение или пока пользователь не завершит программу.

Теперь, если посмотреть на анимацию выше, мы увидим, что в какой-то момент мы начали передавать и принимать данные. «Но если этот цикл в строке 24 никогда не заканчивается, как такое могло произойти?» Причина кроется именно в строке 29. Прошу заметить, если нам удастся подключиться к серверу, будет выполнена строка 30, и мы выйдем из цикла, начавшегося со строки 24.

А теперь давайте посмотрим на кое-что очень интересное. В строке 34 выполнение программы будет успешным только в том случае, если программа не была завершена пользователем. Другими словами, в данном случае мы подключены к серверу. Следовательно, нам нужно сообщить серверу, кто мы. Таким образом, сообщение, которое надо отправить на сервер, создается в строке 36. Обратите внимание на данное сообщение. Сервер должен его распознать. В ином случае сервер отключит клиента, и мы вернемся к циклу в строке 24. Поэтому, если мы планируем вносить какие-либо изменения в систему в будущем, нужно быть предельно внимательными. Но если всё прошло хорошо и сервер распознал нас как действительного клиента, то придется предпринять ряд действий и определенные меры предосторожности. Поэтому в строке 41 выполняется очистка буфера памяти. Сразу после этого, в строке 42, мы указываем на нулевую позицию данного буфера.

Если вы только начинаете осваивать мир программирования сокетов, вы, вероятно, не поймете причину работы, описанной в строках 41 и 42. Но если у вас уже есть некоторый опыт, вы, наверное, знаете, что при записи в сокет может накапливаться гораздо больше информации, чем мы ожидаем увидеть при чтении. А если говорить точнее, то это часто происходит в TCP-соединениях. Так как мы не хотим потерять никакие запросы или данные, полученные из Excel, при передаче через сервер, мы должны принять меры предосторожности, чтобы избежать потери данных. Поэтому необходимо предпринять ряд действий. Но чтобы лучше понять, как это делать и почему это необходимо, нам нужно взглянуть на код подробнее.

Затем мы входим в новый цикл, который является основным, т.е. циклом, который отвечает за обмен сообщениями между Excel и MetaTrader 5. Данный цикл начинается со строки 43. Теперь взгляните на объявление цикла. Прошу заметить, что мы проверяем завершение программы и то, подключен ли сокет. Мы предположим, что всё в порядке, и мы можем войти в этот цикл и оставаться в нём долгое время.

Таким образом, первым делом нужно инициализировать некоторые переменные. Это делается в строках 45 и 46, и сразу после этого мы входим в другой цикл, который проходит от строки 47 до строки 81. Внимательно следите за тем, что происходит внутри данного цикла. Это важно, потому что именно здесь нам потребуется внести изменения или улучшения, если мы захотим или нам понадобится сделать что-то ещё, помимо того, что мы показывали и комментировали. Это, скорее всего, произойдет, когда возникнет необходимость перенести больше информации в Excel. Или даже для понимания команд, которые будут поступать в Excel.

Например, в строке 48 мы видим, сколько информации находится в сокете. Далее, в строке 51 мы попытались прочитать эту же информацию. Однако есть одна небольшая деталь, которую вам, возможно, захочется изменить. В строке 49 мы проверяем, превышает ли объем информации, помещаемой в буфер памяти, размер выделенного буфера. В данном случае мы просто изменяем объем считываемых данных таким образом, чтобы он не превышал уже выделенный размер. Но, при желании, мы можем изменить размер выделенной области. В любом случае, конечный результат будет очень схожим.

После того, как мы объяснили почему появилась строка 50, мы можем перейти к строке 51. Прошу заметить, что если какие-либо данные будут считаны, то в строке 52 эти данные будут вставлены в выделенную память. На данном этапе объяснения строка 52 не имеет смысла, создается впечатление, будто её вообще не существует. Но давайте продолжим рассматривать, как работает код; тогда данная строка станет понятной. Однако важно понимать, что данные, считанные из сокета, будут размещены, начиная с определенной позиции. Эта позиция обозначается переменной iMem. Рекомендую не забывать об этом, так как при первом считывании переменная iMem содержит нулевое значение. Однако при последующих считываниях она может иметь другое значение.

Вот так мы и добрались до строки 53. Здесь мы запускаем цикл, который составляет ядро данного кода, поскольку он будет выполнять большую часть работы. Обратите внимание, что в этом процессе мы проверяем определенные условия; если они выполняются, то выполнится и серия небольших шагов. Упомянутые шаги описывают протокол связи между MetaTrader 5 и Excel. Соответственно, любые внесенные здесь изменения, должны быть учтены и в коде VBA, поскольку VBA будет обрабатывать ответы от MetaTrader 5. Если обработка выполняется в серверном коде, соответствующие изменения также необходимо будет внести в код на Python.

Данный цикл, состоящий из строки 53, будет посимвольно обрабатывать опубликованное сообщение, чтобы понять то, что происходит и, прежде всего, как действовать дальше. Но мы должны сразу уточнить, что этот код предназначен для образовательных целей. Однако, если вы понимаете, как всё работает здесь, вы сможете адаптировать этот же код под свои конкретные нужды.

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

В конце статьи мы приведем необходимые ссылки для этого, поскольку данная функция уже реализована в системе репликации/моделирования. Но те, кто не будут следовать этой последовательности, не узнают, как это сделать. Однако это несложно. Вам потребуется лишь создать протокол. Для создания данного протокола нам потребуется знать, как выполнять указанные команды. Если не знаете, как это сделать, не забудьте ознакомиться со статьями, которые мы оставим в качестве справочного материала.

Итак, вернувшись к коду, мы обнаружили нечто, что может запутать многих, особенно начинающих. Посмотрите на строку 55. На данный момент у нас открытая фигурная скобка. Это обозначает конец названия символа и начало команды Excel. Чтобы внести ясность, в строке 56 мы изменили значение переменной id, которое было равно нулю, на единицу. Не забудьте об этом. Когда цикл начался, значение переменной id было равно нулю из-за строки 46, это произошло при первом запуске цикла на строке 43. Обратите внимание на эти моменты.

Так как открывающая скобка указывает на то, что название символа уже было получено, нам необходимо получить данные для этого символа. В данном случае мы будем учитывать только цену закрытия бара. Это всё, но можно зафиксировать любую информацию, которую хотим или в которой нуждаемся. Для этого достаточно будет создать правила, которые указывают, какое значение должно быть получено. Но давайте вернемся к главному вопросу. Прошу заметить, что оператор case в строке 55 вторгается в оператор case в строке 57, при этом между ними нет команды break. Возможно ли это? Да, можно это сделать, но, прежде чем объяснять case с 57-й строкой, отметим, что это другой символ. Почему?

Теперь мы дошли до той части, которая действительно имеет решающее значение. Символ, появляющийся после case в строке 57, указывает на возможность разделения нескольких символов. Другими словами, если Excel хочет найти информацию, используя несколько символов, он может сделать это, разделив их этим символом. Однако, если мы обращаемся к коду VBA из предыдущей статьи, то увидим, что данная функциональность не используется. Просто выведите возвращаемое значение в одной ячейке. На самом деле, это задание именно для вас, дорогие читатели: разделите эти данные и перенесите их в соответствующую ячейку. Поскольку я не знаю, как каждый программист создает свою электронную таблицу, способ выполнения данного разделения будет меняться в зависимости от конкретного случая. Но это несложно сделать, только будет зависеть от того, как вы создали свою электронную таблицу.

В любом случае, в строке 58 мы проверим, существует ли искомый нами символ. В этом случае, в строке 59 мы создадим возвращаемую строку. Но обратите на это внимание. Хотя мы и создаём возвращаемую строку, на самом деле это не та строка, которую мы вернём на сервер и, возможно, в Excel. Причину объясним позже. Теперь, поскольку мы только что обработали символ, в строке 60 мы очищаем строку, чтобы попытаться захватить следующий символ, а в строке 61 используем команду break, чтобы избежать вторжения в следующий case.

В следующем case, в строке 62, мы видим закрывающую фигурную скобку. Это означает, что команда, отданная Excel, была перехвачена, и мы перейдем к определению названия следующего символа. Но даже если из сокета будет считана дополнительная информация, она сейчас не будет использована. Это связано с тем, что при проверке строки 58 будет замечено, что строка 63 указывает на то, что данные не следует использовать. Давайте теперь мы разделим символы команд. Но нам нужно знать, что представляет собой каждая из этих вещей. Если ни один case не будет выполнен, то выполнится вариант по умолчанию, указанный в строке 66.

Прошу заметить, что тип информации и способ её обработки будут зависеть от значения переменной id. Таким образом, пока значение равно нулю, название символа будет зафиксировано. Это делается в строке 70. Если id равен единице, команда, предоставленная Excel, будет перехвачена. Это делается в строке 73. Если значение равно двум, мы переместим данные из текущей позиции в начало области памяти.

Теперь прошу заметить, что приводит к тому, что цикл, начавшийся на строке 47, заканчивается в строке 81. Одной из причин будет именно тот факт, что был захвачен конец блока команд. Таким образом, мы переходим к заключительной части работы. Но сначала нам нужно провести ещё одну проверку строки 82. Если мы добьемся успеха, мы получим новую проверку. Наша цель — удостовериться, отправляется ли какая-либо команда. Если отправляется, то данная команда будет иметь приоритет над всем остальным. Именно в этом месте, в строке 86, следует выполнить действия, описанные в других статьях данной серии. Таким образом мы сможем оформить запрос на покупку или продажу из Excel.

Для правильного выполнения задания предлагаю сначала изучать вспомогательные материалы, которые мы укажем в разделе ссылок. В ответ на запрос выполнить команду, возвращаемое значение или ответ MetaTrader 5 изменяется и перестает являться захваченными данными символов, превращаясь вместо этого в определенную символьную строку. Наконец, в строках 89 и 90 отправляется ответ от MetaTrader 5. Прошу заметить, что данный ответ будет зависеть от того, выполняем ли мы команду или захватываем данные от символа.


Заключительные идеи

Хотя сегодняшний код не включает реализацию того, как выполнить команду, заданную Excel, можно увидеть, что взаимодействие между Excel и MetaTrader 5 происходит достаточно плавно и без особых проблем. Однако, скорее всего, вам потребуется внести некоторые мелкие улучшения и исправления в эту реализацию. Но, если это произойдет, то будет означать, что мы действительно достигли своей цели на этом этапе, где мы объяснили, как использовать сокеты, поскольку многие люди не знали, что можно торговать на рынке, не глядя на график MetaTrader 5 и без использования какого-либо фундаментального анализа.

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


Ссылки:

Разработка системы репликации (Часть 74): Новый Chart Trade (I)

Разработка системы репликации (Часть 75): Новый Chart Trade (II)

Разработка системы репликации (Часть 76): Новый Chart Trade (III)

Разработка системы репликации (Часть 77): Новый Chart Trade (IV)

Разработка системы репликации (Часть 78): Новый Chart Trade (V)

ФайлОписание
Experts\Expert Advisor.mq5
Демонстрирует взаимодействие между Chart Trade и советником (для взаимодействия требуется Mouse Study).
Indicators\Chart Trade.mq5Создает окно для настройки отправляемого ордера (для взаимодействия требуется Mouse Study).
Indicators\Market Replay.mq5Создайте элементы управления для взаимодействия с сервисом репликации/моделирования (для взаимодействия требуется Mouse Study).
Indicators\Mouse Study.mq5Обеспечивает взаимодействие между графическими элементами управления и пользователем (необходимо как для работы системы репликации, так и на реальном рынке).
Servicios\Market Replay.mq5Создает и поддерживает сервис репликации/моделирования рынка (основной файл всей системы).
Код VS C++ Server.cppСоздает и поддерживает сокет-сервер, разработанный на C++ (версия мини-чата).
Код на Python Server.pyСоздание и поддержка сокета Python для связи между MetaTrader 5 и Excel.
ScriptsCheckSocket.mq5Позволяет выполнить тест соединения с внешним сокетом
Indicators\Mini Chat.mq5Позволяет реализовать мини-чат через индикатор (для работы требуется использование сервера)
Experts\Mini Chat.mq5Позволяет реализовать мини-чат через советник (для работы требуется использование сервера).

Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/12829

Прикрепленные файлы |
Anexo.zip (560.03 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (1)
William da Paz
William da Paz | 27 апр. 2025 в 03:07
Отличная работа, мой друг!

Есть ли способ извлечь данные из книги и/или времени и сделок в Excel или даже Python?

Спасибо за внимание.
Индикатор CandleCode: Формализация свечных моделей в MQL5 Индикатор CandleCode: Формализация свечных моделей в MQL5
В статье показана практическая реализация CandleCode для MetaTrader 5: расчет кодов свечей по методу Лиховидова с адаптацией порогов к волатильности (Bollinger Bands) и гистограммное отображение. Дополнительно представлен советник, который строит базу исторических паттернов по ZigZag, сравнивает их с текущим "слепком" через ATR и выдает статистику совпадений на панели.
Торговые инструменты на MQL5 (Часть 3): Создание панели сканера по нескольким таймфреймам для стратегической торговли Торговые инструменты на MQL5 (Часть 3): Создание панели сканера по нескольким таймфреймам для стратегической торговли
В этой статье мы создадим панель сканера по нескольким таймфреймам на MQL5 для отображения торговых сигналов в режиме реального времени. Мы планируем создать интерактивный грид-интерфейс, реализовать расчеты сигналов с использованием нескольких индикаторов и добавить кнопку закрытия. Статья завершается бэктестингом и стратегическими торговыми преимуществами
Моделирование рынка (Часть 18): Первые шаги на SQL (I) Моделирование рынка (Часть 18): Первые шаги на SQL (I)
Неважно, какую программу SQL мы будем использовать: MySQL, SQL Server, SQLite, OpenSQL или другую. У всех есть что-то общее, а этот общий элемент — язык SQL. Даже если мы не собираемся использовать WorkBench, можно манипулировать или работать с базой данных непосредственно в MetaEditor или через MQL5 для выполнения действий в MetaTrader 5, но для этого вам понадобятся знания SQL. Итак, здесь мы выучим, как минимум, основы.
Нейросети в трейдинге: Адаптивная факторная токенизация (MTmixAtt) Нейросети в трейдинге: Адаптивная факторная токенизация (MTmixAtt)
Статья разбирает архитектуру MTmixAtt для адаптивной структуризации признаков и показывает первый шаг практической реализации в MQL5 — модуль AutoToken. Описаны выравнивание эмбеддингов, матрица выбора, механизм Top‑K и разреженная селекция. Приведен класс CNeuronAutoToken на базе OpenCL. Читатель получает работающий блок компрессии признакового пространства и основу для дальнейшего смешивания токенов и MoE.