程序库: MT4Orders - 页 68

 
fxsaber #:
最新版本尽在这里

有一家受欢迎的经纪商删除了客户所有交易账户中的部分交易历史记录。因此,许多用户都遇到过由于交易服务器上的历史记录不正确而导致库发出警告的情况。


这一问题已在最新版本中得到修复。

请从俄语页面下载最新版本的程序库。

 
'DEAL_SL' - undeclared identifier       MT4Orders.mqh   1186    89
'DEAL_TP' - undeclared identifier       MT4Orders.mqh   1187    91
'MQL_HANDLES_USED' - undeclared identifier      MT4Orders.mqh   1345    104
'MQL_HANDLES_USED' - undeclared identifier      MT4Orders.mqh   1726    124

MT5 不支持旧版本。

而且最新发布的版本漏洞百出 https://www.mql5.com/ru/forum/380278/page31#comment_26286913

Новая версия платформы MetaTrader 5 build 3091: Улучшения в работе
Новая версия платформы MetaTrader 5 build 3091: Улучшения в работе
  • 2021.12.04
  • www.mql5.com
В пятницу 22 октября 2021 года будет выпущена обновленная версия платформы MetaTrader 5...
 
traveller00 #:

它不支持旧版本的 MT5。

我在新版本上编译,并在 b2958 上使用。我对待发行版和测试版的态度是一样的。

 

我有一个关于部分平仓的简单问题。

在 MT4 中,关闭 0.1 手订单中的 0.01 手,会导致原始订单以 0.01 手的大小关闭,该部分关闭订单的订单注释 变为 "to: xxxxxx"。与此同时,一个新的 0.09 手订单被打开,其注释设置为 "from: xxxxxxx"。

这在 MT5 中似乎没有发生(至少,OrdersToString() 没有列出开仓或平仓部分的订单注释文本),因此我无法像通常那样跟踪部分平仓的链条。

您是否有与 MT4Orders 兼容的代码片段可以分享,或者您能否解释一下我如何才能可靠地做到这一点?

 

如何查看 未结头寸的部分执行情况。

#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  // 打开位置。
  const TICKET_TYPE Ticket  = OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0, "Hello!");
  
  // 部分关闭。
  if (OrderSelect(Ticket, SELECT_BY_TICKET))
  {
    OrderClose(OrderTicket(), 0.01, OrderClosePrice(), 0);
    OrderClose(OrderTicket(), 0.02, OrderClosePrice(), 0);
  }
    
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      PrintFullOrder();
      
      Print("");
    }
}

#include <fxsaber\TradesID\TradesID.mqh> //https://www.mql5.com/zh/code/34173

void PrintFullOrder()
{
  static TRADESID TradesID;
  
  long Deals[];  
  const int Size = TradesID.GetDealsByID(OrderTicketID(), Deals);
  
  for (int i = 0; i < Size; i++)
    if (OrderSelect(Deals[i], SELECT_BY_TICKET))
      OrderPrint();  
}


结果。

#50005051444 2021.12.20 21:22:29.566 buy 0.07 GBPUSD 1.32174 0.00000 0.00000 1.32169 0.00 0.00 -0.31 Hello! 0
#50004982892 2021.12.20 21:22:29.566 buy 0.01 GBPUSD 1.32174 0.00000 0.00000 2021.12.20 21:22:29.631 1.32169 0.00 0.00 -0.04 Hello! 0
#50004982893 2021.12.20 21:22:29.566 buy 0.02 GBPUSD 1.32174 0.00000 0.00000 2021.12.20 21:22:29.694 1.32169 0.00 0.00 -0.09 Hello! 0

#50005051217 2021.12.20 21:22:05.921 buy 0.09 USDCHF 0.92179 0.00000 0.00000 0.92179 0.00 0.00 0.00 Hello! 0
#50004982634 2021.12.20 21:22:05.921 buy 0.01 USDCHF 0.92179 0.00000 0.00000 2021.12.20 21:22:05.984 0.92174 0.00 0.00 -0.05 Hello! 0
 
SysFX 订单注释 变为 "to: xxxxxx"。与此同时,一个新的 0.09 手订单被打开,其注释设置为 "from: xxxxxxx"。

这在 MT5 中似乎没有发生(至少,OrdersToString() 没有列出开仓或平仓部分的订单注释文本),因此我无法像通常那样跟踪部分平仓的链条。

