| Buổi 5.1 — Phụ đạo OOP trong MQL5: Từ thủ tục Grid đến Class Multi-Cluster (5000 từ)

Được viết bởi Đặng Trí Thanh vào ngày 06/08/2026 lúc 15:24 | 10 lượt xem

Buổi 5.1 — Phụ đạo OOP trong MQL5: Từ lập trình thủ tục đến Class & Multi-Cluster

Khóa học: Xây dựng IB bằng Bot Auto Trading — Phần 2: Chiến thuật rải quân (Grid Logic)

Disclaimer: Giao dịch Forex, CFD và các công cụ đòn bẩy có rủi ro cao, có thể mất toàn bộ vốn. Bài viết phục vụ đào tạo lập trình Bot MT5 và vận hành hệ thống IB; không cam kết lợi nhuận. Mọi backtest và demo cần kiểm chứng trên tài khoản của bạn.


Mở đầu: Vì sao Buổi 5.1 tồn tại?

Trong Phần 1, bạn xây dựng hạ tầng Grid: Global Variable lưu P0, RAM Cache chống nhồi trùng Step, Magic kép Buy/Sell, Comment DNA. Ở Buổi 4–5 (Phần 2), bạn mở rộng chiến thuật: Dynamic Step, Basket TP, Surplus, Hedge Lockdown — vẫn trong phong cách lập trình thủ tục: hàng loạt biến toàn cục (m_buy_p0, m_sell_p0, cache mảng, cờ lockdown…) và chuỗi hàm ProcessCluster, CacheAllPositions.

Cách làm này đúng và mạnh cho EA hai cụm. Nhưng khi khóa học bước sang Buổi 6 — Multi-Cluster (nhiều cụm lưới độc lập, con trỏ động, class CCluster), tiếp tục nhân bản biến cluster3_, cluster4_ sẽ dẫn tới mã nguồn khó bảo trì, dễ xung đột dữ liệu trên VPS chạy 24/7.

Buổi 5.1cầu nối bắt buộc: không yêu cầu bạn viết lại ngay toàn bộ Nhị Quái V9, mà dạy tư duy OOP trong MQL5 qua file Buoi5.1_Code_Mau.mq5 và bài tập Bai_tap_Buoi5.1.md. Từ Buổi 6, mã nguồn Nhị Quái V9.2.2 Pro trở đi được tổ chức hoàn toàn hướng đối tượng để quản lý đa cụm an toàn.


1. Lập trình thủ tục — nền bạn đã nắm (Buổi 1 → 5)

1.1. Tư duy “công thức nấu ăn”

Lập trình thủ tục coi chương trình là dãy bướcmodule hàm. EA MT5 điển hình:

  1. OnInit() — khôi phục P0 từ F3, gán Magic cho CTrade, kiểm tra input.
  2. OnTick() — quét vị thế một lần, nạp cache, tính Step, kiểm tra spread, mở lệnh hoặc Basket TP.
  3. OnDeinit() — dọn timer, log.

Dữ liệu chia sẻ giữa các hàm thường nằm ở biến toàn cục để tránh truyền 20 tham số mỗi lần gọi. Đó chính xác là cách Mini-Nhị Quái ProBuoi5_Code vận hành — và trong giai đoạn học, đó là bước đi đúng.

1.2. Ưu điểm thủ tục với Bot Grid giai đoạn đầu

  • Dễ đọc với người mới: luồng từ trên xuống, Journal in log theo thứ tự.
  • Hiệu năng tốt trên VPS cấu hình thấp: không cấp phát Heap liên tục.
  • Debug nhanh khi mới có 2 Magic: đặt breakpoint tại một hàm OpenGridBuy.

1.3. Bốn “điểm gãy” khi scale lên IB / đa cụm

Một — Global State Corruption: Biến như last_entry_price dùng chung cho Buy và Sell bị ghi đè → khoảng cách DCA sai, nhồi lệnh dày bất thường.

Hai — Spaghetti Code: Hàng trăm hàm + global; sửa InpBuyStep có thể vô tình ảnh hưởng Sell vì dùng chung helper.

Ba — Khó tái sử dụng: Copy “logic Surplus” sang EA khác phải kéo theo cả cụm biến phụ thuộc.

Bốn — Không mở rộng theo cấu hình động: Khách IB muốn 4 cụm (Buy XAU, Sell XAU, Buy BTC, Hedge) — thủ tục thuần buộc copy-paste thủ công.

