SL/TP siparişlerinin kabulü

 

Bu başlık , açık pozisyonların SL / TP seviyelerini tetiklemenin bir sonucu olarak oluşturulan emirler hakkında konuşacaktır .

Belirli bir SL/TP siparişi için tetikleyici olan bir onay işareti almak için karmaşık ancak çalışan bir işlev yazılmıştır.

 #define SEARCH_TICK(A, B)                             \
{                                                     \
   if (!(Ticks[Pos]. ##A B Price) && ((Pos <= 1 ) ||     \
      (!StopLevel && (Ticks[Pos - 1 ]. ##A == Price)))) \
    Tick = Ticks[Pos];                                \
   else                                                 \
  {                                                   \
     while ((Pos >= 0 ) && !(Ticks[Pos]. ##A B Price))   \
      Tick = Ticks[Pos--];                            \
                                                      \
     if (!Tick.time)                                   \
    {                                                 \
       while ((Pos >= 0 ) && (Ticks[Pos]. ##A B Price))  \
        Pos--;                                        \
                                                      \
       while ((Pos >= 0 ) && !(Ticks[Pos]. ##A B Price)) \
        Tick = Ticks[Pos--];                          \
    }                                                 \
  }                                                   \
}

// Получение тика, который акцептировал TP/SL-ордер.
bool GetAcceptedTick( const ulong Ticket, MqlTick &Tick, const bool PrintFlag = false )
{
   bool Res = false ;

   if (! IsStopped () && HistoryOrderSelect2(Ticket))
  {
     const ENUM_ORDER_REASON Reason = ( ENUM_ORDER_REASON ) HistoryOrderGetInteger (Ticket, ORDER_REASON );

     if ((Reason == ORDER_REASON_TP ) || (Reason == ORDER_REASON_SL ))
    {
       const long CreateTime = HistoryOrderGetInteger (Ticket, ORDER_TIME_SETUP_MSC );
       const long DoneTime = HistoryOrderGetInteger (Ticket, ORDER_TIME_DONE_MSC );
       const string Symb = HistoryOrderGetString (Ticket, ORDER_SYMBOL );
       const ENUM_ORDER_STATE State = ( ENUM_ORDER_STATE ) HistoryOrderGetInteger (Ticket, ORDER_STATE );
       const ENUM_ORDER_TYPE Type = ( ENUM_ORDER_TYPE ) HistoryOrderGetInteger (Ticket, ORDER_TYPE );
       const double Price = HistoryOrderGetDouble (Ticket, ORDER_PRICE_OPEN );

       const ulong TicketOpen = HistoryOrderGetInteger (Ticket, ORDER_POSITION_ID );

       if ( SymbolInfoInteger (Symb, SYMBOL_EXIST ) && TicketOpen && HistoryOrderSelect2(TicketOpen))
      {
       #define TOSTRING(A) ", " + #A + " = " + ( string )(A)
         const int digits = ( int ) SymbolInfoInteger (Symb, SYMBOL_DIGITS );

         const int StopLevel = ( int ) SymbolInfoInteger (Symb, SYMBOL_TRADE_STOPS_LEVEL );
         long PositionCreated = HistoryOrderGetInteger (TicketOpen, ORDER_TIME_DONE_MSC );
        
         // Условие может сработать при частичном исполнении.
         if ((PositionCreated >= CreateTime) && HistorySelectByPosition (TicketOpen) && HistoryDealsTotal ())
        {
          PositionCreated = HistoryDealGetInteger ( HistoryDealGetTicket ( 0 ), DEAL_TIME_MSC );
          
           HistoryOrderSelect (TicketOpen); // Не HistoryOrderSelect2, т.к. нужно HistoryOrdersTotal() <= 1.
        }

       #define HOUR ( 3600 * 1000 )
         long From = MathMax (PositionCreated,     // Время открытия позиции
                            CreateTime - HOUR); // Час - просто с запасом.

         MqlTick Ticks[];

         ResetLastError ();
         int Pos = CopyTicksRange (Symb, Ticks, COPY_TICKS_INFO , From, CreateTime) - 1 ;

         if ((Pos < 0 ) && ! _LastError && (From == PositionCreated))
          Pos = CopyTicksRange (Symb, Ticks, COPY_TICKS_INFO , From -= HOUR, CreateTime) - 1 ;

         if (Pos >= 0 )
        {
           const MqlTick LastTick = Ticks[Pos];

          Tick.time = 0 ;

           if (Type == ORDER_TYPE_BUY )
          {
             if (Reason == ORDER_REASON_TP )
              SEARCH_TICK(ask, >)
             else
              SEARCH_TICK(ask, <)
          }
           else if (Reason == ORDER_REASON_TP )
            SEARCH_TICK(bid, <)
           else
            SEARCH_TICK(bid, >)

           if (!(Res = /*(Pos >= 0) && */ Tick.time))
             Alert ( __FUNCSIG__ + ": Error!" ); // Ошибка при расчетах
           else if (PrintFlag) // Выводим найденный тик.
          {
             Print ( "Last Tick " + TickToString(LastTick, digits));

             Print ( "Accepted Tick " + TickToString(Tick, digits));
             Print ( "Accepted Length = " + ( string )(CreateTime - Tick.time_msc) + " ms." );
          }
        }
         else // В случае ошибки CopyTicks - сообщаем.
           Alert ( __FUNCSIG__ + ": CopyTicksRange(" + Symb + ", " + TimeToString (From) + ", " +
                                                 TimeToString (CreateTime) + ") = " + ( string )(Pos + 1 ) + TOSTRING( _LastError ));

         if (PrintFlag || !Res) // Распечатываем данные ордера.
           Print ( "Order " + ( string )Ticket + " " + EnumToString (Type) + " " + Symb + " " + TimeToString (CreateTime) + " " +
                           DoubleToString (Price, digits) + " " + EnumToString (Reason) + " " + EnumToString (State) + " " +
                           TimeToString (DoneTime) + ", Position " + ( string )TicketOpen + " created " +
                           TimeToString (PositionCreated) + TOSTRING(StopLevel) + "\n" );
      }
    }
  }

   return (Res);
}

// Преобразование времени в миллисекундах в строку.
string TimeToString ( const long time, const int FlagTime = TIME_DATE | TIME_SECONDS )
{
   return ( TimeToString (( datetime )time / 1000 , FlagTime) + "." + IntegerToString (time % 1000 , 3 , '0' ));
}

// Преобразование тика в строку.
string TickToString( const MqlTick &Tick, const int digits )
{
   return ( TimeToString (Tick.time_msc) + " " + DoubleToString (Tick.bid, digits) + " " + DoubleToString (Tick.ask, digits));
}

// Правильный выбор исторического ордера.
bool HistoryOrderSelect2( const ulong Ticket)
{
   return ((( HistoryOrderGetInteger (Ticket, ORDER_TICKET ) == Ticket) || HistoryOrderSelect (Ticket)));
}


Bu harika özelliğin uygulanması, bu dalın yaratılmasının nedeniydi. Koddaki tüm hataları yakalamadığımdan eminim, ancak tarih adına ve bunun gerçekten kolay olmadığını anlamak için tam bir liste verdim.

 

TP emirlerinin yerine getirilmesi konularını incelerken, bazı TP emirlerinin, onları kabul eden onay işaretlerinin önemli ölçüde gerisinde bırakılarak oluşturulduğunu fark ettim.

Bilgilendirme, bu durumun sadece farklı brokerlerde değil, İşlem Sunucusu ile aynı makinede bulunan Terminal'de ticaretin gerçekleştiği bir durumda da tekrarlandığını gösterdi. Onlar. çok düşük ping ve Ticaret Sunucusu için tek ticaret hesabı ile.



GetAcceptedTick işlevini yazmak, sorunu kapsamlı bir şekilde incelememize ve sorunu yapıcı bir şekilde göstermemize izin verdi.


Senaryo.

Yani, fragmanda aşağıdaki senaryo yatıyor.

 // Скрипт выводит самое длительное или конкретное акцептирование SL/TP-ордера.
#property script_show_inputs

input datetime inFrom = D'2020.01.01' ; // С какого времени проверять ордера
input ulong inTicket = 0 ;               // Отдельно проверяемый тикет

// Возвращает самый медленный TP/SL-ордер с определенной даты.
ulong GetSlowestOrder( const datetime From );

// Распечатывает подробности акцепта SL/TP-ордера.
void PrintOrder( const ulong MaxTicket );

void OnStart ()
{
   Print ( "\n\nStart " + MQLInfoString ( MQL_PROGRAM_NAME ) + TOSTRING(inFrom) + TOSTRING(inTicket) + "\n" );
  
  PrintOrder(inTicket ? inTicket : GetSlowestOrder(inFrom));
}


MQ-Demo'da çalıştırmanın sonucu.

Total Orders (from 2020.09 . 01 00 : 00 : 00 ) = 58493 , calculated = 439
Calculation time = 00 : 00 : 11.328 , Performance = 38.0 orders/sec.

ServerName: MetaQuotes-Demo

Last Tick 2020.09 . 30 19 : 07 : 32.917 1.80181 1.80205
Accepted Tick 2020.09 . 30 19 : 07 : 32.716 1.80178 1.80202
Accepted Length = 357 ms.
Order 726444166 ORDER_TYPE_BUY GBPAUD 2020.09 . 30 19 : 07 : 33.073 1.80206 ORDER_REASON_TP ORDER_STATE_FILLED 2020.09 . 30 19 : 07 : 33.082 , Position created 2020.09 . 30 17 : 21 : 17.933 , StopLevel = 0

Orders ( 2 ) before 726444166 with PositionID = 725926764 :
------------------------
Checked Orders = 0
------------------------


Komut dosyası, bir TP siparişi ve bunun oluşturulmasını tetikleyen onay işareti (metinde vurgulanmıştır) bulduğunu iddia ediyor. Bir alım satım sunucusunda (özellikle bir demoda) fiyat açık pozisyonun TP seviyesine ulaştıysa, hemen karşılık gelen bir TP emri oluşturulmalıdır (mutlaka yürütülmez). Ancak bu durumda bu anında değil, 357 milisaniye sonra oldu!


Bir milisaniyelik bir gecikmenin bile yeterli olmadığını şimdiden söyleyeyim. Zamanında olmak, algoritmik ticarette önemli bir fiildir.


muayene

Komut dosyasına körü körüne güvenmeyeceğiz, ancak bu durumu manuel olarak kontrol edeceğiz. İşte siparişimiz.


Ve burada, komut dosyası tarafından bulunan ilgili kabul eden onay işaretini görebilirsiniz.


Ok, hangi tikler arasında bir TP siparişinin oluşturulduğunu gösterir. Ekran görüntüleri, betiğin doğru olduğunu ve TP emrinin oluşturulmasının Ticaret Sunucusu tarafında büyük bir gecikmeyle gerçekleştiğini açıkça gösteriyor.


Sonuç.

Artık TP/SL seviyelerinde işlem yaparken Trade Server tarafında fren miktarını gösteren bir araç var. Şu anda çok büyükler. Ve bu kesinlikle düzeltilmesi gereken platformun ciddi bir eksi.

Ne yazık ki, yeminli ifadelerin kabulü tespit edilememektedir, çünkü. bu bilgi Terminal tarafında mevcut değildir. Ancak neredeyse ironik bir şekilde, TP/SL siparişlerinin önemli gecikmelerinin varlığı, ertelemelerin uygulanması sırasında gecikmeleri etkileyemez. Çünkü nedeni aynı nitelikte gibi görünüyor.


Genel olarak, MT5 platformu şu anda özellikle bu durumlarda %100 yavaşlıyor. Ve sıfır gecikme olana kadar düzeltmeler gerektirir.


Sonuçları hesaplarınızdan paylaşmanızı rica ediyorum. MT5'in geliştirilmesine katkıda bulunun!

Dosyalar:
 
fxsaber :

Sonuçları hesaplarınızdan paylaşmanızı rica ediyorum. MT5'in geliştirilmesine katkıda bulunun!

Total Orders (from 2020.11 . 01 00 : 00 : 00 ) = 21725 , calculated = 10465
Calculation time = 00 : 04 : 33.609 , Performance = 38.0 orders/sec.

ServerName: RannForex-Server

Last Tick 2020.11 . 16 00 : 34 : 35.201 104.630 104.640
Accepted Tick 2020.11 . 16 00 : 34 : 06.309 104.627 104.639
Accepted Length = 28894 ms.
Order 1715452 ORDER_TYPE_SELL USDJPY 2020.11 . 16 00 : 34 : 35.203 104.627 ORDER_REASON_TP ORDER_STATE_REJECTED 2020.11 . 16 00 : 34 : 35.217 , Position created 2020.11 . 16 00 : 33 : 51.196 , StopLevel = 0

Orders ( 4 ) before 1715452 with PositionID = 1715287 :
-----------------------
Last Tick 2020.11 . 16 00 : 34 : 06.309 104.627 104.639
Accepted Tick 2020.11 . 16 00 : 34 : 06.309 104.627 104.639
Accepted Length = 3 ms.
Order 1715425 ORDER_TYPE_SELL USDJPY 2020.11 . 16 00 : 34 : 06.312 104.625 ORDER_REASON_TP ORDER_STATE_REJECTED 2020.11 . 16 00 : 34 : 06.327 , Position created 2020.11 . 16 00 : 33 : 51.196 , StopLevel = 0

Checked Orders = 1
------------------------

28 saniye gecikme! Muhtemelen, bu gibi durumlarda bir komisyoncu ile iletişime geçmek zaten daha iyidir.

 
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) ServerName: ICMarkets-MT5
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) 
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) Last Tick 2020.11.24 23:00:49.327 1.33569 1.33570
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) Accepted Tick 2020.11.24 23:00:49.327 1.33569 1.33570
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) Accepted Length = 7 ms.
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) Order 106887648 ORDER_TYPE_BUY GBPUSD 2020.11.24 23:00:49.334 1.33572 ORDER_REASON_TP ORDER_STATE_FILLED 2020.11.24 23:00:49.830, Position created 2020.11.24 22:57:47.071, StopLevel = 0
2020.11.25 02:42:17.718 CheckOrders (EURUSD,H1) 
2020.11.25 02:42:17.719 CheckOrders (EURUSD,H1) Orders (2) before 106887648 with PositionID = 106886713:
2020.11.25 02:42:17.719 CheckOrders (EURUSD,H1) ------------------------
2020.11.25 02:42:17.719 CheckOrders (EURUSD,H1) Checked Orders = 0
2020.11.25 02:42:17.719 CheckOrders (EURUSD,H1) ------------------------
2020.11.25 02:47:22.624 CheckOrders (EURUSD,H1) ServerName: ICMarkets-MT5
2020.11.25 02:47:22.624 CheckOrders (EURUSD,H1) 
2020.11.25 02:47:22.633 CheckOrders (EURUSD,H1) Last Tick 2020.11.18 12:44:37.354 1.18748 1.18748
2020.11.25 02:47:22.633 CheckOrders (EURUSD,H1) Accepted Tick 2020.11.18 12:44:37.354 1.18748 1.18748
2020.11.25 02:47:22.633 CheckOrders (EURUSD,H1) Accepted Length = 17 ms.
2020.11.25 02:47:22.633 CheckOrders (EURUSD,H1) Order 105637485 ORDER_TYPE_SELL EURUSD 2020.11.18 12:44:37.371 1.18749 ORDER_REASON_SL ORDER_STATE_FILLED 2020.11.18 12:44:37.476, Position created 2020.11.17 22:24:15.116, StopLevel = 0
2020.11.25 02:47:22.633 CheckOrders (EURUSD,H1) 
2020.11.25 02:47:22.634 CheckOrders (EURUSD,H1) Orders (2) before 105637485 with PositionID = 105516718:
2020.11.25 02:47:22.634 CheckOrders (EURUSD,H1) ------------------------
2020.11.25 02:47:22.634 CheckOrders (EURUSD,H1) Checked Orders = 0
2020.11.25 02:47:22.634 CheckOrders (EURUSD,H1) ------------------------
 
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) ServerName: OctaFX-Real
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) 
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) Last Tick 2020.11.23 18:14:35.081 1.18108 1.18115
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) Accepted Tick 2020.11.23 18:14:35.081 1.18108 1.18115
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) Accepted Length = 11 ms.
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) Order 8950107 ORDER_TYPE_SELL EURUSD 2020.11.23 18:14:35.092 1.18105 ORDER_REASON_TP ORDER_STATE_FILLED 2020.11.23 18:14:35.104, Position created 2020.11.23 18:11:38.678, StopLevel = 20
2020.11.25 02:50:58.687 CheckOrders (EURUSD,H1) 
2020.11.25 02:50:58.688 CheckOrders (EURUSD,H1) Orders (2) before 8950107 with PositionID = 8950014:
2020.11.25 02:50:58.688 CheckOrders (EURUSD,H1) ------------------------
2020.11.25 02:50:58.688 CheckOrders (EURUSD,H1) Checked Orders = 0
2020.11.25 02:50:58.688 CheckOrders (EURUSD,H1) ------------------------
 
