Tự khởi động lại MT5 sau khi VPS reboot: Scheduled Task, chế độ portable và 3 phép thử
Hướng dẫn13/09/2026 · 17 phút đọc

Tự khởi động lại MT5 sau khi VPS reboot — Scheduled Task, chế độ portable và 3 phép thử

Có một sự cố đơn giản đến mức nhiều người không coi nó là sự cố: VPS tự khởi động lại. Windows cài bản vá, nhà cung cấp bảo trì hypervisor, hoặc máy bị treo rồi tự hồi phục. Máy chạy lại trong 2 phút, mạng có lại, RDP hoạt động. Mọi thứ "bình thường" — trừ một chi tiết: MT5 không tự mở, và bot của bạn không chạy nữa.

Điều tệ là kiểu sự cố này rất khó nhận ra. Bạn kết nối RDP, thấy màn hình desktop trống, không có cửa sổ nào mở. Bạn tưởng mình chỉ cần mở MT5 là xong. Nhưng câu hỏi thật sự cần trả lời không phải là "mở MT5 thế nào", mà là:

Sau khi mở MT5, EA có tự nạp lên chart không? Algo Trading có tự bật không? Tài khoản có tự đăng nhập không?

Bài này trả lời cả bốn câu hỏi đó. Phần đầu là cấu hình Scheduled Task đúng cách — kể cả những tham số mà nếu bỏ sót thì task sẽ "chạy thành công" mà không làm gì. Phần sau là ba phép thử để chứng minh bot của bạn thật sự tự sống lại, thay vì tin vào cảm giác.


1. Vì sao "VPS reboot" là sự cố phổ biến nhất mà ít ai chuẩn bị

Có ba lý do khiến sự cố này bị xem nhẹ:

Thứ nhất, nó xảy ra ngoài giờ bạn làm việc. Windows Update mặc định chọn khung 2–5 giờ sáng. Nhà cung cấp VPS cũng chọn khung đó cho bảo trì. Kết quả là khi bạn mở máy buổi sáng, sự cố đã xảy ra bốn tiếng trước.

Thứ hai, nó không tạo ra lỗi rõ ràng. Không có popup, không có email, không có dấu chấm than đỏ. Nếu bạn không để ý tới giờ uptime của Windows, bạn sẽ không biết là máy đã khởi động lại.

Thứ ba, và quan trọng nhất: bật tính năng tự khởi động không có nghĩa là bot tự chạy lại. Đây là hiểu nhầm phổ biến nhất. Người ta cấu hình VPS "auto restart MT5" và tin rằng thế là xong. Nhưng một lần khởi động đi qua sáu bước, và việc tự mở chương trình chỉ giải quyết bước thứ ba.

Bước 4, 5, 6 — đăng nhập tài khoản, nạp EA lên chart, bật Algo Trading — không xảy ra tự động. Và vì terminal vẫn "đang chạy", mọi cách kiểm tra ngây thơ đều báo xanh. Bạn có một cửa sổ MT5 sáng đèn và một bot đã chết từ bốn tiếng.

2. Một lần khởi động đi qua 6 bước

Một lần khởi động lại VPS đi qua 6 bước
Một lần khởi động lại VPS đi qua 6 bước

Nhìn vào sơ đồ này, hãy tự hỏi: trong sáu bước, bước nào hệ thống của bạn đang tự làm?

  • Bước 1–3 (Windows khởi động, task chạy, mở terminal64.exe) là phần mà hầu hết mọi người đã cấu hình, và thường là phần duy nhất họ nghĩ tới.
  • Bước 4 (đăng nhập tài khoản) thất bại khi MT5 mở trước lúc mạng sẵn sàng, hoặc khi broker đổi server và cấu hình cũ không còn đúng.
  • Bước 5 (nạp EA lên chart) thất bại khi MT5 mở mà không có profile — tức là mở ra một chart trống. Không có lỗi nào được ghi, vì không có gì sai: MT5 đang chạy bình thường, chỉ là không có EA nào.
  • Bước 6 (bật Algo Trading) là bước hay thất bại nhất. MT5 có thể trở về trạng thái AutoTrading tắt sau khi khởi động, và mọi lệnh gửi đi sẽ bị từ chối với mã 4109.