OOP không thay thế nghiệp vụ Grid bạn đã học; nó thay cách đóng gói nghiệp vụ đó.


2. OOP là gì? Class, Object và ẩn dụ IB

Class (lớp)bản thiết kế. Object (đối tượng)thực thể tạo từ bản thiết kế.

Ẩn dụ Grid Bot
Bản vẽ xe class CGridCluster
Xe trên đường buy_cluster, sell_cluster
Xăng riêng từng xe P0, cache Step, realized profit riêng từng cụm

Mỗi cụm lưới IB (một Magic, một P0, một dòng Comment) là một object — không chen chúc chung biến global.

2.1. Bốn trụ cột OOP — giải thích bằng ngôn ngữ Trader

Đóng gói (Encapsulation): m_buy_p0 để private; bên ngoài chỉ đổi P0 qua ResetP0(double price) có kiểm tra hợp lệ. Tránh hàm lạ gán m_buy_p0 = 0 giữa tick.

Kế thừa (Inheritance): Buổi 6+ có thể có class cơ sở quản lý lệnh, class con CBuyCluster / CSellCluster bổ sung hành vi — tránh viết lại CountPositions.

Đa hình (Polymorphism): Cùng gọi ProcessTick() trên từng object; Buy rải khi giá giảm dưới P0, Sell rải khi giá tăng — một interface, nhiều hành vi.

Trừu tượng (Abstraction): OnTick() EA chỉ gọi for each cluster → cluster.OnTick(). Chi tiết Surplus/Lockdown nằm bên trong class.

2.2. Constructor và Destructor — vòng đời trên VPS

  • Constructor chạy khi new CCluster(...) — khởi tạo Magic, đọc GV, tạo handle indicator.
  • Destructor chạy khi deletebắt buộc IndicatorRelease, tránh handle MA rò trên VPS tháng.

Thiếu destructor trên EA chạy 24/7 là nguồn memory leak và MT5 chậm dần — CTrendFilter trong code mẫu minh họa điểm này.

2.3. Static object vs con trỏ new

Static CAccountTracker tr; Dynamic CAccountTracker* p = new ...
Bộ nhớ Stack, tự hủy Heap, phải delete
Dùng khi Object sống cùng EA Số lượng cụm không cố định, mảng con trỏ
Buổi 6 Ít ChínhCCluster* m_clusters[]

MQL5 cho phép gọi method qua con trỏ class bằng cú pháp ptr.Method() (không bắt buộc -> như C++).

Quy tắc vàng:

if(CheckPointer(p) == POINTER_DYNAMIC) delete p;

Luôn kiểm tra POINTER_INVALID trước khi gọi method trong OnTick.


3. Struct vs Class — Cache Phần 1 vs Cụm lưới Buổi 6

Bạn đã dùng struct OrderCache (ticket, step, type) trong Mini-Nhị Quái — đúng chuyên môn: dữ liệu nhẹ, public, nằm trong mảng Stack/heap của mảng, quét nhanh.

Class dùng khi có trạng thái + hành vi + vòng đời (đếm lệnh, lọc MA, quản lý equity).

Tiêu chí Struct Class
Mặc định public private
new/destructor Không (struct MQL5)
Kế thừa Không
Ví dụ khóa OrderCache buy_cache_db[] CCluster, CTrendFilter

Sai lầm phổ biến: nhét toàn bộ ProcessCluster 300 dòng vào struct — khó test, khó tái sử dụng. Đúng: struct = bản ghi; class = “máy” xử lý cụm.


4. So sánh thực chiến: Thủ tục vs OOP (hai cụm Buy/Sell)

4.1. Thiết kế thủ tục (rút gọn)

double buy_last_price, sell_last_price;
int buy_orders, sell_orders;
void CheckRaiGridBuy() { /* dùng buy_* */ }
void CheckRaiGridSell() { /* dùng sell_* */ }

Thêm cụm thứ ba → thêm bộ biến + hai hàm mới → nhân bản logic.

4.2. Thiết kế OOP (hướng Buổi 6)

class CGridCluster {
private:
    double m_last_price;
    int m_total_orders;
    int m_direction;
public:
    CGridCluster(int direction);
    void UpdateEquity();
    void CheckRaiGrid();
};

Khởi tạo:

CGridCluster* buy_cluster = new CGridCluster(0);
CGridCluster* sell_cluster = new CGridCluster(1);

