Hierarchical gene data structure for genetic algorithms
Project description
ff-genetic-algorithm
Hierarchical gene structure based genetic algorithm framework for Python.
Schema-driven DNA representation with layered pool management, multiple spawner strategies, and end-to-end generation cycle support.
Installation
pip install ff-genetic-algorithm
Requires Python >= 3.10. No external dependencies.
Usage
DNA Schema Definition
from ff_genetic_algorithm.l0.gene_schema import GeneSchema
from ff_genetic_algorithm.l0.sequence_schema import SequenceSchema
# -- Gene types --
# bool: True/False
GeneSchema("use_trailing", bool)
# int: range required (inclusive)
GeneSchema("leverage", int, range=(1, 10))
# float: range required, values rounded to 3 decimal places
GeneSchema("stop_loss", float, range=(0.01, 0.1))
# choices: enum-like selection from a list
GeneSchema("strategy", choices=["momentum", "mean_reversion", "breakout"])
# -- Sequence: groups genes into a named unit --
SequenceSchema("rsi", [
GeneSchema("period", int, range=(5, 50)),
GeneSchema("threshold", float, range=(20.0, 80.0)),
])
# -- Nested sequences --
SequenceSchema("indicators", [
SequenceSchema("rsi", [
GeneSchema("period", int, range=(5, 50)),
GeneSchema("threshold", float, range=(20.0, 80.0)),
]),
SequenceSchema("macd", [
GeneSchema("fast", int, range=(5, 20)),
GeneSchema("slow", int, range=(20, 50)),
]),
])
# -- Full schema list --
schemas = [
GeneSchema("leverage", int, range=(1, 10)),
GeneSchema("stop_loss", float, range=(0.01, 0.1)),
GeneSchema("use_trailing", bool),
GeneSchema("strategy", choices=["momentum", "mean_reversion", "breakout"]),
SequenceSchema("rsi", [
GeneSchema("period", int, range=(5, 50)),
GeneSchema("threshold", float, range=(20.0, 80.0)),
]),
]
# -- DNA access --
from ff_genetic_algorithm.l2.dna import DNA
dna = DNA(schemas) # random init
dna = DNA(schemas, values={"leverage": 5}) # partial values, rest random
dna.get("leverage").value # -> 5
dna.get_path("rsi.period").value # -> nested access
dna.to_values() # -> {"leverage": 5, "rsi.period": 30, ...}
# -- Hangul naming --
# DNA bit-strings are encoded into Hangul syllables (0xAC00~0xD7A3).
# Each character encodes 13 bits (2^13 = 8,192 < 11,172 syllables),
# providing lossless compression with high information density per character.
from ff_genetic_algorithm.l3.naming import dna_to_name, name_to_bits, name_to_short
name = dna_to_name(dna) # -> "갈힣뮤텨퍅곣릐봤"
short = name_to_short(name) # -> first 8-char group
bits = name_to_bits(name) # -> lossless bit-string restoration
Individual Implementation
Individual is a Protocol -- any object with dna and scores attributes satisfies it.
from ff_genetic_algorithm.l2.dna import DNA
class Trader:
def __init__(self, dna):
self.dna = dna
self.scores = {}
def grow(self):
"""Domain-specific evaluation. Fill scores after simulation."""
leverage = self.dna.get("leverage").value
period = self.dna.get_path("rsi.period").value
# ... run trading simulation ...
self.scores["sharpe"] = 1.5
self.scores["mdd"] = -0.12
Metagenesis (Generation Cycle)
from ff_genetic_algorithm.l4.culling_pool import CullingPool
from ff_genetic_algorithm.l4.population import PopulationPool
from ff_genetic_algorithm.l4.spawning_pool import SpawningPool
from ff_genetic_algorithm.l5.elite_spawner import EliteSpawner
from ff_genetic_algorithm.l5.tournament_spawner import TournamentSpawner
from ff_genetic_algorithm.l5.ranking_spawner import RankingSpawner
from ff_genetic_algorithm.l5.random_spawner import RandomSpawner
from ff_genetic_algorithm.l7.metagenesis import Metagenesis
# -- Initial population --
spawning = SpawningPool(schemas)
culling = CullingPool()
population = PopulationPool()
for dna in spawning.spawn_batch(512):
population.add(Trader(dna))
culling.mark(dna)
# -- Purge rules --
def top_half(individuals):
ranked = sorted(individuals, key=lambda i: i.scores.get("sharpe", 0), reverse=True)
return ranked[:len(ranked) // 2]
# -- Metagenesis setup --
score_names = ["sharpe", "mdd"]
meta = Metagenesis(
spawners=[
(EliteSpawner(schemas, score_names), 128),
(TournamentSpawner(schemas, k=5, score_names=score_names), 128),
(RankingSpawner(schemas, score_names), 128),
(RandomSpawner(schemas), 128),
],
purge_rules=[top_half],
)
# -- Generation loop --
for gen in range(100):
# Grow: domain fills scores
for ind in population:
ind.grow()
# Next generation
population, culling = meta.next(population, culling)
Reference
l0
gene_schema
GeneSchema.__init__(name, type=None, *, range=None, choices=None)
GeneSchema.create(value=None) -> Gene
sequence_schema
SequenceSchema.__init__(name, children)
SequenceSchema.create(values=None) -> Sequence
l1
gene
Gene.__init__(schema, value=None)
Gene.bit_length() -> int
Gene.to_bits() -> str
Gene.from_bits(bit_str) -> None
sequence
Sequence.__init__(name, children)
Sequence.get(name) -> Gene | Sequence | None
Sequence.flat() -> list[Gene]
l2
dna
DNA.__init__(schemas, values=None)
DNA.get(name) -> Gene | Sequence | None
DNA.get_path(path) -> Gene | Sequence | None
DNA.flat() -> list[Gene]
DNA.to_bits() -> str
DNA.to_int() -> int
DNA.from_bits(bit_str) -> None
DNA.to_values() -> dict[str, any]
dna_ops
crossover(dna_a, dna_b, schemas, alpha=0.5) -> DNA
mutate(dna, schemas, rate=0.005) -> DNA
l3
dna_pool
DnaPool.__init__()
DnaPool.add(dna) -> bool
DnaPool.contains(dna) -> bool
DnaPool.remove(dna) -> bool
individual
Individual (Protocol)
Individual.dna: DNA
Individual.scores: dict[str, float]
naming
dna_to_name(dna) -> str
bits_to_name(bits) -> str
name_to_bits(name) -> str
name_to_short(name) -> str
l4
culling_pool
CullingPool.__init__()
CullingPool.mark(dna) -> bool
CullingPool.seen(dna) -> bool
spawning_pool
SpawningPool.__init__(schemas)
SpawningPool.spawn() -> DNA
SpawningPool.spawn_batch(n) -> list[DNA]
SpawningPool.contains(dna) -> bool
SpawningPool.clear() -> None
score_ranking
rank_sum(individuals, score_names) -> dict[int, int]
population
PopulationPool.__init__()
PopulationPool.add(individual) -> bool
PopulationPool.get(dna) -> Individual | None
PopulationPool.sort_by(score_name, reverse=True) -> list[Individual]
PopulationPool.filter_by(score_name, min_val=None, max_val=None) -> list[Individual]
PopulationPool.top(n, score_name) -> list[Individual]
PopulationPool.clear() -> None
l5
spawner
Spawner (Protocol)
Spawner.spawn(population, culling_pool) -> DNA
population_filter
PopulationPurgeFilter.__init__()
PopulationPurgeFilter.apply(population, culling_pool, rules)
-> tuple[PopulationPool, CullingPool]
elite_spawner
EliteSpawner.__init__(schemas, score_names)
EliteSpawner.spawn(population, culling_pool) -> DNA
tournament_spawner
TournamentSpawner.__init__(schemas, k, score_names,
mutation_rate=0.005, alpha=0.5)
TournamentSpawner.spawn(population, culling_pool) -> DNA
ranking_spawner
RankingSpawner.__init__(schemas, score_names,
decay=0.9, mutation_rate=0.005, alpha=0.5)
RankingSpawner.spawn(population, culling_pool) -> DNA
random_spawner
RandomSpawner.__init__(schemas)
RandomSpawner.spawn(population, culling_pool) -> DNA
l6
evolution_pool
EvolutionPool.__init__(spawners)
EvolutionPool.evolve(population, culling_pool)
-> tuple[PopulationPool, CullingPool]
l7
metagenesis
Metagenesis.__init__(spawners, purge_rules)
Metagenesis.next(population, culling_pool)
-> tuple[PopulationPool, CullingPool]
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ff_genetic_algorithm-0.0.2.tar.gz.
File metadata
- Download URL: ff_genetic_algorithm-0.0.2.tar.gz
- Upload date:
- Size: 15.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a381594759478339667d8913c024d0a6c787556aa9dcbebaafd1c5186df5bc09
|
|
| MD5 |
78870feec6f97a97e39909652668e63e
|
|
| BLAKE2b-256 |
2ab2dafab5d9c1e311fc32211829a7fd275abb008e6eb0039bbeb5ed3b2ac674
|
File details
Details for the file ff_genetic_algorithm-0.0.2-py3-none-any.whl.
File metadata
- Download URL: ff_genetic_algorithm-0.0.2-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2149335a20197d8fb08fc6e5bbc3bf72f25bde263dc9ccbb4b3e3dacead0440f
|
|
| MD5 |
d2d5cc7b2455bde40d3156814f981178
|
|
| BLAKE2b-256 |
97f280ae4b347320567d02f3a2265d75e52631800d7aa84f6d5df85c29d12fd1
|