Как запустить скрипт python из процесса MQL4 EA (терминал MetaTrader4)?

У меня есть простой скрипт test.py, который я хочу запустить из советника MQL4.

Как я могу реализовать это?

Я пробовал использовать ShellExecute(), но в моем случае это не сработает, так как я запускаю терминал MetaTrader4 на компьютере с Linux и поэтому не могу вызывать ShellExecute() на базе Windows (даже с wine).


person xion    schedule 08.09.2017    source источник


Ответы (1)


Вариант 0: использование wine-обещания для полной DLL-абстракции

Проект wine, если он сконфигурирован должным образом, должен обеспечить полную абстракцию DLL, так что легитимный ShellExecute() должен обеспечить способ запуска терминала MetaTrader4 в винной оболочке при запуске такого предполагаемого процесса.


Вариант 1: использовать распределенную обработку { ZeroMQ | наномсг }

Учитывая, что этот вариант стал возможным, начиная с ZeroMQ v2.11, python всегда был готов взаимодействовать с MQL4 и запускать/останавливать предоставление любых услуг по-{MQL4|*}-требованию. Это был бы мой предпочтительный способ, поскольку рабочий процесс не ограничивается только управлением ракетами по принципу «выстрелил-забыл».

Используя эту архитектуру много лет для AI/ML-predictive Engine, удаленных клавиатур, удаленной централизованной интеллектуальной регистрации, интеграции сервисов телеметрии работоспособности/производительности процессов (не только с модулями выполнения кода MQL4) и оставаясь довольным всем лет за то, что выбрали этот передовой путь распределенной архитектуры.


Nota Bene: Справедливо отметить, что где-то около версии MQL4 Build 850 / 900 MetaTrader4 Terminal ревизия механизма выполнения кода создала несколько десятков проблем с DLL-оболочкой / оригинальной ZeroMQ v2. .11 обертка, но умеренные усилия заставили New-MQL4.56789 заменить string, который больше не был string (будучи на удивление переодетым struct ), но в большинстве высокопроизводительных процессоров взаимодействия упакованы побитно, поэтому из-за этого не должно возникать проблем с сердцем.


Сторона питона:

def main():
    # setup ZeroMQ infrastructure and map all resources
    import  zmq
    ...
    pass; mainloopSTAY = True
    #     mainloop(): -----------------------------
    while mainloopSTAY:
       try:
           # ----------------------- event-handling:
           pass;   
       except:
           # ------------------------- EXC-handling: { continue }
           pass;
       finally:
           # dismantle ZeroMQ infrastructure and release all resources
           pass;   print( "INF: main().finally: EXIT" )
           # { break | if mainloopSTAY }
    #----------------------------------------------
    pass;          print( "INF: main().pre-return SECTION" )

if __name__ == '__main__':
    main()   #  EXECUTED only if this module-file was called to run from a command-line ( Ref. SECTION: import for def: )

Сторона MQL4:

#include   <mql4zmq_for_Terminal_4.00_Build.840.mqh>        // STILL BUG/ERROR on zmq_poll() while missing zmq_poll_struct_t

         string   aTemp = ">>> ";                           // globally visible ...
         int      aZmqCONTEXT,                              // globally visible ...
                  aZmqSOCKET;                               // globally visible ... so as to be able to auto-deinit in { EA -s | #Indicators } .deinit() on panic termination(s)

//+------------------------------------------------------------------+
//|      msMOD_deinit( int       aZmqSOCKET  = EMPTY )               |
//+------------------------------------------------------------------+
void     msMOD_deinit( const int aZmqSOCKET  = EMPTY ) {
         if (                    aZmqSOCKET != EMPTY ) {
               zmq_setsockopt(   aZmqSOCKET, ZMQ_LINGER, 0 );
               zmq_close(        aZmqSOCKET );
               }
         zmq_term(               aZmqCONTEXT );
         return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void  OnDeinit( const int anAutoDeinitREASON ){ // auto-generated ONLY for { EA-s , #Indicator-s }
      msMOD_deinit( aZmqSOCKET );
   }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void  OnStart()
{                                      aZmqCONTEXT = zmq_init(1);                            // .init into globally visible int
                                 if (  aZmqCONTEXT < 0 ){   
                                                            msMOD_deinit();                  // GRACEFUL CLEANUP
                                                            return;                          // DEBUG: RET()
                                 }
                                 int   aZmqPAIR = zmq_socket( aZmqCONTEXT, ZMQ_PAIR );       // .sock PAIR
                                 if (  aZmqPAIR < 0 ){
                                                            msMOD_deinit( aZmqPAIR );        // GRACEFUL CLEANUP
                                                            return;                          // DEBUG: RET()
                                 }
                                 int   aZmqBindPAIR = zmq_bind(   aZmqPAIR,
                                                                  "tcp://A.B.C.D:PORT"  // i5-eth0-IP:#####
                                                                  );                     
                                 if (  aZmqBindPAIR < 0 ){
                                                            msMOD_deinit( aZmqPAIR );        // GRACEFUL CLEANUP
                                                            return;                          // DEBUG: RET()
                                 }
       ...
       int RC = mql4zmq_msg_init_data( aSendMsgOBJ, aSendMsgBuffUCHAR, aSendMsgBUFF_SIZE * 4 );
       zmq_send( aZmqPAIR,             aSendMsgOBJ );
       ...
}

person user3666197    schedule 08.09.2017
comment
Извините, но мне это не очень помогает. Прежде чем задать этот вопрос в stackoverflow, я провел исследование и нашел несколько оболочек, таких как ZeroMQ, но не смог найти простого решения для простого запуска из них скрипта Python. Не могли бы вы привести рабочий пример? - person xion; 08.09.2017
comment
Конечно, это работает как шарм. Процесс сценария Python запускается первым, имея подготовленную конечную точку службы .bind()-RTO, и простаивает в цикле событий или какой-либо форме многопоточного монитора службы. Сторона MQL4 свободно connect()-s к этому, как только она запускается, и если ей нужно какое-то взаимодействие с python (даже если это происходит по принципу «запустил и забыл»), она запрашивает python, используя этот самый уровень сигнализации/обмена сообщениями. Возможен и обратный { .bind() | .connect() } сценарий, где это необходимо, так что только собственное воображение является потолком. Если можно интегрировать ZeroMQ внутри Python, MQL4 (почти) бесплатно. - person user3666197; 08.09.2017
comment
Я признателен за это. Я хотел знать, как просто выполнить скрипт Python из моего советника. Простое выполнение файла .py из MQL4. Я чувствую, что это немного более продвинуто, чем то, что я хочу сделать. Есть идеи? - person xion; 10.09.2017
comment
Что ж, чувак, мир может быть сложным и часто таковым и является. Смотрите, вы получили полный набор из двух разных подходов, каждый из которых работает на достижение указанной цели. Вы даже получили полные примеры кода, чтобы следовать им и просто собрать свои конкретные части решения в каждый из шаблонов кода. Крики Есть идеи? на членов сообщества, которые стремились сделать все возможное, чтобы помочь вам достичь ни вежливо, ни конструктивно, не так ли?. Так в чем проблема? Есть идеи? - person user3666197; 10.09.2017