| Sanity Checks: Những Bẫy Lỗi Toán Học Cần Tránh Tuyệt Đối

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:13 | 50 lượt xem

Sanity Checks: Những Bẫy Lỗi Toán Học Cần Tránh Tuyệt Đối

Bạn code công thức chia Lot:
double lots = Risk / StopLoss;
Một ngày đẹp trời, sàn bị lỗi, trả về giá trị StopLoss = 0.
Kết quả: lots = Infinity. Bot vào lệnh với khối lượng Max 1000 Lots -> Cháy tài khoản trong 1 nốt nhạc.

Đó là lý do ta cần Sanity Checks (Kiểm Tra Tỉnh Táo).

1. Nguyên Tắc “Paranoid” (Hoang Tưởng)

Hãy luôn giả định rằng mọi dữ liệu đầu vào đều có thể SAI. Đừng tin ai cả, kể cả Server của sàn.

Tất cả các hàm tính toán đều phải có rào chắn bảo vệ.

2. Danh Sách Các Bẫy Thường Gặp

Bẫy chia cho 0 (Zero Division)

SAI:
return A / B;

ĐÚNG:

if (B == 0) {
    CAuditManager::Error("Lỗi chia cho 0!");
    return 0; // Hoặc giá trị mặc định an toàn
}
return A / B;

Bẫy Tràn Mảng (Array Out of Range)

Truy cập Close[100] khi nến chưa load đủ 100 cây -> Crash Bot.
Luôn kiểm tra ArraySize() hoặc Bars() trước khi truy cập nến.

Bẫy Sai Số Lot (Invalid Volume)

Tính ra Lot = 0.12345. Sàn chỉ cho phép bước giá 0.01. Gửi lệnh 0.12345 sẽ bị từ chối.
Phải dùng hàm NormalizeDouble() và kiểm tra MinLot, MaxLot, LotStep.

// Hàm chuẩn hóa Lot an toàn
double CheckLot(double lots) {
    if (lots < MinLot) return MinLot;
    if (lots > MaxLot) return MaxLot;
    // Làm tròn theo Step
    return MathFloor(lots / LotStep) * LotStep;
}

3. Internal Bug Audit

Thêm các điểm ASSERT vào code.
Nếu một biến số có giá trị vô lý (ví dụ: Balance < 0), Bot phải tự động Shutdown (Tự ngắt) và gửi báo động. Thà dừng chạy còn hơn chạy sai.


TỔNG KẾT LOẠT BÀI

Chúc mừng bạn đã đi hết hành trình 10 bài viết nâng cấp Bot Trading lên Chuẩn Công Nghiệp.
Từ việc tách File, dùng Database, tự phục hồi đến Test hỗn loạn. Đây là con đường chông gai mà chỉ những Quant Trader nghiêm túc mới dám đi.

Robot V5 giờ đây không chỉ là một con Bot kiếm tiền, nó là một Hệ Thống Di Sản có thể chạy bền bỉ năm này qua năm khác.
Hãy bắt đầu code dòng đầu tiên của CStateEngine ngay hôm nay!

👉 Khóa học tham khảo: Đăng ký ngay khóa học “Lập Trình Bot Auto Trading Đa Nền Tảng” để nhận trọn bộ Source Code mẫu chuẩn công nghiệp này.

| Stress & Chaos Testing: Kế Hoạch “Tra Tấn” Bot Trước Khi Go-Live

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 34 lượt xem

Stress & Chaos Testing: Kế Hoạch “Tra Tấn” Bot Trước Khi Go-Live

Một con Bot chạy tốt trên Backtest 5 năm chưa chắc đã sống sót được 1 tuần trên VPS.
Tại sao? Vì Backtest là môi trường Sạch (Clean Room): Không delay, không ngắt mạng, không trượt giá.

Để đạt chuẩn công nghiệp, Robot V5 phải vượt qua 2 bài kiểm tra tàn khốc: Stress TestChaos Test.

1. Stress Test (Kiểm Tra Gánh Nặng)

Mục đích: Xem Bot xử lý được bao nhiêu dữ liệu cùng lúc.

  • Dữ liệu: Tick Data (Every tick) của năm biến động nhất (Ví dụ 2020 Covid hoặc 2022 War).
  • Tốc độ: Chớp nhoáng.
  • Thử thách:
    • Mở hàng trăm lệnh cùng lúc (Grid dày đặc).
    • Xem RAM có bị tràn không? (Memory Leak).
    • Xem Cache CInventory có hoạt động đúng không hay làm treo Bot?

