Quyền giao dịch
Tiếp nối chủ đề liên quan đến việc chuẩn bị đúng các lệnh giao dịch mà chúng ta đã bắt đầu trong phần trước, hãy chuyển sang cặp thuộc tính sau đây đóng vai trò rất quan trọng trong việc phát triển Expert Advisors.
Định danh | Mô tả |
---|---|
SYMBOL_TRADE_MODE | Quyền cho các chế độ giao dịch khác nhau của ký hiệu (xem ENUM_SYMBOL_TRADE_MODE) |
SYMBOL_ORDER_MODE | Cờ của các loại lệnh được phép, mặt nạ bit (xem thêm) |
Cả hai thuộc tính đều thuộc kiểu số nguyên và có thể truy cập thông qua hàm SymbolInfoInteger
.
Chúng ta đã sử dụng thuộc tính SYMBOL_TRADE_MODE
trong kịch bản SymbolPermissions.mq5
. Giá trị của nó là một trong những phần tử của liệt kê ENUM_SYMBOL_TRADE_MODE
.
Định danh | Giá trị | Mô tả |
---|---|---|
SYMBOL_TRADE_MODE_DISABLED | 0 | Giao dịch bị vô hiệu hóa cho ký hiệu |
SYMBOL_TRADE_MODE_LONGONLY | 1 | Chỉ cho phép giao dịch mua |
SYMBOL_TRADE_MODE_SHORTONLY | 2 | Chỉ cho phép giao dịch bán |
SYMBOL_TRADE_MODE_CLOSEONLY | 3 | Chỉ cho phép các hoạt động đóng |
SYMBOL_TRADE_MODE_FULL | 4 | Không hạn chế hoạt động giao dịch |
Nhớ lại rằng lớp Permissions
chứa phương thức isTradeOnSymbolEnabled
, kiểm tra nhiều khía cạnh ảnh hưởng đến khả năng giao dịch của ký hiệu, và một trong số đó là thuộc tính SYMBOL_TRADE_MODE
. Theo mặc định, chúng ta cho rằng mình quan tâm đến quyền truy cập đầy đủ vào giao dịch, tức là mua và bán: SYMBOL_TRADE_MODE_FULL
. Tùy thuộc vào chiến lược giao dịch, chương trình MQL có thể xem xét đủ, ví dụ, chỉ quyền mua, chỉ quyền bán, hoặc chỉ quyền đóng hoạt động.
static bool isTradeOnSymbolEnabled(string symbol, const datetime now = 0,
const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
{
// kiểm tra phiên giao dịch
bool found = now == 0;
...
// kiểm tra chế độ giao dịch cho ký hiệu
return found && (SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE) == mode);
}
2
3
4
5
6
7
8
9
Ngoài chế độ giao dịch, chúng ta sẽ cần phân tích quyền cho các loại lệnh khác nhau trong tương lai: chúng được biểu thị bằng các bit riêng trong thuộc tính SYMBOL_ORDER_MODE
và có thể được kết hợp tùy ý với phép OR logic (|
). Ví dụ, giá trị 127 (0x7F) tương ứng với tất cả các bit được đặt, tức là tất cả các loại lệnh đều có sẵn.
Định danh | Giá trị | Mô tả |
---|---|---|
SYMBOL_ORDER_MARKET | 1 | Cho phép lệnh thị trường (Buy và Sell) |
SYMBOL_ORDER_LIMIT | 2 | Cho phép lệnh giới hạn (Buy Limit và Sell Limit) |
SYMBOL_ORDER_STOP | 4 | Cho phép lệnh dừng (Buy Stop và Sell Stop) |
SYMBOL_ORDER_STOP_LIMIT | 8 | Cho phép lệnh dừng giới hạn (Buy Stop Limit và Sell Stop Limit) |
SYMBOL_ORDER_SL | 16 | Cho phép đặt mức Stop Loss |
SYMBOL_ORDER_TP | 32 | Cho phép đặt mức Take Profit |
SYMBOL_ORDER_CLOSEBY | 64 | Cho phép đóng vị thế bằng vị thế ngược lại cùng ký hiệu, hoạt động Close By |
Thuộc tính SYMBOL_ORDER_CLOSEBY
chỉ được đặt cho các tài khoản sử dụng chế độ kế toán hedging (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING
, xem Loại tài khoản).
Trong kịch bản thử nghiệm SymbolFilterTradeMode.mq5
, chúng ta sẽ yêu cầu một vài thuộc tính đã mô tả cho các ký hiệu hiển thị trong Market Watch
. Việc xuất các bit và kết hợp của chúng dưới dạng số không quá rõ ràng, vì vậy chúng ta sẽ tận dụng việc trong lớp SymbolMonitor
, chúng ta có một phương thức tiện lợi stringify
để in các thành viên liệt kê và mặt nạ bit của tất cả các thuộc tính.
void OnStart()
{
SymbolFilter f; // đối tượng bộ lọc
string symbols[]; // mảng cho tên
long permissions[][2]; // mảng cho dữ liệu (giá trị thuộc tính)
// danh sách các thuộc tính ký hiệu được yêu cầu
ENUM_SYMBOL_INFO_INTEGER modes[] =
{
SYMBOL_TRADE_MODE,
SYMBOL_ORDER_MODE
};
// áp dụng bộ lọc, lấy mảng kết quả
f.let(SYMBOL_VISIBLE, true).select(true, modes, symbols, permissions);
const int n = ArraySize(symbols);
PrintFormat("===== Quyền giao dịch cho các ký hiệu (%d) =====", n);
for(int i = 0; i < n; ++i)
{
Print(symbols[i] + ":");
for(int j = 0; j < ArraySize(modes); ++j)
{
// hiển thị mô tả bit và số "nguyên bản"
PrintFormat(" %s (%d)",
SymbolMonitor::stringify(permissions[i][j], modes[j]),
permissions[i][j]);
}
}
}
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
Dưới đây là một phần của nhật ký kết quả từ việc chạy kịch bản.
===== Quyền giao dịch cho các ký hiệu (13) =====
EURUSD:
SYMBOL_TRADE_MODE_FULL (4)
[ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
_SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP
_SYMBOL_ORDER_CLOSEBY ] (127)
GBPUSD:
SYMBOL_TRADE_MODE_FULL (4)
[ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
_SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP
_SYMBOL_ORDER_CLOSEBY ] (127)
...
SP500m:
SYMBOL_TRADE_MODE_DISABLED (0)
[ _SYMBOL_ORDER_MARKET _SYMBOL_ORDER_LIMIT _SYMBOL_ORDER_STOP
_SYMBOL_ORDER_STOP_LIMIT _SYMBOL_ORDER_SL _SYMBOL_ORDER_TP ] (63)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Vui lòng lưu ý rằng giao dịch cho ký hiệu cuối cùng SP500m
bị vô hiệu hóa hoàn toàn (giá báo của nó chỉ được cung cấp dưới dạng "tham khảo"). Đồng thời, tập hợp cờ theo loại lệnh của nó không phải là 0 nhưng không tạo ra bất kỳ sự khác biệt nào.
Tùy thuộc vào các sự kiện trên thị trường, nhà môi giới có thể thay đổi các thuộc tính của ký hiệu theo quyết định của họ, ví dụ, chỉ để lại khả năng đóng vị thế trong một khoảng thời gian, vì vậy một robot giao dịch đúng phải kiểm soát các thuộc tính này trước mỗi hoạt động.