Как отправить сообщение в MQL4 / 5 из терминала MetaTrader на python, используя ZeroMQ? - PullRequest
0 голосов
/ 30 апреля 2018

Я просто хочу отправить сообщение из терминала MetaTrader, используя его MQL4 / 5 для Python, просто простой клиентский сервер, в котором MQL4 / 5 - это клиент, который отправляет, а python - сервер, который получает и эти два синхронизируются с ZeroMQ.

Код на стороне Python, и я уверен, что эта часть работает нормально:

    import zmq
    import time


    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://127.0.0.1:9999")

    print("Server Started")
    while True:
        message = socket.recv()              # Wait for next request from client
        print("Received request: ", message)
        time.sleep (1)
        socket.send_string("World")

сторона MQL4 / 5 такая:

   Context context( "helloworld" );
   Socket socket( context, ZMQ_REQ );

   Print( "Connecting to hello world server…" );
   socket.connect( "tcp://127.0.0.1:9999" );

   while ( True )
   {
      ZmqMsg request( "Hello" );
      socket.send( request );

      ZmqMsg reply;
      socket.recv( reply );           // Get the reply.

      Sleep( 1000 );
   }

похоже, что MQL4 / 5 ничего не отправляет.
Можете ли вы сказать, что с ним не так?

1 Ответ

0 голосов
/ 01 мая 2018

Можете ли вы сказать, что с ним не так?

Несколько вещей для начала на стороне MQL4 / 5:

Терминал MetaTrader может работать с скомпилированным языком MQL4 / 5 в нескольких совершенно разных режимах выполнения кода.

Если попытаться выполнить это в Script, ущерб будет менее кардинальным, чем если бы это было в ExpertAdvisor, и наихудшие побочные эффекты произойдут, если он будет запущен в некоторые CustomIndicator -типа-типа MQL4 / 5-кода.


На стороне ZeroMQ:

В любом случае, REQ/REP Встроенный масштабируемый шаблон архетипа формального общения - худший вариант выбора, так как во многих предыдущих постах было объяснено, насколько хрупким был этот встроенный и что он может легко попасть в принципиально неразрешимое взаимное расположение взаимоблокировок, поэтому лучше перечитайте эти посты и постарайтесь избежать этого риска, прежде чем переходить к разработке и внедрению сервисов промышленного уровня.

Всегда устанавливать socket.setsockopt( zmq.LINGER, 0 ), и на сторонах MQL4 / 5 и Python. Без исключений, без оправданий.

Установка с socket.setsockopt( zmq.COMPLETE, 1 ), и на сторонах MQL4 / 5 и Python также более чем целесообразна.


Привязки к языку ZeroMQ для MQL4 / 5:

Поскольку существует несколько активных привязок для MQL4 / 5 #import -редированных посредников между экосистемой выполнения кода MetaTrader Terminal MQL4 / 5 и DLL-библиотекой ZeroMQ API vXYZ, невозможен ATM вдаваться в подробности. Воспользовавшись API v2.1.11 (я изменил .MQH -файл для решения #import -оданных несовместимостей интерфейса, введенных в игру с New - MQL4.56789 изменил игру - так как string фактически перестал быть string и некоторыми другими) и видел другие привязки, вплоть до API ZeroMQ v.4.2. +, есть подробности, о которых нужно знать, если выходить за рамки простого "Helloworld" - пример.

Тем не менее, Context() инициация экземпляра должна быть оснащена соответствующими настройками / параметрами, и при тестировании ваш код должен регулярно получать все коды возврата + обрабатывать все исключения программно (не менее * 1076). * их в журнал для дальнейшей отладки с FILE и LINE ).

Также используйте функцию #import -ed int aZmqERROR = zmq_errno();, где бы ни возникали ваши сомнения, чтобы знать, что не было никакого состояния ошибки ZeroMQ, связанного непосредственно до / после вызов состоялся, или чтобы точно знать, что было сигналом ZeroMQ с его внутренних уровней, что могло помешать вызову API доставить ожидаемое функциональное состояние / результат. MQL4 / 5-сторона string Zmq::errorMessage( int error ) готова дать совет по некоторым более понятным для человека подсказкам при наблюдении любого такого флага ошибки со стороны ZeroMQ.


Последнее, но не менее важное:

также проверьте локальную конфигурацию FireWall на локальном хосте, если TCP port# == 9999 фактически был свободен для использования или административные запреты в политиках безопасности FireWall действительно препятствовали любой попытке успешного запуска и использования этот порт #.

До публичного подтверждения лучше прекратить каждый экземпляр Context() явно и с должной тщательностью (после того, как явно .close() -ед все локально созданные ZeroMQ- Socket() -инстанции. В более ранних версиях API могли происходить неприятные вещи, поэтому лучше проявлять систематичность и защищаться во всех новых версиях API, даже если примеры или размещенный код не делают этого систематически.

...