Nếu Bot chạy ì ạch, đơ máy -> Trượt (Fail). Cần tối ưu lại Code.

2. Chaos Test (Thử Nghiệm Hỗn Loạn) – Mô Phỏng Sự Cố

Lấy cảm hứng từ Chaos Monkey của Netflix. Chúng ta sẽ cố tình phá hoại khi Bot đang chạy.

Kịch bản 1: Mất Mạng Giả Lập
– Viết code chèn vào class CExecution:

if (MathRand() % 100 < 20) return false; // 20% cơ hội giả vờ mất mạng
  • Xem Bot có Retry đúng 5 lần không? Hay Retry vô tận?

Kịch bản 2: Restart Đột Ngột
– Khi Bot đang gồng lỗ chùm 10 lệnh -> Tắt ngang Terminal MT5.
– Bật lại -> Xem CStateEngineSQLite có khôi phục lại đúng trạng thái không? Hay Bot lại mở thêm 10 lệnh mới (thảm họa)?

Kịch bản 3: Sàn Chơi Xấu (Slippage)
– Giả lập độ trượt giá 50 Points khi vào lệnh. Xem cơ chế Slippage Control có chặn lệnh lại không?

3. Tiêu Chí Đạt (Pass Criteria)

  • Không mất tiền oan (do vào lệnh đúp).
  • Không crash phần mềm.
  • Log ghi lại đầy đủ sự cố.

Chỉ khi vượt qua “Địa ngục” này, Bot V5 mới xứng đáng được nạp tiền thật (Real Money).

👉 Tiếp theo: Bài cuối cùng – Những nguyên tắc an toàn cốt lõi để bảo vệ dòng code khỏi những lỗi ngu ngốc. Xem ngay: Sanity Checks: Những Bẫy Lỗi Toán Học Cần Tránh Tuyệt Đối

| Hệ Thống Tự Phục Hồi (Disparity Recovery): Khi Bot Tự Chữa Lành

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 37 lượt xem

Hệ Thống Tự Phục Hồi (Disparity Recovery): Khi Bot Tự Chữa Lành

Trong thế giới lý tưởng, Bot vào lệnh nào, Sàn nhận lệnh đó.
Trong thế giới thực:
– Mạng rớt đúng lúc gửi lệnh.
– Sàn tự đóng lệnh (Stop Out) vì Margin Call.
– Bạn lỡ tay đóng nhầm lệnh trên điện thoại.

Lúc này, xảy ra Disparity (Sự sai lệch) giữa:
1. Dữ liệu Bot nghĩ (Internal State): “Tao đang có 5 lệnh”.
2. Dữ liệu Sàn có (Broker State): “Mày chỉ còn 4 lệnh thôi”.

Nếu không xử lý, Bot sẽ bị loạn (loạn Logic tính toán).

1. Cơ Chế Phát Hiện (Detection)

Tại hàm OnInit() (khi khởi động) và định kỳ mỗi 1 phút, Bot sẽ chạy quy trình Audit:
1. Đọc DB SQLite -> Lấy số lượng lệnh lý thuyết (Theoretical Count).
2. Quét CInventory -> Lấy số lượng lệnh thực tế (Actual Count).

2. Chiến Lược Phục Hồi (Recovery Strategy)

Nếu Actual != Theoretical, Bot kích hoạt chế độ STATE_RECOVERY.

Kịch bản 1: Thiếu Lệnh (Missing Order)
– DB báo có 5 lệnh, Sàn chỉ có 4.
– Nguyên nhân: Lệnh bị đóng tay hoặc Sàn lỗi.
– Hành động:
– Nếu lệnh mất là lệnh dương -> Coi như đã chốt lời -> Cập nhật DB lại thành 4.
– Nếu lệnh mất là lệnh âm (cắt lỗ ngoài ý muốn) -> MỞ LẠI NGAY LẬP TỨC (Re-open) để đảm bảo trạng thái Hedge của cả chùm lệnh không bị phá vỡ.

