← j4red.net

ga_trader / genome.py + features.py

What one trader's brain actually looks like

Every trader in the population is one tiny MLP plus a handful of evolved scalar genes riding alongside the weights. No backprop — crossover and mutation shape everything below. Two architectures actually run in this project; toggle between them.

Network

tanh(W₁x + b₁)  →  softmax(W₂h + b₂)
33 hand-engineered features, 200-bar lookback 12 hidden units, tanh 3 actions, softmax

How a softmax probability becomes a trade

engine.py — Market.step()
01
Forward pass
Batched across all 2,000 traders at once, every tick. Same features, 2,000 different evolved weight sets.
02
Confidence gate
Acts only if max(prob) ≥ conf and its margin over "flat" clears margin — both evolved per trader.
03
RSI gate
If rsi_gate > 0.55, blocks buying overbought / shorting oversold — an optional evolved guard.
04
Position sizing
Notional = cash equity × 2× leverage × size gene, frozen at entry.
05
Exit
Whichever comes first: stop_frac adverse move, max_hold_sec elapsed, or a confident reversal signal.

The genes — evolved, not trained

genome.py — random_genome() / mutate()
conf
0.34 – 0.62
Minimum softmax confidence required before acting on any signal at all.
margin
0.04 – 0.22
How far the top action's probability must clear "flat" — decisiveness, not just confidence.
stop_frac
0.004 – 0.06
Adverse price move (as a fraction) that force-closes the position early.
max_hold_sec
45s – 5min *
Hard ceiling on how long a position can stay open, whatever else happens.
size
0.35 – 1.0
Fraction of allowed notional (cash × leverage) committed when a position opens.
rsi_gate
0.0 – 1.0
Threshold controlling whether the optional overbought/oversold guard is active.