Engineering note · Monitoring and recovery
MT5 VPS Monitoring: A Heartbeat Is Not Command Confirmation
A recent heartbeat proves that one component sent a message. It does not prove that a trading terminal is connected, that its account snapshot is current or that an emergency command finished. A useful MT5 monitoring dashboard keeps those facts separate and shows uncertainty before it shows a reassuring green status.
- 01Identify the target
- 02Check freshness
- 03Track the command
- 04Reconcile the result
Split health into facts a buyer can verify
Start by naming what the dashboard measures. A VPS process can be running while the terminal has lost its broker connection. The terminal can reconnect while the dashboard still displays an older position snapshot. The message transport can recover while a queued command remains unresolved. One online badge cannot describe all of these states.
For each terminal, show the last received heartbeat, the time and identity of the last accepted account snapshot, reported connection state and any unresolved command. Choose freshness limits in the specification. Label those limits as configuration choices rather than platform guarantees.
Record both the source timestamp and server receipt time. A clock error on a VPS should not make an old message appear fresh. An increasing sequence within a terminal session can help detect gaps, but it needs a defined reset rule after restart. Otherwise a legitimate new session can look like replayed traffic.
Bind telemetry to the correct terminal and account
Assign a stable terminal identity and a separate session identity. Bind each authorized sender to its expected account and server configuration. If the terminal switches accounts, the dashboard should show the mismatch until the intended binding is re-established. Do not silently route a command to whichever account happens to be open.
Use a configuration version in status messages and command records. A changed risk policy, account selection or group membership can change what a command means. The receiver should be able to identify the version it acted on, and the dashboard should retain that value alongside the result.
A global action needs a frozen target list. Suppose a new VPS registers while a group command is being dispatched. The specification must say whether that VPS is included. A snapshot of targets at command creation is one reviewable design; silently expanding the target set halfway through is not.
Give every command a visible lifecycle
Use a durable command identity, intended target, creation time, expiry time and requested action. Keep delivery acknowledgement separate from execution evidence. A practical display might distinguish queued, delivered, executing, reconciled, failed, expired and uncertain. These are proposed application states, not built-in MetaTrader status names.
An MT5 OrderSend call returning true is not proof that the requested market action has already completed. The official reference explains the need to inspect the result and track later trade events. OnTradeTransaction can report several transactions from one request, and the documentation warns against assuming one fixed arrival order.
Keep callbacks short and use them to update a clear record of the observed state. A command to cancel pending orders and close positions is a collection of possible outcomes. Some targets may complete while others reject or remain uncertain. Report the outcome per target before deriving a group summary.
- Queued: stored, but the intended terminal has not acknowledged delivery.
- Delivered: the terminal received the command; the requested effect is still unproven.
- Reconciled: the observed orders and positions meet the frozen completion condition.
- Uncertain: evidence is missing or inconsistent; an automatic green result is prohibited by the proposed design.
Recover without repeating a dangerous action
When the connection fails after dispatch, the dashboard does not know whether the terminal acted. Reconcile the current state and the durable command record before deciding to retry. Keep retry limits and allowed transitions explicit. A fresh HTTP response alone cannot resolve an earlier broker-side outcome.
On restart, load unresolved commands before accepting unrelated new work. Expired commands should not execute simply because connectivity returned. A repeated delivery of the same command identity should recover or return the existing result rather than start a second independent action.
Closing current positions also differs from preventing new entries. If another EA continues to trade, it may open a new position after the monitoring tool has closed the old one. Define the entry-blocking mechanism and its ownership separately. A second EA on another chart does not automatically control the strategy running on the first chart.
Start with one demo terminal and adverse cases
Before expanding across VPSs, agree one test terminal, an authorized demo environment and a small target set. Disconnect the transport at defined points, restart the receiver and introduce deliberately stale snapshots. Record command identities and observed terminal state for each run.
The handoff should include configuration, deployment notes, state definitions, logs and the three acceptance cases below. Make it possible to reproduce a failed case without exposing credentials. A screenshot of a green dashboard is only a screenshot; the matching command and terminal records explain what happened.
No monitoring design can guarantee that a disconnected terminal closes a position on demand. Market availability, broker rejection, partial execution and independent strategy activity remain relevant. The first deliverable should expose those boundaries accurately. More charts and more servers can come after the single-terminal evidence is sound.
Three acceptance checks
Proposed tests, not executed customer results. Record actual outcomes separately.
Heartbeat without fresh state
Input: Continue heartbeats while deliberately withholding new account snapshots.
Expected: The process may remain reachable, but account state becomes stale under the agreed limit. The dashboard never reports a completed command from heartbeat alone.
Response lost after dispatch
Input: Interrupt the connection after a demo command reaches the terminal, then reconnect.
Expected: The same command identity is reconciled against observed state. It is not blindly reissued as a new command.
Wrong target or expired command
Input: Change the terminal account binding, or deliver a command after its expiry.
Expected: The receiver refuses the action with an explicit reason. Other intended targets retain their own independently evidenced outcomes.
Sources and related guides
- MQL5: OrderSend result and execution boundary
- MQL5: OnTradeTransaction events and queue behavior
- Webhook retries and uncertain outcomes
- Define what an MT5 EA does after a manual close
- Three tests before a trading bot handoff
For your own brief, write the starting state, expected behavior and evidence for each case. The free Bot Blueprint gives you a place to collect those requirements.