2020.11.25 02:54:37.912 CheckOrders (EURUSD,H1) ServerName: Pepperstone-MT5-Live01
2020.11.25 02:54:37.912 CheckOrders (EURUSD,H1) 
2020.11.25 02:54:37.934 CheckOrders (EURUSD,H1) Last Tick 2020.09.03 01:00:02.426 106.199 106.199
2020.11.25 02:54:37.934 CheckOrders (EURUSD,H1) Accepted Tick 2020.09.03 01:00:02.426 106.199 106.199
2020.11.25 02:54:37.934 CheckOrders (EURUSD,H1) Accepted Length = 4 ms.
2020.11.25 02:54:37.934 CheckOrders (EURUSD,H1) Order 18982771 ORDER_TYPE_SELL USDJPY 2020.09.03 01:00:02.430 106.191 ORDER_REASON_TP ORDER_STATE_FILLED 2020.09.03 01:00:02.466, Position created 2020.09.02 22:57:47.081, StopLevel = 0
2020.11.25 02:54:37.934 CheckOrders (EURUSD,H1) 
2020.11.25 02:54:37.935 CheckOrders (EURUSD,H1) Orders (2) before 18982771 with PositionID = 18975080:
2020.11.25 02:54:37.935 CheckOrders (EURUSD,H1) ------------------------
2020.11.25 02:54:37.935 CheckOrders (EURUSD,H1) Checked Orders = 0
2020.11.25 02:54:37.935 CheckOrders (EURUSD,H1) ------------------------
 

