使用 ZeroMQ Push/Pull 模式将非常长的字符串从 MetaTrader 4 发送到 Python 后端

Sending very long strings from MetaTrader 4 to Python backend using ZeroMQ Push/Pull Pattern

我有一个非常奇怪的问题,与 MetaTrader 4 和 python 后端之间的 ZeroMQ 消息传递有关。

下面显示的代码创建了三个字符串,它们应该被转发到 ZeroMQ PUSH 套接字。但是,它仅通过套接字发送 live_trades 字符串。 account_infohistorical_trades 字符串均未发送。

调试的时候怪怪的只增加了:

我实际排除的可能问题:

任何其他我无法通过调试验证的想法:

或者我的代码可能有问题..

非常感谢任何想法!

int OnInit()
  {
//---

   EventSetTimer(2);     // Set Second Timer as push intervall

   context.setBlocky(false);

   // Send data to PULL_PORT that consumer is listening to.
   Print("Connecting MT4 Dashex Feeder to Dashboard on Port " + IntegerToString(PUSH_PORT) + "..");
   pushSocket.connect(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));

   pushSocket.setSendHighWaterMark(100);
   pushSocket.setLinger(0); 

//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

   Print("Disconnecting MT4 Dashex Feeder on Port " + IntegerToString(PUSH_PORT) + "..");
   pushSocket.disconnect(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));

   // Shutdown ZeroMQ Context
   context.shutdown();
   context.destroy(0);

   EventKillTimer();
}


//---

//+------------------------------------------------------------------+
//| Expert timer function                                             |
//+------------------------------------------------------------------+
void OnTimer()
{

   /*
      1.) Account information
   */   

      string account_info = "";   
      account_info = account_info +

         "account_info|" +
         version + "|" +
         DID + "|" +
         IntegerToString(AccountNumber()) + "|" +
         AccountInfoString(ACCOUNT_COMPANY) + "|" +
         IntegerToString(AccountInfoInteger(ACCOUNT_LEVERAGE)) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE),2) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_PROFIT),2) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY),2) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN),2) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_FREE),2) + "|" +
         DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),2) + "|" +
         AccountInfoString(ACCOUNT_CURRENCY) + "|" +
         IntegerToString(IsDemo()) + "|" +

         pushSocket.send(StringFormat("%s", account_info, true));
         Print("Pushing Account Information To Dashex.Finance Dashboard For Account No. " + IntegerToString(AccountNumber()));


//+------------------------------------------------------------------+
//+------------------------------------------------------------------+         

   /*
      2.) Pending and running trades
   */

      int live_orders = OrdersTotal();
      string live_trades = "";

      for(int i=live_orders; i >= 0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS)==false) continue;

           live_trades = live_trades +

           "live_trades|" +
           version + "|" +
           DID + "|" +
           IntegerToString(AccountNumber()) + "|" +
           IntegerToString(OrderTicket()) + "|" +
           TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS) + "|" +
           TimeToString(OrderCloseTime(), TIME_DATE|TIME_SECONDS) + "|" +
           IntegerToString(OrderType()) + "|" +
           DoubleToString(OrderLots(),2) + "|" +
           OrderSymbol() + "|" +
           DoubleToString(OrderOpenPrice(),5) + "|" +
           DoubleToString(OrderClosePrice(),5) + "|" +
           DoubleToString(OrderStopLoss(),5) + "|" +
           DoubleToString(OrderTakeProfit(),5) + "|" +
           DoubleToString(OrderCommission(),2) + "|" +
           DoubleToString(OrderSwap(),2) + "|" +
           DoubleToString(OrderProfit(),2) + "|" +
           "<" + OrderComment() + ">|";
      }

      pushSocket.send(StringFormat("%s", live_trades, true));
      Print("Pushing Live Trades To Dashex.Finance Dashboard For Account No. " + IntegerToString(AccountNumber()));

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

   /*
      3.) History Trades      
   */


         int hstTotal = OrdersHistoryTotal();
         string historical_trades = "";

         Print(hstTotal);
         for(int i=hstTotal; i >= 0; i--)
         {

           if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) continue;

           historical_trades = historical_trades +

              "historical_trades|" +
              version + "|" +
              DID + "|" +
              IntegerToString(AccountNumber()) + "|" +
              IntegerToString(OrderTicket()) + "|" +
              TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS) + "|" +
              TimeToString(OrderCloseTime(), TIME_DATE|TIME_SECONDS) + "|" +
              IntegerToString(OrderType()) + "|" +
              DoubleToString(OrderLots(),2) + "|" +
              OrderSymbol() + "|" +
              DoubleToString(OrderOpenPrice(),5) + "|" +
              DoubleToString(OrderClosePrice(),5) + "|" +
              DoubleToString(OrderStopLoss(),5) + "|" +
              DoubleToString(OrderTakeProfit(),5) + "|" +
              DoubleToString(OrderCommission(),2) + "|" +
              DoubleToString(OrderSwap(),2) + "|" +
              DoubleToString(OrderProfit(),2) + "|" +
              "<" + OrderComment() + ">|"; 
         }

         pushSocket.send(StringFormat("%s", historical_trades, true));
         Print("Pushing History Trades To Dashex.Finance Dashboard For Account No. " + IntegerToString(AccountNumber()));

         Sleep(1);
}

MetaTrader 4 log.editor:

MetaTrader 4 控制台:

Q : Any chance that the account related information is not accessible on weekends?

这有一个简单的证明:做一个 Comment( aStringUnderTEST ); + 检查所有与账户/经纪人相关的项目。


Q : Maybe there is a maximum string size in MT4 which blocks the string creation loop...?

除了等待 BugFIX 的 MT4-Build-X.Y.Z 发布错误之外,这是非常低概率的假设。

然而它有一个简单的证明:做一个不断增加字符串长度的循环并测试直到处理保持工作的大小。间接证明的大小限制将帮助您追踪根本原因,MT4 不是这里的 SPoF,是吗?


Q : The MT4 Print function does some other stuff behind the scenes which enables the EA to send the string?

如果要确认或拒绝,应联系 MT4 支持。该软件作为原样产品获得许可,因此如果您试图深入了解其封闭和密封产品内的螺栓和螺母,不要指望会发生任何快速响应或火箭科学。