Tính năng khởi động và dừng các chương trình thuộc nhiều loại khác nhau
Trong lập trình, thuật ngữ khởi tạo được sử dụng trong nhiều ngữ cảnh khác nhau. Trong MQL5, cũng có một số sự mơ hồ. Trong phần Khởi tạo, chúng ta đã sử dụng từ này để chỉ việc thiết lập các giá trị ban đầu của biến. Sau đó, chúng ta đã thảo luận về sự kiện khởi tạo OnInit
trong các chỉ báo và Expert Advisors. Mặc dù ý nghĩa của cả hai lần khởi tạo này là tương tự (đưa chương trình vào trạng thái làm việc), chúng thực sự biểu thị các giai đoạn chuẩn bị khác nhau cho việc khởi chạy một chương trình MQL: hệ thống và ứng dụng.
Vòng đời của một chương trình MQL hoàn chỉnh có thể được biểu diễn bằng các bước chính sau:
- Tải — đọc chương trình từ tệp vào bộ nhớ của terminal: bao gồm các hướng dẫn, dữ liệu được xác định trước (hằng số), tài nguyên, và thư viện. Đây là nơi các chỉ thị
#property
phát huy tác dụng. - Phân bổ bộ nhớ cho các biến toàn cục và thiết lập giá trị ban đầu của chúng — đây là khởi tạo hệ thống được thực hiện bởi môi trường thực thi. Hãy nhớ lại rằng trong phần Khởi tạo, khi nghiên cứu việc khởi động chương trình dưới trình gỡ lỗi từng bước, chúng ta đã thấy mục
@global_initializations
trên ngăn xếp. Đây là khối mã cho mục này, được trình biên dịch tạo ra một cách ẩn. Nếu chương trình sử dụng các đối tượng toàn cục của lớp/cấu trúc, các hàm tạo của chúng sẽ được gọi ở giai đoạn này. - Gọi hàm xử lý sự kiện
OnInit
(nếu có): nó thực hiện khởi tạo ứng dụng ở cấp cao hơn, và do đó mỗi chương trình thực hiện nó một cách độc lập, theo nhu cầu. Ví dụ, nó có thể là phân bổ bộ nhớ động cho mảng các đối tượng, mà vì một lý do nào đó, bạn cần sử dụng các hàm tạo có tham số thay vì hàm tạo mặc định. Như chúng ta biết, việc phân bổ bộ nhớ tự động cho mảng chỉ sử dụng các hàm tạo mặc định, và do đó chúng không thể được khởi tạo trong bước trước (2). Nó cũng có thể là mở tệp, gọi các hàm API tích hợp để kích hoạt các chế độ biểu đồ cần thiết, v.v. - Một vòng lặp cho đến khi người dùng đóng chương trình hoặc terminal hoặc thực hiện bất kỳ hành động nào khác yêu cầu khởi tạo lại (xem thêm):
- Gọi các hàm xử lý khác khi các sự kiện tương ứng xảy ra.
- Gọi hàm xử lý sự kiện
OnDeinit
(nếu có) khi phát hiện nỗ lực đóng chương trình bởi người dùng hoặc theo chương trình (hàm tương ứng ExpertRemove chỉ có sẵn trong Expert Advisors và scripts). - Kết thúc: giải phóng bộ nhớ đã phân bổ và các tài nguyên khác mà lập trình viên không coi là cần thiết để giải phóng trong
OnDeinit
. Nếu chương trình sử dụng OOP, các hàm hủy của các đối tượng toàn cục và tĩnh được gọi ở đây. - Dỡ chương trình.
Scripts và services không có sẵn các hàm xử lý OnInit
và OnDeinit
, và do đó các bước 3 và 5 không tồn tại đối với chúng, và bước 4 suy giảm thành một lần gọi duy nhất OnStart
.
Khởi tạo hệ thống (bước 2) không thể tách rời khỏi việc tải, tức là nó luôn theo sau việc tải. Kết thúc luôn diễn ra trước khi dỡ bỏ. Tuy nhiên, các chỉ báo và Expert Advisors trải qua các giai đoạn tải và dỡ bỏ khác nhau trong các tình huống khác nhau. Do đó, các lần gọi OnInit
và OnDeinit
(các bước 3 và 5) là các điểm tham chiếu mà tại đó có thể cung cấp khởi tạo và hủy khởi tạo ứng dụng nhất quán cho Expert Advisors và các chỉ báo.
Việc tải các chỉ báo và Expert Advisors được thực hiện trong các trường hợp sau:
Trường hợp | ![]() | ![]() |
---|---|---|
Người dùng khởi chạy chương trình trên biểu đồ | + | + |
Khởi động terminal (nếu chương trình đang chạy trên biểu đồ trước khi đóng terminal trước đó) | + | + |
Tải một mẫu (nếu mẫu chứa chương trình gắn vào biểu đồ) | + | + |
Thay đổi hồ sơ (nếu chương trình được gắn vào một trong các biểu đồ của hồ sơ) | + | + |
Sau khi biên dịch lại thành công, nếu chương trình đã được gắn vào biểu đồ | + | + |
Thay đổi tài khoản đang hoạt động | + | + |
- | - | - |
Thay đổi ký hiệu hoặc chu kỳ của biểu đồ mà chỉ báo được gắn vào | + | - |
Thay đổi tham số đầu vào của chỉ báo | + | - |
- | - | - |
Kết nối với tài khoản (xác thực), ngay cả khi số tài khoản không thay đổi | - | + |
Dưới dạng cô đọng hơn, có thể đưa ra quy tắc sau: Expert Advisors không trải qua toàn bộ vòng đời, tức là chúng không tải lại khi ký hiệu/khung thời gian của biểu đồ thay đổi, cũng như khi các tham số đầu vào thay đổi.
Do đó, một sự bất đối xứng tương tự có thể được quan sát khi dỡ bỏ các chương trình. Các lý do để dỡ bỏ các chỉ báo và Expert Advisors là:
Trường hợp | ![]() | ![]() |
---|---|---|
Xóa chương trình khỏi biểu đồ | + | + |
Đóng terminal (khi chương trình được gắn vào biểu đồ) | + | + |
Tải một mẫu lên biểu đồ mà chương trình đang chạy | + | + |
Đóng biểu đồ mà chương trình đang chạy | + | + |
Thay đổi hồ sơ nếu chương trình được gắn vào một trong các biểu đồ của hồ sơ | + | + |
Thay đổi tài khoản mà terminal được kết nối | + | + |
- | - | - |
Thay đổi ký hiệu và/hoặc chu kỳ của biểu đồ mà chỉ báo được gắn vào | + | - |
Thay đổi tham số đầu vào của chỉ báo | + | - |
- | - | - |
Gắn một EA khác hoặc cùng EA vào biểu đồ nơi EA hiện tại đang chạy | - | + |
Gọi hàm ExpertRemove | - | + |
Lý do cho việc hủy khởi tạo có thể được tìm thấy trong chương trình bằng cách sử dụng hàm UninitializeReason
hoặc cờ _UninitReason
(xem phần Kiểm tra trạng thái và lý do dừng chương trình MQL).
Xin lưu ý rằng khi bạn thay đổi ký hiệu hoặc khung thời gian của biểu đồ, cũng như khi bạn thay đổi các tham số đầu vào, Expert Advisor vẫn ở trong bộ nhớ, tức là các bước 6-7 (kết thúc và dỡ bỏ) và các bước 1-2 (tải và phân bổ bộ nhớ ban đầu) không được thực hiện, do đó các giá trị của biến toàn cục và tĩnh không được đặt lại. Trong trường hợp này, các hàm xử lý OnDeinit
và OnInit
được gọi liên tiếp trên ký hiệu/khung thời gian cũ và mới tương ứng (hoặc tại cài đặt cũ và mới).
Hậu quả của việc các biến toàn cục không bị xóa trong Expert Advisors là mã hủy khởi tạo _UninitReason
vẫn không thay đổi để phân tích trong hàm xử lý OnInit
. Mã mới sẽ được ghi vào biến chỉ trong trường hợp sự kiện tiếp theo, ngay trước khi gọi OnDeinit
.
Tất cả các sự kiện nhận được cho Expert Advisor trước khi kết thúc hàm OnInit
đều bị bỏ qua.
Khi chương trình MQL được khởi chạy lần đầu tiên, hộp thoại cài đặt được hiển thị giữa các bước 1 và 2. Khi thay đổi các tham số đầu vào, hộp thoại cài đặt được chèn vào vòng lặp chung theo các cách khác nhau tùy thuộc vào loại chương trình: đối với các chỉ báo, nó vẫn xuất hiện trước bước 2, và đối với Expert Advisors – trước bước 3.
Cuốn sách đi kèm với một mẫu chỉ báo và Expert Advisor có tiêu đề
LifeCycle.mq5
. Nó ghi lại các bước khởi tạo/kết thúc toàn cục trong các hàm xử lýOnInit/OnDeinit
. Đặt các chương trình lên biểu đồ và xem các sự kiện nào xảy ra để đáp ứng các hành động khác nhau của người dùng: tải/dỡ bỏ, thay đổi tham số, chuyển đổi ký hiệu/khung thời gian.
Script chỉ được tải khi nó được thêm vào biểu đồ. Nếu một script đang chạy trong một vòng lặp, việc biên dịch lại nó không dẫn đến việc khởi động lại.
Service được tải và dỡ bỏ bằng các lệnh menu ngữ cảnh trong giao diện terminal. Khi một service đang chạy được biên dịch lại, nó sẽ được khởi động lại. Hãy nhớ rằng các phiên bản hoạt động của services được tự động tải khi terminal khởi động và dỡ bỏ khi đóng.
Trong hai phần tiếp theo, chúng ta sẽ xem xét các tính năng của việc khởi chạy các chương trình MQL khác nhau ở cấp độ các hàm xử lý sự kiện.