Kịch bản 2: Thừa Lệnh (Ghost Order)
– DB báo 5, Sàn có 6.
– Nguyên nhân: Bot lag nên vào đúp 2 lần.
– Hành động: Đóng ngay lệnh thừa (ưu tiên đóng lệnh có lợi nhuận thấp nhất hoặc lệnh mới nhất).

3. Thông Báo Khẩn Cấp

Bất kỳ khi nào Tự Phục Hồi kích hoạt, Bot phải:
– Gửi thông báo Push về điện thoại: “ALERT: Disparity Detected! Auto-healing running…”.
– Ghi Log ERROR vào CAuditManager.

Nhờ hệ thống này, Bot V5 có thể tự vận hành hàng năm trời mà không cần bạn phải can thiệp thủ công mỗi khi mạng chập chờn.

👉 Tiếp theo: Làm sao biết hệ thống tự phục hồi này hoạt động tốt? Chẳng lẽ đợi mạng rớt thật? Không, chúng ta sẽ giả lập lỗi. Xem ngay: Stress & Chaos Testing: Kế Hoạch “Tra Tấn” Bot Trước Khi Go-Live

| Lưu Trữ Bền Vững (Persistent Memory): Sức Mạnh Của SQLite Trong MT5

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 38 lượt xem

Lưu Trữ Bền Vững (Persistent Memory): Sức Mạnh Của SQLite Trong MT5

Vấn đề lớn nhất của biến trong RAM là: Mất điện = Mất sạch.
Một con Bot đang gồng lỗ ở Level 5 (Martingale), nếu bị restart máy tính, nó sẽ quên mất mình đang ở Level 5 và bắt đầu lại từ Level 1.
-> Thảm họa.

Giải pháp: Chúng ta cần một “Bộ nhớ vĩnh cửu”.

1. GlobalVariables Có Tốt Không?

MQL5 có hàm GlobalVariableSet để lưu biến vào ổ cứng.
Tuy nhiên:
– Nó chỉ lưu được Double (Số thực).
– Không có cấu trúc (chỉ là cặp Key-Value).
– Nếu bạn có hàng trăm biến trạng thái, việc quản lý Key rất rối rắm.

2. SQLite Database – Chuẩn Mực Mới

Từ phiên bản build 2xxx, MT5 đã hỗ trợ SQLite native.
Đây là một bước tiến vĩ đại cho Bot Trading.
Bạn có thể lưu toàn bộ trạng thái Bot vào một file TinhBot_State.db.

Bảng State:
| ID | Key | Value |
| :— | :— | :— |
| 1 | current_step | 5 |
| 2 | total_profit | 150.5 |
| 3 | last_entry_time | 1712345678 |

3. Class CStorage

Chúng ta sẽ xây dựng class CStorage để wrap các câu lệnh SQL.

class CStorage {
public:
    bool CreateDatabase();
    bool SaveState(int step, double profit);
    bool LoadState(int &step, double &profit);
};

Quy trình:
OnInit: Bot gọi LoadState. Nếu có file DB, nó khôi phục trạng thái cũ (Step 5). Nếu chưa có, nó khởi tạo (Step 1).
OnTick: Mỗi khi vào lệnh xong, Bot gọi SaveState để cập nhật DB ngay lập tức.

4. Lợi Ích Của SQLite

  1. Portable: Bạn có thể copy file .db từ máy cá nhân lên VPS, Bot sẽ tiếp tục chạy tiếp tục đúng trạng thái đó.
  2. Backup: Dễ dàng backup history giao dịch riêng của Bot.
  3. Complex Data: Lưu được cả String, BLOB, cấu trúc phức tạp.

Với SQLite, Bot của bạn trở nên “Bất tử” với việc Restart VPS.

👉 Tiếp theo: Nhưng nếu Bot khởi động lại và thấy dữ liệu trong DB khác với dữ liệu thực tế trên sàn thì sao? Xem ngay: Hệ Thống Tự Phục Hồi (Disparity Recovery): Khi Bot Tự Chữa Lành

| [Audit] CAuditManager: “Hộp Đen” Ghi Log – Không Ghi Là Không Tồn Tại

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 40 lượt xem

[Audit] CAuditManager: “Hộp Đen” Ghi Log – Không Ghi Là Không Tồn Tại

Trong ngành hàng không, khi máy bay gặp sự cố, thứ đầu tiên người ta tìm là Hộp Đen.
Trong Trading, khi tài khoản bị lỗ bất thường, thứ duy nhất cứu rỗi bạn là File Log.

