Quy tắc hết hạn của lệnh chờ
Khi làm việc với các lệnh chờ (bao gồm cả mức Stop Loss
và Take Profit
), một chương trình MQL cần kiểm tra một vài thuộc tính xác định quy tắc hết hạn của chúng. Cả hai thuộc tính này đều có sẵn dưới dạng thành viên của liệt kê ENUM_SYMBOL_INFO_INTEGER
để gọi hàm SymbolInfoInteger
(SymbolInfoInteger).
Định danh | Mô tả |
---|---|
SYMBOL_EXPIRATION_MODE | Các cờ của các chế độ hết hạn lệnh được phép (mặt nạ bit) |
SYMBOL_ORDER_GTC_MODE | Thời hạn hiệu lực được xác định bởi một trong các phần tử của liệt kê ENUM_SYMBOL_ORDER_GTC_MODE |
Thuộc tính SYMBOL_ORDER_GTC_MODE
chỉ được tính đến nếu SYMBOL_EXPIRATION_MODE
chứa SYMBOL_EXPIRATION_GTC
(xem thêm phía dưới). GTC là viết tắt của "Good Till Canceled" (Hiệu lực cho đến khi bị hủy).
Đối với mỗi công cụ tài chính, thuộc tính SYMBOL_EXPIRATION_MODE
có thể chỉ định một số chế độ hiệu lực (hết hạn) của các lệnh chờ. Mỗi chế độ có một cờ (bit) liên quan đến nó.
Định danh (Giá trị) | Mô tả |
---|---|
SYMBOL_EXPIRATION_GTC (1) | Lệnh có hiệu lực theo thuộc tính ENUM_SYMBOL_ORDER_GTC_MODE |
SYMBOL_EXPIRATION_DAY (2) | Lệnh có hiệu lực đến cuối ngày hiện tại |
SYMBOL_EXPIRATION_SPECIFIED (4) | Ngày và giờ hết hạn được chỉ định trong lệnh |
SYMBOL_EXPIRATION_SPECIFIED_DAY (8) | Ngày hết hạn được chỉ định trong lệnh |
Các cờ có thể được kết hợp bằng phép toán OR logic (|
), ví dụ: SYMBOL_EXPIRATION_GTC | SYMBOL_EXPIRATION_SPECIFIED
, tương đương với 1 | 4
, tức là số 5. Để kiểm tra xem một chế độ cụ thể có được bật cho một công cụ hay không, thực hiện phép toán AND logic (&
) trên kết quả hàm và bit chế độ mong muốn: giá trị khác 0 nghĩa là chế độ đó có sẵn.
Trong trường hợp SYMBOL_EXPIRATION_SPECIFIED_DAY
, lệnh có hiệu lực đến 23:59:59 của ngày được chỉ định. Nếu thời gian này không rơi vào phiên giao dịch, việc hết hạn sẽ xảy ra vào thời điểm giao dịch gần nhất tiếp theo.
Liệt kê ENUM_SYMBOL_ORDER_GTC_MODE
bao gồm các thành viên sau.
Định danh | Mô tả |
---|---|
SYMBOL_ORDERS_GTC | Các lệnh chờ và mức Stop Loss /Take Profit có hiệu lực vô thời hạn cho đến khi được hủy rõ ràng |
SYMBOL_ORDERS_DAILY | Các lệnh chỉ có hiệu lực trong một ngày giao dịch: khi ngày kết thúc, tất cả lệnh chờ bị xóa, cùng với mức Stop Loss và Take Profit |
SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS | Khi thay đổi ngày giao dịch, chỉ các lệnh chờ bị xóa, nhưng mức Stop Loss và Take Profit được giữ lại |
Tùy thuộc vào các bit được đặt trong thuộc tính SYMBOL_EXPIRATION_MODE
, khi chuẩn bị một lệnh để gửi, chương trình MQL có thể chọn một trong các chế độ tương ứng với các bit này. Về mặt kỹ thuật, điều này được thực hiện bằng cách điền vào trường type_time
trong cấu trúc đặc biệt MqlTradeRequest
(MqlTradeRequest) trước khi gọi hàm OrderSend
(OrderSend). Giá trị trường phải là một phần tử của liệt kê ENUM_ORDER_TYPE_TIME
(xem Ngày hết hạn của lệnh chờ): như chúng ta sẽ thấy sau, nó có điểm chung với tập hợp cờ trên, tức là mỗi cờ đặt chế độ tương ứng trong lệnh: ORDER_TIME_GTC
, ORDER_TIME_DAY
, ORDER_TIME_SPECIFIED
, ORDER_TIME_SPECIFIED_DAY
. Thời gian hoặc ngày hết hạn phải được chỉ định trong một trường khác của cùng cấu trúc.
Kịch bản SymbolFilterExpiration.mq5
cho phép tìm hiểu thống kê về việc sử dụng từng cờ trong các ký hiệu có sẵn (trong tổng quan thị trường hoặc tổng thể, tùy thuộc vào tham số đầu vào UseMarketWatch
). Tham số thứ hai trong ShowPerSymbolDetails
, khi được đặt thành true
, sẽ khiến tất cả các cờ cho mỗi ký hiệu được ghi lại, vì vậy hãy cẩn thận: nếu đồng thời chế độ UseMarketWatch
bằng false
, một số lượng rất lớn các mục nhật ký sẽ được tạo ra.
#property script_show_inputs
#include <MQL5Book/SymbolFilter.mqh>
input bool UseMarketWatch = false;
input bool ShowPerSymbolDetails = false;
2
3
4
5
6
Trong hàm OnStart
, ngoài đối tượng bộ lọc và các mảng nhận cho tên ký hiệu và giá trị thuộc tính, chúng ta mô tả MapArray
để tính toán thống kê riêng cho từng thuộc tính SYMBOL_EXPIRATION_MODE
và SYMBOL_ORDER_GTC_MODE
.
void OnStart()
{
SymbolFilter f; // đối tượng bộ lọc
string symbols[]; // mảng nhận cho tên ký hiệu
long flags[][2]; // mảng nhận cho giá trị thuộc tính
MapArray<SYMBOL_EXPIRATION,int> stats; // bộ đếm chế độ
MapArray<ENUM_SYMBOL_ORDER_GTC_MODE,int> gtc; // bộ đếm GTC
ENUM_SYMBOL_INFO_INTEGER ints[] =
{
SYMBOL_EXPIRATION_MODE,
SYMBOL_ORDER_GTC_MODE
};
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Tiếp theo, áp dụng bộ lọc và tính toán thống kê.
f.select(UseMarketWatch, ints, symbols, flags);
const int n = ArraySize(symbols);
for(int i = 0; i < n; ++i)
{
if(ShowPerSymbolDetails)
{
Print(symbols[i] + ":");
for(int j = 0; j < ArraySize(ints); ++j)
{
// thuộc tính dưới dạng mô tả và số
PrintFormat(" %s (%d)",
SymbolMonitor::stringify(flags[i][j], ints[j]),
flags[i][j]);
}
}
const SYMBOL_EXPIRATION mode = (SYMBOL_EXPIRATION)flags[i][0];
for(int j = 0; j < 4; ++j)
{
const SYMBOL_EXPIRATION bit = (SYMBOL_EXPIRATION)(1 << j);
if((mode & bit) != 0)
{
stats.inc(bit);
}
if(bit == SYMBOL_EXPIRATION_GTC)
{
gtc.inc((ENUM_SYMBOL_ORDER_GTC_MODE)flags[i][1]);
}
}
}
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Cuối cùng, chúng ta xuất các số nhận được vào nhật ký.
PrintFormat("===== Chế độ hết hạn cho các ký hiệu %s =====",
(UseMarketWatch ? "Market Watch" : "tất cả có sẵn"));
PrintFormat("Tổng số ký hiệu: %d", n);
Print("Thống kê theo chế độ hết hạn:");
stats.print();
Print("Chú thích: khóa=chế độ hết hạn, giá trị=số lượng");
for(int i = 0; i < stats.getSize(); ++i)
{
PrintFormat("%d -> %s", stats.getKey(i), EnumToString(stats.getKey(i)));
}
Print("Thống kê theo chế độ GTC:");
gtc.print();
Print("Chú thích: khóa=chế độ GTC, giá trị=số lượng");
for(int i = 0; i < gtc.getSize(); ++i)
{
PrintFormat("%d -> %s", gtc.getKey(i), EnumToString(gtc.getKey(i)));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Hãy chạy kịch bản hai lần. Lần đầu tiên, với cài đặt mặc định, chúng ta có thể nhận được kết quả như sau.
===== Chế độ hết hạn cho tất cả các ký hiệu có sẵn =====
Tổng số ký hiệu: 52357
Thống kê theo chế độ hết hạn:
[key] [value]
[0] 1 52357
[1] 2 52357
[2] 4 52357
[3] 8 52303
Chú thích: khóa=chế độ hết hạn, giá trị=số lượng
1 -> _SYMBOL_EXPIRATION_GTC
2 -> _SYMBOL_EXPIRATION_DAY
4 -> _SYMBOL_EXPIRATION_SPECIFIED
8 -> _SYMBOL_EXPIRATION_SPECIFIED_DAY
Thống kê theo chế độ GTC:
[key] [value]
[0] 0 52357
Chú thích: khóa=chế độ GTC, giá trị=số lượng
0 -> SYMBOL_ORDERS_GTC
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ở đây bạn có thể thấy rằng hầu hết các cờ đều được phép cho phần lớn các ký hiệu, và đối với chế độ SYMBOL_EXPIRATION_GTC
, chỉ có biến thể SYMBOL_ORDERS_GTC
được sử dụng.
Chạy kịch bản lần thứ hai bằng cách đặt UseMarketWatch
và ShowPerSymbolDetails
thành true
(giả định rằng một số lượng ký hiệu hạn chế được chọn trong Market Watch
).
GBPUSD:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
SYMBOL_ORDERS_GTC (0)
USDCHF:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
SYMBOL_ORDERS_GTC (0)
USDJPY:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
SYMBOL_ORDERS_GTC (0)
...
XAUUSD:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
_SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
SYMBOL_ORDERS_GTC (0)
SP500m:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
_SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
SYMBOL_ORDERS_GTC (0)
UK100:
[ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
_SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
SYMBOL_ORDERS_GTC (0)
===== Chế độ hết hạn cho các ký hiệu Market Watch =====
Tổng số ký hiệu: 15
Thống kê theo chế độ hết hạn:
[key] [value]
[0] 1 15
[1] 2 15
[2] 4 15
[3] 8 6
Chú thích: khóa=chế độ hết hạn, giá trị=số lượng
1 -> _SYMBOL_EXPIRATION_GTC
2 -> _SYMBOL_EXPIRATION_DAY
4 -> _SYMBOL_EXPIRATION_SPECIFIED
8 -> _SYMBOL_EXPIRATION_SPECIFIED_DAY
Thống kê theo chế độ GTC:
[key] [value]
[0] 0 15
Chú thích: khóa=chế độ GTC, giá trị=số lượng
0 -> SYMBOL_ORDERS_GTC
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Trong số 15 ký hiệu được chọn, chỉ có 6 ký hiệu có cờ SYMBOL_EXPIRATION_SPECIFIED_DAY
được đặt. Chi tiết về các cờ cho mỗi ký hiệu có thể được tìm thấy ở trên.