使用ZeroMQ推/拉模式将很长的字符串从MetaTrader 4发送到Python后端

问题描述 投票:0回答:1

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

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

虽然调试怪异性只会增加:

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

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

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

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

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

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

非常感谢任何想法!

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:

enter image description here

MetaTrader 4控制台:

enter image description here

zeromq mql4 metatrader4
1个回答
1
投票

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

这很容易证明:执行Comment( aStringUnderTEST ); +检查所有帐户/经纪人相关项目。


Q

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

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

然而,它有一个简单的证明:进行不断增长的字符串长度的循环,并进行测试,直到处理能够正常工作的大小为止。间接证明的大小限制将帮助您跟踪根本原因,MT4不是此处的SPoF,对吗?


Q

MT4 Print函数还执行了其他一些后台操作,这使得EA可以发送字符串?

如果要确认或拒绝,请联系MT4支持。该软件按原样授权使用,因此,如果您尝试深入研究封闭和密封产品内部的螺栓和螺母,不要指望有任何快速反应或火箭科学。

© www.soinside.com 2019 - 2024. All rights reserved.