Nhưng dùng hàm Print() của MQL5 là chưa đủ. Bạn cần CAuditManager.

1. Tại Sao Print() Là Không Đủ?

  • Print() chỉ ghi vào tab Experts của MT5. Khi bạn tắt MT5 hoặc quá nhiều log, nó sẽ bị trôi đi mất.
  • Không có cấu trúc: Bạn không thể lọc ra “Chỉ xem các lỗi Error” hay “Chỉ xem các lệnh Buy”.

2. Ghi Log Ra File (File Logging)

CAuditManager sẽ ghi log vào file text riêng biệt trong thư mục MQL5/Files/Logs/.
Mỗi ngày một file: 2023-10-25.log.

Cấu trúc một dòng log chuẩn công nghiệp:
[TIME] [LEVEL] [CLASS] :: Message

Ví dụ:
[10:15:01] [INFO] [CStateEngine] :: Chuyển trạng thái IDLE -> ENTRY_WAIT
[10:15:02] [ERROR] [CExecution] :: Vào lệnh thất bại. Error: 10004 (Requote)

3. Phân Cấp Mức Độ (Log Levels)

Không phải cái gì cũng ghi. CAuditManager hỗ trợ các Level:
DEBUG: Ghi chi tiết từng biến số (chỉ bật khi Dev đang sửa lỗi).
INFO: Ghi các sự kiện chính (Vào lệnh, Đóng lệnh).
WARNING: Ghi các vấn đề nhẹ (Trượt giá, Lag mạng).
ERROR: Ghi lỗi nghiêm trọng (Mất kết nối DB, Hết tiền ký quỹ).

Giao diện Setting của Bot sẽ cho phép chọn mức độ Log muốn ghi.

4. Tầm Quan Trọng Của Audit Trail

Audit Trail (Vết kiểm toán) giúp bạn trả lời các câu hỏi hóc búa từ sếp hoặc nhà đầu tư:
– “Tại sao lúc 2h chiều qua Bot không cắt lỗ?” -> Mở log ra thấy: “Lúc 2h mất mạng, Bot đã cố Retry 5 lần nhưng thất bại”.
– “Tại sao Bot vào lệnh khối lượng lớn thế?” -> Mở log ra thấy: “Do số dư tài khoản tăng đột biến (Nạp tiền), Bot tự tính lại Volume theo Kelly”.

Nếu không có CAuditManager, bạn sẽ mãi mãi chỉ là một Trader “đoán mò” về chính con Bot của mình.

👉 Tiếp theo: Log giúp ta xem lại quá khứ, nhưng làm sao để Bot “nhớ” được quá khứ đó sau khi khởi động lại? Xem ngay: Lưu Trữ Bền Vững (Persistent Memory): Sức Mạnh Của SQLite Trong MT5

| [Exec] CExecution: Nghệ Thuật Đẩy Lệnh, Xử Lý Trượt Giá & Retry

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 37 lượt xem

[Exec] CExecution: Nghệ Thuật Đẩy Lệnh, Xử Lý Trượt Giá & Retry

Bạn gọi hàm OrderSend(). Sàn trả về true. Bạn yên tâm đi ngủ. Sáng hôm sau dậy thấy tài khoản không có lệnh nào, hoặc tệ hơn, có 2 lệnh trùng nhau.

Tại sao? Vì Network Latency (Độ trễ mạng)Requote (Báo giá lại).

Class CExecution sinh ra để đảm bảo: Một khi Bot đã muốn vào lệnh, lệnh đó PHẢI được vào, và chỉ vào MỘT lần duy nhất.

1. Retry Có Giới Hạn (Smart Retry)

Khi gửi lệnh thất bại (do mất mạng 1s, hoặc giá chạy quá nhanh), Bot “cỏ” thường bỏ cuộc luôn hoặc spam lệnh liên tục.
CExecution sử dụng cơ chế Retry thông minh:
– Gửi lệnh lần 1 -> Thất bại.
– Chờ 200ms -> Gửi lần 2 -> Thất bại.
– Chờ 500ms -> Gửi lần 3 -> Thành công.
– Nếu quá 5 lần -> Báo lỗi Critical cho CAuditManager và dừng lại (tránh spam nát tài khoản).

2. Quản Lý ID Lệnh (Request ID)

