Files
Multi_Swarm_Coevolutive/tests/integration/test_e2e_minimal_run.py
T
Adriano Dal Pastro b6539802e0 refactor(layout): rename multi_swarm → multi_swarm_core con doppia nidificazione uv workspace
- mv src/multi_swarm → src/multi_swarm_core/multi_swarm_core (member layout)
- sed-replace globale degli import: from/import multi_swarm.* → multi_swarm_core.*
- 115 occorrenze aggiornate in src/ scripts/ tests/
- multi_swarm_coevolutive (nome repo) preservato dal word boundary

Pre-condizione per il setup uv workspace della Fase 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 17:43:48 +00:00

135 lines
3.6 KiB
Python

import json
from pathlib import Path
import numpy as np
import pandas as pd
import pytest
from multi_swarm_core.genome.hypothesis import ModelTier
from multi_swarm_core.llm.client import CompletionResult
from multi_swarm_core.orchestrator.run import RunConfig, run_phase1
from multi_swarm_core.persistence.repository import Repository
@pytest.fixture
def synthetic_ohlcv():
idx = pd.date_range("2024-01-01", periods=500, freq="1h", tz="UTC")
close = 100 + np.cumsum(np.random.RandomState(0).normal(0.01, 1.0, 500))
return pd.DataFrame(
{
"open": close,
"high": close + 0.5,
"low": close - 0.5,
"close": close,
"volume": 1.0,
},
index=idx,
)
_STRATEGY_PAYLOAD = json.dumps(
{
"rules": [
{
"condition": {
"op": "gt",
"args": [
{"kind": "indicator", "name": "rsi", "params": [14]},
{"kind": "literal", "value": 70.0},
],
},
"action": "entry-short",
},
{
"condition": {
"op": "lt",
"args": [
{"kind": "indicator", "name": "rsi", "params": [14]},
{"kind": "literal", "value": 30.0},
],
},
"action": "entry-long",
},
]
}
)
@pytest.fixture
def fake_llm(mocker):
"""LLM mock che ritorna sempre una strategia JSON valida."""
fake = mocker.MagicMock()
fake.complete.return_value = CompletionResult(
text="```json\n" + _STRATEGY_PAYLOAD + "\n```",
input_tokens=200,
output_tokens=80,
tier=ModelTier.C,
model="qwen",
)
return fake
def test_e2e_minimal_run_completes(
tmp_path: Path,
synthetic_ohlcv,
fake_llm,
mocker,
):
cfg = RunConfig(
run_name="e2e-test",
population_size=5,
n_generations=2,
elite_k=1,
tournament_k=2,
p_crossover=0.5,
seed=42,
model_tier=ModelTier.C,
symbol="BTC/USDT",
timeframe="1h",
fees_bp=5.0,
n_trials_dsr=10,
db_path=tmp_path / "runs.db",
)
run_id = run_phase1(cfg, ohlcv=synthetic_ohlcv, llm=fake_llm)
repo = Repository(db_path=tmp_path / "runs.db")
run = repo.get_run(run_id)
assert run["status"] == "completed"
gens = repo.list_generations(run_id)
assert len(gens) == 2
evals = repo.list_evaluations(run_id)
assert len(evals) >= 5 # almeno una popolazione
def test_e2e_wfa_populates_fitness_oos(
tmp_path: Path,
synthetic_ohlcv,
fake_llm,
mocker,
):
"""WFA: train_split=0.7 → top genomi devono avere fitness_oos popolato."""
cfg = RunConfig(
run_name="e2e-wfa-test",
population_size=5,
n_generations=2,
elite_k=1,
tournament_k=2,
p_crossover=0.5,
seed=42,
model_tier=ModelTier.C,
symbol="BTC/USDT",
timeframe="1h",
fees_bp=5.0,
n_trials_dsr=10,
db_path=tmp_path / "runs.db",
wfa_train_split=0.7,
wfa_top_k=3,
)
run_id = run_phase1(cfg, ohlcv=synthetic_ohlcv, llm=fake_llm)
repo = Repository(db_path=tmp_path / "runs.db")
evals = repo.list_evaluations(run_id)
# Almeno 1 genome con fitness > 0 deve avere fitness_oos popolato.
oos_evals = [e for e in evals if e.get("fitness_oos") is not None]
assert len(oos_evals) >= 1, f"Nessun OOS popolato; evals={evals}"