OnTick gọi song song; thêm cụm = thêm một dòng new (hoặc push vào mảng). DRY — một implementation CheckRaiGrid dùng m_direction.


5. Phân tích sâu Buoi5.1_Code_Mau.mq5

File mẫu gồm 3 class — mỗi class một bài học OOP.

5.1. CAccountTracker — đóng gói số dư & drawdown

  • Constructor ghi nhận balance lúc EA attach.
  • Method GetDrawdownPercent() tính (Balance - Equity) / Balance — logic ẩn trong class, Dashboard chỉ gọi một dòng.
  • DisplayStats() in Journal — tách view khỏi tính toán.

Bài học IB: Khi tư vấn khách, bạn monitor drawdown theo cụm; class giúp sau này gắn drawdown per cluster thay vì chỉ số tài khoản chung.

5.2. CPositionCounter — tham chiếu & trả nhiều giá trị

Hàm CountPositions(int &b_cnt, int &s_cnt, double &b_vol, double &s_vol) ghi trực tiếp vào biến caller — pattern MQL5 khi cần trả nhiều output mà không dùng struct tạm.

Bên trong: CPositionInfo m_pos, lọc Symbol + Magic — giống tinh thần cache Phần 1 nhưng đóng gói trong class.

5.3. CTrendFilter — handle indicator và destructor

  • Init() tạo iMA H1.
  • GetTrend(price) trả 1 / -1 / 0.
  • Destructor gọi IndicatorRelease(m_ma_handle).

Đây là mẫu bắt buộc cho mọi class dùng indicator trong khóa (MA filter Buổi 6, ATR Buổi 6.1…).

5.4. Luồng OnInit / OnDeinit / OnTick mẫu

  1. OnInit: new ba object, m_filter.Init(), EventSetTimer(10).
  2. OnTick: kiểm tra con trỏ → đọc trend → đếm lệnh → Comment dashboard.
  3. OnDeinit: delete từng con trỏ nếu POINTER_DYNAMIC.

Đây là khuôn bạn sẽ gặp lại trong Buoi6_Code.mq5 với mảng CCluster*.


6. Năm bài tập OOP trong Bai_tap_Buoi5.1.md (luyện tay)

# Class Kỹ năng
1 CAccountBalance private balance, Deposit/Withdraw
2 CSymbolSpread Ask/Bid, spread points
3 CPositionState ticket, type, lots, PrintInfo
4 CLotManager risk USD, SL points → normalize lot
5 CTickCounter new global, Increment, OnDeinit delete

Làm ít nhất 2/5 trước Buổi 6; làm 5/5 nếu bạn chưa từng viết class nào.


7. Liên hệ với Surplus & Lockdown (Buổi 5)

Buổi 5 thủ tục vẫn hợp lệ: Surplus harvest, Hedge Lockdown, cờ IsClusterLocked. Khi chuyển OOP, không đổi nghiệp vụ — chỉ chuyển:

  • IsClusterLocked(magic) → method bool CCluster::IsLocked().
  • HarvestSurplusAtStep → method private trong class.
  • GV lock → m_gv_prefix + "_Locked".

Hiểu Buổi 5 giúp bạn map hàm cũ sang method mới; Buổi 5.1 dạy cú pháp map đó.


8. Lộ trình sau Buổi 5.1

graph LR
    A[Buổi 5 Surplus/Lockdown] --> B[Buổi 5.1 OOP]
    B --> C[Buổi 6 Multi-Cluster]
    C --> D[Buổi 6.1 Tốt nghiệp Phần 2]

Checklist vào Buổi 6:

  • [ ] Viết class có private + public method
  • [ ] Dùng new/delete/CheckPointer
  • [ ] Phân biệt struct cache vs class logic
  • [ ] Đọc được Buoi6_Code.mq5 ở mức “biết class nào làm gì”

9. Câu hỏi thường gặp (FAQ)

OOP có làm EA chậm hơn không? Overhead nhỏ so với quét PositionsTotal(). Lợi ích ổn định VPS 24/7 lớn hơn chi phí.

Có phải viết lại toàn bộ Nhị Quái ngay Buổi 5.1 không? Không. Buổi 5.1 là phụ đạo; refactor dần từ Buổi 6.

Struct OrderCache có bỏ không? Không — vẫn dùng trong class để lưu snapshot lệnh.

