# 接受SL/TP订单

```#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 (Reason == ORDER_REASON_TP)
else
}
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)));
}```

### 脚本。

```// Скрипт выводит самое длительное или конкретное акцептирование 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));
}```

```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
------------------------```

### 底线。

fxsaber:

```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秒的滞后!在这些情况下，可能最好已经联系了经纪人。

```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的另一个大脑爆炸。我甚至不知道该说什么。

- 经受住开发商的一连串批评，并证明滞后已经发生（考虑到你可能不知道的事情，例如，经纪人的服务器硬件）

- 说服你，这是很关键的

- 等待修复

- 热心地推动经纪人升级到最新的版本，这可能比前面所有的项目都要难得多。

```ServerName: RannForex-Server
Accepted Length = 28894 ms.```

Andrey Khatimlianskii:

...经纪人的服务器可以是你想要的任何东西，也可能是交流区中关于滞后的主题链接，我们只能猜测。

Andrei Trukhanovich:

- 你将不得不承受来自开发商的一连串批评，并证明滞后的发生（考虑到你可能不知道的细微差别，例如，经纪人的服务器部分的硬件）。

fxsaber, 2020.11.25 00:47

MQ-Demo 上运行的结果。

```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```