Làm sao để tránh vào 2 lệnh trùng nhau khi mạng Lag?
Mỗi Request gửi đi đều kèm theo một ID duy nhất (Ví dụ: Timestamp + Random Number).
Khi nhận phản hồi, CExecution sẽ kiểm tra ID này. Nếu Sàn báo “Đã nhận ID này rồi”, Bot sẽ không gửi lại nữa.

3. Xử Lý Trượt Giá (Slippage Control)

Trong thị trường biến động (như tin Non-farm), giá hiển thị trên màn hình và giá khớp thật có thể lệch nhau cả chục Points.
CExecution cho phép cài đặt MaxDeviation:
– Nếu trượt giá < 5 Point: Chấp nhận khớp.
– Nếu trượt giá > 5 Point: Hủy lệnh, chờ giá ổn định.

4. Snippet Code Minh Họa

class CExecution {
public:
    bool ExecuteOrder(int type, double volume, double price) {
        int retry = 0;
        while (retry < 5) {
            if (OrderSend(...) == true) return true;

            int error = GetLastError();
            if (error == ERR_REQUOTE) {
                RefreshRates(); // Lấy giá mới
                retry++;
                Sleep(200); // Nghỉ 1 chút rồi thử lại
            } else {
                // Lỗi nghiêm trọng (sai volume, hết tiền) -> Dừng ngay
                return false;
            }
        }
        return false;
    }
};

Nhờ CExecution, Bot V5 có thể “lì lợm” bám đuổi giá để khớp lệnh bằng được, nhưng cũng đủ thông minh để dừng lại đúng lúc trước khi gây họa.

👉 Tiếp theo: Mọi hành động của Bot, dù thành công hay thất bại, đều phải được ghi lại. Xem ngay: [Audit] CAuditManager: “Hộp Đen” Ghi Log – Không Ghi Là Không Tồn Tại

| [Core] CStateEngine: Cỗ Máy Trạng Thái FSM Điều Khiển Bot

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 44 lượt xem

[Core] CStateEngine: Cỗ Máy Trạng Thái FSM Điều Khiển Bot

Bạn có bao giờ viết một con Bot với hàng tá câu lệnh if...else lồng nhau?
if (RSI < 30) { if (MA > 200) { if (Balance > 1000) { ... } } }

Kết quả là một “nồi lẩu thập cẩm” logic rất khó debug. Khi muốn sửa một điều kiện, bạn phải rà soát lại toàn bộ.

Giải pháp chuẩn công nghiệp là: Finite State Machine (FSM) – Máy trạng thái hữu hạn, được hiện thực hóa qua class CStateEngine.

1. Tư Duy Hướng Trạng Thái (State-Oriented)

Thay vì hỏi “Giá đang là bao nhiêu?”, hãy hỏi “Bot đang ở trạng thái nào?”.
Tại mỗi thời điểm, Bot chỉ có thể ở MỘT trạng thái duy nhất.

Ví dụ các trạng thái của Robot V5:
STATE_IDLE: Rảnh rỗi, chờ tín hiệu.
STATE_ENTRY_WAIT: Đã có tín hiệu, đang chờ Retest để vào.
STATE_HEDGED: Đang gồng lỗ 2 tài khoản (Buy/Sell cân bằng).
STATE_RECOVERY: Đang xử lý lệnh lỗ (Tự cứu).
STATE_SURPLUS: Đã chốt lời, chờ Reset.

2. Thiết Kế Class CStateEngine

CStateEngine sẽ quản lý việc chuyển đổi trạng thái (Transition).

class CStateEngine {
private:
    ENUM_BOT_STATE m_current_state;
public:
    void OnTick() {
        switch (m_current_state) {
            case STATE_IDLE:
                // Chỉ kiểm tra tín hiệu vào lệnh
                if (SignalTriggered()) SwitchState(STATE_ENTRY_WAIT);
                break;
            case STATE_HEDGED:
                // Chỉ tập trung tính toán gỡ lệnh
                if (CanUnhedge()) SwitchState(STATE_RECOVERY);
                break;
        }
    }
};