IB không code có cần buổi này không? Nên hiểu khái niệm để giám sát dev và đọc log; dev bắt buộc thực hành code mẫu.


10. Tài liệu trong repo khóa

  • Buoi5.1_Phu_dao_OOP.md — bài giảng chi tiết
  • Lap_trinh_thu_tuc.md — hạn chế thủ tục, ví dụ Buy/Sell global
  • Buoi5.1_Code_Mau.mq5 — EA demo 3 class
  • Bai_tap_Buoi5.1.md — bài tập trading OOP dễ

Kết luận

Buổi 5.1 trả lời câu hỏi: Tại sao từ Buổi 6, Nhị Quái chuyển sang OOP? — vì đa cụm, an toàn bộ nhớ, và bảo trì khi scale IB. Bạn giữ nguyên kiến thức Grid, Magic, P0, Surplus; chỉ thay cách tổ chức code từ “biến + hàm” sang object có trách nhiệm rõ ràng.

Hướng Nghiệp Dữ Liệu — Đào tạo lập trình Bot MT5 & vận hành IB chuyên nghiệp.


Phụ lục A — Ôn cấu trúc thủ tục Nhị Quái (ánh xạ sang OOP)

Trước OOP, hãy liệt kê thực thể nghiệp vụ bạn đã có — mỗi thực thể sẽ trở thành class hoặc thuộc tính class ở Buổi 6:

Thực thể thủ tục Biến/hàm điển hình Hướng OOP
Cụm Buy InpBuyMagic, m_buy_p0, cache Buy CCluster instance #0
Cụm Sell InpSellMagic, m_sell_p0, cache Sell CCluster instance #1
Trạng thái khóa IsClusterLocked, GV Locked bool m_locked + method
Lợi nhuận đã đóng m_buy_realized_profit double m_realized private
Bộ lọc spread InpMaxSpread method bool IsSpreadOk()

Ánh xạ này giúp bạn không học lại nghiệp vụ — chỉ học cách đặt nghiệp vụ vào class.


Phụ lục B — Stack, Heap và VPS chạy 24/7

Stack: biến local, struct nhỏ trong hàm — tự giải phóng khi thoát hàm. Heap: vùng new cấp phát — sống đến khi delete.

EA tắt bình thường → OnDeinit chạy → destructor + delete dọn Heap. EA crash hoặc quên delete → handle indicator và object còn sót → MT5 chậm sau vài tuần.

Thói quen Buổi 5.1:

  1. Mọi new trong OnInitdelete tương ứng trong OnDeinit.
  2. Mọi iMA / iATRIndicatorRelease trong destructor.
  3. Trước mỗi lần gọi method qua con trỏ: CheckPointer != POINTER_INVALID.

VPS IB thường chạy nhiều chart — leak nhỏ nhân lên = rủi ro thực.


Phụ lục C — Getter/Setter: tại sao không public hết?

Người mới hay hỏi: Sao không để public double m_balance cho nhanh? — Vì bất kỳ hàm nào cũng gán m_balance = -999 sẽ phá logic rút tiền.

Setter cho phép validate:

bool Withdraw(double amount)
{
    if(amount <= 0 || amount > m_balance) return false;
    m_balance -= amount;
    return true;
}

Trong Grid, setter P0 có thể từ chối P0 <= 0 — cùng tư tưởng validate F3 Buổi 1.


Phụ lục D — Walkthrough từng bài tập OOP (chi tiết)

D.1. CAccountBalance

Mục tiêu: Encapsulation thuần. Balance là private; nạp/rút qua method. Bài này không cần con trỏ — object stack trong OnInit là đủ. In Journal số dư sau Deposit/Withdraw để quen unit test tay.

D.2. CSymbolSpread

Mục tiêu: Method tính toán từ trạng thái nội bộ. UpdatePrice(bid, ask) mỗi tick; GetSpreadInPoints() đọc SYMBOL_POINT. Liên hệ InpMaxSpread Buổi 2–5: sau này class cụm sẽ gọi helper spread tương tự.

D.3. CPositionState

Mục tiêu: Constructor có tham số — gán ticket/type/lots một lần. Chuẩn bị cho việc tạo object từ vòng lặp PositionsTotal() (Buổi 6 cache nâng cao).

D.4. CLotManager

