Đọc log MT5 để tìm nguyên nhân: bảng tra 25 dòng log hay gặp và cách dựng cảnh báo theo log
Khi bot ngừng làm việc, câu hỏi duy nhất bạn cần trả lời là: nó ngừng ở đâu, và vì sao? Không có phỏng đoán nào trả lời được câu đó. Chỉ có log.
Vấn đề là phần lớn trader không đọc log, vì ba lý do rất dễ hiểu: log dài và khô khan; bạn không biết dòng nào quan trọng; và quan trọng nhất — log của chính bạn không nói được gì, vì EA chỉ in ra những dòng chung chung như OrderSend failed hoặc không in gì cả.
Bài này giải quyết cả ba. Phần đầu là cách phân biệt bốn loại log trong MT5 và mở đúng log cho đúng câu hỏi. Phần giữa là bảng tra 25 dòng log hay gặp — mỗi dòng kèm nghĩa, nguyên nhân thường gặp và việc cần làm. Phần sau là cách viết log cho EA (có ví dụ MQL5) và cách đặt cảnh báo tự động theo mẫu log, để bạn không phải ngồi đọc log bằng mắt nữa.
1. Vì sao log là nguồn thông tin duy nhất đáng tin
Trực giác của bạn khi bot ngừng chạy là đoán. "Chắc mạng có vấn đề." "Chắc sàn bảo trì." "Chắc EA bị lỗi gì đó." Những phỏng đoán này đều có thể đúng, nhưng chúng không cho bạn biết nên sửa gì — và bạn sẽ sửa sai thứ rồi gặp lại đúng sự cố đó một tuần sau.
Log khác ở ba điểm:
Log có mốc thời gian. Nó cho biết sự việc xảy ra lúc nào, và trình tự các sự kiện. Trình tự quan trọng: "mất kết nối rồi EA bị gỡ" khác hoàn toàn với "EA bị gỡ rồi mất kết nối" — sự việc thứ hai nghĩa là bạn có một lỗi độc lập cần tìm riêng.
Log có mã lỗi. Mã 130 và mã 134 là hai câu chuyện khác nhau, dẫn tới hai cách xử lý khác nhau. Không có mã, bạn chỉ có một từ "failed".
Log là bằng chứng, không phải ký ức. Một tháng sau bạn sẽ không nhớ đêm đó đã xảy ra chuyện gì. FILE log thì nhớ.
Có một điều cần nói thẳng để bạn không mất niềm tin ở bước này: log chỉ hữu ích nếu EA của bạn có viết log. Nếu EA không in gì, bạn không "đọc log" được — bạn đang đọc log của terminal, thứ chỉ biết về kết nối và đăng nhập, không biết gì về logic của bạn. Vì vậy mục 5 của bài này là phần quan trọng nhất: cách tự thêm log vào EA.
2. Bốn loại log trong MT5 — mỗi loại trả lời một câu hỏi khác
Đây là chỗ gây nhầm lẫn nhiều nhất. MT5 có nhiều tab log, và người mới thường mở sai tab rồi kết luận "log không có gì".
Journal (của terminal). Ghi các sự kiện của terminal: kết nối tới server, đăng nhập, nạp EA, thay đổi symbol, đồng bộ dữ liệu lịch sử, khởi động lại. Đây là log của chương trình, không phải của bạn. Dùng khi nghi ngờ tầng máy, mạng, hoặc phiên đăng nhập.
Experts (do EA của bạn viết). Chỉ chứa những dòng mà EA gọi Print() hoặc PrintFormat(). Nếu tab này trống, hoặc dừng ở một thời điểm cụ thể, đó là dấu hiệu trực tiếp về việc EA ngừng chạy. Đây là tab quan trọng nhất — và cũng là tab bị bỏ trống nhiều nhất.
Trade (giao dịch). Ghi lệnh đã gửi, khớp, hoặc bị từ chối, kèm mã lỗi. Khi câu hỏi là "vì sao bot không vào lệnh", đây là tab duy nhất trả lời được. Lưu ý: một số trường hợp từ chối không xuất hiện ở tab Experts vì EA chưa kịp in gì — lệnh bị sàn từ chối ngay ở tầng truyền tin.
Event Viewer của Windows. Không nằm trong MT5. Ghi reboot, cập nhật hệ thống, tiến trình bị kết thúc, và hoạt động của Task Scheduler. Đây là nơi duy nhất cho biết máy đã khởi động lại lúc 3 giờ sáng — thông tin mà MT5 không thể biết, vì nó chưa chạy.
Thứ tự đọc thực tế: Trade → Experts → Journal → Event Viewer. Từ cụ thể tới tổng quát, từ trong EA ra tới hệ điều hành.
3. Quy trình 5 bước đọc log để tìm nguyên nhân
Bước 1 — Xác định mốc thời gian. Tìm thời điểm bot ngừng làm việc. Cách nhanh nhất: nhìn nến cuối cùng đã cập nhật trên chart, hoặc đọc dòng heartbeat cuối cùng trong file log của EA. Mọi thứ trước mốc này là bình thường, mọi thứ sau là hệ quả.
Bước 2 — Mở tab Trade. Lệnh cuối cùng đã gửi là khi nào? Có bị từ chối không? Nếu có, mã lỗi là gì? Nếu không có lệnh nào bị từ chối và cũng không có lệnh nào được gửi, nguyên nhân nằm ở tầng logic (EA không tạo tín hiệu), không phải ở tầng giao dịch.
Bước 3 — Mở tab Experts. Dòng cuối cùng của EA là gì, và lúc nào? Nếu dòng cuối là một dòng lỗi, bạn đã có câu trả lời. Nếu tab trống hoàn toàn, EA chưa từng chạy hoặc không có log. Nếu tab dừng đột ngột giữa một chuỗi bình thường, EA bị gỡ hoặc terminal bị kill.
Bước 4 — Mở tab Journal. Tìm các mẫu: no connection, invalid account, trading has been disabled, expert removed, terminal started. Mỗi mẫu tương ứng một nguyên nhân cụ thể trong bảng tra ở mục 4.
Bước 5 — Mở Event Viewer. Tìm mã 41, 6008, 1074 (khởi động lại) và thông tin Task Scheduler. Nếu có reboot, mọi phân tích ở bước 2–4 cần đọc lại theo giả thuyết "máy đã khởi động lại".
Hai nguyên tắc khi thực hành:
- Đọc từ dòng cuối lên, không đọc từ đầu. Dòng đầu file là trạng thái sáu tiếng trước, thường hoàn toàn không liên quan.
- Đừng cuộn bằng mắt. Dùng tìm kiếm với các từ khoá:
error,failed,rejected,no connection,removed,invalid,timeout. Log 10.000 dòng sẽ rút xuống còn 20 dòng đáng đọc.
Và một trường hợp cần chuẩn bị tinh thần: nếu cả năm bước đều sạch, nguyên nhân không phải một lỗi. Đó là trường hợp "điều kiện vào lệnh không bao giờ tới" — bot chạy hoàn hảo nhưng bộ lọc spread hoặc khung giờ giao dịch chặn mọi tín hiệu. Với trường hợp này, không có gì trong log để tìm, và cách duy nhất là ghi log giá trị của từng điều kiện (mục 5).
4. Bảng tra 25 dòng log hay gặp
Bảng này là phần bạn nên lưu lại. Cột cuối là việc cần làm, không phải việc cần nghĩ.
| # | Dòng log / mã | Nghĩa | Nguyên nhân thường gặp | Việc cần làm |
|---|---|---|---|---|
| 1 | no connection | MT5 không kết nối được server | Mạng VPS, broker bảo trì, sai server | Ping tới server broker; kiểm tra DNS |
| 2 | network error | Lỗi ở tầng mạng | Firewall, DNS, card mạng | Thử ping bằng IP thay vì tên miền |
| 3 | connection closed | Kết nối bị đóng | Broker ngắt session định kỳ | Bình thường nếu 1 lần/ngày; cảnh báo nếu >2 lần/5 phút |
| 4 | invalid account | Số tài khoản không hợp lệ | Broker đổi server, sai số tài khoản | Sửa cấu hình đăng nhập theo server mới |
| 5 | authorization failed | Sai mật khẩu | Đã đổi mật khẩu, chưa cập nhật VPS | Cập nhật mật khẩu trên VPS |
| 6 | previous session closed | Phiên trước đã bị đóng | MT5 khởi động lại | Bình thường — nhưng là dấu hiệu đã có reboot |
| 7 | terminal started / build ... started | MT5 vừa khởi động | Reboot, hoặc mở lại sau khi bị kill | Đếm số lần trong ngày: >1 lần là bất thường |
| 8 | trading has been disabled | Giao dịch tự động bị tắt | AutoTrading off, tài khoản read-only | Bật lại, kiểm tra trạng thái tài khoản |
| 9 | expert removed | EA bị gỡ khỏi chart | Refresh chart, đổi symbol, lỗi khởi tạo | Kiểm tra profile; gắn lại EA |
| 10 | cannot load expert | Không nạp được EA | Thiếu .ex5, thiếu DLL, sai kiến trúc | Kiểm tra file và quyền DLL |
| 11 | not enough money (134) | Không đủ ký quỹ | Khối lượng quá lớn | Giảm volume, kiểm tra margin level |
| 12 | invalid stops (130) | Stops quá gần giá | Vi phạm khoảng cách tối thiểu của sàn | Chuẩn hoá theo SYMBOL_TRADE_STOPS_LEVEL |
| 13 | invalid volume (131) | Khối lượng sai bước | Không theo VOLUME_STEP / MIN / MAX | Chuẩn hoá volume trước khi gửi |
| 14 | requote (138) | Giá đổi trong lúc gửi | Mạng chậm, biến động mạnh | Thêm retry tối đa 3 lần |
| 15 | off quotes | Không có giá để khớp | Spread giãn, tin tức | Tránh khung tin, thêm lọc spread |
| 16 | trade is not allowed (4109) | Không được phép giao dịch | AutoTrading off, EA bị tắt quyền | Bật lại, kiểm tra thuộc tính EA |
| 17 | market closed (4108) | Thị trường đóng | Ngoài giờ, cuối tuần, ngày lễ | Lọc theo giờ giao dịch của symbol |
| 18 | too many orders (148) | Vượt số lệnh tối đa | Giới hạn của tài khoản hoặc symbol | Kiểm tra giới hạn tài khoản |
| 19 | symbol not found / invalid symbol | Không có symbol đó | Broker thêm hậu tố .r / .pro | Dò symbol theo tiền tố, không hardcode |
| 20 | cannot open file | Không mở được file | Sandbox, sai đường dẫn, ổ đĩa đầy | Kiểm tra quyền, dung lượng ổ đĩa |
| 21 | array out of range | Chỉ số mảng vượt biên | Lỗi trong EA | Kiểm tra ArraySize() trước khi truy cập |
| 22 | zero divide | Chia cho 0 | Dữ liệu bất thường lúc khởi động | Kiểm tra mẫu số trước khi chia |
| 23 | history data synchronization | Đang đồng bộ lịch sử | Lần đầu, hoặc sau reboot | Bình thường; nếu kéo dài >5 phút thì kiểm tra mạng |
| 24 | timeout / no response | Hết thời gian chờ | Mạng nghẽn | Kiểm tra mạng, giảm tần suất gọi |
| 25 | waiting for update | Chờ dữ liệu mới | Mất dữ liệu hoặc thị trường đóng | So TimeCurrent() với giờ hiện tại |
Ba dòng trong bảng này có tính chất đặc biệt, đáng nhớ riêng:
- Dòng 6 và 7 không phải lỗi, nhưng là bằng chứng.
terminal startedxuất hiện trong Journal nghĩa là MT5 đã khởi động lại. Nếu bạn thấy dòng này vài lần một ngày, bạn đang có vấn đề ở tầng máy — dù không có lỗi nào khác. - Dòng 9 (
expert removed) là dòng bạn nên cảnh báo ngay lập tức. Nó nghĩa là EA đã rời khỏi chart, và mọi thứ phía sau nó — cảnh báo, tín hiệu, lệnh — đều đã dừng. - Dòng 23 giúp tránh báo động giả. Sau reboot, MT5 luôn cần một lúc để đồng bộ lịch sử. Đừng đặt cảnh báo cho giai đoạn này.
5. Viết log cho EA: ba dòng bạn nên thêm ngay hôm nay
Đây là phần có giá trị cao nhất trong bài, vì nó biến log từ "không có gì" thành "trả lời được mọi câu hỏi".
Nguyên tắc: mỗi dòng log phải trả lời được bốn câu — ai, làm gì, kết quả nào, số đo bao nhiêu.
Log thứ nhất — nhịp tim và trạng thái. In định kỳ (mỗi 15 phút là đủ, đừng in mỗi tick):
// In mỗi 15 phút: chứng minh EA còn sống, kèm trạng thái để so sánh về sau
void LogNhipTim()
{
static datetime lanInCuoi = 0;
if(TimeLocal() - lanInCuoi < 900) return; // 900 giây = 15 phút
lanInCuoi = TimeLocal();
PrintFormat("HB tick=%s lenh=%d equity=%.2f margin=%.1f%% spread=%d",
TimeToString(TimeCurrent(), TIME_MINUTES | TIME_SECONDS),
PositionsTotal(),
AccountInfoDouble(ACCOUNT_EQUITY),
AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),
(int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD));
}Dòng này cho bạn thứ quan trọng nhất khi điều tra: dấu vết cuối cùng trước khi im lặng. Khi bot chết, dòng cuối cùng này cho biết nó đang ở trạng thái nào.
Log thứ hai — tín hiệu và bước ra quyết định. Không phải in kết quả, mà in lý do:
// Khi có tín hiệu, in ra đầy đủ lý do — kể cả khi tín hiệu bị chặn
void LogTinHieu(bool coTinHieu, string lyDoChan)
{
if(coTinHieu)
PrintFormat("SIGNAL %s %s | spread=%d | gia=%.5f",
(TinHieuMua() ? "buy" : "sell"), _Symbol,
(int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD), SymbolInfoDouble(_Symbol, SYMBOL_ASK));
else
PrintFormat("NO-SIGNAL ly-do=%s | spread=%d | gio=%s",
lyDoChan, (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD),
TimeToString(TimeCurrent(), TIME_DATE | TIME_MINUTES));
}Dòng NO-SIGNAL là dòng cứu bạn khỏi việc chẩn đoán sai. Nếu log đầy dòng NO-SIGNAL ly-do=spread suốt ba ngày, bạn biết ngay vấn đề nằm ở bộ lọc spread — không phải ở chiến lược, không phải ở mạng.
Log thứ ba — kết quả gửi lệnh, kèm mã trả về và độ trễ. Đây là dòng bạn sẽ đọc nhiều nhất:
// Ghi kết quả gửi lệnh — phải log CẢ trường hợp thành công
bool GuiLenhVaGhiLog(ENUM_ORDER_TYPE loai, double kl, double gia, double sl, double tp)
{
MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
req.action = TRADE_ACTION_DEAL; req.symbol = _Symbol; req.volume = kl;
req.type = loai; req.price = gia; req.sl = sl; req.tp = tp;
req.deviation = 20; req.magic = 20260913; req.comment = "FindMe";
uint t0 = GetTickCount();
if(!OrderSend(req, res))
{
// Thất bại: log ĐẦY ĐỦ tham số đã gửi → mới tìm ra nguyên nhân
PrintFormat("REJECT retcode=%d (%s) | kl=%.2f gia=%.5f sl=%.5f tp=%.5f | tick=%dms",
res.retcode, LoiThanhCong(res.retcode), kl, gia, sl, tp, (int)(GetTickCount() - t0));
return(false);
}
// Thành công cũng phải log — không có dòng này thì không biết lệnh đã đi hay chưa
PrintFormat("SEND %s %.2f %s @%.5f sl=%.5f tp=%.5f | retcode=%d order=%I64u | tick=%dms",
(loai == ORDER_TYPE_BUY ? "BUY" : "SELL"), kl, _Symbol, gia, sl, tp,
res.retcode, res.order, (int)(GetTickCount() - t0));
return(true);
}
// Đổi mã lỗi thành chữ để đọc log là hiểu ngay
string LoiThanhCong(uint rc)
{
switch(rc)
{
case 10009: return "done";
case 10004: return "requote";
case 10006: return "rejected";
case 10013: return "invalid request";
case 10014: return "invalid volume";
case 10015: return "invalid price";
case 10016: return "invalid stops";
case 10018: return "market closed";
case 10019: return "no money";
default: return "khac";
}
}Ba điểm đáng chú ý trong đoạn code này:
- Log cả trường hợp thành công. Nhiều người chỉ log lỗi. Nhưng khi bạn cần biết "lệnh cuối cùng gửi lúc nào", chỉ log thành công mới trả lời được — và đây chính là mốc thời gian quan trọng nhất khi điều tra.
- Log độ trễ (`tick=%dms`). Độ trễ tăng dần là dấu hiệu sớm của vấn đề mạng hoặc tài nguyên. Bạn sẽ thấy nó trước khi mọi thứ sập.
- Log toàn bộ tham số đã gửi khi bị từ chối. Lỗi 130 (invalid stops) chỉ chẩn đoán được nếu bạn biết giá trị
slđã gửi và khoảng cách tới giá. Không có số, bạn phải tái hiện lại bằng tay.
6. Sáu dòng log cần cảnh báo tự động
Khi log đã có nội dung tốt, bước tiếp theo là đừng đọc nó bằng mắt nữa. Một script nhỏ đọc file log, khớp mẫu, đếm số lần trong cửa sổ thời gian, và báo động — không cần API, không cần dịch vụ nào.
| Dòng log cần bắt | Ngưỡng cảnh báo | Mức |
|---|---|---|
no connection / network error | 2 lần trong 5 phút | Cao |
authorization failed / invalid account | 1 lần | Cao |
expert removed / cannot load expert | 1 lần | Cao |
trade is not allowed (4109) | 1 lần | Cao |
invalid stops (130) / invalid volume (131) | 3 lần trong 10 phút | Trung bình |
not enough money (134) | 1 lần | Cao |
Điểm cần chú ý về ngưỡng: một số dòng là "1 lần là báo", một số khác thì không. requote xảy ra một lần là chuyện bình thường — báo động vì nó sẽ khiến bạn nhờn cảnh báo. Nhưng expert removed xảy ra một lần là EA đã rời chart, và toàn bộ hệ thống của bạn đã ngừng làm việc. Phân biệt hai loại này là điều kiện để hệ thống cảnh báo còn đáng tin sau vài tuần.
Một ví dụ script đọc log bằng PowerShell, chạy mỗi 5 phút:
# canh-log-mt5.ps1 — đọc log EA, khớp mẫu, báo động khi vượt ngưỡng
$logFile = "C:\MT5\MQL5\Logs" # MT5 ghi log theo ngày: AAAAMMDD.log
$trangThai = "C:\MT5\canh-log-trangthai.json"
$homNay = Get-Date -Format "yyyyMMdd"
$fileLog = Join-Path $logFile "$homNay.log"
if (!(Test-Path $fileLog)) { Write-Output "Chưa có log hôm nay"; exit 0 }
# Các mẫu cần bắt: tên → (mẫu regex, số lần tối đa, cửa sổ phút)
$mau = @{
"mat-ket-noi" = @{ Re = "no connection|network error"; SoLan = 2; Phut = 5 }
"sai-tai-khoan" = @{ Re = "authorization failed|invalid account"; SoLan = 1; Phut = 60 }
"ea-bi-go" = @{ Re = "expert removed|cannot load expert"; SoLan = 1; Phut = 60 }
"khong-duoc-phep"= @{ Re = "trade is not allowed|4109"; SoLan = 1; Phut = 60 }
"stops-volume" = @{ Re = "invalid stops|invalid volume|retcode=130|retcode=131"; SoLan = 3; Phut = 10 }
"thieu-margin" = @{ Re = "not enough money|retcode=134"; SoLan = 1; Phut = 60 }
}
$dong = Get-Content $fileLog -Tail 2000
foreach ($ten in $mau.Keys) {
$m = $mau[$ten]
$khop = $dong | Where-Object { $_ -match $m.Re }
if ($khop.Count -ge $m.SoLan) {
Write-Output "CANH BAO [$ten] $($khop.Count) lan trong $($m.Phut) phut"
# Gọi hàm gửi Telegram/Email ở đây
}
}Script này cố tình đơn giản: nó không có trạng thái, không có database, chỉ đọc 2.000 dòng cuối và đếm. Với cảnh báo theo log, đơn giản là một đức tính — vì bạn cần nó hoạt động trong lúc mọi thứ khác đang hỏng.
7. Phân biệt lỗi ở tầng nào để không sửa sai
Một sai lầm tốn thời gian phổ biến: thấy lỗi giao dịch rồi đi sửa EA, trong khi nguyên nhân nằm ở tài khoản. Bảng dưới đây phân loại nhanh theo tầng.
| Tầng | Dấu hiệu trong log | Sửa ở đâu |
|---|---|---|
| Sàn / tài khoản | 130, 131, 134, 148, 4108, 4109, 4110 | Tham số lệnh, khối lượng, giới hạn tài khoản |
| Mạng / kết nối | no connection, network error, timeout, 138 | Hạ tầng VPS, mạng, DNS, vị trí đặt VPS |
| Terminal | expert removed, cannot load expert, terminal started | Profile, cấu hình đăng nhập, AutoTrading |
| Máy / hệ điều hành | Không có log nào, Event Viewer có 41/6008/1074 | RAM, ổ đĩa, Windows Update, Scheduled Task |
| Logic EA | array out of range, zero divide, NO-SIGNAL liên tục | Code EA, tham số, bộ lọc điều kiện |
Nguyên tắc đọc bảng này: nếu lỗi thuộc tầng sàn hoặc tầng logic, sửa EA cũng vô ích — bạn cần sửa tham số hoặc điều kiện. Nếu lỗi thuộc tầng máy, EA không có lỗi gì cả và bạn đang tìm ở sai chỗ.
Một chi tiết thực tế: lỗi 138 (requote) không phải lỗi của bạn. Nó là tín hiệu mạng chậm hoặc thị trường đang biến động nhanh. Đừng đi tối ưu logic EA vì requote — hãy thêm retry và xem xét vị trí đặt VPS so với server broker.
8. Quản lý file log: giữ bao lâu và mất log khi nào
Log MT5 có vòng đời riêng và có ba cạm bẫy khiến bạn mất log đúng lúc cần nhất.
Cạm bẫy 1 — log chỉ giữ trong thời gian ngắn. Theo mặc định, MT5 giới hạn số ngày lưu log (thường 7 ngày cho Journal, và file theo ngày trong thư mục Logs). Nếu sự cố xảy ra và bạn chỉ phát hiện sau hai tuần, log có thể đã bị xoá. Nếu bạn dùng log để đối chiếu hiệu suất theo tháng, hãy tự lưu bản sao.
Cạm bẫy 2 — ổ đĩa đầy làm log im lặng. Đây là cạm bẫy khó thấy nhất: khi ổ đĩa gần đầy, MT5 có thể không ghi được log mới. Bạn sẽ thấy hiện tượng "log dừng ở giữa" và tưởng EA đã chết — trong khi EA có thể vẫn chạy. Hãy đặt ngưỡng cảnh báo cho dung lượng ổ đĩa ở 80%, đừng đợi tới khi máy báo đỏ.
Cạm bẫy 3 — file log của EA ghi đè lẫn nhau. Nếu bạn chạy nhiều EA cùng ghi vào một file, nội dung sẽ xen kẽ và khó đọc. Hãy cho mỗi EA một file riêng, tên file có tên EA hoặc tên tài khoản.
Thực hành khuyến nghị:
- Giữ log 30 ngày, có script dọn log cũ hơn 30 ngày.
- Ghi log quan trọng (sự kiện bất thường, lệnh bị từ chối) vào một file riêng, không bị xoá theo ngày.
- Đặt tên file log có ngày tháng để tìm nhanh:
canh-20260913.log. - Sao lưu log ra ngoài VPS định kỳ. Log nằm trong VPS có ích khi VPS còn sống; khi VPS chết, log chết theo — và đó lại đúng là lúc bạn cần log nhất.
9. Thực hành: chẩn đoán ba ca bệnh thật
Ca 1 — "Bot không vào lệnh suốt hai ngày." Log Experts đầy dòng NO-SIGNAL ly-do=spread với spread=38, trong khi bộ lọc đặt ngưỡng 25. Đọc log là biết ngay: bộ lọc quá chặt so với spread thật của symbol trong khung giờ đó. Việc cần làm không phải sửa logic, mà xem lại ngưỡng — dựa trên dữ liệu spread đã ghi, không dựa trên cảm giác.
Ca 2 — "Bot chạy tới 3 giờ sáng rồi im." Log Experts dừng đột ngột giữa một chuỗi dòng bình thường. Tab Trade không có lệnh bị từ chối. Journal có dòng terminal started lúc 5 giờ 12 phút. Event Viewer có mã 1074 lúc 5 giờ 10 phút. Kết luận: Windows Update khởi động lại máy lúc 5 giờ sáng, MT5 bị đóng, và không tự mở lại. Không có lỗi nào trong EA — vấn đề hoàn toàn ở tầng máy.
Ca 3 — "Có lệnh nhưng lệnh vào sai khối lượng." Log Trade cho thấy lệnh được gửi với khối lượng 0.13 trên một symbol yêu cầu bước 0.01 nhưng tối đa 0.10 cho tài khoản nhỏ. Lỗi trả về 131 xuất hiện ba lần, sau đó EA tự giảm khối lượng và thành công. Nhìn vào log, bạn thấy rõ nguyên nhân: khối lượng tính từ số tiền mà không chuẩn hoá theo VOLUME_MAX của symbol.
Điểm chung của cả ba ca: không ca nào chẩn đoán được nếu EA không ghi log có nội dung. Ca 1 cần dòng NO-SIGNAL kèm lý do. Ca 2 cần mốc thời gian chính xác của dòng cuối. Ca 3 cần log cả tham số khi bị từ chối. Ba dòng log ở mục 5 chính là thứ tạo ra ba khả năng đó.
Ca 4 — "Bot chạy nhưng không có log nào cả"
Ca này đáng nói riêng vì nó khiến nhiều người mất cả buổi. Bạn mở tab Experts và thấy trống hoàn toàn, hoặc chỉ có vài dòng từ nhiều ngày trước. Bạn kết luận EA bị lỗi. Nhưng thứ tự chẩn đoán đúng phải là:
Bước 1 — EA có thật sự nằm trên chart không? Mở đúng chart, nhìn góc trên bên phải. Có biểu tượng tên EA không? Nếu không có, EA chưa từng được gắn — hoặc đã bị gỡ. Tab Experts trống vì không có gì để chạy, không phải vì EA lỗi.
Bước 2 — EA có được phép in log không? Trong MQL5, Print() ghi vào tab Experts, nhưng chỉ khi EA đang chạy. Nếu EA chạy mà không in gì, nguyên nhân đơn giản là code bạn không có lệnh Print() nào trong luồng thực thi. Đây là trường hợp phổ biến nhất, và nó không phải sự cố — nó là thiếu sót thiết kế.
Bước 3 — Bạn đang mở đúng file log chưa? Nếu EA ghi log ra file riêng (như khuyến nghị ở mục 8) thì tab Experts sẽ trống theo thiết kế. Hãy vào thư mục MQL5\Files hoặc MQL5\Logs và mở file bằng Notepad. Nhiều người tìm trong tab Experts và tưởng không có log, trong khi file log của họ đang phình ra hàng megabyte.
Bước 4 — Log có bị xoay vòng và mất không? MT5 ghi log theo ngày. Nếu bạn tìm log của hôm qua trong file hôm nay, bạn sẽ thấy nó trống. Kiểm tra tên file: AAAMMDD.log — đúng ngày bạn cần mới có nội dung.
Bước 5 — Ổ đĩa có đầy không? Như đã nói ở mục 8, ổ đĩa gần đầy có thể khiến MT5 ngừng ghi log mới trong khi vẫn tiếp tục chạy. Kiểm tra dung lượng trước khi kết luận EA có vấn đề.
Thứ tự năm bước này quan trọng: nó đi từ nguyên nhân đơn giản nhất (EA không ở trên chart) tới phức tạp nhất (lỗi code). Đi ngược lại — bắt đầu bằng việc đọc code để tìm lỗi — là cách tốn thời gian nhất, vì bạn có thể đang tìm bug trong một EA hoàn toàn không chạy.
Một thói quen nhỏ đáng làm: mở log trước khi ngủ
Nếu bạn chạy bot qua đêm, hãy tạo thói quen mở tab Experts và tab Trade đúng một lần trước khi đi ngủ. Việc này mất 20 giây và cho bạn một thứ rất có giá trị: trạng thái nền của một hệ thống đang hoạt động bình thường.
Kiến thức về "bình thường" là thứ bạn không thể có nếu chỉ đọc log khi có sự cố. Khi biết log bình thường trông như thế nào — dòng nhịp tim nào xuất hiện, mật độ bao nhiêu dòng một giờ, RET xuất hiện ra sao — bạn sẽ nhận ra bất thường trong vòng vài giây thay vì phải so sánh với trí nhớ mơ hồ. Và vào đêm có sự cố, chính kiến thức đó là thứ giúp bạn trả lời nhanh câu hỏi: "dòng cuối cùng này có lạ không?"
10. Checklist 12 điểm
- Biết bốn loại log và mở đúng loại cho câu hỏi đang có
- EA có dòng log nhịp tim định kỳ (15 phút một lần là đủ)
- EA có dòng
NO-SIGNALkèm lý do bị chặn - EA log cả trường hợp gửi lệnh thành công
- Khi bị từ chối, log có đầy đủ tham số đã gửi
- Mã trả về được dịch thành chữ đọc được
- Có log độ trễ (
GetTickCount) để thấy vấn đề mạng sớm - Mỗi EA ghi log vào file riêng
- Không ghi đè: file log có ngày hoặc tên EA
- Có script dọn log cũ và cảnh báo dung lượng ổ đĩa
- Có cảnh báo tự động cho ít nhất 4 dòng log ở mục 6
- Log quan trọng được sao lưu ra ngoài VPS
Bốn ý cần nhớ:
- Log là bằng chứng duy nhất, và nó chỉ hữu ích nếu bạn tự viết. MT5 không biết gì về logic của EA bạn.
- Đọc từ dòng cuối lên. Dòng cuối cùng là trạng thái lúc bot ngừng; đó là dòng quan trọng nhất trong cả file.
- Mỗi dòng log phải trả lời: ai, làm gì, kết quả nào, số đo bao nhiêu. Không có số thì không chẩn đoán được.
- Báo động theo log bổ sung cho báo động theo heartbeat. Heartbeat biết bot đã im lặng; log biết vì sao.
Nếu bạn muốn đi tiếp: Bot chết lúc 3h sáng: 12 nguyên nhân thật là bảng tra theo nguyên nhân (bài này là bảng tra theo dấu hiệu), và EA Watchdog: tự viết lớp canh chừng thứ hai hướng dẫn phần heartbeat mà log nhịp tim dựa vào.
Log không làm bot của bạn chạy tốt hơn. Nó chỉ làm bạn biết chuyện gì đã xảy ra — và đó là điều kiện đầu tiên để sửa được.