3. Lợi Ích Của FSM

  • Tách biệt Logic: Khi debug lỗi vào lệnh, bạn chỉ cần nhìn vào STATE_IDLESTATE_ENTRY_WAIT. Không cần quan tâm đến logic gồng lỗ.
  • Tránh Xung Đột: Bot không bao giờ vừa mở lệnh mới vừa đang gồng lỗ (trừ khi bạn thiết kế như vậy), vì 2 trạng thái này tách biệt.
  • Dễ Mở Rộng: Muốn thêm tính năng “Trailing Stop”? Chỉ cần thêm trạng thái STATE_TRAILING.

4. Áp Dụng Thực Tế

Trong Robot V5, CStateEngine sẽ phối hợp với CInventory:
1. CInventory báo: “Đang có 5 lệnh Buy, 0 lệnh Sell”.
2. CStateEngine tự hiểu: “À, vậy là đang ở trạng thái STATE_LONG_ONLY“.
3. Từ đó CStateEngine ra quyết định: “Chỉ tìm điểm Sell để Hedge cân bằng” hoặc “Tìm điểm Buy thêm để Average Down”.

Đây chính là “Bộ não” thông minh giúp Bot tự hành xử trong mọi tình huống thị trường.

👉 Tiếp theo: Khi não đã ra lệnh, cần một “cánh tay” vững chắc để thực thi. Xem ngay: [Exec] CExecution: Nghệ Thuật Đẩy Lệnh, Xử Lý Trượt Giá & Retry

| [Core] CInventory: Quản Lý Kho Lệnh & Cơ Chế Check-sum Đối Soát

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 31 lượt xem

[Core] CInventory: Quản Lý Kho Lệnh & Cơ Chế Check-sum Đối Soát

Trong một cửa hàng, nếu sổ sách ghi tồn kho 10 cái áo mà thực tế chỉ còn 8 cái, đó là thảm họa. Trong Trading, nếu Bot nghĩ nó đang có 1 lệnh Buy mà thực tế lệnh đó đã bị Stoploss, hậu quả là cháy tài khoản.

Đó là lý do chúng ta cần CInventory – Bộ phận quản lý kho lệnh chuyên nghiệp.

1. Vấn Đề Của Hàm PositionsTotal()

Nhiều bạn code bot hay dùng hàm PositionsTotal() của MQL5 để đếm lệnh.
if (PositionsTotal() == 0) OpenBuy();

Rủi ro:
– Hàm này đếm TẤT CẢ lệnh trên tài khoản (bao gồm cả lệnh tay bạn vào vui vui, hoặc lệnh của Bot khác).
– Nó không phân biệt được lệnh nào thuộc về “Chu kỳ” hiện tại của Bot.

2. Thiết Kế Class CInventory

CInventory không chỉ đếm. Nó phân loại và định danh.

class CInventory {
private:
    int m_buy_count;
    int m_sell_count;
    double m_total_buy_volume;
    double m_total_sell_volume;

public:
    void Scan(); // Quét toàn bộ lệnh trên sàn
    bool CheckIntegrity(); // Kiểm tra tính toàn vẹn
};

Magic Number – Chiếc Chìa Khóa

Mỗi con Bot V5 sẽ có một Magic Number riêng. CInventory chỉ lọc và quản lý những lệnh có Magic Number này.

3. Cơ Chế Check-sum (Đối Soát)

Đây là tính năng cao cấp của chuẩn công nghiệp.

  • Local State: Bot lưu trong bộ nhớ (hoặc Database) rằng: “Tao vừa mở 1 lệnh Buy ID #12345”.
  • Broker State: CInventory quét sàn thấy: “Có 1 lệnh Buy ID #12345”.
    –> Khớp (Match): Hệ thống ổn định.

Nếu:
Local: Có lệnh #12345.
Broker: Không thấy lệnh #12345 đâu.
–> Lệch (Disparity):
– Khả năng 1: Lệnh đã chốt lời/cắt lỗ? -> Kiểm tra History.
– Khả năng 2: Sàn xóa lệnh (ít gặp) hoặc lỗi dữ liệu?
– Khả năng 3: Bot chưa kịp cập nhật trạng thái đã bị tắt (Crash).

CInventory sẽ phát hiện sự lệch pha này và báo cho CStateEngine biết để xử lý (ví dụ: Reset trạng thái về 0 hoặc mở lệnh lại).

4. Tại Sao Cần Cache?