Điểm mấu chốt: ba bước cuối không tạo ra lỗi, nên bạn không thể phát hiện bằng cách đọc log của Windows. Cách duy nhất để biết chúng có chạy hay không là kiểm tra kết quả cuối cùng — file heartbeat của EA có được cập nhật lại hay không.

3. Ba cách tự mở MT5 — chọn theo mức độ chịu sự cố

Ba cách tự mở MT5 và cái nào chịu được sự cố thật
Ba cách tự mở MT5 và cái nào chịu được sự cố thật

Cách 1 — Shortcut trong thư mục Startup. Đơn giản nhất: đặt shortcut của MT5 vào thư mục Startup của Windows. Ưu điểm là làm xong trong 30 giây. Nhược điểm quyết định: thư mục Startup chỉ chạy khi có người đăng nhập. VPS bị reboot lúc 3 giờ sáng thì không có ai đăng nhập, và task không chạy. Cách này ổn cho máy cá nhân, không ổn cho VPS.

Cách 2 — Scheduled Task với trigger "At startup". Đây là mức tối thiểu cho VPS. Task chạy khi hệ thống khởi động, không cần có người đăng nhập. Nhược điểm: task không có nhiệm vụ canh chừng. Nếu MT5 tự thoát vì lỗi (không phải do reboot), task không chạy lại — và bạn vẫn không biết gì.

Cách 3 — Scheduled Task + Agent kiểm tra định kỳ. Task mở MT5 lúc khởi động, và một tiến trình nhỏ kiểm tra mỗi 30 giây xem MT5 còn sống, EA còn chạy hay không. Đây là mức dùng cho bot chạy tiền thật. Nhược điểm: phải cấu hình thêm, và phải giới hạn số lần mở lại để không thành vòng lặp vô tận.

Thứ tự đúng để làm: bắt đầu ở cách 1 để chắc chắn MT5 mở được với đúng profile. Khi đã xác nhận, chuyển sang cách 2. Trong tuần đầu chạy thật, nâng lên cách 3. Đừng bắt đầu ở cách 3 — khi có sự cố, bạn sẽ không biết lỗi nằm ở Task hay ở Agent, và mất thời gian gỡ rối ở đúng chỗ phức tạp nhất.

4. Tạo Scheduled Task đúng cách bằng PowerShell

Đây là phần thực hành. Dùng PowerShell thay vì giao diện Task Scheduler vì bạn thấy được đầy đủ tham số, và có thể lưu lại để dựng lại trên VPS mới trong hai phút.

powershell
# Tạo Scheduled Task mở MT5 khi VPS khởi động (không cần đăng nhập)
# Chạy trong PowerShell với quyền Administrator.

$tenTask   = "FindMe-MT5-Startup"
$duongDan  = "C:\MT5\terminal64.exe"
$thamSo    = '/portable /profile:"BotChay"'

# (1) HÀNH ĐỘNG: mở MT5 với đúng profile
$hanhDong = New-ScheduledTaskAction -Execute $duongDan -Argument $thamSo -WorkingDirectory "C:\MT5"

# (2) TRIGGER: khi hệ thống khởi động — KHÔNG dùng "At log on"
$trigger = New-ScheduledTaskTrigger -AtStartup
$trigger.Delay = "PT90S"     # chờ 90 giây cho mạng sẵn sàng

# (3) TÀI KHOẢN: chạy dù không có ai đăng nhập
#     ⚠️ Không dùng "SYSTEM": MT5 cần một phiên người dùng để hiển thị chart.
$taiKhoan = New-ScheduledTaskPrincipal `
    -UserId "$env:COMPUTERNAME\Administrator" `
    -LogonType Password `
    -RunLevel Highest

# (4) CẤU HÌNH: các tham số quyết định thành bại
$caiDat = New-ScheduledTaskSettingsSet `
    -AllowStartIfOnBatteries `
    -DontStopIfGoingOnBatteries `
    -StartWhenAvailable `
    -RestartCount 3 `
    -RestartInterval (New-TimeSpan -Minutes 2) `
    -ExecutionTimeLimit (New-TimeSpan -Seconds 0)   # 0 = không giới hạn thời gian chạy

# (5) ĐĂNG KÝ
Register-ScheduledTask -TaskName $tenTask -Action $hanhDong -Trigger $trigger `
    -Principal $taiKhoan -Settings $caiDat -Force