您是否有与 MT4Orders 兼容的代码片段可以分享,或者您能否解释一下我如何才能可靠地做到这一点?

举例说明。

 
fxsaber #:

例如

太完美了!......感谢您的快速回复 :)

 
// 更改列表:
// 28.12.2021
// 修正:OrderSelect(Index, SELECT_BY_POS, MODE_TRADES)考虑了 MT5 端多出的一个不同步问题。
// 修复:OrderLots(true) 考虑到了 MT5 侧的另一个错误同步。 


特别是更改列表中的第一个编辑,使得两个逻辑完全相同成为可能。

交易、自动交易系统和交易策略测试论坛

库:MT4Orders

fxsaber, 2021.05.12 18:24

乍一看,这两个代码的结果应该是一样的。

while (OrdersTotal() <= 1)
  if (OrderSelect(0, SELECT_BY_POS))
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
  else
    OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0);    


while (OrdersTotal() <= 1)
  if (!OrdersTotal())
    OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0);    
  else if (OrderSelect(0, SELECT_BY_POS))
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);


事实上,并非如此。试着找出原因。

总的来说,在MT5 中 保护订单 不受阻碍 的效果更好。

 
// 更改列表:
// 29.12.2021
// 修复:改进 ByPass 模式下的同步。
 

在 MT4 中,当检索订单时 由于订单表的晃动,可能会出现回溯(重复计算)


在 MT4Orders 中,订单表索引在某种情况下会发生变化。当 MT5-moret 订单变为 MT5 头寸时,就会发生这种情况。如果在某些服务器上遇到这种情况,可能会出现记账失败。我为此编写了一个演示。

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // 等待交易环境同步的最长时间(微秒
#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define  MinLot SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)

double GetLots()
{
  double Lots = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // 运行所有订单 - 这里可能有故障。
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();
      
  return(NormalizeDouble(Lots, 2));
}

void OnStart()
{
  MT4ORDERS::OrderSend_MaxPause = 0; // 拒绝内置的 MT5-OrderSend 结果修正。

  const double NewLots = 0.11;
  
  while (!IsStopped())
  {
    const double Lots = NormalizeDouble(GetLots() + NewLots, 2); // 下订单后,总手数应该是多少。
    const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, NewLots, Ask, 0, 0 ,0); // 已发出市价订单。
    
    if (Ticket != -1)
    {
      while (!PositionSelectByTicket(Ticket)) // 等待市场订单转为头寸。
      {
        const double Lots2 = GetLots(); // 计算总体积。
        
        if (Lots2 != Lots) // 总体积与初步计算不符 - 输出。
          Alert((string)Lots + " " + (string)Lots2);                        
      }
    }
          
    if (OrderSelect(Ticket, SELECT_BY_TICKET) &&
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)) // 发送市场订单平仓。
      while (PositionSelectByTicket(Ticket))                          // 等待平仓。
        ;      
  }
    
  Print(MT4ORDERS::ByPass.ToString()); // 打印同步统计数据。
}


这样的 EA 可在某些配置下运行。ByPass模式可以使警报值保持稳定,但仍无法消除警报值。


我自己不会在没有 ByPass 模式的情况下进行交易,因为绕过 MT5 意外是一件非常强大的事情。我也不会在没有快照的情况下进行交易。快照机制可以帮助您避免过度索引。


在同一个示例中就是这样。

#define  VIRTUAL_SNAPSHOT_REFRESHTIME 1000 // 用于更新的快照寿命。在 MT5 中需要连接 MT4Orders.mqh
#define  VIRTUAL_SNAPSHOT_WITHOUT_HISTORY // 丢弃历史快照以提高性能
#include <fxsaber\Virtual\Virtual.mqh> //https://www.mql5.com/zh/code/22577

double GetLots()
{
  double Lots = 0;

  VIRTUAL::Snapshot(0, -1, false, ""); // Zasnepsholy 真实交易环境。
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // 由于采用了快照机制,所有订单都能安全运行。
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();

  VIRTUAL::SnapshotDelete(); // 删除快照。
      
  return(NormalizeDouble(Lots, 2));
}


我推荐 ByPass+Snapshot 捆绑软件。它不仅有助于绕过陷阱,还能大大减少计算资源的消耗。尤其是在有大量多币种订单/顾问的情况下。