Xóa Expert Advisors và Scripts theo lập trình: ExpertRemove
Khi cần thiết, nhà phát triển có thể tổ chức việc dừng và dỡ bỏ các chương trình MQL thuộc hai loại: Expert Advisors và scripts. Điều này được thực hiện bằng cách sử dụng hàm ExpertRemove
.
void ExpertRemove()
Hàm này không có tham số và không trả về giá trị. Nó gửi một yêu cầu đến môi trường thực thi chương trình MQL để xóa chương trình hiện tại. Trên thực tế, điều này dẫn đến việc đặt cờ _StopFlag
và dừng việc nhận (và xử lý) tất cả các sự kiện tiếp theo. Sau đó, chương trình được cho 3 giây để hoàn thành công việc một cách đúng đắn: giải phóng tài nguyên, phá vỡ các vòng lặp trong thuật toán, v.v. Nếu chương trình không làm điều này, nó sẽ bị dỡ bỏ một cách cưỡng chế, dẫn đến mất dữ liệu trung gian.
Hàm này không hoạt động trong các chỉ báo và services (chương trình sẽ tiếp tục chạy).
Mỗi lần gọi hàm, nhật ký sẽ chứa mục nhập "ExpertRemove() function called".
Hàm này chủ yếu được sử dụng trong các Expert Advisors không thể bị gián đoạn theo bất kỳ cách nào khác. Trong trường hợp scripts, thường dễ dàng hơn để phá vỡ vòng lặp (nếu có) bằng câu lệnh break
. Nhưng nếu các vòng lặp được lồng nhau, hoặc thuật toán sử dụng nhiều lời gọi hàm từ nhau, sẽ dễ dàng hơn để xem xét cờ dừng ở các cấp độ khác nhau trong các điều kiện để tiếp tục tính toán, và trong trường hợp xảy ra tình huống lỗi, đặt cờ này bằng ExpertRemove
. Nếu bạn không sử dụng cờ tích hợp này, dù sao bạn cũng sẽ phải giới thiệu một biến toàn cục với cùng mục đích.
Script ScriptRemove.mq5
cung cấp ví dụ về cách sử dụng ExpertRemove
.
Một vấn đề tiềm ẩn trong hoạt động của thuật toán, dẫn đến nhu cầu dỡ bỏ script, được mô phỏng bởi lớp ProblemSource
. ExpertRemove
được gọi ngẫu nhiên trong hàm tạo của nó.
class ProblemSource
{
public:
ProblemSource()
{
// mô phỏng một vấn đề trong quá trình tạo đối tượng, ví dụ,
// với việc chiếm dụng một số tài nguyên, như tệp, v.v.
if(rand() > 20000)
{
ExpertRemove(); // sẽ đặt _StopFlag thành true
}
}
};
2
3
4
5
6
7
8
9
10
11
12
13
Tiếp theo, các đối tượng của lớp này được tạo ở cấp độ toàn cục và bên trong hàm trợ giúp.
ProblemSource global; // đối tượng có thể gây lỗi
void SubFunction()
{
ProblemSource local; // đối tượng có thể gây lỗi
// mô phỏng một số công việc (chúng ta cần kiểm tra tính toàn vẹn của đối tượng!)
Sleep(1000);
}
2
3
4
5
6
7
8
Bây giờ chúng ta sử dụng SubFunction
trong hoạt động của OnStart
, bên trong vòng lặp với điều kiện IsStopped
.
void OnStart()
{
int count = 0;
// vòng lặp cho đến khi bị dừng bởi người dùng hoặc chính chương trình
while(!IsStopped())
{
SubFunction();
Print(++count);
}
}
2
3
4
5
6
7
8
9
10
Dưới đây là một ví dụ nhật ký (mỗi lần chạy sẽ khác nhau do tính ngẫu nhiên):
1
2
3
ExpertRemove() function called
4
2
3
4
5
Lưu ý rằng nếu xảy ra lỗi trong khi tạo đối tượng toàn cục, vòng lặp sẽ không bao giờ được thực thi.
Vì Expert Advisors có thể chạy trong tester, hàm ExpertRemove
cũng có thể được sử dụng trong tester. Hiệu quả của nó phụ thuộc vào vị trí gọi hàm. Nếu điều này được thực hiện bên trong hàm xử lý OnInit
, hàm sẽ hủy bỏ thử nghiệm, tức là một lần chạy của tester trên tập hợp tham số hiện tại của Expert Advisor. Việc kết thúc như vậy được coi là lỗi khởi tạo. Khi ExpertRemove
được gọi ở bất kỳ vị trí nào khác trong thuật toán, việc thử nghiệm Expert Advisor sẽ bị gián đoạn sớm, nhưng sẽ được xử lý theo cách thông thường, với các lời gọi OnDeinit
và OnTester
. Trong trường hợp này, thống kê giao dịch tích lũy và giá trị của tiêu chí tối ưu hóa sẽ được thu thập, có tính đến việc thời gian máy chủ mô phỏng TimeCurrent
không đạt đến ngày kết thúc trong cài đặt tester.