Mục tiêu: Tích hợp SymbolInfo — tick value, tick size, normalize lot. Ôn lại Phụ đạo chuẩn hóa volume; class gom công thức rủi ro vào một chỗ thay vì rải rác hàm global.

D.5. CTickCounter

Mục tiêu: Con trỏ toàn cục + new/delete — giống khung Buoi5.1_Code_Mau.mq5. Sau bài này bạn phải thuộc lòng mẫu OnDeinit giải phóng con trỏ.


Phụ lục E — Sai lầm thường gặp khi mới OOP (và cách sửa)

Sai lầm Hậu quả Cách sửa
Quên delete Memory leak VPS Template OnDeinit chuẩn
Gọi method khi con trỏ NULL Crash EA CheckPointer đầu OnTick
Mọi thứ nhét một class “God Class” Khó sửa Tách Tracker, Counter, Filter như mẫu
Public hết biến Global corruption kiểu cũ private + method
Copy class bằng gán thô Lỗi handle trùng Disable copy hoặc implement copy ctor cẩn thận

Phụ lục F — Lộ trình tự học 7 ngày trước Buổi 6

Ngày 1–2: Đọc Buoi5.1_Phu_dao_OOP.md + compile Buoi5.1_Code_Mau.mq5, quan sát Journal timer. Ngày 3: Bài 1–2 Bai_tap_Buoi5.1.md. Ngày 4: Bài 3–4. Ngày 5: Bài 5 (con trỏ). Ngày 6: Đọc lướt Buoi6_Code.mq5 — gạch chân mọi chỗ thấy classnew. Ngày 7: Viết lại pseudo-code: “OnTick chỉ lặp mảng cluster” — không cần compile.


Phụ lục G — Góc nhìn IB: giải thích cho khách hàng

Khách IB không cần biết OOP — họ cần tin cậy. Câu chuyện đơn giản:

“Bot được chia thành từng phòng ban (Buy, Sell, Hedge). Mỗi phòng có sổ cái riêng, không ai sửa sổ của phòng khác. Khi mở rộng thêm chiến lược, ta thêm phòng mới mà không phá hệ thống cũ.”

OOP là cách kể chuyện kỹ thuật đó với dev và auditor.


Phụ lục H — Từ khóa SEO & tìm kiếm (tham khảo)

Lập trình MQL5 OOP, Expert Advisor Grid, Bot MT5 đa cụm, Introducing Broker auto trading, EA Nhị Quái V9, class CCluster, quản lý Magic Number, VPS MetaTrader 5 24/7, phụ đạo lập trình Bot Việt Nam.


Phụ lục I — Tóm tắt một trang (cheat sheet)

  • Class = bản thiết kế; Object = cụm lưới thực tế.
  • Struct = cache dòng lệnh; Class = máy xử lý cụm.
  • new đi với delete; indicator đi với IndicatorRelease.
  • Buổi 5 = nghiệp vụ Surplus/Lockdown; Buổi 5.1 = cú pháp OOP; Buổi 6 = ghép nghiệp vụ vào CCluster.
  • File bắt buộc: Buoi5.1_Code_Mau.mq5, Bai_tap_Buoi5.1.md.


Phụ lục J — Đọc sâu ví dụ thủ tục đa cụm (bài học chuyển OOP)

Trong tài liệu Lap_trinh_thu_tuc.md, đoạn mã minh họa hai cụm Buy/Sell dùng biến toàn cục buy_grid_last_price, sell_grid_last_price, buy_grid_total_orders, sell_grid_total_orders. Hàm UpdateBuyGridEquityUpdateSellGridEquity đều gọi AccountInfoDouble(ACCOUNT_EQUITY) — tức cả hai hàm ghi cùng một nguồn sự thật tài khoản vào hai biến cụm riêng biệt. Khi logic phình to, dev dễ sửa một hàm quên hàm kia, dẫn đến dashboard hiển thị equity cụm không đồng bộ với cách tính nội bộ khi rải lệnh.

Hàm CheckRaiGridBuyCheckRaiGridSell gần như copy-paste chỉ đổi điều kiện so sánh giá và biến cập nhật. Đây là mùi code (code smell) kinh điển: mọi sửa lỗi khoảng cách lưới phải sửa hai nơi. OOP gom vào CheckRaiGrid() dùng m_directionmột nguồn sửa.