Mỗi lần gọi hàm lấy dữ liệu từ sàn (PositionGetDouble) đều tốn tài nguyên và thời gian (vài miliseconds). Nếu trong vòng lặp OnTick bạn gọi hàng nghìn lần, Bot sẽ bị lag.
CInventory sẽ Cache (lưu tạm) các thông số này vào biến nội bộ. Bot chỉ cần đọc từ biến nội bộ -> Tốc độ xử lý siêu nhanh (Microseconds).

👉 Tiếp theo: Sau khi đã nắm rõ mình đang có gì trong tay, Bot cần một bộ não để ra quyết định. Xem ngay: [Core] CStateEngine: Cỗ Máy Trạng Thái FSM Điều Khiển Bot

| Kiến Trúc Đa Tầng (Layered Architecture): Tách File .mq5 Thành Thư Viện .mqh

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 35 lượt xem

Kiến Trúc Đa Tầng (Layered Architecture): Tách File .mq5 Thành Thư Viện .mqh

Trong xây dựng, không ai xây nhà chọc trời bằng cách đổ một đống bê tông trộn lẫn lộn. Họ có móng, khung, tường, hệ thống điện nước riêng biệt. Bot Trading chuẩn công nghiệp cũng vậy.

Thay vì dồn tất cả vào file .mq5, Robot V5 sẽ được tái cấu trúc thành các lớp (Layer) riêng biệt, giao tiếp với nhau qua các Interface chuẩn.

1. Tại Sao Phải Chia Tách? (Separation of Concerns)

Nguyên lý Single Responsibility Principle (SRP): Một module chỉ nên chịu trách nhiệm cho một việc duy nhất.
– Module Vào Lệnh không được phép dính dáng đến Module Ghi Log.
– Module Tính Toán không được phép vẽ vời lên biểu đồ.

Lợi ích:
Tái sử dụng: Bạn có thể bê nguyên module CExecution sang một con Bot khác mà không cần sửa dòng nào.
Dễ Test: Bạn có thể kiểm tra riêng module tính toán mà không cần phải kết nối đến sàn.

2. Bản Vẽ Thiết Kế Bot V5

Chúng ta sẽ chia Bot thành 4 tầng, lưu trong các thư viện .mqh (Include file) riêng biệt:

Tầng 1: The Brain (Core Logic)

  • File: CStateEngine.mqh
  • Nhiệm vụ: Bộ não ra quyết định. Nó không biết vào lệnh như thế nào, nó chỉ biết “Lúc này nên Mua hay Nên Nghỉ”. Nó quản lý trạng thái (FSM) của Bot: Đang Hedged, Đang Lãi, hay Đang Chờ.

Tầng 2: The Warehouse (Data Management)

  • File: CInventory.mqh
  • Nhiệm vụ: Thủ kho. Nó nắm giữ danh sách lệnh hiện có.
  • “Hiện tại mình đang có 3 lệnh Buy, 2 lệnh Sell. Tổng Lot là 0.05”.
  • Nó chịu trách nhiệm đối soát (Check-sum) với sàn.

Tầng 3: The Hands (Execution)

  • File: CExecution.mqh
  • Nhiệm vụ: Chân tay thực thi. Khi CStateEngine ra lệnh “MUA!”, thằng này sẽ lo liệu việc gửi lệnh đi, đặt Stoploss, xử lý nếu bị Requote (báo giá lại) hoặc mất kết nối.

Tầng 4: The Blackbox (Audit & Logging)

  • File: CAuditManager.mqh
  • Nhiệm vụ: Hộp đen. Ghi lại mọi hành động.
  • “Lúc 10:00:01, Brain bảo Mua. Lúc 10:00:02, Hand báo Mua thành công giá 2000”.

3. Cấu Trúc Thư Mục Dự Án

Folder Bot V5 của bạn sẽ trông như thế này:

MQL5/Experts/Robot_V5/
├── Robot_V5.mq5         (File chính, chỉ dài khoảng 50 dòng để gọi các module)
├── include/
│   ├── CStateEngine.mqh
│   ├── CInventory.mqh
│   ├── CExecution.mqh
│   ├── CAuditManager.mqh
│   └── CStorage.mqh     (Quản lý Database - sẽ nói ở bài 7)

Việc này đòi hỏi bạn phải học cách dùng #include và Lập trình hướng đối tượng (OOP) cơ bản trong MQL5. Nhưng tin tôi đi, kết quả rất xứng đáng.

