Моделирование рынка (Часть 15): Сокеты (IX)
Введение
В предыдущей статье, "Моделирование рынка (Часть 14): Сокеты (VIII)", мы рассмотрели, как можно делать определенные вещи с помощью Python, не полагаясь на сторонние пакеты или инструменты. Я не хочу вас отговорить от использования пакетов, которые помогают выполнять задачи на Python, но цель этих демонстраций - побудить вас изучать концепции с большим интересом. Нет смысла полагаться на внешние пакеты или решения, если мы можем сделать всё на основе того, что позволяет наш любимый язык.
Думаю, в упомянутой статье мне удалось пробудить ваше любопытство по поводу некоторых вопросов, работу которых многие не знают. Я считаю, что большинство людей, если они проходили какой-либо курс или изучали обычные материалы по этому вопросу, никогда не слышали о некоторых технологиях. Один из примеров - технология COM, о которой мы вкратце упоминали в предыдущей статье. Однако, умение использовать эти методы, поможет вам на всех этапах программирования.
В этой статье мы объясним одно из возможных решений того, что мы пытались показать, то есть как позволить пользователю Excel выполнить действие в MetaTrader 5 без отправки ордеров, открытия или закрытия позиции. Идея заключается в том, что пользователь использует Excel для проведения фундаментального анализа какого-то символа. И что при использовании только Excel, можно указать советнику, работающему в MetaTrader 5, открыть или закрыть определенную позицию.
Пока всё, что показали и продемонстрировали, направлено исключительно на передачу данных, как будто мы используем чат. Однако я думаю, что вам, будучи не таким опытным в работе с сокетами, было проще понять основные концепции благодаря этим методам. Помните, что мы лишь пощупали поверхность большого айсберга, под названием «сокет». Я вам советую изучить эту технологию подробнее, ведь если вы поймете, как она работает, вы полюбите её и будете в восторге от возможностей, которые она откроет.
Но давайте перейдем непосредственно к сегодняшней теме. Поскольку большинство вещей, которые нужно реализовать, относительно сложные, а другие достаточно простые, мы рассмотрим их неспешно. Таким образом, даже если не покажем всё, вы поймете, как это работает. Если эта цель будет достигнута, то вы сможете адаптировать то, что будет показано и получите свое собственное решение, которое, скорее всего, намного превзойдет представленное сегодня здесь. Наша основная задача - образовательная, так что давайте начнем.
Создание сервера в Python
Как уже пояснили на предыдущих статьях, создать и запустить сервер непосредственно в Excel невозможно. Мы могли бы это сделать, но нам пришлось бы много трудиться, чтобы сервер не мешал нам при использовании Excel. Один из способов сделать это - создать сервер в одном потоке. Однако создание и запуск сервера на потоке Excel - сложная задача. Конечно, это не самая сложная задача, но она, безусловно, гораздо сложнее, чем предложение, которое мы здесь представим.
Первое, что нужно сделать, - это создать изолированный сервер на Python. Данный сервер будет фактически обращаться к электронной таблице Excel. Однако есть некоторые моменты, которые необходимо учитывать. Опять же, идея сугубо дидактическая. То, что мы представляем, можно значительно улучшить. Ниже мы видим основной код сервера на Python. Я называю его "основным", потому что этот код может быть доработан и адаптирован под наши нужды и требует корректировки только в нужных местах. Но прежде чем мы это сделаем, давайте разберемся, как это работает? Это поможет нам понять, какие изменения можно и нужно внести.
001. import socket as sock 002. import select 003. import sys 004. from win32com import client as win32 005. 006. class LinkMT5Excel: 007. def __init__(self, host, port, sheet, cell) -> None: 008. try: 009. self.__CMD = '' 010. self.__MT5 = None 011. self.__server = sock.socket(sock.AF_INET, sock.SOCK_STREAM) 012. self.__server.setblocking(False) 013. self.__server.bind((host, int(port))) 014. self.__server.listen() 015. self.__CONN_LIST = [self.__server] 016. EXCEL = win32.GetActiveObject('Excel.Application') 017. self.__SHEET = EXCEL.Worksheets(sheet) 018. self.__COLUNN, L = cell.split('$') 019. self.__LINE = int(L) 020. except: 021. self.__CONN_LIST.clear() 022. 023. def __WriteInExcel(self, index, msg) -> None: 024. try: 025. if self.__SHEET: 026. self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value = msg 027. except: 028. self.__SHEET = None 029. self.__ShutdownServer() 030. 031. def __ReadInExcel(self, index) -> str: 032. try: 033. if self.__SHEET: 034. return self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value 035. except: 036. self.__SHEET = None 037. self.__ShutdownServer() 038. return '' 039. 040. def __MT5_Disconnect(self, conn) -> None: 041. if conn == self.__MT5: 042. self.__WriteInExcel(2, 'MetaTrader 5 is offline.') 043. self.__MT5 = None 044. if conn: 045. conn.close() 046. if self.__CONN_LIST: 047. self.__CONN_LIST.remove(conn) 048. 049. def __ShutdownServer(self) -> None: 050. for conn in self.__CONN_LIST: 051. conn.close() 052. self.__CONN_LIST.clear() 053. 054. def __Command(self, cmd, conn) -> bool: 055. if cmd.lower() == '/force server shutdown': 056. self.__ShutdownServer() 057. return True 058. elif cmd.lower() == '/shutdown': 059. self.__MT5_Disconnect(conn) 060. return True 061. self.__CMD = '' if cmd.lower() == 'n/d' else cmd 062. return False 063. 064. def __Refused(self, conn) -> bool: 065. conn.send('Connection Refused...\n\r'.encode()) 066. conn.close() 067. return False 068. 069. def __Checking(self, conn) -> bool: 070. try: 071. info, cmd = conn.recv(512).decode().rstrip(None).split(':') 072. if info.lower() != '<mt5 with excel>': 073. return self.__Refused(conn) 074. if self.__Command(cmd, conn): 075. return True 076. if (self.__MT5) or (cmd.lower() != 'mt5'): 077. return self.__Refused(conn) 078. self.__MT5 = conn 079. self.__WriteInExcel(2, 'MetaTrader 5 is online.') 080. except: 081. return self.__Refused(conn) 082. return True 083. 084. def __SwapMsg(self, rec, conn) -> None: 085. try: 086. if rec: 087. data = conn.recv(1024).decode().rstrip(None) 088. if data: 089. if '/' in data: 090. if self.__Command(data, conn): 091. return 092. else: 093. self.__WriteInExcel(4, data) 094. else: 095. self.__MT5_Disconnect(conn) 096. return 097. conn.send((self.__ReadInExcel(3) + f'[{self.__CMD}]').encode()) 098. except: 099. self.__MT5_Disconnect(conn) 100. 101. def Run(self) -> None: 102. self.__WriteInExcel(0, 'Server online.') 103. self.__MT5_Disconnect(None) 104. while self.__CONN_LIST: 105. read, write, err = select.select(self.__CONN_LIST, [], [], 0.5) 106. for slave in read: 107. if slave is self.__server: 108. conn, addr = slave.accept() 109. conn.setblocking(False) 110. if not self.__Checking(conn): 111. continue 112. self.__CONN_LIST.append(conn) 113. self.__SwapMsg(False, conn) 114. else: 115. self.__SwapMsg(True, slave) 116. 117. def __del__(self) -> None: 118. for n in range(3): 119. self.__WriteInExcel(n, '') 120. self.__WriteInExcel(0, 'Server offline...') 121. 122. if __name__ == '__main__': 123. if len(sys.argv) == 5: 124. Mt5_Excel = LinkMT5Excel(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) 125. Mt5_Excel.Run() 126. del Mt5_Excel 127. else: 128. print(f'Usage: {sys.argv[0]} <HOST> <PORT> <SHEET> <CELL>')
Код на Python
Если вы следили за этим этапом работы с сервисом репликации/моделирования, где мы сосредоточились на объяснении сокетов, то ничего из этого кода не покажется вам странным. А если вы уже давно изучаете Python, то данный код будет ещё проще для понимания. Однако, если это не ваш случай, не волнуйтесь, мы сейчас разберемся, что здесь происходит. Итак, касаемо тех, кто соблюдает последовательность, давайте будем терпеливы к другим, особенно к тем, у кого меньше опыта в этой области, поскольку в этом коде есть вещи, которые нужно хорошо понять.
Теперь между строками 01 и 04 мы импортируем некоторые необходимые нам пакеты. Прошу заметить, что мы не используем никаких пакетов, кроме стандартной установки Python, и что мы не делаем ничего слишком сложного на данном этапе. Можно использовать такие пакеты, как pandas, xlwings, openpyxl или любой другой пакет для выполнения некоторых шагов, которые будут показаны в этой статье. Но чтобы не создавалось впечатления дискриминации одних пакетов по отношению к другим, мы будем использовать только стандартную установку Python. Таким образом, нам будет проще выбрать тот пакет, который мы предпочитаем, и воспользоваться тем вариантом, который мы считаем наиболее подходящим. Наша цель - достичь максимальной простоты, не перевешивая баланс в какую-то определенную сторону.
После того, как упомянутый импорт был выполнен, мы начинаем создавать класс в строке 06. Мы могли бы обойтись и без классов, но если мы их используем, то можем получить и другие преимущества. Итак, в строке 07 мы начинаем с определения инициализатора класса. Здесь мы получаем несколько аргументов, которые говорят нам о важных элементах, необходимых для правильной работы сервера. Посмотрите, где используются данные параметры, чтобы понять, что ожидается и как улучшить этот же код.
В строках 09 и 10 мы объявляем и инициализируем две переменные, которые будут важны в дальнейшем. В строке 13 мы начинаем использовать переданные аргументы. Прошу заметить, что мы указываем серверу хост, то есть место, откуда мы ожидаем получить соединение. Если значение хоста равно 0.0.0.0.0, это означает, что мы примем любой адрес клиента, но это может быть и конкретное значение. Это остается на ваше усмотрение. Важным моментом в этой строке является то, что, поскольку инициализация сервера будет выполняться из Excel, передаваемые аргументы будут строками. Поэтому необходимо преобразовать строковое значение в подходящее значение, которое в данном случае является целочисленным, чтобы указать используемый порт. После этого Python будет знать, как правильно интерпретировать используемое значение. Остальные строки (то есть от 11 до 14) отвечают за инициализацию сокета, чтобы сервер мог следить за портом и ожидать соединения. Если у вас есть сомнения на этот счет, обратитесь к предыдущим статьям.
Теперь вернемся к строке 08, потому что, хотя предыдущие шаги не должны генерировать сбои без веской причины, в строке 08 мы открываем точку для анализа возможных ошибок в коде. Такие сбои происходят во время выполнения программы. Поэтому, для того, чтобы пользователь не видел странных вещей при выполнении скрипта, мы делаем так, чтобы все исключения обрабатывались самим кодом.
В строке 16 мы пытаемся захватить активную секцию Excel. Поскольку сервер инициализируется сам, мы успешно справимся с данной задачей. Однако в строке 17 есть кое-что, что может дать сбои. В этот момент мы пытаемся получить доступ к листу Excel. Это может произойти в любой момент, просто потому что лист не существует в книге, а нам нужно, чтобы он существовал. В случае успеха, в строке 18 захватим конкретную ячейку, которая будет использоваться сервером. Прошу заметить, что мы разделили этот процесс на два этапа. В строке 18 мы вводим столбец и числовое значение. Это числовое значение преобразуется в целочисленное значение в строке 19, чтобы можно было выполнить некоторые простые вычисления на сервере. Но не волнуйтесь, это станет понятно позже.
Теперь вам нужно понять, что если во время этой инициализации произойдет сбой, строка 21 выключит сервер и предотвратит любую попытку отправить данные в Excel. Важно это сделать, потому что доступ к чему-то не был получен или он не был настроен правильно, и мы не хотим, чтобы пользователь видел сообщения, которые он не понимает.
Теперь мы приступаем к трудной задаче - заставить всё работать. Начнем со строки 23, где у нас есть процедура, которая попытается записать что-то в Excel. Но мы не будем писать где попало, мы будем делать это достаточно контролируемо. Поэтому нам нужен индекс для перемещения относительно столбца и ряда, указанных в инициализации. Поскольку цель чисто образовательная, мы не будем использовать столбец, только ряд. Таким образом, основываясь на значении первого ряда, мы попытаемся записать на указанный лист во время инициализации. Однако, поскольку данный процесс может завершиться неудачей, в строке 24 мы говорим Python, что нужно дождаться ошибки.
В строке 25 мы проверяем, содержит ли переменная что-то допустимое. Это важно, так как может случиться, что во время выключения лист не существует, и мы не хотим без причины попасть в цикл, в котором сервер пытается закрыться, генерируется исключение, которое вызывает новую попытку выхода, и процедура вызывается снова, генерируя ещё одно исключение и так далее. Чтобы избежать этого, мы осуществляем проверку в строке 25. Затем, в строке 26, мы пытаемся записать данные в электронную таблицу. В этот момент может возникнуть ошибка, поскольку пользователь мог случайно удалить нужный серверу лист в книге. В этом случае будет выполнена строка 27 и соответствующий код, а сервер закроется.
Переходим к строке 31. Данная строка фиксирует содержимое конкретной ячейки электронной таблицы. Эта ячейка имеет в качестве ссылки ячейку, указанную при инициализации. Вот почему так важно не торопиться и понимать всё происходящее. Как попытка записи в ячейку может привести к сбою процесса, так и здесь может произойти то же самое. Но если чтение происходит как ожидалось, строка 34 вернет значение ячейки для использования сервером.
Возможно, вы подумали: если этой функции в строке 31 удается прочитать таблицу Excel, почему бы просто не указать при инициализации, что это за лист и ячейка, чтобы сервер мог искать остальную информацию непосредственно в Excel? Если вы додумались до этого, то я вас искренне поздравляю, это означает, что вы уже заметили возможное улучшение, которое можно сделать здесь, в скрипте Python. Но давайте двигаться дальше, ведь нам ещё есть на что посмотреть.
В строке 40 находится процедура, которая помогает пользователю Excel узнать, когда MetaTrader 5 по какой-то причине становится недоступным. Это происходит, когда устройство отключено. Данная процедура простая и не требует дополнительных объяснений. В строке 49 находится другая, не менее простая процедура отключения сервера по какой-либо причине. Многие из этих причин связаны со сбоями во время выполнения серверного скрипта, но есть и другие, о которых мы расскажем позже. Пока что не беспокойтесь об этом. Кроме того, в строке 54 у нас есть очень интересная функция. Дальше всё становится по-настоящему интересным. Но сначала давайте посмотрим, что происходит в функции в строке 54.
Она довольно простая и предназначена для разбора любой команды, которая могла быть отправлена на сокет. Данная команда должна быть выполнена сервером. На данный момент у нас есть только две команды. Первая находится в строке 55 и предназначена для принудительного отключения сервера, что просто и понятно. Вторая команда находится в строке 58 и принудительно отключает клиента, которым в данном случае является MetaTrader 5. Если на сервер не поступало запроса на выполнение команды, в строке 62 будет возвращается значение false. Другими словами, то, что было отправлено, не являлось командой.
Но почему мы возвращаем значение false? Причина кроется именно в функции строки 69. Её основная задача - проверить, может ли быть принят клиент, который пытается подключиться к серверу. Вот тут-то и становится интересно, ведь, в принципе, любой может подключиться к серверу. Однако эта функция призвана предотвратить такое. Как она это делает? Она просто протестирует то, что клиент отправит в сокет, как только сервер согласится проверить соединение. В строке 72 теперь мы проверяем начальный заголовок соединения. Только во время попытки соединения должен присутствовать такой заголовок, в остальное время он не нужен. Позже вы поймете, как всё это работает на самом деле.
Здесь должно быть ясно для вас, что в строке 71 делается разделение между заголовком и любой передаваемой командой. Причина проста и вы её поймете в следующей статье, где мы рассмотрим соответствующую часть VBA-кода из Excel. Если заголовок, предоставленный клиентом, не совпадает с тем, который ожидает сервер, выполнится функция в строке 64. Данная функция сообщит клиенту, что сервер отключает его, так как он не был распознан.
Если заголовок совпадает с ожидаемым, в строке 74 мы попытаемся выполнить команду, отправленную клиентом. Если это не команда, строка 76 проверит, есть ли уже соединение с MetaTrader 5. Если соединение отсутствует или если команда отличается от ожидаемой (что указывает на то, что клиент не MetaTrader 5), соединение будет отклонено. В последнем случае в строках 78 и 79 мы получим информацию о том, что MetaTrader 5 находится в режиме онлайн. Если в какой-то момент происходит исключение, соединение будет отклонено из-за выполнения строки 80.
Теперь мы переходим к важнейшей процедуре, которая находится в строке 84. А что делает она? Она управляет обменом сообщениями между MetaTrader 5 и Excel. Прошу обратить внимание, потому что, хотя эта процедура относительно проста, но без её понимания, вы не сможете адаптировать код к тому, что вы хотите сделать. Правда, после знакомства с несколькими следующими статьями, всё это приобретет смысл. Но сейчас давайте попробуем понять, что происходит в скрипте на Python.
Поскольку могут возникнуть ошибки, мы запустим код, сообщая Python, что ожидаем их появления, это и делается в строке 85. Если вызывающая сторона укажет, что данная процедура должна прочитать сокет, строка 86 завершится успешно, и мы перейдем к чтению части сокета. Это делается в строке 87.
Теперь читайте внимательно, потому что следующее объяснение будет иметь огромное значение в дальнейшем. В строке 88 мы проверяем, получили ли мы что-нибудь на сокете. Если нет, мы отключаем MetaTrader 5. Если на сокете есть что-то, в строке 89 мы проверяем наличие заданного символа в полученном сообщении. Если такой символ есть в сообщении, значит, это команда от MetaTrader 5, которая приведет к выполнению строки 90. Но если такое выполнение не получится, ничего больше не будет опубликовано. Если смотреть на код команды, можно будет понять, какие данные ожидаются от MetaTrader 5. Когда мы будем говорить о коде на MQL5, мы ещё вернемся к этому вопросу. На данный момент достаточно знать, что MetaTrader 5 может отправлять команды на сервер для их выполнения.
Хорошо, но что, если это была не команда? Это происходит так, потому что в строке 89 произошел сбой. Тогда, что же произойдет? В этом случае выполнится строка 93. Она запишет в определенную ячейку информацию, отправленную MetaTrader 5 в ответ на запрос Excel. Но какой это запрос? Теперь мы подошли к действительно интересному моменту: к строке 97. Посмотрите, что мы делаем в этой строке. В ней мы используем сервер для отправки запроса к MetaTrader 5 через сокет. Такое заявление можно подать двумя способами:
- Первый - это в виде содержимого, считанного из определенной ячейки или диапазона ячеек в Excel. Хотя для простоты мы используем не диапазон, а содержимое конкретной ячейки.
- Второе - внутри скобок мы будем отправлять по указанию Excel какую-либо команду для выполнения MetaTrader 5.
Позже расскажем о том, как такие команды или запросы в Excel будут выполняться в MetaTrader 5. Пока что отметим, что у нас есть довольно простой протокол для взаимодействия. То есть, по сути, всё, что находится в ячейке или как команда, отправленная Excel, будет передано в MetaTrader 5. Сервер не будет активно участвовать в этом этапе обмена сообщениями, а только будет регистрировать сообщения в указанных в этой процедуре точках, чтобы VBA и MQL5 могли выполнить свою работу.
Однако, если мы хотим увеличить или улучшить количество и качество информации, передаваемой между Excel и MetaTrader 5, можно использовать Python, чтобы упростить работу, которую пришлось бы выполнять в VBA или MQL5. Но так как мы хотим быть максимально дидактичными, мы будем использовать очень простой протокол сообщений, с одной всего лишь ячейкой в Excel. Если вы поймете, как это делается, вы сможете заниматься всем, чем захотите.
Прошу заметить, что все используемые здесь позиции ячеек имеют своим началом именно первую ячейку, указанную при инициализации сервера. Важно, чтобы вы поняли эти моменты, поскольку всё остальное будет выполняться непосредственно в Excel VBA. Это будет довольно просто и легко сделать и выполнить.
Хорошо, мы подошли к концу. Это приводит нас к строке 101. Практически всё, что касается данной процедуры, уже рассмотрели в предыдущих статьях о сокетах, но есть несколько моментов, которые заслуживают внимания. Например, в строке 113 мы находим то, что может показаться странным на первый взгляд, хотя это не так, если задуматься и проследить за этой последовательностью. Если проверка в строке 110 выполнена, то клиенту, который только что подключился, отправится сообщение. Обычно это приветствие.
Но здесь мы сделаем нечто совершенно другое. Поскольку Excel не будет долго находиться в сети, он понимает, что информация для отправки направляется в MetaTrader 5, поэтому важно понять процедуру на строке 84, которую описали некоторое время назад. Таким образом, в первом вызове мы не будем читать сокет, а только запишем в него. Когда сервер получит ответ от MetaTrader 5, выполнится строка 115, и на этот раз мы будем читать сокет и записывать в него. Таким образом, мы будем оставаться в цикле, постоянно получая информацию от MetaTrader 5 и передавая данную информацию в Excel.
И наконец, у нас есть процедура, которая многим покажется довольно странной. Это происходит так, потому что это деструктор класса. Так же, как у нас был конструктор, который называется __init__, у нас есть и деструктор, который в данном случае называется __del__. Обычно этот деструктор не включается в код скрипта Python, поскольку в Python есть сборщик мусора, который при завершении работы скрипта удаляет объекты и освобождает использованную ими память. Однако функция этого деструктора несколько благороднее. По сути, он заставляет Excel отображать сообщение в том месте, где обычно указывается, что сервер находится в режиме онлайн, сообщая о том, что сервер находится в автономном режиме. Можно просмотреть его прямо в Excel, без необходимости использовать другие носители или ресурсы. Остальная часть кода настолько проста, что не требует дополнительного внимания с нашей стороны.
Заключительные идеи
С помощью приведенных здесь объяснений мы закончили часть, посвященную серверу Python. Цель данного сервера - быть максимально дидактичным и простым для работы на Python, используя только пакеты, входящие в стандартную установку языка. Но сам читатель может создать нечто гораздо более сложное и практичное, используя другие пакеты и компоненты для работы с файлами Excel. Даже можно сгенерировать всю таблицу Excel, а также множество других функций прямо в этом коде Python.
Но я не хочу усложнять ситуацию, отдавая предпочтение какому-то конкретному пакету Python. Я знаю, что существует множество отличных пакетов, которые позволяют выполнять многообразные задачи и даже полностью заменяют необходимость создавать что-то с помощью Excel. Однако, как уже говорилось в другой части серии, идея здесь заключается в том, чтобы удовлетворить клиента или пользователя, который отказывается использовать какой-либо инструмент, кроме Excel. Цель - создать электронную таблицу для фундаментального анализа данного символа, чтобы у нас была возможность покупать или продавать в определенных ценовых диапазонах. Некоторые из вас могут спросить: «почему бы не разместить ордер непосредственно в книге символа в нужных позициях?» Таким образом, не придется постоянно работать в Excel, и мы сможем делать это прямо в MetaTrader 5».
Я прекрасно понимаю тех, кто так думает. Но есть и люди, у которых нет ни терпения, ни желания смотреть на график, выставляя и удаляя ордера, открывая и закрывая позиции. Они просто предпочитают составлять всё с помощью нескольких программ, обычно тех, которые они освоили и на которых разработали свои методы анализа, и не хотят от этого отказываться. Поэтому эти люди хотят, чтобы вы, как программисты, создавали некий метод или средство для отправки ордеров, закрытия или открытия позиций в определенном ценовом диапазоне с помощью этой конкретной программы, которой в данном случае является Excel.
Но они при этом не хотят беспокоиться о том, чтобы понять, как это будет сделано. Вас просто нанимают и платят за то, что вы сделали всё возможное. Именно это предложение показываю я: как его реализовать, хотя бы частично. Поскольку вы, как программисты, можете захотеть сделать это по-другому или с небольшими отличиями. Лично меня это не сильно волнует. Что действительно приносит мне удовлетворение, так это осознание того, что вы, прочитав эти статьи, сможете создавать некоторые вещи, которые вы считали невозможными. Можно добиться чего угодно, если только учиться и уделять этому время. В следующей статье мы рассмотрим VBA-часть Excel, где проанализируем, как заставить этот сервер работать вместе с Excel. До следующей статьи из этой серии.
| Файл | Описание |
|---|---|
| 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++ (версия мини-чата). |
| Code in Python\Server.py | Создание и поддержка сокета Python для связи между MetaTrader 5 и Excel. |
| Scripts\CheckSocket.mq5 | Позволяет выполнить проверку соединения с внешним сокетом |
| Indicators\Mini Chat.mq5 | Позволяет реализовать мини-чат через индикатор (для работы требуется использование сервера) |
| Experts\Mini Chat.mq5 | Позволяет реализовать мини-чат через советник (для работы требуется использование сервера). |
Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/12827
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Нейросети в трейдинге: Спайковая архитектура пространственно-временного анализа рынка (Окончание)
Знакомство с языком MQL5 (Часть 13): Руководство для начинающих по созданию пользовательских индикаторов (II)
Обучаем нейросети на осцилляторах без подглядывания в будущее
Трейдинг с экономическим календарем MQL5 (Часть 6): Автоматизация входа в сделку с анализом новостей и таймерами обратного отсчета
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования