Backtesting and Optimization

Genetic Strategy Optimization

Deep dive into the DEAP-based genetic evolution algorithm, parameter mutation, crossover operations, fitness functions, and Out-of-Sample validation inside DepthSight.

โฑ๏ธ 10 min read๐Ÿ“Š Level: Advanced

Manual parameter optimization (trying different EMA periods, RSI thresholds, or Stop Loss multipliers) can take weeks. DepthSight leverages genetic algorithms via the DEAP library (ot_module/genetic_strategy_finder.py, ~2,270 lines) to automate strategy optimization by simulating evolutionary processes.


Evolutionary Optimization Cycle

The GeneticStrategyFinder (line 906) maintains a "population" of strategy configurations and evolves them over multiple generations. Each "individual" is a complete strategy JSON (dict with ilters, entryConditions, initialization, positionManagement).

Rendering diagram...

Evolutionary Loop (run(), line 1191)

Sources:

Default Parameters:

ParameterValueDescription
population_size50Number of strategy individuals per generation
generations20Number of evolutionary iterations
crossover_probability0.7Likelihood of crossover between two parents
mutation_probability0.3Likelihood of mutation per individual
elite_count3Top strategies preserved unchanged each generation
hall_of_fame_size10Best-ever strategies tracked across all generations

Gene Pool Initialization

Dynamic GENE_POOL from UI (uild_dynamic_gene_pool, line 287)

The UI configuration drives which indicators, filters, and risk parameters are evolvable. The gene pool defines the valid ranges for each parameter the algorithm is allowed to modify:

Block TypeEvolvable ParametersRange
rsi_conditionperiod, threshold5โ€“50, 10โ€“90
ma_cross_conditionfast_period, slow_period5โ€“50, 10โ€“200
bollinger_bands_conditionperiod, std_dev10โ€“50, 1โ€“4
atr_stop_lossatr_multiplier0.5โ€“5.0
trailing_stopactivation_pct, trail_pct0.1โ€“5.0, 0.1โ€“3.0

Seeded Population (_init_seeded_population, line 1074)

Instead of starting from complete randomness, the algorithm initializes a "seeded" population using the user's base strategy parameters:

Sources:

The seed fills population_size // 2 slots with exact copies of user strategies, then fills the remaining slots with slightly mutated variations. This bootstraps the evolutionary curve, ensuring it builds upon viable logic rather than random noise.


Crossover Operations

The _crossover_individuals() method (line 1805) operates at two levels:

Level 1 โ€” Initialization Parameter Swap

For each common parameter in the initialization sections (SL type, TP value, direction), there is a 50% chance of swapping:

Sources:

Level 2 โ€” Sub-Tree Exchange in Logic Sections

For ilters and entryConditions sections (70% probability each):

Sources:

This allows entire logical branches (e.g., an RSI condition with all its children) to migrate between strategies, creating novel hybrid approaches.


Mutation Operations

The _mutate_individual() method (line 1870) supports four mutation types:

1. Parameter Mutation (per-param, ind_pb=0.1)

Randomly re-initializes individual parameters from the GENE_POOL allowed ranges:

Sources:

2. Structural Node Replacement (20%)

Replaces a leaf node with a randomly generated node of a different type (e.g., replacing an RSI condition with a Bollinger Bands condition).

3. Logical Tree Mutation (15%)

Adds or removes a child from AND/OR nodes, effectively changing the complexity and logic of the condition tree.

4. Operator Flip

For AND/OR nodes, flips the logical operator, changing the relationship between child conditions.

Timeframe Mutation

Each node has a 30% chance of having its timeframe parameter randomly changed (e.g., from 5m to 15m), enabling cross-timeframe strategy evolution.


Fitness Function (_evaluate_fitness, line 997)

The success of each individual is assessed using a multi-asset, multi-metric fitness function:

Sources:

Three Objective Modes

The optimizer supports three main fitness goals configurable by the user:

ModeFormulaBehavior
Maximize Net Profitscore = avg_pnlFinds highest absolute profit, may accept high drawdowns
Maximize Sharpescore = sharpe_ratio * 10Prioritizes risk-adjusted returns
Minimize Drawdownscore = 100 - avg_max_ddMinimizes risk, seeks smooth equity curves

Overfitting Prevention

A common issue in genetic search is overfitting โ€” creating a strategy that memorized historical data perfectly but fails in live trading. DepthSight implements multiple safeguards:

In-Sample / Out-of-Sample Split (split_data_is_oos, line 863)

The historical data is chronologically split with oos_ratio=0.30 (30% held out):

[========= In-Sample (70%) =========][=== OOS (30%) ===]
  Genetic search runs here                Final validation

Walk-Forward Windows (split_data_into_windows, line 818)

Supports N-window walk-forward optimization where the strategy is tested across multiple non-overlapping time periods:

Sources:

OOS Validation in Final Results (lines 1506โ€“1542)

After evolution completes, each Hall of Fame strategy is evaluated on the OOS window:

Sources:

Multi-Asset Training

Fitness is averaged across multiple assets (configurable list), preventing single-asset overfitting. A strategy that works on both BTCUSDT and ETHUSDT is more likely to generalize.

Hall of Fame Diversity

The top 10 strategies across all generations are preserved, with diversity tracked by their JSON structure hash to prevent the population from converging on a single solution.


Checkpointing & Resume

The genetic optimizer supports JSON-safe checkpoints (lines 1400โ€“1435) โ€” no pickle serialization:

Sources:

This allows resuming evolution from any checkpoint, useful for long-running optimizations that may need to survive server restarts.


Configuration Reference

ParameterDefaultDescription
population_size50Number of strategy individuals per generation
generations20Maximum evolutionary generations
crossover_probability0.7Likelihood of crossover between parents
mutation_probability0.3Likelihood of mutation per individual
tournament_size2Selection tournament participants
elite_count3Top strategies preserved unchanged
hall_of_fame_size10Best-ever strategies tracked
walk_forward_oos_ratio0.30Fraction of data held out for OOS
keep_structuretrueWhen true, only numeric params mutate
min_trades_kill_switch30Minimum trades to avoid elimination
max_trades_kill_switch1000Maximum trades before spam filter
max_drawdown_kill_switch25%Maximum drawdown before elimination