Đọc lại đoạn trên, có năm tham số mà nếu sai thì task sẽ "chạy thành công" nhưng không làm gì:

Tham sốGiá trị đúngNếu sai thì sao
Trigger-AtStartupDùng "At log on" → reboot lúc 3h sáng thì không chạy
UserTài khoản có mật khẩu, -LogonType PasswordTask bị bỏ qua trong im lặng
ProgramĐường dẫn đầy đủ tới terminal64.exeTask báo thành công nhưng không mở gì
Arguments/portable /profile:"BotChay"MT5 mở ra chart trống, không có EA
DelayPT90S (90 giây)MT5 mở trước khi mạng sẵn sàng → mất phiên đăng nhập
Nội dung Scheduled Task cần có — 5 tham số quyết định
Nội dung Scheduled Task cần có — 5 tham số quyết định

Sau khi đăng ký, kiểm tra ngay bằng hai lệnh:

powershell
# Xem task có tồn tại và lần chạy gần nhất có lỗi không
Get-ScheduledTask -TaskName "FindMe-MT5-Startup" | Select-Object TaskName, State
Get-ScheduledTaskInfo -TaskName "FindMe-MT5-Startup" |
    Select-Object LastRunTime, LastTaskResult, NumberOfMissedRuns

# Chạy thử ngay, không cần khởi động lại máy
Start-ScheduledTask -TaskName "FindMe-MT5-Startup"
Start-Sleep -Seconds 5
Get-Process terminal64 -ErrorAction SilentlyContinue | Select-Object Id, StartTime

`LastTaskResult = 0` nghĩa là task đã chạy xong không lỗi — nhưng nó KHÔNG có nghĩa là MT5 đã mở đúng. Đây là điểm dễ bị hiểu sai nhất khi đọc Task Scheduler: task chỉ báo cáo rằng nó đã khởi chạy tiến trình, không báo cáo rằng tiến trình đó làm được gì. Một đường dẫn sai cũng cho LastTaskResult = 0 trong nhiều trường hợp. Vì vậy phép thử thật sự là phép thử ở mục 9.

5. Chế độ portable: vì sao /portable là bắt buộc

Mặc định, MT5 lưu toàn bộ dữ liệu của bạn — profile, template, EA, log, file cấu hình — trong một thư mục có tên dạng mã băm, nằm sâu trong %APPDATA%\MetaQuotes\Terminal\<MÃ BĂM>\. Thư mục này:

  • Không nằm cạnh chương trình, nên bạn không biết nó ở đâu nếu không tra cứu.
  • Phụ thuộc vào tài khoản Windows đang chạy. Chạy MT5 bằng tài khoản khác → không thấy dữ liệu cũ, mở ra một terminal trống.
  • Khó backup: bạn phải nhớ sao chép đúng thư mục có mã băm, không phải sao chép thư mục cài đặt.

Khi thêm tham số /portable, MT5 chuyển sang lưu mọi thứ trong thư mục cài đặt. Cấu trúc trở thành:

C:\MT5\
├── terminal64.exe
├── config\
├── profiles\        ← profile bạn tạo, gồm chart + EA đã gắn
├── MQL5\
│   ├── Experts\     ← file .ex5 của EA
│   └── Files\       ← file heartbeat, log của EA
└── templates\       ← template chart (.tpl)

Ba lợi ích cụ thể:

  1. Scheduled Task hoạt động độc lập với tài khoản đăng nhập — vì dữ liệu không còn phụ thuộc %APPDATA% của người dùng nào.
  2. Backup bằng một lệnh: sao chép cả thư mục C:\MT5 là xong. Dựng lại trên VPS mới chỉ cần copy thư mục và sửa lại Scheduled Task.
  3. Đường dẫn heartbeat cố định — file MQL5\Files\findme_hb.txt luôn nằm ở cùng một chỗ, nên script bên ngoài đọc được mà không cần dò tìm.

Một lưu ý khi chuyển sang portable: nếu bạn đã chạy MT5 ở chế độ thường, dữ liệu cũ nằm ở %APPDATA%. Hãy copy thư mục MQL5profiles từ đó vào thư mục cài đặt trước khi chạy portable lần đầu, nếu không bạn sẽ thấy một terminal trắng.

