FORTS. Questions relatives à l'application de la loi - page 74

 
leonerd:
Je vois, il n'y a donc aucune garantie de performance.
Il n'y a pas de garantie à 100%, même avec une banque. Essayez de jouer avec une politique d'exécution du tout-rien. Seulement sur les Forts, ce mode ne semble pas fonctionner. Vous pouvez également analyser la liquidité de la pile avant d'entrer directement sur le marché - dans de nombreux cas, cela peut être utile. Cependant, il ne peut y avoir de garantie à 100% : le marché peut soit garantir l'exécution, soit garantir le prix, mais pas les deux en même temps. C'est à vous de décider ce qui est le plus important.
 

Eh bien, ils ont débanaliséMikhail Filimonov apparemment après sa demande.

C'est tout ce qu'il y a à faire.

 

Lisez longuement et attentivement.

La raison pour laquelle l'auteur du sujet a été banni est claire :

Pas d'homme, pas de problème.

Les retards ont-ils été corrigés ?

 
prostotrader:

Lisez longuement et attentivement.

La raison pour laquelle l'auteur du sujet a été banni est claire :

Pas d'homme, pas de problème.

Les retards ont-ils été éliminés ?

Qui les mesurera maintenant à part lui ? Tout le monde a peur d'être banni :)

 
coderex :

et qui les mesurera maintenant à part lui ? tout le monde a peur de l'interdiction :)

Eh bien, tout d'abord, vous devez écrire un test EA :

 //+------------------------------------------------------------------+
