FORTS. Fragen der Durchsetzung - Seite 74

 
leonerd:
Ich verstehe, es gibt also keine Garantie für die Leistung.
Eine 100%ige Garantie gibt es auch bei einer Bank nicht. Versuchen Sie es doch einmal mit einer Politik des " Alles-oder-nichts-Vollzugs ". Nur bei Festungen scheint dieser Modus nicht zu funktionieren. Sie können auch die Liquidität des Stacks analysieren, bevor Sie direkt in den Markt einsteigen - in vielen Fällen kann dies hilfreich sein. Eine 100%ige Garantie kann es jedoch nicht geben: Der Markt kann entweder die Ausführung oder den Preis garantieren, aber nicht beides gleichzeitig. Was wichtiger ist, müssen Sie selbst entscheiden.
 

Die Sperre vonMichail Filimonow wurde offenbar auf seinen Antrag hin aufgehoben.

Mehr gibt es nicht zu sagen.

 

Lesen Sie lange und gründlich.

Es ist klar, warum der Ersteller des Themas gesperrt wurde:

Kein Mann, kein Problem.

Wurden die Verzögerungen behoben?

 
prostotrader:

Lesen Sie lange und gründlich.

Es ist klar, warum der Ersteller des Themas gesperrt wurde:

Kein Mann, kein Problem.

Wurden die Verzögerungen beseitigt?

Wer wird sie jetzt noch messen, außer ihm? Jeder hat Angst davor, gesperrt zu werden :)

 
coderex :

und wer misst sie jetzt außer ihm? alle haben angst vor dem verbot :)

Nun, zuerst müssen Sie einen Test-EA schreiben:

 //+------------------------------------------------------------------+
//|                                                   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);
     }
  }
//+------------------------------------------------------------------+
 

Die Tests wurden auf einem realen Konto beim Broker "0t", Terminal Build 1375, auf einem Instrument des mittleren Marktes SILV-9.16 durchgeführt.

Während 1500 Transaktionen (~3 Stunden) haben wir Folgendes herausgefunden:

Die durchschnittliche Geschwindigkeit (abgesehen von sehr seltenen Verzögerungen) betrug ~22ms

Die sehr seltenen Verzögerungen von etwas über 300 ms können durch Netzwerkverbindungen verursacht werden.

Wahrscheinlich haben die Entwickler das Problem behoben.

Vollständiger Expert Advisor und Terminalprotokolle im Keller.

Dateien:
MT-5.zip  76 kb
 

Übrigens, ich habe mir das Protokoll genau angesehen und manchmal sehe ich folgendes:

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

Warum? Weil der Code vorschreibt, auf 2 Dezimalstellen zu runden:

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

Übrigens, ich habe mir das Protokoll genau angesehen und manchmal sehe ich folgendes:

Warum? Weil der Code eine Rundung auf 2 Dezimalstellen vorsieht:

Um zu drucken, müssen Sie die Funktion zur Umwandlung von double in string verwenden:

//+------------------------------------------------------------------+
//| 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");
     }
  }

und geben den Text in "Experten" aus:

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
 
Sagen Sie mir, gleitet der Kauf-Stopp-Auftrag auf den FORTS, wenn er eröffnet wird?
 
Евгений:
Können Sie mir sagen, ob der Kauf-Stopp-Auftrag bei der Eröffnung des FORTS durchfällt?

Der Kaufstopp wird nicht an die Börse ausgegeben, sondern "dienstlich" auf dem MT5-Server, also,

Wenn der Markt stark in Bewegung ist, kann es zu Kursverlusten kommen.