fxsaber'dan bir beyin patlaması daha. Ne diyeceğimi bilmiyorum.

Bence işe yarayan tek çözüm, komisyoncuyla birlikte bir darboğaz bulmak ve mümkünse düzeltmeye çalışmak.

düzenli bir düzeltme için yapmanız gerekecek

- geliştiricilerden gelen bir eleştiri telaşına katlanın ve gecikmenin gerçekleştiğini kanıtlayın (örneğin, komisyoncunun sunucu bölümünün donanımını bilemeyeceğiniz nüansları dikkate alarak)

- kritik olduğundan emin olun

- düzeltmeyi bekleyin

- önceki tüm noktalardan çok daha zor olabilen sunucu bölümünü en son yapıya güncellemek için aracıyı özenle tekmelemek.

 
peki, hackneyed MT HFT için değil)
 
ServerName: RannForex-Server
Accepted Length = 28894 ms.

Burada, onunla ticaret yaptığınız çok havalı komisyoncu teknolojilerine dair ciddi bir şüphe var.

Limitlerin özel işlenmesi için eklentilerde bir şey yavaşlıyor.

 
Andrey Khatimlianskii :

Burada, onunla ticaret yaptığınız çok havalı komisyoncu teknolojilerine dair ciddi bir şüphe var.

