【问题标题】:Sending very long strings from MetaTrader 4 to Python backend using ZeroMQ Push/Pull Pattern使用 ZeroMQ 推/拉模式从 MetaTrader 4 向 Python 后端发送很长的字符串
【发布时间】:2019-12-22 03:48:25
【问题描述】:

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

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

在调试的同时,怪事只会增加:

  • 当我打印 historical_trades 字符串时,它会显示在 MT4 专家日志中,但不会显示在 MT4 日志编辑器中
  • 当我在 pushSocket.send(StringFormat("%s", historical_trades, true)); 之前或之后添加 Print( historical_trades ) 时,它会发送字符串。

我实际上排除的可能问题:

  • PUSH 套接字太慢:我将计时器减少到 10 秒或更多,结果相同
  • MT4 本身创建字符串太慢:它可以正确打印它们,因此速度足够快
  • ZeroMQ SNDHWM (HighWaterMark) 阻止 EA/socket 立即发送多个字符串:已经将其增加到 100,这应该绰绰有余

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

  • MT4 Print() 函数在幕后做了一些其他的事情,使 EA 能够发送字符串?
  • 也许 MT4 中有一个最大字符串大小,它会阻止字符串创建循环(我的字符串大约 35.000 个字符长)。但是,当我在 onTimer() 函数中只使用一次 Print() 字符串时,为什么它会起作用呢?...
  • 是否有可能在周末无法访问帐户相关信息?

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

任何想法都非常感谢!

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 日志编辑器:

MetaTrader 4 控制台:

【问题讨论】:

    标签: zeromq mql4 metatrader4


    【解决方案1】:

    是否有可能周末无法访问帐户相关信息?

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


    Q也许 MT4 中有一个最大字符串大小会阻止字符串创建循环...?

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

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


    QMT4 Print 函数做了一些其他幕后工作,使 EA 能够发送字符串? p>

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      相关资源
      最近更新 更多