Home / Process Reveal / How We Evaluate: Fix the EA or Rebuild It

How We Evaluate: Fix the EA or Rebuild It

Tangled circuitry versus organized cable management — visual metaphor for the fix-or-rebuild decision in Expert Advisor development

“Fix one small thing” can turn out, twenty minutes into a code review, to take longer than a rebuild. An EA can compile, backtest fine and run on demo for weeks while every function is wired to every other function, so that touching one line means 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.

This is the decision a code review has to make. 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.

Consider three separate rounds of patching on the same EA. The first round fixes a trailing stop that is not respecting the broker’s minimum stop level. The second adds error handling to OrderSend() calls that are failing silently. The third attempts to add state persistence so the EA can survive terminal restarts. Each patch is technically correct — but every fix uncovers another structural problem, because the EA was built without error handling, without state management, and with hardcoded lot sizes embedded directly in the logic. The total patching cost exceeds what a clean rebuild would have cost from the start.

The opposite mistake: a full rebuild of an EA that has been running live for over a year. The core logic is sound — profitable strategy, clean entry signals, proper risk management. The only problems are a trailing stop module that does not account for spread widening and order management that occasionally sends duplicate close commands. Targeted fixes cost a few hundred dollars and ship in days. A rebuild costs four times as much and takes weeks, with the added risk of introducing new bugs into logic that is 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
Monolithic EA code versus modular EA code — the structure determines whether targeted fixes are possible or a rebuild is required

Picture an OnTick() of 450 lines of nested conditions. The developer who built it copied the entry logic block, changed two parameters, and pasted it below the original to handle a second currency pair. The trailing stop logic appears in three different places, each with slightly different math. Fixing the trailing stop in one place breaks the other two. Every “small fix” in that codebase is a full regression test.

Compare that with an EA built from separated functions, with consistent naming and error handling on every order call. Replacing its trailing stop module takes an afternoon, because nothing else depends 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?

Take an EA with genuinely well-structured code. Clean functions, proper error handling, reasonable naming. The problem is the entry logic: a single moving average crossover with MA periods optimized across an 18-month window of EURUSD data. The Strategy Tester shows a beautiful equity curve for that specific period. On out-of-sample data — the 12 months before and after — the system loses money consistently.

The code is professional. The strategy is curve-fitted. Rebuilding the code would produce a beautifully engineered system that still loses money. The right call: 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.

Take an EA that tracks a basket of correlated positions in a global array. The code is clean. The strategy is valid. But every time the terminal restarts — after a VPS reboot, a weekend, or a MetaTrader update — the basket array reinitializes to empty. The EA sees no tracked positions, scans the market, finds valid entry signals, and opens a second basket on top of the existing one. After three restarts, the account has triple the intended exposure.

Timeline showing how missing state persistence causes duplicate basket positions after each terminal restart — exposure triples over three restarts

The fix seems straightforward: add file-based persistence to save basket state. In practice, it means modifying every function that adds to, removes from, or reads the basket array. The initialization logic has to reconstruct state from disk. The closing logic has to update the file. The modification logic has to sync changes. By the time every function is touched, the EA has effectively been rewritten. The “fix” and the “rebuild” converge to the same amount of work — except the “fix” tries to preserve a codebase that was never designed for persistence, while the rebuild can 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:

Three-factor decision flowchart for evaluating whether to fix or rebuild an Expert Advisor — branching through code structure, strategy logic, and state management
Code StructureStrategy LogicState ManagementRecommendation
AdequateValidAdequateFix — targeted optimization
AdequateValidInadequatePartial rebuild — state management rewrite
AdequateUnclearAnyPause — validate strategy first
InadequateValidAdequatePartial rebuild — restructure code, preserve logic
InadequateValidInadequateFull rebuild — valid strategy, new codebase
InadequateUnclearAnyFull rebuild — after strategy validation

The combination that points to a rebuild: 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

Your email address will not be published. Required fields are marked *

Get a free quote

Fixed price within 24–48 hours. No subscriptions, no demos.