Dựng lại VPS mới trong 15 phút — lợi ích thật của chế độ portable

Chế độ portable không chỉ giúp Scheduled Task hoạt động. Nó biến việc dựng lại môi trường từ một buổi chiều thành một quy trình 15 phút. Điều này quan trọng vì có hai tình huống bạn không thể tránh: nhà cung cấp VPS ngừng dịch vụ, hoặc máy bị lỗi ổ đĩa và không khởi động được nữa.

Nếu chưa chuẩn bị, tình huống đó diễn ra như sau: bạn mở VPS mới, tải MT5, đăng nhập kho tài khoản, tìm lại từng file .ex5 (không biết bản nào đang chạy), dựng lại từng chart (không nhớ tham số nào đã đặt), gắn EA, đặt lại tham số (không chắc giống bản cũ), rồi bật Algo Trading. Mất một buổi, và bạn không có cách nào chắc chắn rằng VPS mới chạy giống hệt VPS cũ.

Nếu đã chuẩn bị, quy trình chỉ còn bốn bước:

  1. Trên VPS cũ, sao chép cả thư mục `C:\MT5` ra một nơi khác — ổ đĩa thứ hai, Google Drive, hoặc máy của bạn. Vì chạy portable nên toàn bộ profile, EA, template, file .set đều nằm trong đó. Không có gì nằm rải rác.
  2. Trên VPS mới, chép thư mục `C:\MT5` về đúng đường dẫn đó. Giữ nguyên đường dẫn (ví dụ C:\MT5) để mọi thứ bên trong vẫn tìm thấy nhau.
  3. Tạo lại Scheduled Task bằng đúng đoạn PowerShell ở mục 4 — đổi tên tài khoản và mật khẩu cho phù hợp.
  4. Chạy phép thử 1 và phép thử 2 ở mục 9 để xác nhận.

Một chi tiết dễ bỏ sót: đừng sao chép thư mục `C:\MT5` khi MT5 đang chạy. MT5 đang mở có thể đang ghi file cấu hình, và bạn sẽ sao chép ra một bản sao nửa vời. Hãy đóng MT5 trước — hoặc tốt hơn, sao chép theo định kỳ tự động bằng một task chạy vào cuối tuần khi thị trường đóng.

Một chi tiết nữa: sao lưu thư mục EA (`.ex5`) không phải là sao lưu mã nguồn (`.mq5`). Nếu bạn chỉ giữ file đã biên dịch, bạn có thể chạy lại được nhưng không sửa được gì khi cần. Hãy giữ cả hai, và giữ .mq5 ở một repo mã nguồn riêng — không phải trên VPS, vì VPS có thể chết bất cứ lúc nào.

Cuối cùng, hãy đặt lịch kiểm tra bản sao lưu bằng cách khôi phục thật: ba tháng một lần, giải nén bản sao lưu ra một thư mục tạm và mở MT5 portable từ đó để xác nhận profile còn dùng được. Bản sao lưu chưa từng được khôi phục thử là bản sao lưu bạn không biết có tồn tại hay không.

6. Làm sao để EA tự nạp lên chart

Đây là bước 5 trong sơ đồ, và là bước bị bỏ qua nhiều thứ hai. Cách làm:

Bước 1 — Mở MT5 portable, gắn EA lên chart như bình thường. Chọn chart, gắn EA, cấu hình tham số, xác nhận EA đang chạy. Lưu ý bật AutoTrading cho EA ở bước này.

Bước 2 — Lưu thành profile có tên. Trong MT5: File → Profiles → Save As…, đặt tên ví dụ BotChay. Profile ghi lại chính xác tập chart đang mở, mỗi chart đang ở symbol/khung thời gian nào, và EA nào đang gắn trên đó.

Bước 3 — Dùng đúng tên profile trong tham số task: /profile:"BotChay". Chữ trong dấu ngoặc kép phải khớp chính xác với tên profile, kể cả dấu tiếng Việt nếu có — nên đặt tên profile không dấu để tránh rắc rối.

Bước 4 (kiểm tra). Mở lại MT5 bằng chính lệnh trong task. Nếu bạn thấy đúng các chart với đúng EA đã gắn, profile hoạt động.

