Is your guard real or decorative? A checklist
Every question below can be answered by running something rather than reading code. That is the point: guards fail silently, so the only useful evidence is behaviour under conditions you deliberately created.
A. Is it on the path that can act?
- Does the component that decides also prevent, or does it write a flag somebody else is supposed to read? (A signal nobody consults is a log line with a notification attached.)
- If you disable the guard, does an order get refused - or does everything look identical? Try it.
- Is the check the last thing before submission, or one of several parallel opinions that can disagree?
B. Does it survive being killed?
- Let the limit trip with a position open, then kill the process (not the unit test), restart it, and watch the next cycle. Does the block survive? (If not, your protection has the lifetime of an in-memory variable.)
- Does the restored state know which day it belongs to? Without that, it is either ignored or applied forever. (Both look like success.)
- Can the resumed process tell how old its own memory is? If not, it will act on a stale premise confidently.
C. Does it know what time it is?
- Is "today" derived from the broker's clock or from
TimeLocal()? Change the host timezone and re-run the rollover test. (The boundary moves by hours and nothing throws.) - Do you log the drift between the two clocks every cycle? If the answer is no, the first time you will see a two-hour disagreement is during an incident.
- Is "no data" distinguishable from "zero"? A guard that reads zero because its feed died is a guard that is not guarding.
D. Does anything measure the effect?
- What is your time-to-effect - wall-clock from a real breach to the system being genuinely unable to act? If you have never measured it, you do not know what you bought. (Time-to-detect is the easy number.)
- Which alerts, if ignored entirely, would change no decision? Those are not alerts. (Decisionless is not the same as wrong.)
- When the guard last fired for real, what did anyone do differently - and did the log say so out loud?
What a "yes" set looks like
| Property | Evidence that satisfies it |
|---|---|
| On the action path | Disabling it provably refuses an order |
| Restart-proof | Kill-with-position test, verdict survives, dated |
| Clock-correct | Timezone-changed rollover test passes |
| Freshness-aware | Feed cut -> guard reports an incident, not a zero |
| Effect measured | A number, in seconds, from breach to inability to act |
| Loud when it fires | The blocked state is visible without reading a database |
Six properties, five of which are found by breaking something on purpose. That is the whole difference between a guard and a decoration: the decoration is only ever tested on the day everything works. (The silent failure modes that make this list necessary.)
If you want a reference implementation of the state/persistence half of this list, the free MT5 guard is here - source included, nothing to install beyond the terminal.
Related notes
- Your daily loss limit resets when MetaTrader restarts. Here is the fix.
- Memory plus an expiry policy: what a restarted guard is allowed to assume
- Detection is not resolution: the gap that makes guards decorative
- Decisionless monitoring: the reports nobody acts on
- What a kill switch should actually do (and the four ways they fail)
- Silent failures in trading automation: the three that cost the most
- Which day is it? Broker time, host time, and the trading-day boundary
Risk disclosure
Algorithmic trading carries both technical and market risk. No tool eliminates the possibility of loss. Nothing on this page is investment advice, and no performance is implied or promised.