Características da linguagem mql5, subtilezas e técnicas - página 185

 
Há mais um bug em jogo. Estabelecemos uma ordem Limitada ao preço actual e observamos o seu enchimento gradual. Verificamos o lote total de todas as posições e encomendas em cada passo. Não deve mudar, e deve ser igual à que foi enviada para 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!");
}


Resultado.

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

Foram colocados 100 lotes, mas a certa altura os lotes tornaram-se 72,8. Obviamente, o algoritmo de negociação pode ser desorientado em tal situação.

Cadeia de pesquisa: Oshibka 011.
 

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

Na verdade, não, há a possibilidade de um mau funcionamento no tempo, que é o que acontece, mas não há nenhuma solução fácil

 
Andrei Trukhanovich:

Na verdade não, há uma hipótese de haver uma descoordenação temporal, que é o que acontece, não há nenhuma solução fácil

Eu nem sequer tenho uma solução simples. Como ter a certeza de que existe um desync em algum guião em execução não é de todo claro.

 
fxsaber:

Eu nem sequer tenho uma solução complicada. Como garantir em qualquer script em execução que existe uma assincronia não é de todo claro.

Se o lote total mudou, continuar a contar até que os lotes para encomendas e posições sejam os mesmos duas vezes.

Há uma probabilidade de fracções ou apenas alguns por cento, pelo que não afectará o desempenho.

__________

Olhei para as suas impressões, talvez seja um bug, se é um caso de assimetria, a quantidade errada não deve ser repetida da mesma forma em vários cálculos

 
Andrei Trukhanovich:

Se o lote total mudou, continuar a contar até que os lotes para encomendas e posições sejam os mesmos duas vezes.

Há uma fracção ou alguns por cento de probabilidade de um desalinhamento, pelo que o desempenho é quase inalterado.

No registo acima, três cálculos consecutivos mostram o resultado errado. Precisamos de dormir, mas isto pode levar a atrasos, quando não teremos tempo de reagir à emissão da ordem comercial.

Esta não é uma situação agradável.

 
fxsaber:

No registo acima, três cálculos consecutivos mostram o resultado errado.

Sim, eu vi isso, eu adicionei-o ao topo

 
Comentários não relacionados com este tópico foram movidos para"Quaisquer perguntas de novatos sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos".
 
Alexey Viktorov:

Não se deve ofender. A maior probabilidade é um erro no código. Em segundo lugar está a propagação exorbitante. Mas quem, senão você, pode descartar a primeira opção e começar a considerar a segunda sem ver o código. Espero que os moderadores passem o tópico para o tópico errado.

Obrigado pela resposta adequada. Não estou ofendido, estou chateado))). Escrevi para tentar encontrar uma solução rápida, que pode ser alguém que já a tenha encontrado. O código é absolutamente padrão, soma de loop total de lucro e comparação com um determinado valor, além disso, o código tem estado a trabalhar há alguns meses em duas contas diferentes sem falhar. Tenha um bom dia.

 
Evgeny Vlasov:

Obrigado pela resposta adequada. Não estou ofendido, estou triste))). Escrevi para tentar encontrar uma solução rápida, que talvez alguém que já a tenha encontrado tenha. O código é absolutamente padrão, soma de loop total de lucro e comparação com um determinado valor, além disso, o código tem estado a trabalhar há alguns meses em duas contas diferentes sem falhar. Tenha um bom dia.

Isto não é sobre o tema das características.
 
Artyom Trishkin:
Isto não é sobre o tema das características.

Concordo.