Hai lưu ý thực tế về profile:

  • Profile lưu trạng thái EA, nhưng không phải lúc nào cũng lưu trạng thái "cho phép giao dịch". Nếu bạn gỡ EA, lưu profile, rồi gắn lại mà quên lưu lại, profile sẽ nhớ trạng thái cũ. Hãy kiểm tra sau mỗi lần thay đổi.
  • Nếu bạn đổi tên file EA (.ex5), profile sẽ không tìm thấy EA và gắn ra chart trống — MT5 có thể báo lỗi ngắn hoặc im lặng tùy trường hợp. Vì vậy đừng đổi tên file .ex5 sau khi đã lưu profile. Nếu buộc phải đổi, hãy gắn lại và lưu lại profile mới.

Một cách khác để chắc chắn EA nằm trên chart, độc lập với profile: template. Lưu chart có EA thành template (Charts → Template → Save Template), rồi khi MT5 mở có thể dùng tùy chọn mở chart từ template. Nhưng template chỉ gắn được khi có chart; profile là thứ quyết định chart nào tồn tại lúc khởi động. Vì vậy trong thực tế, profile là thứ quan trọng nhất, template là hỗ trợ.

7. Algo Trading: chỗ hay thất bại nhất

Đây là bước 6, và là bước tệ nhất vì nó không tạo ra dấu hiệu nào. Cần nói rõ cơ chế:

Trong MT5, có hai lớp "cho phép giao dịch":

  • Nút Algo Trading trên thanh công cụ — quyết định toàn terminal có cho phép EA giao dịch hay không.
  • Trạng thái Allow live trading trong hộp thoại thuộc tính của từng EA.

Nếu lớp thứ nhất tắt, mọi EA trên mọi chart đều không gửi được lệnh, và lỗi trả về là mã 4109 — "trade is not allowed". Nếu lớp thứ hai tắt, chỉ EA đó bị ảnh hưởng, và biểu tượng EA trên chart sẽ hiển thị trạng thái có dấu "x".

Cách xử lý có ba mức:

Mức 1 — Kiểm tra bằng mắt sau mỗi lần khởi động. Đúng, nhưng không đáng tin: bạn không thể kiểm tra bằng mắt một lần khởi động lại lúc 3 giờ sáng.

Mức 2 — Kiểm tra bằng log. Cho EA in ra một dòng xác nhận ngay trong OnInit(), ví dụ:

mql5
// Trong OnInit() của EA — chứng minh EA đã khởi tạo lại
PrintFormat("EA khởi tạo lúc %s | AlgoTrading=%s | tài khoản=%d",
   TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS),
   (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) ? "BẬT" : "TẮT"),
   (int)AccountInfoInteger(ACCOUNT_LOGIN));

Sau đó, script bên ngoài chỉ cần kiểm tra: file log có dòng "EA khởi tạo lúc ..." mới kể từ lần khởi động gần nhất không? Nếu không có, EA đã không nạp lại — bất kể MT5 có đang chạy hay không.

Mức 3 — Phép thử chủ động. Một lần mỗi ngày, vào giờ có thanh khoản, gửi một lệnh thử khối lượng nhỏ nhất vào một symbol ít biến động, rồi đóng ngay. Nếu lệnh thử bị từ chối, bạn biết ngay đường vào lệnh đang tắc — dù nguyên nhân là AutoTrading, tài khoản read-only, hay hết margin. Cách này tốn một chút phí spread, nhưng nó là cách duy nhất xác nhận toàn bộ chuỗi từ EA tới sàn còn thông.

Nhiều terminal trên một VPS: nhân bản đúng cách

Khi bạn chạy từ hai tài khoản trở lên trên cùng một VPS, câu chuyện tự khởi động phức tạp hơn theo cấp số nhân. Mỗi terminal là một tiến trình riêng, có thư mục dữ liệu riêng, có profile riêng. Và có hai cách dựng sai rất phổ biến.

Cách sai thứ nhất: dùng chung một thư mục MT5 cho hai tài khoản. Bạn mở hai cửa sổ từ cùng một terminal64.exe. MT5 cho phép điều này ở một mức độ, nhưng hai cửa sổ sẽ tranh nhau cùng thư mục dữ liệu: cùng file cấu hình, cùng MQL5/Files, cùng file heartbeat. Kết quả là một tài khoản ghi heartbeat đè lên tài khoản kia, và bạn không thể biết tài khoản nào đang chết. Đây là lỗi âm thầm và cực kỳ khó tìm, vì cả hai terminal đều trông như đang chạy.