... veya değişim bölümündeki gecikmelerle ilgili konuyu tekrarlar, yalnızca tahmin edebiliriz. sunuculardaki her komisyoncu her şeye sahip olabilir

 
Andrei Trukhanovich :

düzenli bir düzeltme için yapmanız gerekecek

- geliştiricilerden gelen bir eleştiri telaşına katlanın ve gecikmenin gerçekleştiğini kanıtlayın (örneğin, komisyoncunun sunucu bölümünün donanımını bilemeyeceğiniz nüansları dikkate alarak)

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

SL/TP siparişlerinin kabulü

fxsaber , 2020.11.25 00:47

MQ-Demo üzerinde çalıştırmanın sonucu.

Total Orders (from 2020.09 . 01 00 : 00 : 00 ) = 58493 , calculated = 439
Calculation time = 00 : 00 : 11.328 , Performance = 38.0 orders/sec.

ServerName: MetaQuotes-Demo


Başka bir başlıkta, Terminal'in bile çok sayıda faktörden yavaşladığı defalarca belirtildi. Sonuç olarak, çok daha karmaşık bir Ticaret Sunucusu daha da yavaşlayacaktır. Bununla birlikte, algoritmik optimizasyonun hala mümkün olduğunu umuyorum. 5 ms gecikme bile zaten çok kötü. Yüzlerce milisaniye hakkında ne söyleyebiliriz.