//|                                                   Test_delay.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
input int Transactions= 1500 ;
ulong order_ticket;
int tr_cnt;
ulong Magic= 1234567890 ;
ulong order_id;
ulong start,stop;
#define ERR_ZERO_TICKET - 1 ;
bool exp_busy;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_ORD_SELECT
  {
   SELECT_ERROR = 0 ,
   SELECT_FALSE = 1 ,
   SELECT_TRUE  = 2 ,
   SELECT_BUSY  = 3
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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    //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct ORDER_DATA
  {
   int                error_code;
   datetime           time_setup;
   ENUM_ORDER_TYPE    type;
   ENUM_ORDER_STATE   state;
   ENUM_ORD_REAL_STATE real_state;
   datetime           expiration;
   datetime           time_done;
   long               t_set_msc;
   long               t_done_msc;
   ENUM_ORDER_TYPE_FILLING type_filling;
   ENUM_ORDER_TYPE_TIME type_time;
   long               magic;
   long               pos_id;
   double             vol_init;
   double             vol_cur;
   double             price_open;
   double             sl;
   double             tp;
   double             price_cur;
   double             price_stlim;
   string             symbol;
   string             comment;
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
  {
//---
   order_ticket= 0 ;
   tr_cnt= 0 ;
   start= 0 ;
   stop= 0 ;
   exp_busy= false ;
   Print ( "Тест начат: " , TimeTradeServer ());
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ()
  {
//---
   ORDER_DATA order_data;
   if (!exp_busy)
     {
       if (tr_cnt>=Transactions)
        {
         if ((order_ticket> 0 ) && (OrderRealSelect(order_ticket,order_data, false )==SELECT_TRUE)) RemoveOrder(order_ticket);
         Print ( "Тест закончен: " , TimeTradeServer ());
        }
       else
        {
         if (order_ticket> 0 )
           {
             if (OrderRealSelect(order_ticket,order_data, false )==SELECT_TRUE) RemoveOrder(order_ticket);
           }
         else
           {
            SetOrder();
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         const MqlTradeRequest &request,
                         const MqlTradeResult &result)
  {
   switch (trans.type)
     {
       case TRADE_TRANSACTION_REQUEST : if ((order_id!= 0 ) && (result.request_id==order_id))
        {
         order_ticket=result.order;
         order_id= 0 ;
        }
       break ;
       case TRADE_TRANSACTION_ORDER_UPDATE :   if ((order_ticket!= 0 ) && (trans.order==order_ticket))
        {
         ORDER_DATA order_data;
         if (OrderRealSelect(order_ticket,order_data, false )==SELECT_TRUE)
           {
            stop= GetMicrosecondCount ();
            tr_cnt++;
             Print ( "Время установки ордера: " , NormalizeDouble ( double (stop-start)/ 1000 , 2 ), " ms" );
             Sleep ( 1000 );
            exp_busy= false ;
           }
        }
       break ;
       case TRADE_TRANSACTION_HISTORY_ADD : if ((order_ticket!= 0 ) && (trans.order==order_ticket))
        {
         ORDER_DATA order_data;
         if (OrderRealSelect(order_ticket,order_data, false )==SELECT_FALSE)
           {
            stop= GetMicrosecondCount ();
            tr_cnt++;
            order_ticket= 0 ;
             Print ( "Время удаления ордера: " , NormalizeDouble ( double (stop-start)/ 1000 , 2 ), " ms" );
             Sleep ( 1000 );
            exp_busy= false ;
           }
        }
       break ;
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetOrder()
  {
   MqlTradeRequest request={ 0 };
   MqlTradeResult   result={ 0 };
   order_id= 0 ;
   order_ticket= 0 ;
   request.magic=Magic;
   request.symbol= Symbol ();
   request.volume= 1 ;
   request.type_filling= ORDER_FILLING_RETURN ;
   request.type_time= ORDER_TIME_DAY ;
   request.action= TRADE_ACTION_PENDING ;
   request.type= ORDER_TYPE_SELL_LIMIT ;
   request.comment= "" ;
   request.price= SymbolInfoDouble ( Symbol (), SYMBOL_SESSION_PRICE_LIMIT_MAX );
   if ( OrderSendAsync (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         order_id=result.request_id;start= GetMicrosecondCount ();exp_busy= true ;
         Print ( "Запрос на установку ордера." );
        }
     }
   else
     { Print ( "Ордер не отослан!" );}
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void RemoveOrder( const ulong o_ticket)
  {
   MqlTradeRequest request={ 0 };
   MqlTradeResult   result={ 0 };
   order_id= 0 ;
   request.action= TRADE_ACTION_REMOVE ;
   request.order=o_ticket;
   if ( OrderSendAsync (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         order_id=result.request_id;start= GetMicrosecondCount ();exp_busy= true ;
         Print ( "Запрос на удаление ордера." );
        }
     }
   else
     { Print ( "Ордер не отослан!" );}
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ENUM_ORD_SELECT OrderRealSelect( const ulong ticket,ORDER_DATA &ord_data, const bool get_data) //Отличная функция, спасибо Михаилу
  {
   double init_vol= 0 ;
   double cur_vol = 0 ;
   ZeroMemory (ord_data);
   ord_data.real_state = ORD_NOT_SPECIFIED;
   ord_data.error_code = ERR_SUCCESS ;
   ResetLastError ();
//---  
   if (ticket> 0 )
     {
       if ( HistoryOrderSelect (ticket))
        {
         if (get_data)
           {
            ord_data.comment= HistoryOrderGetString (ticket, ORDER_COMMENT );
            ord_data.expiration= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_EXPIRATION ));
            ord_data.magic= HistoryOrderGetInteger (ticket, ORDER_MAGIC );
            ord_data.pos_id= HistoryOrderGetInteger (ticket, ORDER_POSITION_ID );
            ord_data.price_cur= HistoryOrderGetDouble (ticket, ORDER_PRICE_CURRENT );
            ord_data.price_open= HistoryOrderGetDouble (ticket, ORDER_PRICE_OPEN );
            ord_data.price_stlim= HistoryOrderGetDouble (ticket, ORDER_PRICE_STOPLIMIT );
            ord_data.sl= HistoryOrderGetDouble (ticket, ORDER_SL );
            ord_data.state= ENUM_ORDER_STATE ( HistoryOrderGetInteger (ticket, ORDER_STATE ));
            ord_data.symbol= HistoryOrderGetString (ticket, ORDER_SYMBOL );
            ord_data.t_done_msc= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_DONE_MSC ));
            ord_data.t_set_msc = datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_SETUP_MSC ));
            ord_data.time_done = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_DONE ));
            ord_data.time_setup= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_SETUP ));
            ord_data.tp= HistoryOrderGetDouble (ticket, ORDER_TP );
            ord_data.type= ENUM_ORDER_TYPE ( HistoryOrderGetInteger (ticket, ORDER_TYPE ));
            ord_data.type_filling= ENUM_ORDER_TYPE_FILLING ( HistoryOrderGetInteger (ticket, ORDER_TYPE_FILLING ));
            ord_data.type_time= ENUM_ORDER_TYPE_TIME ( HistoryOrderGetInteger (ticket, ORDER_TYPE_TIME ));
            ord_data.vol_cur= HistoryOrderGetDouble (ticket, ORDER_VOLUME_CURRENT );
            ord_data.vol_init= HistoryOrderGetDouble (ticket, ORDER_VOLUME_INITIAL );
           }
         else
           {
            ord_data.state= ENUM_ORDER_STATE ( HistoryOrderGetInteger (ticket, ORDER_STATE ));
            cur_vol= HistoryOrderGetDouble (ticket, ORDER_VOLUME_CURRENT );
            init_vol= HistoryOrderGetDouble (ticket, ORDER_VOLUME_INITIAL );
           }
         //---
         switch (ord_data.state)
           {
             case ORDER_STATE_CANCELED : if (get_data)
              {
               if (ord_data.vol_init==ord_data.vol_cur)
                 {
                  ord_data.real_state=ORD_NONE_CANCELED;
                 }
               else
                 {
                  ord_data.real_state=ORD_NONE_PARTIAL_CANCELED;
                 }
              }
             else
              {
               if (init_vol==cur_vol)
                 {
                  ord_data.real_state=ORD_NONE_CANCELED;
                 }
               else
                 {
                  ord_data.real_state=ORD_NONE_PARTIAL_CANCELED;
                 }
              }
             break ;

             case ORDER_STATE_PARTIAL :  ord_data.real_state=ORD_NONE_PARTIAL;
             break ;

             case ORDER_STATE_EXPIRED :  ord_data.real_state=ORD_NONE_EXPIRED;
             break ;

             case ORDER_STATE_FILLED :   ord_data.real_state=ORD_NONE_FILLED;
             break ;

             case ORDER_STATE_REJECTED : ord_data.real_state=ORD_NONE_REJECTED;
             break ;
           }
        }
       else
       if ( OrderSelect (ticket))
        {
         if (get_data)
           {
            ord_data.comment= OrderGetString ( ORDER_COMMENT );
            ord_data.expiration= datetime ( OrderGetInteger ( ORDER_TIME_EXPIRATION ));
            ord_data.magic= OrderGetInteger ( ORDER_MAGIC );
            ord_data.pos_id= OrderGetInteger ( ORDER_POSITION_ID );
            ord_data.price_cur= OrderGetDouble ( ORDER_PRICE_CURRENT );
            ord_data.price_open= OrderGetDouble ( ORDER_PRICE_OPEN );
            ord_data.price_stlim= OrderGetDouble ( ORDER_PRICE_STOPLIMIT );
            ord_data.sl= OrderGetDouble ( ORDER_SL );
            ord_data.state= ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ));
            ord_data.symbol= OrderGetString ( ORDER_SYMBOL );
            ord_data.t_done_msc= datetime ( OrderGetInteger ( ORDER_TIME_DONE_MSC ));
            ord_data.t_set_msc = datetime ( OrderGetInteger ( ORDER_TIME_SETUP_MSC ));
            ord_data.time_done = datetime ( OrderGetInteger ( ORDER_TIME_DONE ));
            ord_data.time_setup= datetime ( OrderGetInteger ( ORDER_TIME_SETUP ));
            ord_data.tp= OrderGetDouble ( ORDER_TP );
            ord_data.type= ENUM_ORDER_TYPE ( OrderGetInteger ( ORDER_TYPE ));
            ord_data.type_filling= ENUM_ORDER_TYPE_FILLING ( OrderGetInteger ( ORDER_TYPE_FILLING ));
            ord_data.type_time= ENUM_ORDER_TYPE_TIME ( OrderGetInteger ( ORDER_TYPE_TIME ));
            ord_data.vol_cur= OrderGetDouble ( ORDER_VOLUME_CURRENT );
            ord_data.vol_init= OrderGetDouble ( ORDER_VOLUME_INITIAL );
           }
         else
           {
            ord_data.state= ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ));
           }
         //--- 
         switch (ord_data.state)
           {
             case ORDER_STATE_STARTED :
             case ORDER_STATE_REQUEST_ADD :
             case ORDER_STATE_REQUEST_MODIFY :
             case ORDER_STATE_REQUEST_CANCEL : ord_data.real_state=ORD_BUSY;
             break ;

             case ORDER_STATE_PARTIAL :        ord_data.real_state=ORD_EXIST_PARTIAL;
             break ;

             case ORDER_STATE_PLACED :         ord_data.real_state=ORD_EXIST;
             break ;
           }
        }
       else
        {
         ord_data.error_code= GetLastError ();
        }
       //---   
       if (( ord_data.error_code!= ERR_SUCCESS ) || 
         (ord_data.real_state==ORD_NOT_SPECIFIED))
        {
         return (SELECT_ERROR);
        }
       else
        {
         switch (ord_data.real_state)
           {
             case ORD_BUSY:           return (SELECT_BUSY);
             break ;

             case ORD_EXIST:
             case ORD_EXIST_PARTIAL: return (SELECT_TRUE);
             break ;

             default :                 return (SELECT_FALSE);
             break ;
           }
        }
     }
   else
     {
      ord_data.error_code=ERR_ZERO_TICKET;
       return (SELECT_ERROR);
     }
  }