Khi thêm cụm Hedge thứ ba, thủ tục buộc bạn thêm hedge_grid_* và thêm CheckRaiGridHedge(). OOP thêm hedge_cluster = new CGridCluster(0) với tham số cấu hình magic riêng — không nhân đôi mã nguồn.

Câu hỏi tự kiểm tra: Trong Buoi5_Code, có bao nhiêu biến global bắt đầu bằng m_buy_ và m_sell_? Nếu câu trả lời > 15, bạn đã có lý do đủ mạnh để chào đón Buổi 6.


Phụ lục K — Constructor có tham số và danh sách khởi tạo

CPositionCounter(int magic) nhận magic lúc tạo object — mỗi object counter gắn một cụm. Tương lai CCluster(int magic, double step, string botName) sẽ gom toàn bộ input IB vào constructor thay vì #define rải rác.

Anti-pattern: tạo object rỗng rồi gán magic bằng hàm SetMagic từ bên ngoài — dễ quên gọi Set, object chạy magic 0. Pattern khuyến nghị: bắt buộc tham số hợp lệ ngay constructor; magic trùng nhau → Alert ngay OnInit.


Phụ lục L — Tham chiếu & trong MQL5 (CPositionCounter)

Hàm CountPositions(int &b_cnt, ...) truyền tham chiếu — bên trong hàm gán b_cnt = 0 sẽ sửa trực tiếp biến ở OnTick. Đây là idiom khi bạn cần nhiều output mà không muốn tạo struct kết quả.

So sánh:

  • Return một int: chỉ đếm được một loại.
  • Return struct: sạch hơn với dev đã quen struct Phần 1.
  • Tham chiếu &: giống style API MQL5 chuẩn và code mẫu khóa học.

Buổi 6 có thể chuyển sang struct SCountResult — cả hai đều OOP-friendly hơn global buy_count.


Phụ lục M — Indicator handle và trách nhiệm destructor

CTrendFilter minh họa RAII (Resource Acquisition Is Initialization): handle tạo trong Init(), giải phóng trong destructor. Nếu bạn tạo handle trong OnInit thủ tục mà quên release khi remove EA, MT5 vẫn sống nhưng handle rác tích lũy.

Thực hành: mỗi lần viết class có iCustom/iMA, viết ngay destructor trước khi viết logic signal. Copy template từ CTrendFilter.


Phụ lục N — Comment DNA và OOP (liên thông Phần 1)

Comment _B_S3 vẫn là string gắn lệnh sàn — OOP không thay Comment. Class cụm sẽ có method string BuildComment(int step) trả về InpBotName + "_B_S" + IntegerToString(step)gom quy tắc đặt tên vào một method thay vì nối chuỗi rải rác mười hàm.

GetStepFromComment có thể là static method hoặc function namespace — Buổi 6 quyết định; Buổi 5.1 chỉ cần hiểu logic parse không đổi.


Phụ lục O — Global Variable F3 và object

P0 lưu F3 vẫn cần khi OOP — nhưng thay vì double m_buy_p0 global, object có double m_p0 private, method LoadP0FromGV() / SaveP0ToGV(). Persistence là trách nhiệm object cụm, không phải file EA chính.

Lockdown flag IsClusterLocked tương tự — method LoadLockState() / SetLocked(bool).


Phụ lục P — Kiểm tra chất lượng trước khi publish EA OOP

  1. Compile 0 errors, 0 warnings (tối đa warning chấp nhận được).
  2. Attach EA demo account → chạy 24h → quan sát RAM MT5 (Task Manager).
  3. Remove EA → Journal có log destructor / không crash.
  4. Re-attach → P0 và trạng thái khôi phục đúng F3.
  5. Code review: không biến global trừ con trỏ mảng cluster và input.

Phụ lục Q — Lời khuyên mentor (dành cho học viên IB)

Đừng sợ OOP — bạn đã từng sợ F3, Cache, Step, Surplus và đã qua. OOP chỉ là lớp vỏ mới. Đừng bỏ qua Buổi 5.1 rồi nhảy thẳng Buổi 6 — bạn sẽ mất 3–5 ngày debug con trỏ thay vì 1 buổi luyện mẫu.

Hãy git commit (hoặc copy zip) sau mỗi bài tập OOP hoàn thành — portfolio IB cho khách thấy bạn học có hệ thống.


Phụ lục R — Bảng thuật ngữ Anh–Việt (tra cứu nhanh)