Cách sai thứ hai: dùng `/portable` trên thư mục cài đặt chung. Nếu hai tài khoản cùng trỏ vào C:\MT5, tham số /portable chỉ làm vấn đề rõ hơn: hai tiến trình ghi vào cùng một thư mục, và file heartbeat bị ghi đè luân phiên.

Cách đúng: mỗi tài khoản một thư mục riêng, mỗi thư mục một bản MT5.

C:\MT5\TK-A\   terminal64.exe + profiles\TK-A + MQL5\Files\heartbeat-TKA.txt
C:\MT5\TK-B\   terminal64.exe + profiles\TK-B + MQL5\Files\heartbeat-TKB.txt

Với cấu trúc này, Scheduled Task của bạn có hai action — một cho mỗi tài khoản — và mỗi action dùng một tên profile khác nhau. Trong EA, hãy đặt tên file heartbeat khác nhau bằng một tham số đầu vào (input string TenFile = "heartbeat-TKA.txt";), nếu không hai EA sẽ ghi vào hai file khác nhau nhưng cùng tên.

Chi phí thật của cách này là dung lượng ổ đĩa: mỗi bản MT5 khoảng vài trăm MB. Trên VPS 40 GB, ba tài khoản vẫn thoải mái. Đổi lại, bạn có ba môi trường hoàn toàn tách biệt — và đây là điều kiện để chẩn đoán được sự cố: khi tài khoản A chết, tài khoản B vẫn chạy, và bạn biết vấn đề nằm ở tài khoản chứ không phải ở máy.

Một lưu ý về tài nguyên: ba terminal trên một VPS 2 GB RAM sẽ cạnh tranh bộ nhớ gay gắt. Trước khi nhân bản, hãy đo RAM thật của một terminal (chạy 24 giờ, xem mức đỉnh trong Task Manager), rồi nhân lên. Nếu tổng vượt 70% RAM của VPS, hãy tách sang máy thứ hai thay vì nhồi thêm.

8. Giới hạn số lần mở lại để không thành vòng lặp vô tận

Khi bạn thêm cơ chế tự mở lại, bạn vừa thêm một rủi ro mới: vòng lặp. Hãy tưởng tượng MT5 bị lỗi khi khởi động vì một file cấu hình hỏng. Cơ chế tự mở lại sẽ mở MT5, MT5 lỗi và thoát, rồi lại mở, lại lỗi — 200 lần một đêm. Kết quả: log dài 40.000 dòng, ổ đĩa gần đầy, và bạn vẫn không biết gì hơn.

Nguyên tắc cần áp dụng:

  1. Giới hạn số lần mở lại trong một khung thời gian. Ví dụ: tối đa 3 lần mỗi giờ. Sau đó dừng và chờ người thật.
  2. Luôn thông báo mỗi lần tự sửa. Tự sửa im lặng là kiểu hỏng tệ nhất: hệ thống có thể đang thử 40 lần một đêm và bạn không biết.
  3. Ghi lại mỗi lần thử vào file log riêng, kèm thời gian và lý do, để có dấu vết điều tra.
  4. Nếu 3 lần liên tiếp thất bại → leo thang. Gửi cảnh báo rõ ràng rằng hệ thống không thể tự sửa và cần người.

Một "Agent-lite" bằng PowerShell làm được đủ ba điều trên:

powershell
# canh-mt5.ps1 — chạy mỗi 30 giây qua Scheduled Task (trigger: At startup, repetition 30 giây)
$log       = "C:\MT5\canh-mt5.log"
$heartbeat = "C:\MT5\MQL5\Files\findme_hb.txt"
$nguongGiay = 90
$toiDaTrongGio = 3

function Ghi-Log($s) {
    "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')  $s" | Add-Content -Path $log -Encoding UTF8
}