//+------------------------------------------------------------------+
 

Les tests ont été effectués sur un compte réel chez le courtier "0t", terminal build 1375, sur un instrument de marché intermédiaire SILV-9.16.

Au cours de 1500 transactions (~3 heures), nous avons constaté ce qui suit :

La vitesse moyenne (à l'exception de très rares retards) était de 22 ms.

Les très rares retards d'un peu plus de 300 ms peuvent être causés par les connexions réseau.

Les développeurs l'ont probablement corrigé.

Un Expert Advisor complet et des logs de terminal au sous-sol.

Dossiers :
MT-5.zip  76 kb
 

Au fait, j'ai regardé de près le journal et je vois parfois ce qui suit :

PN      0       16:44:22.973    Test_delay (SILV-9.16,M1)       Время удаления ордера: 91.84999999999999 ms

Pourquoi, parce que le code dit d'arrondir à 2 décimales :

Print("Время удаления ордера: ",NormalizeDouble(double(stop-start)/1000,2)," ms");
 
prostotrader:

Au fait, j'ai regardé de près le journal et je vois parfois ce qui suit :

Pourquoi, parce que le code spécifie l'arrondi à 2 décimales :

Pour imprimer, vous devez utiliser la fonction permettant de convertir le double en chaîne :

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   ulong  stop=123457;
   ulong  start=123400;
   for(int i=0;i<10;i++)
     {
      stop+=i;
      Print("Время удаления ордера, old: ",NormalizeDouble(double(stop-start)/1000,2)," ms",
            ", new: ",DoubleToString((double)(stop-start)/1000.0,2)," ms");
     }
  }

et sortir le texte dans "Experts" :

2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.06 ms, new: 0.06 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.06 ms, new: 0.06 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.06 ms, new: 0.06 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.06 ms, new: 0.06 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.07000000000000001 ms, new: 0.07 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.07000000000000001 ms, new: 0.07 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.08 ms, new: 0.08 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.09 ms, new: 0.09 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.09 ms, new: 0.09 ms
2016.08.20 11:53:50.227 Test (EURUSD,D1)        Время удаления ордера, old: 0.1 ms, new: 0.10 ms
 
Dites-moi, l'ordre d'achat stop glisse-t-il sur le FORTS à l'ouverture ?
 
Евгений:
Pouvez-vous me dire si l'ordre d'achat-stop glisse sur le FORTS à l'ouverture ?

Le stop d'achat n'est pas envoyé à la bourse, mais il est "en service" sur le serveur MT5, d'où le fait que le stop d'achat ne soit pas envoyé à la bourse,

S'il y a un fort mouvement sur le marché, il peut y avoir un dérapage.