English Tiếng Việt
Class Lớp (bản thiết kế)
Object Đối tượng
Instance Thể hiện / bản thể
Constructor Hàm dựng
Destructor Hàm hủy
Encapsulation Đóng gói
Inheritance Kế thừa
Polymorphism Đa hình
Pointer Con trỏ
Heap / Stack Vùng nhớ động / ngăn xếp
Memory leak Rò rỉ bộ nhớ
Method Phương thức (hàm thành viên)

Phụ lục S — Hành trình học OOP gắn với Grid (mở rộng)

S.1. Giai đoạn 1 — Nhận diện “object ẩn” trong code cũ

Mở file Buoi5_Code.mq5 (hoặc bản bạn đã fork). Khoanh đỏ từng nhóm biến phục vụ một cụm Buy. Nhóm đó chính là object chưa được đặt tên class. Làm tương tự Sell. Bạn sẽ thấy hai khối gần đối xứng — đó là bằng chứng bạn đã nghĩ theo object nhưng chưa viết class.

Ghi chú vào sổ: magic nào, P0 nào, cache nào, realized profit nào. Sang Buổi 6, slide sẽ map y chang vào CCluster.

S.2. Giai đoạn 2 — Viết class “dummy” không giao dịch

Trước khi port Surplus, tạo class CClusterStub chỉ có Print("Buy cluster tick") trong method OnTickStub(). Gọi từ OnTick thủ tục song song logic cũ. Mục tiêu: quen gọi method, chưa đụng tiền.

S.3. Giai đoạn 3 — Chuyển một hàm mỗi tuần

Tuần 1: chuyển CacheAllPositions thành method nạp OrderCache[] private. Tuần 2: chuyển tính Step. Tuần 3: mở lệnh. Tuần 4: Surplus/Lockdown. Cách incremental refactor giảm rủi ro so với viết lại 2000 dòng một đêm.

S.4. Giai đoạn 4 — Multi-cluster

Khi CCluster ổn với một magic, tạo mảng CCluster* clusters[5] và input InpClusterCount. Vòng lặp for trong OnTick — đây là đích Buổi 6.

S.5. Vì sao khóa IB đặt Buổi 5.1 sau Surplus/Lockdown?

Surplus/Lockdown là đỉnh cao nghiệp vụ phần thủ tục — bạn thấy toàn cảnh EA trước khi đổi vỏ. Nếu học OOP trước Step/Cache, ví dụ xe máy trừu tượng không gắn trading. Nếu học OOP sau Buổi 6, bạn đọc code không hiểu. Thứ tự 5 → 5.1 → 6 là pedagogy cố ý.

S.6. Compliance và marketing IB khi viết blog OOP

Khi đăng website, không hứa “OOP giúp lãi hơn thủ tục”. Thông điệp đúng: OOP giúp vận hành ổn định, mở rộng nhiều cụm, giảm lỗi kỹ thuật — lợi nhuận phụ thuộc thị trường, quản trị rủi ro và tuân thủ broker.

Luôn có disclaimer Forex rủi ro — đã đặt ở đầu bài.

S.7. Thực hành trên Strategy Tester vs Demo

Buoi5.1_Code_Mau.mq5 không bắn lệnh — an toàn chạy mọi symbol. Bài tập CAccountBalance cũng vậy. CLotManager in lot ra Journal — kiểm tra trên XAUUSD demo spread cao. OOP học trên môi trường không giao dịch trước, giống Phụ đạo toán lot.

S.8. Hợp tác nhóm — review code OOP

Pair programming: A viết class, B viết OnInit gọi new/delete. Đổi vai ngày sau. Review checklist: có public biến lộ balance không? Có path không delete không?

S.9. Câu hỏi phỏng vấn nội bộ IB (tự luyện)

  1. Giải thích sự khác Stack và Heap bằng ngôn ngữ VPS.
  2. Vì sao struct không dùng new trong MQL5?
  3. Method nào trong mẫu giải phóng indicator?
  4. Làm sao đếm Buy/Sell cùng magic mà không global buy_count?
  5. Map một hàm ProcessCluster sang method — liệt kê 3 method con.

S.10. Kết nối Phần 3 khóa (Brain / FSM)

Phần 3 sẽ có máy trạng thái hữu hạn — mỗi state có thể là method private hoặc class con. OOP Buổi 5.1 là điều kiện tiên quyết đọc FSM không sợ cú pháp. Bạn không cần thuộc FSM hôm nay — chỉ cần tin Buổi 5.1 không phí thời gian.

