Hạn chế và quyền cho các hoạt động tài khoản
Trong số các thuộc tính của tài khoản, có những hạn chế đối với các hoạt động giao dịch, bao gồm việc vô hiệu hóa hoàn toàn giao dịch. Tất cả các thuộc tính này thuộc về liệt kê ENUM_ACCOUNT_INFO_INTEGER
và là các cờ boolean, ngoại trừ ACCOUNT_LIMIT_ORDERS
.
Định danh | Mô tả |
---|---|
ACCOUNT_TRADE_ALLOWED | Quyền giao dịch trên tài khoản hiện tại |
ACCOUNT_TRADE_EXPERT | Quyền giao dịch thuật toán bằng Cố vấn Chuyên gia và tập lệnh |
ACCOUNT_LIMIT_ORDERS | Số lượng tối đa cho phép của các lệnh chờ hợp lệ |
ACCOUNT_FIFO_CLOSE | Yêu cầu chỉ đóng vị thế theo quy tắc FIFO |
Vì cuốn sách của chúng ta nói về lập trình MQL5, bao gồm giao dịch thuật toán, cần lưu ý rằng quyền ACCOUNT_TRADE_EXPERT
bị vô hiệu hóa cũng quan trọng như lệnh cấm giao dịch chung khi ACCOUNT_TRADE_ALLOWED
bằng false
. Nhà môi giới có khả năng cấm giao dịch bằng Cố vấn Chuyên gia và tập lệnh trong khi vẫn cho phép giao dịch thủ công.
Thuộc tính ACCOUNT_TRADE_ALLOWED
thường bằng false
nếu kết nối với tài khoản được thực hiện bằng mật khẩu đầu tư.
Nếu giá trị của thuộc tính ACCOUNT_FIFO_CLOSE
là true
, các vị thế cho mỗi ký hiệu chỉ có thể được đóng theo thứ tự mở, tức là đóng lệnh cũ nhất trước, sau đó đến lệnh mới hơn, và tiếp tục như vậy cho đến lệnh cuối cùng. Nếu bạn cố gắng đóng các vị thế theo thứ tự khác, bạn sẽ nhận được lỗi. Đối với các tài khoản không có phòng ngừa vị thế, tức là nếu thuộc tính ACCOUNT_MARGIN_MODE
không bằng ACCOUNT_MARGIN_MODE_RETAIL_HEDGING
, thì thuộc tính ACCOUNT_FIFO_CLOSE
luôn là false
.
Trong các phần Quyền và Lịch trình của các phiên giao dịch và báo giá, chúng ta đã bắt đầu phát triển một lớp để phát hiện các hoạt động giao dịch khả dụng cho chương trình MQL. Bây giờ chúng ta có thể bổ sung nó với các kiểm tra quyền tài khoản và đưa nó đến phiên bản cuối cùng (Permissions.mqh
).
Các mức hạn chế được cung cấp trong liệt kê TRADE_RESTRICTIONS
, sau khi thêm hai phần tử mới liên quan đến thuộc tính tài khoản, có dạng như sau.
class Permissions
{
enum TRADE_RESTRICTIONS
{
NO_RESTRICTIONS = 0,
TERMINAL_RESTRICTION = 1, // hạn chế của người dùng đối với tất cả các chương trình
PROGRAM_RESTRICTION = 2, // hạn chế của người dùng đối với một chương trình cụ thể
SYMBOL_RESTRICTION = 4, // ký hiệu không được giao dịch theo thông số kỹ thuật
SESSION_RESTRICTION = 8, // thị trường đóng cửa theo lịch trình phiên
ACCOUNT_RESTRICTION = 16, // mật khẩu nhà đầu tư hoặc hạn chế từ nhà môi giới
EXPERTS_RESTRICTION = 32, // nhà môi giới hạn chế giao dịch thuật toán
};
...
2
3
4
5
6
7
8
9
10
11
12
13
Trong quá trình kiểm tra, chương trình MQL có thể phát hiện nhiều hạn chế vì nhiều lý do khác nhau, do đó các phần tử được mã hóa bằng các bit riêng biệt. Kết quả cuối cùng có thể đại diện cho sự chồng chất của chúng.
Hai hạn chế cuối cùng tương ứng với các thuộc tính mới và được thiết lập trong phương thức getTradeRestrictionsOnAccount
. Mặt nạ bit tổng quát của các hạn chế được phát hiện (nếu có) được hình thành trong biến lastRestrictionBitMask
.
private:
static uint lastRestrictionBitMask;
static bool pass(const uint bitflag)
{
lastRestrictionBitMask |= bitflag;
return lastRestrictionBitMask == 0;
}
public:
static uint getTradeRestrictionsOnAccount()
{
return (AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) ? 0 : ACCOUNT_RESTRICTION)
| (AccountInfoInteger(ACCOUNT_TRADE_EXPERT) ? 0 : EXPERTS_RESTRICTION);
}
static bool isTradeOnAccountEnabled()
{
lastRestrictionBitMask = 0;
return pass(getTradeRestrictionsOnAccount());
}
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Nếu mã gọi không quan tâm đến lý do hạn chế mà chỉ cần xác định khả năng thực hiện các hoạt động giao dịch, thì việc sử dụng phương thức isTradeOnAccountEnabled
thuận tiện hơn, phương thức này trả về dấu hiệu boolean (true/false
).
Các kiểm tra thuộc tính ký hiệu và thiết bị đầu cuối đã được tổ chức lại theo nguyên tắc tương tự. Ví dụ, phương thức getTradeRestrictionsOnSymbol
chứa mã nguồn đã quen thuộc từ phiên bản trước của lớp (kiểm tra các phiên giao dịch và chế độ giao dịch của ký hiệu) nhưng trả về mặt nạ cờ. Nếu ít nhất một bit được đặt, nó mô tả nguồn gốc của hạn chế.
static uint getTradeRestrictionsOnSymbol(const string symbol, datetime now = 0,
const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
{
if(now == 0) now = TimeTradeServer();
bool found = false;
// kiểm tra các phiên giao dịch của ký hiệu và đặt 'found' thành 'true',
// nếu thời gian 'now' nằm trong một trong các phiên
...
// ngoài các phiên, kiểm tra chế độ giao dịch
const ENUM_SYMBOL_TRADE_MODE m = (ENUM_SYMBOL_TRADE_MODE)SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE);
return (found ? 0 : SESSION_RESTRICTION)
| (((m & mode) != 0) || (m == SYMBOL_TRADE_MODE_FULL) ? 0 : SYMBOL_RESTRICTION);
}
static bool isTradeOnSymbolEnabled(const string symbol, const datetime now = 0,
const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
{
lastRestrictionBitMask = 0;
return pass(getTradeRestrictionsOnSymbol(symbol, now, mode));
}
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Cuối cùng, việc kiểm tra tổng quát tất cả các "thực thể" tiềm năng, bao gồm (ngoài các cấp độ trước) cài đặt của thiết bị đầu cuối và chương trình, được thực hiện trong các phương thức getTradeRestrictions
và isTradeEnabled
.
static uint getTradeRestrictions(const string symbol = NULL, const datetime now = 0,
const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
{
return (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) ? 0 : TERMINAL_RESTRICTION)
| (MQLInfoInteger(MQL_TRADE_ALLOWED) ? 0 : PROGRAM_RESTRICTION)
| getTradeRestrictionsOnSymbol(symbol == NULL ? _Symbol : symbol, now, mode)
| getTradeRestrictionsOnAccount();
}
static bool isTradeEnabled(const string symbol = NULL, const datetime now = 0,
const ENUM_SYMBOL_TRADE_MODE mode = SYMBOL_TRADE_MODE_FULL)
{
lastRestrictionBitMask = 0;
return pass(getTradeRestrictions(symbol, now, mode));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Việc kiểm tra toàn diện các quyền giao dịch với lớp mới được thể hiện bởi tập lệnh AccountPermissions.mq5
.
#include <MQL5Book/Permissions.mqh>
void OnStart()
{
PrintFormat("Run on %s", _Symbol);
if(!Permissions::isTradeEnabled()) // kiểm tra ký hiệu hiện tại, mặc định
{
Print("Giao dịch bị vô hiệu hóa vì các lý do sau:");
Print(Permissions::explainLastRestrictionBitMask());
}
else
{
Print("Giao dịch được bật");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Nếu phát hiện hạn chế, mặt nạ bit của chúng có thể được hiển thị dưới dạng biểu diễn chuỗi rõ ràng bằng phương thức explainLastRestrictionBitMask
.
Dưới đây là một số kết quả của tập lệnh. Trong hai trường hợp đầu tiên, giao dịch bị vô hiệu hóa trong cài đặt toàn cục của thiết bị đầu cuối (các thuộc tính TERMINAL_TRADE_ALLOWED
và MQL_TRADE_ALLOWED
bằng false
, tương ứng với các bit TERMINAL_RESTRICTION
và PROGRAM_RESTRICTION
).
Khi chạy trên USDRUB
trong giờ thị trường đóng cửa, chúng ta sẽ nhận thêm SESSION_RESTRICTION
:
Giao dịch bị vô hiệu hóa cho USDRUB vì các lý do sau:
TERMINAL_RESTRICTION PROGRAM_RESTRICTION SESSION_RESTRICTION
2
Đối với ký hiệu SP500m
, nơi giao dịch bị vô hiệu hóa hoàn toàn, cờ SYMBOL_RESTRICTION
xuất hiện.
Giao dịch bị vô hiệu hóa cho SP500m vì các lý do sau:
TERMINAL_RESTRICTION PROGRAM_RESTRICTION SYMBOL_RESTRICTION SESSION_RESTRICTION
2
Cuối cùng, sau khi cho phép giao dịch trong thiết bị đầu cuối nhưng đăng nhập vào tài khoản bằng mật khẩu nhà đầu tư, chúng ta sẽ thấy ACCOUNT_RESTRICTION
trên bất kỳ ký hiệu nào.
Run on XAUUSD
Giao dịch bị vô hiệu hóa vì các lý do sau:
ACCOUNT_RESTRICTION
2
3
Việc kiểm tra sớm quyền trong chương trình MQL giúp tránh các nỗ lực liên tục không thành công khi gửi lệnh giao dịch.