A client asked me to “fix one small thing” in their EA last month — twenty minutes into the code review, I could see the fix would take longer than a rebuild. The EA compiled, backtested fine, and had been running on demo for weeks, but every function was wired to every other function and touching one line meant testing the entire system. Whether a struggling EA deserves optimization or a full rebuild depends on three structural factors — code structure quality, strategy logic validity, and state management architecture — and most traders waste money by defaulting to the wrong choice.
I evaluate this for clients regularly. The answer is never obvious from the outside. An EA that “mostly works” can be a cheap fix or a total rebuild depending on what is happening under the surface. Here is the framework I use.
The Wrong Default
Traders almost always default to one of two extremes: “just fix this one thing” or “start from scratch.” Both defaults are expensive when applied to the wrong situation.
I had a client who paid for three separate rounds of patching on the same EA. The first round fixed a trailing stop that was not respecting the broker’s minimum stop level. The second round added error handling to `OrderSend()` calls that were failing silently. The third round attempted to add state persistence so the EA could survive terminal restarts. Each patch was technically correct — but every fix uncovered another structural problem, because the EA had been built without error handling, without state management, and with hardcoded lot sizes embedded directly in the logic. The total patching cost exceeded what a clean rebuild would have cost from the start.
The opposite mistake is just as common. A different client wanted a full rebuild of an EA that had been running live for over a year. The core logic was sound — profitable strategy, clean entry signals, proper risk management. The only problems were a trailing stop module that did not account for spread widening and order management that occasionally sent duplicate close commands. Targeted fixes would have cost a few hundred dollars and shipped in days. A rebuild would have cost four times as much and taken weeks, with the added risk of introducing new bugs into logic that was already working.
The fix-or-rebuild decision is not intuitive. It requires looking at three specific factors.
Factor 1: Code Structure Quality
The first question is whether the existing code can absorb changes without breaking something else.
Signs the code can be fixed:
- Functions have single responsibilities — entry logic is separate from risk management, which is separate from order execution
- Named constants instead of magic numbers — `RISK_PERCENT` instead of `0.02` scattered across 15 lines
- Error handling exists on order operations — `OrderSend()` return values are checked and logged
- Conditional logic is shallow — you can read a function and understand what it does without tracing through 6 levels of nested if-statements
Signs the code needs replacing:
- One monolithic `OnTick()` function running 400+ lines with everything — signal detection, position sizing, order management, trailing stops, and logging — wired together
- Magic numbers everywhere — `if(iRSI(NULL, 0, 14, PRICE_CLOSE, 0) < 30)` with no explanation of why 14 or why 30
- Copy-pasted blocks with slight variations — the same order-sending logic repeated five times with minor tweaks, so fixing a bug means finding and editing all five copies
- Zero error handling — `OrderSend()` called with no check on the return value, meaning failed orders are invisible

I reviewed an EA last year where `OnTick()` was 450 lines of nested conditions. The developer who built it had copied the entry logic block, changed two parameters, and pasted it below the original to handle a second currency pair. The trailing stop logic appeared in three different places, each with slightly different math. Fixing the trailing stop in one place broke the other two. Every “small fix” in that codebase was a full regression test.
Compare that with an EA I reviewed the same month — separated functions, consistent naming, error handling on every order call. Replacing the trailing stop module took an afternoon because nothing else depended on its internals.
Factor 2: Strategy Logic Validity
Code quality is irrelevant if the trading logic underneath is flawed.
Before evaluating the code, I verify whether the strategy itself has an edge. Does the entry signal work on out-of-sample data, or does the backtest result only look good because the parameters were optimized to fit a specific historical window?
A client sent me an EA with genuinely well-structured code. Clean functions, proper error handling, reasonable naming. The problem was the entry logic: a single moving average crossover with MA periods optimized across an 18-month window of EURUSD data. The Strategy Tester showed a beautiful equity curve for that specific period. On out-of-sample data — the 12 months before and after — the system lost money consistently.
The code was professional. The strategy was curve-fitted. Rebuilding the code would have produced a beautifully engineered system that still lost money. My recommendation: validate the strategy first with walk-forward testing, then decide if the code infrastructure is worth keeping. No amount of code quality compensates for an entry signal that does not have an edge.
An EA built on a valid strategy with bad code is a rescue candidate — the hard part (finding an edge) is done. An EA built on a flawed strategy with clean code is worthless. This is counterintuitive for traders because the bad-code EA looks broken and the clean-code EA looks professional, but the rescue economics favor the first one every time.
Factor 3: State Management Architecture
This is the factor that most often tips the decision from “fix” to “rebuild.”
State management is how the EA tracks positions, persists data across terminal restarts, and recovers from crashes. It is architectural — woven into every function that reads or writes position data. It cannot be bolted on after the fact.
I evaluated an EA that tracked a basket of correlated positions using a global array. The code was clean. The strategy was valid. But every time the terminal restarted — after a VPS reboot, a weekend, or a MetaTrader update — the basket array reinitialized to empty. The EA saw no tracked positions, scanned the market, found valid entry signals, and opened a second basket on top of the existing one. After three restarts, the account had triple the intended exposure.

The fix seemed straightforward: add file-based persistence to save basket state. In practice, this meant modifying every function that added to, removed from, or read the basket array. The initialization logic needed to reconstruct state from disk. The closing logic needed to update the file. The modification logic needed to sync changes. By the time every function was touched, I had effectively rewritten the EA. The “fix” and the “rebuild” converged to the same amount of work — except the “fix” attempted to preserve a codebase that was never designed for persistence, while the rebuild could design around it from the start.
When state management is missing, assume it is a rebuild. The rare exception: an EA where all state is implicitly stored in open orders and can be reconstructed from `OrdersTotal()` on restart without any internal tracking.
The Three-Factor Decision Matrix
Three factors, two states each. Here is how the combinations map to recommendations:

| Code Structure | Strategy Logic | State Management | Recommendation |
|---|---|---|---|
| Adequate | Valid | Adequate | Fix — targeted optimization |
| Adequate | Valid | Inadequate | Partial rebuild — state management rewrite |
| Adequate | Unclear | Any | Pause — validate strategy first |
| Inadequate | Valid | Adequate | Partial rebuild — restructure code, preserve logic |
| Inadequate | Valid | Inadequate | Full rebuild — valid strategy, new codebase |
| Inadequate | Unclear | Any | Full rebuild — after strategy validation |
At barmenteros FX, the most common scenario in our rescue projects: inadequate code, valid strategy, no state management. The trader has a system that works in backtest and mostly works in live trading — until something goes wrong. The strategy is worth saving. The code is not. That is a rebuild, and knowing it upfront prevents three rounds of patching that lead to the same conclusion.
What This Means for Your Next Decision
The cost of getting this wrong runs in one direction. Patching an unfixable EA accumulates cost without progress — each fix reveals the next structural problem, and the total bill exceeds a rebuild. Rebuilding what could have been fixed wastes time and money when targeted optimization would have shipped in days.
The evaluation itself is cheap relative to either path. A code review takes hours, not weeks. The information it produces determines whether you spend $500 on targeted fixes or $2,000 on a full rebuild. Either path is valid when it is the right one for the codebase. The expensive mistake is the one you defaulted to without evaluating.
Before committing money to fix or rebuild your EA, ask the three questions: Can the code absorb changes without cascading failures? Does the strategy have an out-of-sample edge? Can the EA recover its state after a restart? If you cannot answer those yourself, a professional code review is the cheapest way to find out — and it pays for itself by preventing the wrong investment.


Leave a Reply