S.11. Mẫu OnDeinit chuẩn (copy vào mọi EA OOP)

void OnDeinit(const int reason)
{
    if(CheckPointer(m_tracker) == POINTER_DYNAMIC) delete m_tracker;
    if(CheckPointer(m_counter) == POINTER_DYNAMIC) delete m_counter;
    if(CheckPointer(m_filter)  == POINTER_DYNAMIC) delete m_filter;
    m_tracker = NULL;
    m_counter = NULL;
    m_filter  = NULL;
}

Gán NULL sau delete tránh double delete nếu OnInit được gọi lại trong tester. Buổi 6 mở rộng thành vòng lặp trên mảng m_clusters[].

S.12. Debug Journal — dấu hiệu OOP đúng

Khi attach EA mẫu, bạn nên thấy log balance timer mỗi 10 giờ (EventSetTimer), Comment chart cập nhật trend MA, không có lỗi “invalid pointer”. Nếu Comment trống — kiểm tra CheckPointer và thứ tự Init() MA.

S.13. Tài nguyên mở rộng (đọc thêm)

Tài liệu chính thức MQL5 về Classes and structures trên trang MetaQuotes; phần Object-Oriented Programming trong Help. Đọc song song file Buoi5.1_Phu_dao_OOP.md trong repo khóa — bài website này là bản public rút gọn có hệ thống, không thay thế slide lớp.

S.14. Cam kết chất lượng bài đăng

Bài viết được biên soạn ~5000 từ phục vụ SEO và ôn tập học viên: từ khóa OOP MQL5, Grid Bot, IB Auto Trading, Nhị Quái V9, Multi-Cluster. Nội dung bám sát buổi giảng 5.1 Phụ đạo OOP và không mâu thuẫn với bài tập tổng hợp Phần 1 + Buổi 4–5 (nếu giáo viên giao riêng).

S.15. Bối cảnh phiên bản Bot trong khóa (V6 → V9 → OOP)

Nhị Quái V6 nhấn mạnh DNA Comment và Magic cho bản IB tinh gọn. V9.x tích hợp Surplus, Lockdown, Dynamic Step — phần bạn vừa hoàn thiện ở Buổi 4–5. V9.2.2 Pro + Buổi 6 đưa các cụm vào class để một EA quản lý nhiều magic, nhiều symbol, dashboard tách cụm. Hiểu timeline này giúp bạn không “sợ mất code cũ”: nghiệp vụ giữ, kiến trúc nâng.

Khi khách hàng IB hỏi “Bot version mấy?”, câu trả lời marketing: Phiên bản OOP Multi-Cluster — hạ tầng Grid đã kiểm chứng từ V6/V9, refactor cho scale IB. Kỹ thuật: bạn đang học đúng nhánh đó tại Buổi 5.1.

S.16. Checklist đăng bài WordPress (vận hành website)

  1. Upload banner ib-buoi5-1-oop-phu-dao-banner.png (Featured image).
  2. Chọn category Bot Auto Trading.
  3. Dán nội dung từ Bai_Viet_Website.md (bỏ block meta đầu file) hoặc chạy publish_to_wordpress.ps1 với Application Password.
  4. Kiểm tra slug: buoi-5-1-phu-dao-oop-mql5-lap-trinh-huong-doi-tuong.
  5. Preview mobile — bảng markdown hiển thị đủ cột.
  6. Gắn internal link về trang khóa học và bài Buổi 5 (Surplus) nếu đã có trên site.

Bài viết ~5000 từ — phục vụ học viên khóa Xây dựng IB bằng Bot Auto Trading (06–07.2026). Chạy build_bai_viet_website.py để tái tạo từ nguồn; publish_to_wordpress.ps1 để đăng.

Hướng Nghiệp Dữ Liệu — Đào tạo lập trình Bot MT5 & vận hành IB chuyên nghiệp.

Đặng Trí Thanh

Đặng Trí Thanh

Giám đốc Công nghệ · DNT Digital · Giảng viên HNDL
836 Bài viết
15.4k Người theo dõi
120k+ Lượt đọc

Đặng Trí Thanh — Founder & CTO · Hướng Nghiệp Dữ Liệu - DNT Digital. Chuyên đào tạo và triển khai thực chiến Python, MT5 và hệ thống bot auto trading / IB cho học viên và doanh nghiệp.