# Kiểm tra file heartbeat có mới không
if (!(Test-Path $heartbeat)) { Ghi-Log "Không thấy file heartbeat"; exit 0 }
$phan    = (Get-Content $heartbeat -Raw).Trim() -split '\|'
$gioMay  = [int]$phan[1]
$treGiay = [int]([DateTimeOffset]::Now.ToUnixTimeSeconds() - $gioMay)
if ($treGiay -le $nguongGiay) { exit 0 }        # bot còn sống → không làm gì

# Bot im lặng quá ngưỡng
$daThu = @(Get-Content $log -ErrorAction SilentlyContinue |
           Where-Object { $_ -match 'MỞ LẠI MT5' -and
                          ([datetime]::Parse($_.Substring(0,19)) -gt (Get-Date).AddHours(-1)) }).Count
if ($daThu -ge $toiDaTrongGio) {
    Ghi-Log "Đã thử $daThu lần trong giờ — DỪNG, cần người xử lý"
    exit 0
}

if (!(Get-Process terminal64 -ErrorAction SilentlyContinue)) {
    Ghi-Log "MỞ LẠI MT5 (heartbeat cũ $treGiay giây)"
    Start-Process "C:\MT5\terminal64.exe" -ArgumentList '/portable', '/profile:"BotChay"'
} else {
    Ghi-Log "MT5 CÒN CHẠY nhưng heartbeat cũ $treGiay giây — treo, cần xem tay"
}

Hai dòng cuối cùng thể hiện một điểm quan trọng: script phân biệt "MT5 không chạy" với "MT5 chạy nhưng treo". Chỉ trường hợp thứ nhất mới mở lại được; trường hợp thứ hai phải kill tiến trình trước (và đó là hành động cần cân nhắc, vì có thể đang có lệnh mở).

9. Ba phép thử chứng minh bot thật sự tự sống lại

Ba phép thử này mất khoảng 15 phút và là bằng chứng duy nhất đáng tin.

Phép thử 1 — Chạy task bằng tay, kiểm tra MT5 mở đúng profile. Không cần khởi động lại máy. Bắt đầu ở đây để loại trừ lỗi cấu hình đơn giản trước khi thử thứ phức tạp.

Phép thử 2 — Khởi động lại VPS, KHÔNG đăng nhập. Đây là phép thử quyết định. Khởi động lại, rồi không kết nối RDP. Chờ 5 phút, sau đó từ máy khác (hoặc dịch vụ giám sát ngoài) kiểm tra: file findme_hb.txt có thời gian mới không? Nếu có, chuỗi bước 1–5 đã hoạt động mà không cần người đăng nhập. Nếu không, task của bạn đang phụ thuộc vào phiên đăng nhập.

Phép thử 3 — Kill MT5 và xem cơ chế tự mở lại. Đang trong phiên RDP, dùng Task Manager End Task terminal64.exe. Với Agent ở mục 8, hệ thống phải mở lại MT5 trong vòng khoảng 2 phút (90 giây ngưỡng + 30 giây chu kỳ). Ghi lại thời gian thực tế — đây là MTTR (thời gian phục hồi trung bình) của bạn, một con số bạn nên biết.

Sau ba phép thử, hãy kiểm tra thêm hai thứ:

  • Trạng thái Algo Trading sau khi tự mở lại. Không phải lúc nào MT5 cũng giữ được trạng thái này. Nếu nó tắt, bạn cần một bước kiểm tra nữa trong Agent.
  • Số lệnh đang mở có bị mất không. Nếu MT5 bị kill khi đang có lệnh, lệnh vẫn nằm ở phía sàn (vì lệnh đã được gửi đi), nhưng EA không còn nhớ trạng thái quản lý của nó. Đây là lý do các lệnh nên có stop-loss đặt ở phía server, không phải stop-loss "mềm" trong code.

10. Sơ đồ quyết định: tự mở lại MT5 đã đủ chưa?

Sơ đồ quyết định — tự mở lại MT5 đã đủ chưa?
Sơ đồ quyết định — tự mở lại MT5 đã đủ chưa?

Ba câu hỏi, theo thứ tự:

  1. MT5 có tự mở sau reboot? Nếu không → dùng Scheduled Task -AtStartup với delay.
  2. EA có tự nạp lên chart? Nếu không → dùng /portable + /profile:"TênProfile", và kiểm tra lại profile sau mỗi lần thay đổi EA.
  3. Algo Trading có tự bật? Nếu không → cần một lớp kiểm tra định kỳ đọc log khởi tạo của EA và bật lại khi cần.

