FORTS: OnTradeTransaction() return codes - page 9

 
Михаил:

You misunderstood.

It was the server that did not send the order status PLASED for 20 seconds.

I meant the server developers.
 
Михаил:

There is an obvious error in the terminal, where theORDER_STATE_STARTED order status "hangs".

Has it been finally sorted out?

What exactly did the exchange say about this order? Was it placed quickly? If so, it is obvious that there was an error on the server or MT terminal that did not update the status. And with this you can go to the service-desk.

 

As a result of the discussion on the problem with Michael at Service Desk:

Apparently we need to explain how the order system works and what the placement means.

So:

1. You send a request

buy limit 5.00 SNGR-3.16 at 35501

2. MT5 server checks this request (parameters, pre-trade, etc.). If there is a problem, you will get a corresponding error code in response to the request.

After that you create a new order giving it a ticket (#24025010) - herewith the state "started" is set for the order. The order ticket is used to link the order identifier in MT5 with the order on the exchange at the moment of placing the order on the exchange.
The terminal sends a transaction about adding a new order in the "started" state, which can be tracked in OnTradeTransaction.

3. Next, the trade server (via the gateway) sends your order to the exchange, if the request was successfully sent, your request will receive a response - this means
"that the request has been sent", the results will be executed asynchronously, as you do not know in advance how long the exchange will reply.

Respectively it is at this point you see the record in the journal

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. After some time, the exchange sets the order in its system, assigns an identifier to it and then notifies the gateway and MT5 server.
If the exchange has set the order, the order identifier is written in the order in MT5 and the order status changes with => placed.
If the exchange refuses to place an order for some reason, the order will be removed.

This can all be tracked by simply logging the transactions coming into OnTradeTransaction.

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

What happens:

1. You submit an order request - see steps 1-3.

And at the moment when the order is already in MT5, and there is no order on the exchange, you send an order to withdraw this order.
But since this order is in its initial state (started) and the existence of an order for it is not defined, you receive a refusal to withdraw the order
.

You need to make appropriate checks-corrections in the logic of your EA.


Z.U. The other thing is that within a second.

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]
(and moreover for 20 seconds) the order should have been placed, this is being dealt with, one of the potential problems has been found - we are correcting it.
 
MQ Alexander:
Thank you for the explanations! Please add this to the documentation!
 
MQ Alexander:

As a result of the discussion on the problem with Michael at Service Desk:

Apparently we need to explain how the order system works and what the placement means.

So:

1. You send a request


2. MT5 server checks this request (parameters, pre-trade, etc.). If there is a problem, you will get a corresponding error code in response to the request.

After that you create a new order giving it a ticket (#24025010) - herewith the state "started" is set for the order. The order ticket is used to link the order identifier in MT5 with the order on the exchange at the moment of placing the order on the exchange.
The terminal sends a transaction about adding a new order in the "started" state, which can be tracked in OnTradeTransaction.

3. Next, the trade server (via the gateway) sends your order to the exchange, if the request was successfully sent, your request will receive a response - this means
"that the request has been sent", the results will be executed asynchronously, as you do not know in advance how long the exchange will reply.

Respectively it is at this point you see the record in the journal

4. After some time, the exchange sets the order in its system, assigns an identifier to it and then notifies the gateway and MT5 server.
If the exchange has set the order, the order identifier is written in the order in MT5 and the order status changes with => placed.
If the exchange refuses to place the order for some reason, the order will be removed.

All of this can be tracked by simply logging the transactions coming into OnTradeTransaction.

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

What happens:

1. You submit an order request - see steps 1-3.

And at the moment when the order is already in MT5, and there is no order on the exchange, you send an order to withdraw this order.
But since this order is in its initial state (started) and the existence of an order for it is not defined, you receive a refusal to withdraw the order
.

You need to make appropriate checks-corrections in the logic of your EA.


Z.U. The other thing is that within a second

(and moreover, for 20 seconds) the order should be placed, we are dealing with it, we have found one of the potential problems - let's fix it.
We still do not understand at what point the state of the order "started" changes into the state "placed". Does this happen according to point 3 of your explanation, according to point 4 of your explanation or in both cases point 3 and 4?
 
Yury Kirillov:
It is not clear at what point the state of the order "started" changes to "placed". Does this happen according to point 3 of your explanation, according to point 4 of your explanation or in both cases point 3 and 4?
MQ Alexander:

4. After some time, the exchange sets the order in its system, assigns its identifier, and then notifies the gateway and MT5 server about it.
If the exchange has set the order - the order identifier is written into the order in MT5, and the order state changes from started => placed.

 
MQ Alexander:

3. Then the trading server (via gateway) sends your request to the exchange, if the request was successfully sent, then your request will be answered, which means

"that the request has been sent", the results of its work will be executed asynchronously, because you do not know in advance what time the exchange response.

Accordingly, it is at this point you see in the journal entry

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. After some time, the exchange sets the order in its system, assigns an identifier to it and then notifies the gateway and MT5 server.
If the exchange has set the order, the identifier of the order in MT5 is written in the order in MT5 and the order status changes with => placed.

Here is another reason for confusion: in the log it says that the order has already been placed, but in fact its state has not yet changed.

Maybe we should write something like "sent" instead of "placed" because the order has not actually been accepted by the exchange?

 

It turns out the following.

Before ( or after ) performing any action on an order,

you have to "check" its status each time (correct me if I'm not sure):

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 );
}
 
Михаил:

It turns out the following.

Before ( or after ) performing any action on an order,

you have to "check" its state each time (correct me if I missed something):

Wrong,

If we look at theHistoryOrderSelect( ticket ), then we need to applyHistoryOrderGetInteger(),HistoryOrderGetDouble()

 
Sergey Chalyshev:

Incorrect,

If we look inHistoryOrderSelect( ticket ), we need to applyHistoryOrderGetInteger(),HistoryOrderGetDouble()

Right, it's a misprint :)

Thank you, corrected it...