An EA without risk controls can damage an account quickly when something goes wrong. A few controls cover most failure scenarios.
Essential controls:
Maximum daily loss: stop trading after a set loss.
Maximum open positions: prevent runaway order loops.
Spread filter: no entries when spread is above a threshold.
News filter: pause around high-impact events.
Maximum lot size: cap regardless of calculation.
Kill switch: a manual or external way to stop the EA immediately.
Testing these controls is as important as testing the strategy: simulate a disconnection, a spread spike, and a calculation error.
It also helps to log every time a control triggers. A spread filter that blocks trades every morning, for example, may indicate that the EA is trading at the wrong time of day.
Maximum open positions does not catch every runaway loop. I once had an EA open and close the same trade 40 times in two minutes because the exit condition was already true at entry, and it never held more than one position.
So I count orders sent per minute as well, with a hard stop at five. When it trips, the EA disables itself and writes the reason to the journal, and it stays off until I reset it by hand.
The daily loss check should use equity, not closed balance. A limit based only on closed trades lets an open loser run straight past it, which is exactly the case a prop rule punishes.
For the news filter I have the opposite worry. If it relies on a downloaded calendar and the download fails, the safe default is no trading, yet a lot of code I have seen falls through to normal behaviour.
My kill switch is a terminal global variable that every instance checks on each tick. Setting it from one script stops all of them, which beats closing six windows during a fast market.
Spread spikes are easy to test with a custom symbol built from recorded ticks. How do others simulate a disconnection in the tester?