Bài viết gần đây
-
-
Đặng Trí Thanh — Giảng Viên Lập Trình Bot Auto Trading | HNDL
Tháng 8 6, 2026
Trang chủ → Bài Viết → Buổi 5.1 — Phụ đạo OOP trong MQL5: Từ thủ tục Grid đến Class Multi-Cluster (5000 từ)
| 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.1 là cầ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ước và module hàm. EA MT5 điển hình:
OnInit()— khôi phục P0 từ F3, gán Magic choCTrade, kiểm tra input.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.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 Pro và Buoi5_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) là bản thiết kế. Object (đối tượng) là 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
delete— bắt buộcIndicatorRelease, 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ính — CCluster* 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) | Có |
| Kế thừa | Không | Có |
| 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ạoiMAH1.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
OnInit:newba object,m_filter.Init(),EventSetTimer(10).OnTick: kiểm tra con trỏ → đọc trend → đếm lệnh →Commentdashboard.OnDeinit:deletetừng con trỏ nếuPOINTER_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)→ methodbool 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ếtLap_trinh_thu_tuc.md— hạn chế thủ tục, ví dụ Buy/Sell globalBuoi5.1_Code_Mau.mq5— EA demo 3 classBai_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:
- Mọi
newtrongOnInitcódeletetương ứng trongOnDeinit. - Mọi
iMA/iATRcóIndicatorReleasetrong destructor. - 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 class và new. 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 UpdateBuyGridEquity và UpdateSellGridEquity đề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 CheckRaiGridBuy và CheckRaiGridSell 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_direction — mộ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
- Compile 0 errors, 0 warnings (tối đa warning chấp nhận được).
- Attach EA demo account → chạy 24h → quan sát RAM MT5 (Task Manager).
- Remove EA → Journal có log destructor / không crash.
- Re-attach → P0 và trạng thái khôi phục đúng F3.
- 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)
- Giải thích sự khác Stack và Heap bằng ngôn ngữ VPS.
- Vì sao struct không dùng
newtrong MQL5? - Method nào trong mẫu giải phóng indicator?
- Làm sao đếm Buy/Sell cùng magic mà không global
buy_count? - Map một hàm
ProcessClustersang 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)
- Upload banner
ib-buoi5-1-oop-phu-dao-banner.png(Featured image). - Chọn category Bot Auto Trading.
- Dán nội dung từ
Bai_Viet_Website.md(bỏ block meta đầu file) hoặc chạypublish_to_wordpress.ps1với Application Password. - Kiểm tra slug:
buoi-5-1-phu-dao-oop-mql5-lap-trinh-huong-doi-tuong. - Preview mobile — bảng markdown hiển thị đủ cột.
- 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.
Weekly Digest — Nhận Bản Tin Hàng Tuần
Nhận các bài viết phân tích kỹ thuật chuyên sâu, thuật toán giao dịch tự động (Trading Bot) và các giải pháp công nghệ mới nhất từ Hướng Nghiệp Dữ Liệu.
Đặng Trí Thanh
Giám đốc Công nghệ · DNT Digital · Giảng viên HNDLĐặ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.