Xóa lệnh chờ
Việc xóa một lệnh chờ được thực hiện ở cấp độ chương trình bằng thao tác TRADE_ACTION_REMOVE: hằng số này cần được gán cho trường action của cấu trúc MqlTradeRequest trước khi gọi một trong các phiên bản của hàm OrderSend. Trường duy nhất cần thiết ngoài action là order để chỉ định vé của lệnh cần xóa.
Phương thức remove trong cấu trúc ứng dụng MqlTradeRequestSync từ tệp MqlTradeSync.mqh khá đơn giản.
struct MqlTradeRequestSync : public MqlTradeRequest
{
...
bool remove(const ulong ticket)
{
if(!OrderSelect(ticket)) return false;
action = TRADE_ACTION_REMOVE;
order = ticket;
ZeroMemory(result);
return OrderSend(this, result);
}
}2
3
4
5
6
7
8
9
10
11
12
Việc kiểm tra thực tế xóa lệnh được thực hiện theo cách truyền thống trong phương thức completed.
bool completed()
{
...
else if(action == TRADE_ACTION_REMOVE)
{
result.order = order;
return result.removed(timeout);
}
...
}2
3
4
5
6
7
8
9
10
Việc chờ đợi việc xóa thực sự của lệnh được thực hiện trong phương thức removed của cấu trúc MqlTradeResultSync.
struct MqlTradeResultSync : public MqlTradeResult
{
...
bool removed(const ulong msc = 1000)
{
if(retcode != TRADE_RETCODE_DONE)
{
return false;
}
if(!wait(orderRemoved, msc))
{
Print("Order removal timeout: #=" + (string)order);
return false;
}
return true;
}
static bool orderRemoved(MqlTradeResultSync &ref)
{
return !OrderSelect(ref.order) && HistoryOrderSelect(ref.order);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Ví dụ về Expert Advisor (PendingOrderDelete.mq5) thể hiện việc xóa một lệnh sẽ được xây dựng hầu như hoàn toàn dựa trên PendingOrderSend.mq5. Điều này là do việc đảm bảo sự tồn tại của một lệnh trước khi xóa sẽ dễ dàng hơn. Do đó, ngay sau khi khởi động, Expert Advisor sẽ tạo một lệnh mới với các tham số đã chỉ định. Sau đó, lệnh sẽ được xóa trong trình xử lý OnDeinit. Nếu bạn thay đổi các tham số đầu vào của Expert Advisor, ký hiệu hoặc khung thời gian biểu đồ, lệnh cũ cũng sẽ bị xóa và một lệnh mới sẽ được tạo.
Biến toàn cục OwnOrder đã được thêm vào để lưu trữ vé của lệnh. Nó được điền vào kết quả của lời gọi PlaceOrder (bản thân hàm này không thay đổi).
ulong OwnOrder = 0;
void OnTimer()
{
// thực thi mã một lần cho các tham số hiện tại
EventKillTimer();
const string symbol = StringLen(Symbol) == 0 ? _Symbol : Symbol;
OwnOrder = PlaceOrder((ENUM_ORDER_TYPE)Type, symbol, Volume,
Distance2SLTP, Expiration, Until, Magic, Comment);
}2
3
4
5
6
7
8
9
10
11
Đây là hàm xóa đơn giản RemoveOrder, tạo đối tượng request và lần lượt gọi các phương thức remove và completed cho nó.
void OnDeinit(const int)
{
if(OwnOrder != 0)
{
RemoveOrder(OwnOrder);
}
}
void RemoveOrder(const ulong ticket)
{
MqlTradeRequestSync request;
if(request.remove(ticket) && request.completed())
{
Print("OK order removed");
}
Print(TU::StringOf(request));
Print(TU::StringOf(request.result));
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Nhật ký sau đây hiển thị các mục xuất hiện do việc đặt Expert Advisor trên biểu đồ EURUSD, sau đó ký hiệu được chuyển sang XAUUSD, và sau đó Expert Advisor bị xóa.
(EURUSD,H1) Autodetected daily range: 0.0094
(EURUSD,H1) OK order placed: #=1284920879
(EURUSD,H1) TRADE_ACTION_PENDING, EURUSD, ORDER_TYPE_BUY_STOP, V=0.01, ORDER_FILLING_FOK, »
» @ 1.11011, ORDER_TIME_GTC, M=1234567890
(EURUSD,H1) DONE, #=1284920879, V=0.01, Request executed, Req=1
(EURUSD,H1) OK order removed
(EURUSD,H1) TRADE_ACTION_REMOVE, EURUSD, ORDER_TYPE_BUY, ORDER_FILLING_FOK, #=1284920879
(EURUSD,H1) DONE, #=1284920879, Request executed, Req=2
(XAUUSD,H1) Autodetected daily range: 47.45
(XAUUSD,H1) OK order placed: #=1284921672
(XAUUSD,H1) TRADE_ACTION_PENDING, XAUUSD, ORDER_TYPE_BUY_STOP, V=0.01, ORDER_FILLING_FOK, »2
3
4
5
6
7
8
9
10
11
Chúng ta sẽ xem xét một ví dụ khác về việc xóa lệnh để thực hiện chiến lược "One Cancel Other" (OCO) trong phần sự kiện OnTrade.