Nhưng kể cả khi cả ba câu đều "có", bạn vẫn chưa xong. Có một trường hợp mà cơ chế tự mở lại không bao giờ xử lý được: VPS chết hoàn toàn. Khi đó không có task nào chạy, không có Agent nào kiểm tra, không có gì báo cho bạn. Đó là lý do lớp giám sát từ bên ngoài không thể bỏ qua — không phải vì nó thay thế được cơ chế tự mở lại, mà vì nó là thứ duy nhất còn sống khi VPS của bạn không còn sống.

11. Nhật ký khởi động: dấu vết để biết đã có reboot

Nếu bạn không biết VPS đã khởi động lại, bạn sẽ không biết cần kiểm tra gì. Cách nhanh nhất để biết:

powershell
# Lần khởi động gần nhất của Windows
(Get-CimInstance Win32_OperatingSystem).LastBootUpTime

# Các lần khởi động trong 7 ngày qua (mã 6005 = Event Log service khởi động)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=6005} -MaxEvents 10 |
    Select-Object TimeCreated, Message

# Các lần tắt/khởi động lại bất thường (41 = kernel-power, 6008 = shutdown ngoài dự kiến)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=41,6008} -MaxEvents 10 |
    Select-Object TimeCreated, Id, Message

# Xem tiến trình nào yêu cầu restart (thường là Windows Update)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=1074} -MaxEvents 5 |
    Select-Object TimeCreated, Message

Hãy dành ba phút để chạy bốn lệnh này ngay hôm nay. Chúng thường tiết lộ điều bất ngờ: máy của bạn đã khởi động lại nhiều lần hơn bạn tưởng, và một số lần là shutdown ngoài dự kiến (mã 6008) — tức là máy bị treo hoặc mất điện, không phải cập nhật.

Nếu bạn dùng dịch vụ giám sát, hãy thêm việc ghi lại thời điểm khởi động gần nhất vào mỗi bản báo cáo định kỳ. Một dòng "uptime: 3 giờ 12 phút" trong báo cáo buổi sáng là tín hiệu bạn cần để biết đêm qua đã có chuyện gì.

12. Checklist và tóm lại

Checklist 10 điểm cho cơ chế tự sống lại:

  1. Có Scheduled Task với trigger -AtStartup (không phải "At log on")
  2. Task chạy dưới tài khoản có mật khẩu, chọn "run whether user is logged on or not"
  3. Đường dẫn terminal64.exe là đường dẫn đầy đủ
  4. Tham số có /portable
  5. Tham số có /profile:"TênProfile" khớp chính xác tên profile
  6. Có delay 90–120 giây cho mạng sẵn sàng
  7. Profile đã được lưu với EA gắn đúng trên chart
  8. Agent kiểm tra định kỳ, có giới hạn số lần mở lại
  9. Mỗi lần tự mở lại đều có thông báo cho bạn
  10. Đã làm phép thử 2 (reboot và KHÔNG đăng nhập)

Bốn ý cần nhớ:

  1. Tự mở MT5 chỉ là bước 3 trong 6 bước. Ba bước cuối không tạo ra lỗi, nên không thể phát hiện bằng cách đọc log hệ thống.
  2. `-AtStartup` + `/portable` + `/profile` là bộ ba bắt buộc. Thiếu bất kỳ thứ nào, MT5 có thể mở ra một terminal trắng mà không báo lỗi.
  3. `LastTaskResult = 0` không chứng minh bot chạy. Nó chỉ chứng minh task đã khởi chạy. Bằng chứng thật là heartbeat được cập nhật.
  4. Tự mở lại không xử lý được trường hợp VPS chết. Chỉ lớp giám sát ngoài VPS làm được điều đó.

Nếu bạn muốn đi tiếp: EA Watchdog: tự viết lớp canh chừng thứ hai hướng dẫn phần heartbeat dùng trong bài này, và Bot chết lúc 3h sáng: 12 nguyên nhân thật là bảng tra cho mọi trường hợp còn lại.

Reboot không giết bot của bạn. Việc không ai kiểm tra sau reboot mới giết nó.
Đọc xong rồi? Hãy thử ngay — miễn phí 7 ngày.