👉 Tiếp theo: Chúng ta sẽ đi sâu vào module đầu tiên – Người thủ kho tin cậy. Xem ngay: [Core] CInventory: Quản Lý Kho Lệnh & Cơ Chế Check-sum Đối Soát

| Từ Bot “Cỏ” Lên Chuẩn Công Nghiệp: Tại Sao Phải Nâng Cấp Robot V5?

Được viết bởi thanhdt vào ngày 06/02/2026 lúc 18:12 | 159 lượt xem

Từ Bot “Cỏ” Lên Chuẩn Công Nghiệp: Tại Sao Phải Nâng Cấp Robot V5?

Bạn có bao giờ tự hỏi: Tại sao các hệ thống giao dịch của ngân hàng hay quỹ lớn có thể chạy liên tục 10 năm không cần tắt máy, trong khi Bot của bạn cứ vài tuần lại phải reset VPS một lần?

Câu trả lời nằm ở hai chữ: Độ Bền Vững (Robustness).

Tiếp nối thành công của Bot V4, phiên bản Robot V5 không chỉ là một bản nâng cấp về chiến thuật, mà là một cuộc cách mạng về Kiến Trúc Hệ Thống (System Architecture). Chúng ta sẽ chuyển mình từ tư duy “Viết Code cho chạy được” sang tư duy “Viết Phần Mềm đạt chuẩn công nghiệp”.

1. Vấn Đề Của Bot “Đơn Khối” (Monolithic)

Hầu hết Trader khi mới học MQL5 đều viết tất cả code vào một file .mq5 duy nhất.
– 500 dòng đầu: Khai báo biến.
– 1000 dòng tiếp: Logic vào lệnh.
– 500 dòng cuối: Quản lý lỗi.

Hậu quả:
Khó bảo trì: Muốn sửa logic Trailing Stop, bạn phải lội qua 2000 dòng code.
Dễ sập: Chỉ cần một lỗi nhỏ ở phần hiển thị (Comment) cũng có thể làm crash cả luồng vào lệnh.
Mất trí nhớ: Nếu VPS khởi động lại, Bot sẽ quên sạch nó đang làm gì, dẫn đến mở lệnh trùng lặp hoặc bỏ sót lệnh.

2. Chuẩn Công Nghiệp (Industrial Standard) Là Gì?

Trong loạt bài viết này, chúng ta sẽ cùng nhau xây dựng một Bot V5 với 4 trụ cột công nghệ:

  1. Kiến Trúc Đa Tầng (Layered Architecture): Chia tách Bot thành các bộ phận chuyên biệt (Thư viện .mqh). Hư đâu sửa đó, không ảnh hưởng toàn cục.
  2. Lưu Trữ Bền Vững (Persistent Memory): Sử dụng Database (SQLite) để ghi nhớ trạng thái. Đổi máy tính, chuyển VPS thoải mái, Bot vẫn chạy tiếp như chưa từng có cuộc chia ly.
  3. Hệ Thống Tự Phục Hồi (Self-Healing): Tự động phát hiện lỗi và sửa sai. Mất mạng? Bot tự kết nối lại. Sàn đóng lệnh láo? Bot tự mở lại lệnh bù.
  4. Kiểm Thử Hỗn Loạn (Chaos Testing): Chúng ta sẽ “tra tấn” Bot bằng các kịch bản khắc nghiệt nhất (ngắt mạng, tin non-farm, spread giãn 200 point) để đảm bảo nó “bất tử”.

3. Lộ Trình Triển Khai

Đây không phải là việc làm trong một sớm một chiều. Chúng ta sẽ đi qua 10 bài viết chuyên sâu:
– [Bài 2] Tách lớp Kiến trúc: Core, Exec, Audit.
– [Bài 3] CInventory: Quản lý kho lệnh.
– [Bài 4] CStateEngine: Cỗ máy trạng thái FSM.
– … và nhiều hơn nữa.

Hãy chuẩn bị tinh thần. Chúng ta không còn chơi đùa với những đoạn script nhỏ lẻ nữa. Chúng ta đang xây dựng một cỗ máy kiếm tiền bền vững.

👉 Tiếp theo: Bắt tay vào việc! Chúng ta sẽ đập bỏ file .mq5 cũ kỹ và vẽ lại bản thiết kế mới. Xem ngay: Kiến Trúc Đa Tầng (Layered Architecture): Tách File .mq5 Thành Thư Viện .mqh