mql5语言的特点、微妙之处以及技巧 - 页 185

 
还有一个错误在起作用。我们在当前价格 设置一个限价订单,并观察其逐步填补。我们在每一步都检查所有头寸和订单的总手数。它不应该改变,而且应该等于发送给OrderSend的那个。
// Демонстрация потери данных во время торговли.

template <typename T>
T MyPrint( const T Value, const string Str )
{
  Print(Str + " = " + (string)Value);

  return(Value);
}

#define _P(A) MyPrint(A, ": " + #A)

sinput double inLots = 100;

int OnInit()
{
  MqlTradeResult Result = {0};
  MqlTradeRequest Request = {0};
  
  Request.action = TRADE_ACTION_PENDING;
  Request.symbol = _Symbol;
  Request.volume = inLots;
  Request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  Request.type = ORDER_TYPE_BUY_LIMIT;
  
  return(OrdersTotal() || PositionsTotal() || !OrderSend(Request, Result)); // Работаем, когда ничего не открыто.
}

// Возвращает сумму лотов всех позиций и ордеров.
double GetSumLots()
{
  double Lots = 0;
  
  for (int i = _P(OrdersTotal()) - 1; i >= 0; i--)
    if (_P(OrderGetTicket(_P(i))))
      Lots += _P(OrderGetDouble(ORDER_VOLUME_CURRENT));
    
  for (int i = _P(PositionsTotal()) - 1; i >= 0; i--)
    if (_P(PositionGetTicket(_P(i))))
      Lots += _P(PositionGetDouble(POSITION_VOLUME));

  return(Lots);
}

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
  Print("---------");
    
  // Проверяем, что сумма лотов всех позиций и ордеров совпадает с заданной.
  if (NormalizeDouble(_P(GetSumLots()) - inLots, _Digits))
    Alert("BUG!");
}


结果。

2020.08.21 01:18:13.375 : OrdersTotal() = 1
2020.08.21 01:18:13.375 : i = 0
2020.08.21 01:18:13.375 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.375 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 68.59999999999999
2020.08.21 01:18:13.375 : PositionsTotal() = 1
2020.08.21 01:18:13.375 : i = 0
2020.08.21 01:18:13.375 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.375 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.375 : GetSumLots() = 100.0
2020.08.21 01:18:13.377 ---------
2020.08.21 01:18:13.377 : OrdersTotal() = 1
2020.08.21 01:18:13.377 : i = 0
2020.08.21 01:18:13.377 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.377 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 68.59999999999999
2020.08.21 01:18:13.377 : PositionsTotal() = 1
2020.08.21 01:18:13.377 : i = 0
2020.08.21 01:18:13.377 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.377 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.377 : GetSumLots() = 100.0
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.390 : PositionGetDouble(POSITION_VOLUME) = 58.6
2020.08.21 01:18:13.390 : GetSumLots() = 100.0

放置了100手,但在某些时候,手数变成了72.8。显然,在这种情况下,交易算法可能会迷失方向。

搜索字符串:Oshibka 011。
 

fxsaber:
Он должен быть неизменным - равным тому, что был отправлен в OrderSend.

其实不是的,有可能会出现定时故障,这就是发生的情况,但根本没有简单的解决办法

 
Andrei Trukhanovich:

实际上不是,有可能会出现时间不匹配,这就是发生的情况,根本没有简单的解决办法。

我甚至没有一个简单的解决方案。如何确保在一些正在运行的脚本中存在解同步的情况,一点都不清楚。

 
fxsaber:

我甚至没有一个复杂的解决方案。如何在任何运行中的脚本中确保有一个异步,一点也不清楚。

如果总手数有变化,继续计算,直到订单和仓位的手数两次相同。

有几分之几的概率,或者只有百分之几,所以不会影响性能。

__________

我看了你的打印件,也许这是一个错误,如果是异步的情况,错误的金额不应该在几次计算中以同样的方式重复出现。

 
Andrei Trukhanovich:

如果总手数有变化,继续计算,直到订单和仓位的手数两次相同。

有一小部分或百分之几的概率出现错位,所以性能几乎不受影响。

在上面的日志中,连续三次计算都显示出错误的结果。我们需要睡眠,但这可能会导致延误,届时我们将没有时间对发出的贸易订单 作出反应。

这不是一个令人愉快的情况。

 
fxsaber:

在上面的日志中,连续三次计算都显示出错误的结果。

是的,我看到了,我把它加到了上面。

 
 
Alexey Viktorov:

你不应该被冒犯。最高的概率是代码中的错误。排在第二位的是过高的价差。但是,除了你之外,谁能在没有看到代码的情况下放弃第一个选项并开始考虑第二个。我希望版主能把这个话题移到错误的地方。

谢谢你的充分答复。我没有被冒犯,我是不高兴))。我写信试图找到一个快速解决方案,这可能是有人已经遇到了这个问题。代码绝对是标准的,totalprofit循环求和并与一个给定值进行比较,此外,代码在两个不同的账户上工作了几个月,没有出现故障。祝您有一个愉快的一天。

 
Evgeny Vlasov:

谢谢你的充分回应。我没有被冒犯,我很难过))。我写信试图找到一个快速的解决方案,也许已经遇到过的人有这样的解决方案。代码绝对是标准的,totalprofit循环求和并与一个给定值进行比较,此外,代码在两个不同的账户上工作了几个月,没有出现故障。祝您有一个愉快的一天。

这不是关于功能的问题。
 
Artyom Trishkin:
这不是关于功能的问题。

我同意。