In a genetic algorithm, the fitness function is the strategy. You can have a flawless evolutionary engine — clean crossover, sensible mutation, a healthy population — and still evolve garbage, because the population only ever becomes as good as the thing you told it to maximize. Choose the wrong objective and the GA will obediently breed a monster that scores perfectly and trades terribly.
Why "net profit" is a trap
The instinct is to maximize total profit. Don't. A GA optimizing raw net profit will reliably converge on strategies that:
The GA isn't broken — it did precisely what you asked. The objective was wrong.
Build a risk-adjusted objective
A good fitness function rewards quality of returns, not just quantity. Useful ingredients:
Add constraints so the GA can't cheat
Evolutionary search is brilliant at finding loopholes. Close them:
Make the fitness itself out-of-sample
The most important upgrade: don't score candidates only on the data they were bred on. Evaluate fitness with walk-forward or on a held-out validation slice, so a strategy's score reflects how it does on data it didn't evolve against. An individual that is brilliant in-sample and mediocre out-of-sample should receive a low fitness — that is exactly the signal you want driving selection.
Multi-objective, when one number isn't enough
Often you care about several things at once (high return and low drawdown and few parameters). You can fold them into a single weighted score, but a cleaner approach is multi-objective optimization (e.g. NSGA-II) that returns a Pareto front of trade-offs. Then you pick the balance you can actually live with, instead of pretending one magic weighting captures your real preferences.
A practical recipe
A solid starting fitness for trading:
Tune the weights deliberately and watch what the GA breeds — the strategies it converges on tell you, brutally honestly, what your fitness function actually values.
Bottom line
Garbage in, garbage out applies twice over to genetic algorithms: the objective you hand the GA is the only definition of "good" it will ever know. Reward risk-adjusted, consistent, out-of-sample, parsimonious performance with enough trades to mean something — and the evolutionary engine becomes a genuinely powerful ally instead of an overfitting machine.
Educational content from the PipFlow staff — not investment advice.
Why "net profit" is a trap
The instinct is to maximize total profit. Don't. A GA optimizing raw net profit will reliably converge on strategies that:
- take enormous, undiversified risk because one lucky run paid off;
- survive on a handful of outlier trades that will never repeat;
- sit through gut-wrenching drawdowns that no human would actually hold;
- overfit the exact wiggles of your training data.
The GA isn't broken — it did precisely what you asked. The objective was wrong.
Build a risk-adjusted objective
A good fitness function rewards quality of returns, not just quantity. Useful ingredients:
- Risk-adjusted return — Sharpe or, better for trading, Sortino (which only penalizes downside volatility). This is usually the backbone of the score.
- Drawdown penalty — divide return by maximum drawdown (a Calmar-style term) or subtract a penalty that grows with the deepest equity dip. This kills the "huge profit, unholdable drawdown" winners.
- Consistency — reward a smooth, steadily-rising equity curve. Measures like the R-squared of equity against a straight line, or profit factor, discourage lumpy, lottery-ticket performance.
Add constraints so the GA can't cheat
Evolutionary search is brilliant at finding loopholes. Close them:
- Minimum trade count. Without it, the fittest "strategy" is often one that took three trades and got lucky. Require statistical significance — heavily penalize candidates below a sample-size floor.
- Parsimony pressure. Penalize complexity (number of rules, parameters, or indicators). Simpler strategies generalize better; this is your main defence against overfitting inside the GA itself.
- Sane exposure limits. Penalize excessive leverage, position size, or time-in-market so the winner isn't just a maximally-geared bet.
Make the fitness itself out-of-sample
The most important upgrade: don't score candidates only on the data they were bred on. Evaluate fitness with walk-forward or on a held-out validation slice, so a strategy's score reflects how it does on data it didn't evolve against. An individual that is brilliant in-sample and mediocre out-of-sample should receive a low fitness — that is exactly the signal you want driving selection.
Multi-objective, when one number isn't enough
Often you care about several things at once (high return and low drawdown and few parameters). You can fold them into a single weighted score, but a cleaner approach is multi-objective optimization (e.g. NSGA-II) that returns a Pareto front of trade-offs. Then you pick the balance you can actually live with, instead of pretending one magic weighting captures your real preferences.
A practical recipe
A solid starting fitness for trading:
- Base score = Sortino (or Sharpe) on walk-forward results;
- multiplied/penalized by maximum drawdown;
- hard penalty if trade count is below your significance floor;
- small penalty per parameter/rule for parsimony.
Tune the weights deliberately and watch what the GA breeds — the strategies it converges on tell you, brutally honestly, what your fitness function actually values.
Bottom line
Garbage in, garbage out applies twice over to genetic algorithms: the objective you hand the GA is the only definition of "good" it will ever know. Reward risk-adjusted, consistent, out-of-sample, parsimonious performance with enough trades to mean something — and the evolutionary engine becomes a genuinely powerful ally instead of an overfitting machine.
Educational content from the PipFlow staff — not investment advice.
clean
by ai-agent