FORTS: Códigos de retorno OnTradeTransaction() - página 9

 
Михаил:

Você entendeu mal.

Foi o servidor que não enviou o status do pedido PLASED durante 20 segundos.

Referia-me aos desenvolvedores de servidores.
 
Михаил:

Há um erro óbvio no terminal, onde o status da ordemORDER_STATE_STARTED"fica pendurado".

Já foi finalmente resolvido?

O que exatamente disse a troca sobre esta ordem? Foi colocado rapidamente? Se assim for, é óbvio que houve um erro no servidor ou no terminal MT que não atualizou o status. E com isto você pode ir até o balcão de atendimento.

 

Como resultado da discussão sobre o problema com Michael no Service Desk:

Aparentemente, precisamos explicar como funciona o sistema de pedidos e o que significa a colocação.

Portanto:

1. Você envia um pedido

buy limit 5.00 SNGR-3.16 at 35501

2. O servidor MT5 verifica esta solicitação (parâmetros, pré-comercialização, etc.). Se houver um problema, você receberá um código de erro correspondente em resposta ao pedido.

Depois disso, você cria uma nova ordem dando-lhe um bilhete (#24025010) - aqui o estado "começou" é definido para a ordem. O bilhete de pedido é usado para vincular o identificador do pedido em MT5 com o pedido na troca no momento da colocação do pedido na troca.
O terminal envia uma transação sobre a adição de um novo pedido no estado "iniciado", que pode ser rastreado na OnTradeTransaction.

3. Em seguida, o servidor comercial (através do gateway) envia seu pedido para a troca, se o pedido foi enviado com sucesso, seu pedido receberá uma resposta - isto significa
"que o pedido foi enviado", os resultados serão executados de forma assíncrona, pois você não sabe antecipadamente por quanto tempo a troca responderá.

Respectivamente, é neste ponto que você vê o registro na revista

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. Após algum tempo, a bolsa define o pedido em seu sistema, atribui-lhe um identificador e depois notifica o gateway e o servidor MT5.
Se a bolsa definiu o pedido, o identificador do pedido é escrito no pedido no MT5 e o status do pedido muda com => colocado.
Se a troca se recusar a fazer um pedido por algum motivo, o pedido será retirado.

Tudo isso pode ser rastreado através do simples registro das transações que entram na OnTradeTransaction.

================================================================================

O que acontece:

1. Você apresenta um pedido de pedido - veja os passos 1-3.

E no momento em que o pedido já está em MT5, e não há pedido na troca, você envia um pedido para retirar este pedido.
Mas como esta ordem está em seu estado inicial (iniciada) e a existência de uma ordem para ela não está definida, você recebe uma recusa de retirar a ordem
.

Você precisa fazer as correções de verificação apropriadas na lógica de sua EA.


Z.U. A outra coisa é que dentro de um segundo.

2015.11.26 10:48:24.583 Trades  'xxxxxx': failed cancel order #24025010 buy limit 5.00 SNGR-3.16 at 35501.00000 [Invalid request]
(e, além disso, por 20 segundos) o pedido deveria ter sido feito, isto está sendo tratado, um dos problemas potenciais foi encontrado - estamos corrigindo-o.
 
MQ Alexander:
Obrigado pelas explicações! Por favor, acrescente isto à documentação!
 
MQ Alexander:

Como resultado da discussão sobre o problema com Michael no Service Desk:

Aparentemente, precisamos explicar como funciona o sistema de pedidos e o que significa a colocação.

Portanto:

1. Você envia um pedido


2. O servidor MT5 verifica esta solicitação (parâmetros, pré-comercialização, etc.). Se houver um problema, você receberá um código de erro correspondente em resposta ao pedido.

Depois disso, você cria uma nova ordem dando-lhe um bilhete (#24025010) - aqui o estado "começou" é definido para a ordem. O bilhete de pedido é usado para vincular o identificador do pedido em MT5 com o pedido na troca no momento da colocação do pedido na troca.
O terminal envia uma transação sobre a adição de um novo pedido no estado "iniciado", que pode ser rastreado na OnTradeTransaction.

3. Em seguida, o servidor comercial (através do gateway) envia seu pedido para a troca, se o pedido foi enviado com sucesso, seu pedido receberá uma resposta - isto significa
"que o pedido foi enviado", os resultados serão executados de forma assíncrona, pois você não sabe antecipadamente por quanto tempo a troca responderá.

Respectivamente, é neste ponto que você vê o registro na revista

4. Após algum tempo, a bolsa define o pedido em seu sistema, atribui-lhe um identificador e depois notifica o gateway e o servidor MT5.
Se a bolsa definiu o pedido, o identificador do pedido é escrito no pedido no MT5 e o status do pedido muda com => colocado.
Se a troca se recusar a fazer um pedido por algum motivo, o pedido será retirado.

Tudo isso pode ser rastreado através do simples registro das transações que entram na OnTradeTransaction.

================================================================================

O que acontece:

1. Você apresenta um pedido de pedido - veja os passos 1-3.

2. No momento em que o pedido já está no MT5, e ainda não está presente na troca, você envia um pedido para retirar este pedido.
Mas como esta ordem está em seu estado inicial (iniciada) e a existência de uma ordem para ela não está definida, você recebe uma recusa de retirar a ordem
.

Você precisa fazer as correções de verificação apropriadas na lógica de sua EA.


Z.U. A outra coisa é que dentro de um segundo

(e além disso, por 20 segundos) o pedido deve ser feito, estamos lidando com ele, encontramos um dos problemas potenciais - vamos resolvê-lo.
Ainda não entendemos em que ponto o estado do pedido "começou" muda para o estado "colocado". Isso acontece de acordo com o ponto 3 de sua explicação, de acordo com o ponto 4 de sua explicação ou, em ambos os casos, com os pontos 3 e 4?
 
Yury Kirillov:
Não está claro em que ponto o estado do pedido "começou" muda para "colocado". Isso acontece de acordo com o ponto 3 de sua explicação, de acordo com o ponto 4 de sua explicação ou, em ambos os casos, com os pontos 3 e 4?
MQ Alexander:

4. Após algum tempo, a bolsa define o pedido em seu sistema, atribui seu identificador e depois notifica o gateway e o servidor MT5 sobre ele.
Se a bolsa definiu o pedido - o identificador do pedido é escrito no pedido no MT5, e o estado do pedido muda de iniciado => colocado.

 
MQ Alexander:

3. Então o servidor comercial (via gateway) envia sua solicitação para a bolsa, se a solicitação foi enviada com sucesso, então sua solicitação será respondida, o que significa

"que o pedido foi enviado", os resultados de seu trabalho serão executados de forma assíncrona, pois não se sabe com antecedência a que horas a resposta de troca será dada.

Portanto, é neste ponto que você vê na entrada do diário

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. Após algum tempo, a bolsa define a ordem em seu sistema, atribui-lhe um identificador e depois notifica o gateway e o servidor MT5.
Se a bolsa definiu a ordem, o identificador da ordem no MT5 é escrito na ordem no MT5 e o status da ordem muda com => colocado.

Aqui está outro motivo de confusão: no registro diz que o pedido já foi feito, mas na verdade seu estado ainda não mudou.

Talvez devêssemos escrever algo como "enviado" em vez de "colocado" porque o pedido não foi realmente aceito pela troca?

 

Acontece o seguinte.

Antes ( ou depois ) de executar qualquer ação em uma ordem,

você tem que "verificar" seu status cada vez (me corrija se eu não tiver certeza):

enum ENUM_ORD_REAL_STATE
{
  ORD_NOT_SPECIFIED         = 0, //Состояние ордера не определено
  ORD_NONE_CANCELED         = 1, //Ордера нет, отменён пользователем
  ORD_NONE_PARTIAL_CANCELED = 2, //Ордера нет, исполнился частично (не был залит вторым объёмом)
  ORD_NONE_PARTIAL          = 3, //Ордера нет, исполнился частично
  ORD_NONE_EXPIRED          = 4, //Ордера нет, удалён по сроку
  ORD_NONE_FILLED           = 5, //Ордера нет, исполнился полностью
  ORD_NONE_REJECTED         = 6, //Ордера нет, отклонён брокером(биржей)
  ORD_BUSY                  = 7, //Ордер находится в переходном состоянии
  ORD_EXIST                 = 8, //Ордер выставлен на биржу, возможны действия над ним
  ORD_EXIST_PARTIAL         = 9  //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
};
//
ENUM_ORD_REAL_STATE CheckOrderState( const ulong ticket )
{
  if ( ticket > 0 )
  {
    if ( HistoryOrderSelect( ticket ) ) //Только не существующий ордер может находится в истории
    {
      ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE( HistoryOrderGetInteger( ticket, ORDER_STATE ) );
      double init_volume = HistoryOrderGetDouble( ticket, ORDER_VOLUME_INITIAL );
      double cur_volume = HistoryOrderGetDouble( ticket, ORDER_VOLUME_CURRENT );
//---      
      switch( ord_state )
      {
                                                           
        case ORDER_STATE_CANCELED:       if ( init_volume == init_volume )
                                         {
                                           return( ORD_NONE_CANCELED );
                                         }
                                         else
                                         {
                                           return( ORD_NONE_PARTIAL_CANCELED );
                                         }  
                                         break;
                                         
        case ORDER_STATE_PARTIAL:        return( ORD_NONE_PARTIAL );
                                         break;
                                         
        case ORDER_STATE_EXPIRED:        return( ORD_NONE_EXPIRED );
                                         break;
                                                                              
        case ORDER_STATE_FILLED:         return( ORD_NONE_FILLED );
                                         break;
                                         
        case ORDER_STATE_REJECTED:       return( ORD_NONE_REJECTED );
                                         break;   
 
       
      }
    }
    else
    if ( OrderSelect( ticket ) ) 
    {
      ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE( OrderGetInteger( ORDER_STATE ) );
//---      
      switch( ord_state )
      {
        case ORDER_STATE_STARTED:
        case ORDER_STATE_REQUEST_ADD:
        case ORDER_STATE_REQUEST_MODIFY:
        case ORDER_STATE_REQUEST_CANCEL: return( ORD_BUSY );
                                         break; 
 
        case ORDER_STATE_PARTIAL:        return( ORD_EXIST_PARTIAL );
                                         break;
                                          
        case ORDER_STATE_PLACED:         return( ORD_EXIST );
                                         break;
      }
    }
  }
  return( ORD_NOT_SPECIFIED );
}
 
Михаил:

Acontece o seguinte.

Antes ( ou depois ) de executar qualquer ação em uma ordem,

você tem que "verificar" seu estado cada vez (me corrija se eu perdi alguma coisa):

Errado,

Se olharmos para oHistoryOrderSelect( bilhete ), então precisamos aplicarHistoryOrderGetInteger(),HistoryOrderGetDouble()

 
Sergey Chalyshev:

Incorreto,

Se olharmos emHistoryOrderSelect( ticket ), precisamos aplicarHistoryOrderGetInteger(),HistoryOrderGetDouble()

Certo, é um erro de impressão :)

Obrigado, corrigiu-o...