Compare commits
2 Commits
a29748e3d8
...
9742df3a1f
| Author | SHA1 | Date | |
|---|---|---|---|
| 9742df3a1f | |||
| 21b5cf1eae |
@@ -111,7 +111,7 @@ Stack: Python 3.13, uv workspace, hatchling, pytest+pytest-mock+responses, opena
|
|||||||
```bash
|
```bash
|
||||||
uv sync # installa entrambi i workspace member come editable
|
uv sync # installa entrambi i workspace member come editable
|
||||||
cp .env.example .env # compila CERBERO_*_TOKEN e OPENROUTER_API_KEY
|
cp .env.example .env # compila CERBERO_*_TOKEN e OPENROUTER_API_KEY
|
||||||
uv run pytest # 250 test attesi (246 core + 4 smoke strategy_crypto)
|
uv run pytest # 252 test attesi (248 core + 4 smoke strategy_crypto)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Variabili .env richieste
|
### Variabili .env richieste
|
||||||
@@ -151,15 +151,16 @@ uv run mypy src/ scripts/
|
|||||||
uv run python scripts/smoke_run.py
|
uv run python scripts/smoke_run.py
|
||||||
|
|
||||||
# Run reale Phase 1/2 (Cerbero + OpenRouter, ~$0.15-0.25 per run K=20 10gen,
|
# Run reale Phase 1/2 (Cerbero + OpenRouter, ~$0.15-0.25 per run K=20 10gen,
|
||||||
# ~$0.40-0.55 per run esteso K=40 20gen con WFA OOS)
|
# ~$0.40-0.55 per run esteso K=40 20gen con WFA OOS).
|
||||||
|
# Default --start ora 2018-09-01 (7.3y, copre bear+halving+covid+ATH+winter+ETF).
|
||||||
uv run python scripts/run_phase1.py \
|
uv run python scripts/run_phase1.py \
|
||||||
--name run-XXX \
|
--name run-XXX \
|
||||||
--exchange deribit --symbol BTC-PERPETUAL --timeframe 1h \
|
--exchange deribit --symbol BTC-PERPETUAL --timeframe 1h \
|
||||||
--start 2024-01-01T00:00:00+00:00 \
|
|
||||||
--end 2026-01-01T00:00:00+00:00 \
|
|
||||||
--population-size 20 --n-generations 10 \
|
--population-size 20 --n-generations 10 \
|
||||||
--prompt-mutation-weight 0.30 --fitness-v2 \
|
--prompt-mutation-weight 0.30 --fitness-v2 \
|
||||||
--llm-concurrency 8 # 5-8x speedup wall time (default 1)
|
--llm-concurrency 8 # 5-8x speedup wall time (default 1)
|
||||||
|
# fitness-v2 hardened: hard-kill su {no_trades, degenerate, undertrading,
|
||||||
|
# fees_eat_alpha, negative_net_pnl}. Override via --fitness-hard-kill CSV.
|
||||||
# Default --prompt-library: importlib.resources del package strategy_crypto/prompts.json
|
# Default --prompt-library: importlib.resources del package strategy_crypto/prompts.json
|
||||||
|
|
||||||
# Multi-fold validation di un run esistente (anti-overfit, 7y expanding-window)
|
# Multi-fold validation di un run esistente (anti-overfit, 7y expanding-window)
|
||||||
|
|||||||
+43
-6
@@ -19,6 +19,30 @@ def _default_prompt_library_path() -> Path:
|
|||||||
return Path(str(importlib.resources.files("strategy_crypto") / "prompts.json"))
|
return Path(str(importlib.resources.files("strategy_crypto") / "prompts.json"))
|
||||||
|
|
||||||
|
|
||||||
|
# Default v2 hard-kill list: oltre ai degenerate originali, fees_eat_alpha e
|
||||||
|
# negative_net_pnl sono deal-breaker non recuperabili via soft penalty (vedi
|
||||||
|
# 7y-overfit incident 2026-05-16: elite IS Sharpe 1.93 -> net -5% su 7y per fees).
|
||||||
|
_DEFAULT_V2_HARD_KILL: tuple[str, ...] = (
|
||||||
|
"no_trades",
|
||||||
|
"degenerate",
|
||||||
|
"undertrading",
|
||||||
|
"fees_eat_alpha",
|
||||||
|
"negative_net_pnl",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_hard_kill(args) -> tuple[str, ...] | None:
|
||||||
|
"""Resolve la lista hard-kill da CLI args.
|
||||||
|
|
||||||
|
Priority: ``--fitness-hard-kill`` esplicito > default v2 > ``None`` (v1).
|
||||||
|
"""
|
||||||
|
if args.fitness_hard_kill:
|
||||||
|
return tuple(s.strip() for s in args.fitness_hard_kill.split(",") if s.strip())
|
||||||
|
if args.fitness_v2:
|
||||||
|
return _DEFAULT_V2_HARD_KILL
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
def parse_args() -> argparse.Namespace:
|
||||||
p = argparse.ArgumentParser(description="Multi-Swarm Phase 1 runner")
|
p = argparse.ArgumentParser(description="Multi-Swarm Phase 1 runner")
|
||||||
p.add_argument("--name", default="phase1-spike-001")
|
p.add_argument("--name", default="phase1-spike-001")
|
||||||
@@ -35,7 +59,10 @@ def parse_args() -> argparse.Namespace:
|
|||||||
)
|
)
|
||||||
p.add_argument("--symbol", default="BTC-PERPETUAL")
|
p.add_argument("--symbol", default="BTC-PERPETUAL")
|
||||||
p.add_argument("--timeframe", default="1h")
|
p.add_argument("--timeframe", default="1h")
|
||||||
p.add_argument("--start", default="2024-01-01T00:00:00+00:00")
|
# Default esteso a 7.3 anni: copre bear 2018-19, halving 2020, COVID,
|
||||||
|
# ATH 2021, winter 2022, ETF rally 2024, regime corrente. Una finestra
|
||||||
|
# corta lascia il GA libero di overfit a un singolo regime.
|
||||||
|
p.add_argument("--start", default="2018-09-01T00:00:00+00:00")
|
||||||
p.add_argument("--end", default="2026-01-01T00:00:00+00:00")
|
p.add_argument("--end", default="2026-01-01T00:00:00+00:00")
|
||||||
p.add_argument("--fees-bp", type=float, default=5.0)
|
p.add_argument("--fees-bp", type=float, default=5.0)
|
||||||
p.add_argument("--n-trials-dsr", type=int, default=50)
|
p.add_argument("--n-trials-dsr", type=int, default=50)
|
||||||
@@ -67,8 +94,10 @@ def parse_args() -> argparse.Namespace:
|
|||||||
"--fitness-v2",
|
"--fitness-v2",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help=(
|
help=(
|
||||||
"Attiva fitness v2: solo {no_trades, degenerate, undertrading} azzerano; "
|
"Attiva fitness v2: hard-kill su {no_trades, degenerate, undertrading, "
|
||||||
"gli altri HIGH applicano soft penalty multiplicativa"
|
"fees_eat_alpha, negative_net_pnl}; gli altri HIGH applicano soft penalty "
|
||||||
|
"multiplicativa. Versione hardened post 7y-overfit incident: fees + "
|
||||||
|
"net negativo non sono recuperabili."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
p.add_argument(
|
p.add_argument(
|
||||||
@@ -77,6 +106,16 @@ def parse_args() -> argparse.Namespace:
|
|||||||
default=0.4,
|
default=0.4,
|
||||||
help="v2: fattore soft penalty per HIGH non-hard (default 0.4 → 1 HIGH → 0.71x)",
|
help="v2: fattore soft penalty per HIGH non-hard (default 0.4 → 1 HIGH → 0.71x)",
|
||||||
)
|
)
|
||||||
|
p.add_argument(
|
||||||
|
"--fitness-hard-kill",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help=(
|
||||||
|
"Override comma-separated della lista di finding name che azzerano la "
|
||||||
|
"fitness in modalita' v2. Es: 'no_trades,degenerate'. Default v2: "
|
||||||
|
"no_trades,degenerate,undertrading,fees_eat_alpha,negative_net_pnl."
|
||||||
|
),
|
||||||
|
)
|
||||||
p.add_argument(
|
p.add_argument(
|
||||||
"--wfa-train-split",
|
"--wfa-train-split",
|
||||||
type=float,
|
type=float,
|
||||||
@@ -188,9 +227,7 @@ def main() -> None:
|
|||||||
fees_eat_alpha_threshold=args.fees_eat_alpha_threshold,
|
fees_eat_alpha_threshold=args.fees_eat_alpha_threshold,
|
||||||
flat_too_long_threshold=args.flat_too_long_threshold,
|
flat_too_long_threshold=args.flat_too_long_threshold,
|
||||||
undertrading_threshold=args.undertrading_threshold,
|
undertrading_threshold=args.undertrading_threshold,
|
||||||
fitness_hard_kill_findings=(
|
fitness_hard_kill_findings=_resolve_hard_kill(args),
|
||||||
("no_trades", "degenerate", "undertrading") if args.fitness_v2 else None
|
|
||||||
),
|
|
||||||
fitness_adversarial_soft_penalty=args.fitness_soft_penalty,
|
fitness_adversarial_soft_penalty=args.fitness_soft_penalty,
|
||||||
wfa_train_split=args.wfa_train_split,
|
wfa_train_split=args.wfa_train_split,
|
||||||
wfa_top_k=args.wfa_top_k,
|
wfa_top_k=args.wfa_top_k,
|
||||||
|
|||||||
@@ -172,10 +172,11 @@ class AdversarialAgent:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fees-eat-alpha: gross_pnl > 0 ma fees > 50% del lordo.
|
# Fees-eat-alpha: gross_pnl > 0 ma fees > soglia del lordo.
|
||||||
# La strategia ha edge teorico ma il margine viene mangiato dai
|
# La strategia ha edge teorico ma il margine viene mangiato dai
|
||||||
# costi di transazione: non sostenibile in produzione.
|
# costi di transazione: non sostenibile in produzione.
|
||||||
# Se gross_pnl <= 0 il check non si applica (gia' perdente).
|
# Se gross_pnl <= 0 il check non si applica (la condizione e' coperta
|
||||||
|
# da ``negative_net_pnl`` sotto).
|
||||||
gross_pnl = sum(t.gross_pnl for t in result.trades)
|
gross_pnl = sum(t.gross_pnl for t in result.trades)
|
||||||
total_fees = sum(t.fees for t in result.trades)
|
total_fees = sum(t.fees for t in result.trades)
|
||||||
if gross_pnl > 0 and total_fees / gross_pnl > self._fees_eat_alpha_threshold:
|
if gross_pnl > 0 and total_fees / gross_pnl > self._fees_eat_alpha_threshold:
|
||||||
@@ -190,4 +191,22 @@ class AdversarialAgent:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Negative-net-pnl: somma di ``trade.net_pnl`` < 0 sul training.
|
||||||
|
# Cattura sia il caso "gross negativo" (no edge direzionale) sia il
|
||||||
|
# caso "gross positivo ma fees superiori a gross" (edge insufficiente).
|
||||||
|
# Sintesi del net-after-fees su finestra continua: deal-breaker, non
|
||||||
|
# negoziabile via soft penalty.
|
||||||
|
net_pnl = gross_pnl - total_fees
|
||||||
|
if net_pnl < 0:
|
||||||
|
report.findings.append(
|
||||||
|
Finding(
|
||||||
|
name="negative_net_pnl",
|
||||||
|
severity=Severity.HIGH,
|
||||||
|
detail=(
|
||||||
|
f"Net PnL ${net_pnl:.2f} < 0 after fees over {n_bars} bars; "
|
||||||
|
f"gross ${gross_pnl:.2f}, fees ${total_fees:.2f}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return report
|
return report
|
||||||
|
|||||||
@@ -108,7 +108,13 @@ def test_e2e_wfa_populates_fitness_oos(
|
|||||||
fake_llm,
|
fake_llm,
|
||||||
mocker,
|
mocker,
|
||||||
):
|
):
|
||||||
"""WFA: train_split=0.7 → top genomi devono avere fitness_oos popolato."""
|
"""WFA: train_split=0.7 → top genomi devono avere fitness_oos popolato.
|
||||||
|
|
||||||
|
Usa fitness v2 con hard-kill minimale (solo no_trades): il fixture sintetico
|
||||||
|
non produce strategie profittevoli, quindi i check aggressivi
|
||||||
|
fees_eat_alpha/negative_net_pnl azzererebbero tutti i genomi rendendo
|
||||||
|
inverificabile il wiring WFA.
|
||||||
|
"""
|
||||||
cfg = RunConfig(
|
cfg = RunConfig(
|
||||||
run_name="e2e-wfa-test",
|
run_name="e2e-wfa-test",
|
||||||
population_size=5,
|
population_size=5,
|
||||||
@@ -125,6 +131,7 @@ def test_e2e_wfa_populates_fitness_oos(
|
|||||||
db_path=tmp_path / "runs.db",
|
db_path=tmp_path / "runs.db",
|
||||||
wfa_train_split=0.7,
|
wfa_train_split=0.7,
|
||||||
wfa_top_k=3,
|
wfa_top_k=3,
|
||||||
|
fitness_hard_kill_findings=("no_trades",),
|
||||||
)
|
)
|
||||||
run_id = run_phase1(cfg, ohlcv=synthetic_ohlcv, llm=fake_llm)
|
run_id = run_phase1(cfg, ohlcv=synthetic_ohlcv, llm=fake_llm)
|
||||||
repo = Repository(db_path=tmp_path / "runs.db")
|
repo = Repository(db_path=tmp_path / "runs.db")
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import json
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from multi_swarm_core.agents.adversarial import (
|
from multi_swarm_core.agents.adversarial import (
|
||||||
AdversarialAgent,
|
AdversarialAgent,
|
||||||
AdversarialReport,
|
AdversarialReport,
|
||||||
@@ -54,7 +53,10 @@ def test_degenerate_always_long_flagged(ohlcv: pd.DataFrame) -> None:
|
|||||||
assert any(f.name == "degenerate" and f.severity == Severity.HIGH for f in report.findings)
|
assert any(f.name == "degenerate" and f.severity == Severity.HIGH for f in report.findings)
|
||||||
|
|
||||||
|
|
||||||
def test_no_findings_on_reasonable_strategy(ohlcv: pd.DataFrame) -> None:
|
def test_rsi_mean_reversion_loses_money_on_synthetic_data(ohlcv: pd.DataFrame) -> None:
|
||||||
|
"""RSI mean-reversion sul fixture sintetico ha net negativo: deve firare
|
||||||
|
negative_net_pnl (deal-breaker). Conferma che il check cattura strategie
|
||||||
|
che perdono sul training, indipendentemente dal motivo (no edge / fees)."""
|
||||||
src = json.dumps(
|
src = json.dumps(
|
||||||
{
|
{
|
||||||
"rules": [
|
"rules": [
|
||||||
@@ -84,8 +86,59 @@ def test_no_findings_on_reasonable_strategy(ohlcv: pd.DataFrame) -> None:
|
|||||||
ast = parse_strategy(src)
|
ast = parse_strategy(src)
|
||||||
agent = AdversarialAgent()
|
agent = AdversarialAgent()
|
||||||
report = agent.review(ast, ohlcv)
|
report = agent.review(ast, ohlcv)
|
||||||
|
assert any(
|
||||||
|
f.name == "negative_net_pnl" and f.severity == Severity.HIGH
|
||||||
|
for f in report.findings
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_profitable_strategy_no_high_findings(
|
||||||
|
monkeypatch: pytest.MonkeyPatch, ohlcv: pd.DataFrame
|
||||||
|
) -> None:
|
||||||
|
"""Sanity test: una strategia con gross > 0 e fees << gross + n_trades ragionevole
|
||||||
|
+ signal misto non deve produrre nessun finding HIGH."""
|
||||||
|
n = 15
|
||||||
|
# entry=100 exit=110 gross=10 per trade, fees a 5bp -> 0.105 per trade
|
||||||
|
# totali: gross=150, fees=1.575 -> net=+148.4
|
||||||
|
fake_trades = [
|
||||||
|
_make_trade(
|
||||||
|
ohlcv.index[i * 30],
|
||||||
|
ohlcv.index[i * 30 + 1],
|
||||||
|
entry_price=100.0,
|
||||||
|
exit_price=110.0,
|
||||||
|
)
|
||||||
|
for i in range(n)
|
||||||
|
]
|
||||||
|
# 50/50 LONG/FLAT per evitare degenerate/flat_too_long/time_in_market.
|
||||||
|
fake_signals = pd.Series(
|
||||||
|
[Side.LONG if i % 2 == 0 else Side.FLAT for i in range(len(ohlcv))],
|
||||||
|
index=ohlcv.index,
|
||||||
|
dtype=object,
|
||||||
|
)
|
||||||
|
|
||||||
|
def fake_run(self, ohlcv: pd.DataFrame, signals: pd.Series) -> BacktestResult: # type: ignore[no-untyped-def]
|
||||||
|
return BacktestResult(
|
||||||
|
equity_curve=pd.Series([0.0] * len(ohlcv), index=ohlcv.index, name="equity"),
|
||||||
|
returns=pd.Series([0.0] * len(ohlcv), index=ohlcv.index, name="returns"),
|
||||||
|
trades=fake_trades,
|
||||||
|
)
|
||||||
|
|
||||||
|
def fake_compile(strategy): # type: ignore[no-untyped-def]
|
||||||
|
return lambda df: fake_signals
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"multi_swarm_core.agents.adversarial.BacktestEngine.run", fake_run
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"multi_swarm_core.agents.adversarial.compile_strategy", fake_compile
|
||||||
|
)
|
||||||
|
|
||||||
|
ast = parse_strategy(_MINIMAL_STRATEGY_SRC)
|
||||||
|
report = AdversarialAgent().review(ast, ohlcv)
|
||||||
high_findings = [f for f in report.findings if f.severity == Severity.HIGH]
|
high_findings = [f for f in report.findings if f.severity == Severity.HIGH]
|
||||||
assert len(high_findings) == 0
|
assert high_findings == [], (
|
||||||
|
f"expected no HIGH findings, got: {[f.name for f in high_findings]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_zero_trade_strategy_flagged(ohlcv: pd.DataFrame) -> None:
|
def test_zero_trade_strategy_flagged(ohlcv: pd.DataFrame) -> None:
|
||||||
@@ -383,6 +436,55 @@ def test_fees_eat_alpha_flagged(monkeypatch: pytest.MonkeyPatch,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_negative_net_pnl_fires_on_negative_gross(
|
||||||
|
monkeypatch: pytest.MonkeyPatch, ohlcv: pd.DataFrame
|
||||||
|
) -> None:
|
||||||
|
"""gross_pnl < 0 (perdente direzionale) -> HIGH negative_net_pnl.
|
||||||
|
fees_eat_alpha NON deve firare perche' la sua condizione richiede gross > 0.
|
||||||
|
"""
|
||||||
|
n = 15
|
||||||
|
# entry=100 exit=95 gross=-5 per trade (LONG perdente)
|
||||||
|
fake_trades = [
|
||||||
|
_make_trade(
|
||||||
|
ohlcv.index[i * 30],
|
||||||
|
ohlcv.index[i * 30 + 1],
|
||||||
|
entry_price=100.0,
|
||||||
|
exit_price=95.0,
|
||||||
|
)
|
||||||
|
for i in range(n)
|
||||||
|
]
|
||||||
|
fake_signals = pd.Series(
|
||||||
|
[Side.LONG if i % 2 == 0 else Side.FLAT for i in range(len(ohlcv))],
|
||||||
|
index=ohlcv.index,
|
||||||
|
dtype=object,
|
||||||
|
)
|
||||||
|
|
||||||
|
def fake_run(self, ohlcv, signals): # type: ignore[no-untyped-def]
|
||||||
|
return BacktestResult(
|
||||||
|
equity_curve=pd.Series([0.0] * len(ohlcv), index=ohlcv.index, name="equity"),
|
||||||
|
returns=pd.Series([0.0] * len(ohlcv), index=ohlcv.index, name="returns"),
|
||||||
|
trades=fake_trades,
|
||||||
|
)
|
||||||
|
|
||||||
|
def fake_compile(strategy): # type: ignore[no-untyped-def]
|
||||||
|
return lambda df: fake_signals
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"multi_swarm_core.agents.adversarial.BacktestEngine.run", fake_run
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"multi_swarm_core.agents.adversarial.compile_strategy", fake_compile
|
||||||
|
)
|
||||||
|
|
||||||
|
ast = parse_strategy(_MINIMAL_STRATEGY_SRC)
|
||||||
|
report = AdversarialAgent().review(ast, ohlcv)
|
||||||
|
assert any(
|
||||||
|
f.name == "negative_net_pnl" and f.severity == Severity.HIGH
|
||||||
|
for f in report.findings
|
||||||
|
)
|
||||||
|
assert not any(f.name == "fees_eat_alpha" for f in report.findings)
|
||||||
|
|
||||||
|
|
||||||
def test_time_in_market_too_high_flagged(monkeypatch: pytest.MonkeyPatch,
|
def test_time_in_market_too_high_flagged(monkeypatch: pytest.MonkeyPatch,
|
||||||
ohlcv: pd.DataFrame) -> None:
|
ohlcv: pd.DataFrame) -> None:
|
||||||
"""Signal LONG per >80% delle bar -> HIGH time_in_market_too_high."""
|
"""Signal LONG per >80% delle bar -> HIGH time_in_market_too_high."""
|
||||||
|
|||||||
@@ -0,0 +1,634 @@
|
|||||||
|
{
|
||||||
|
"run_id": "e263651598894da688d95fda90a34a96",
|
||||||
|
"run_name": "phase1-extended-001",
|
||||||
|
"n_folds": 4,
|
||||||
|
"top_k_requested": 10,
|
||||||
|
"top_k_evaluated": 10,
|
||||||
|
"symbol": "BTC-PERPETUAL",
|
||||||
|
"timeframe": "1h",
|
||||||
|
"start": "2018-09-01T00:00:00+00:00",
|
||||||
|
"end": "2026-01-01T00:00:00+00:00",
|
||||||
|
"ohlcv_bars": 64297,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"genome_id": "fe6e01eb690d3960",
|
||||||
|
"fitness_is": 0.3513762485888574,
|
||||||
|
"sharpe_is": 0.9011072752402621,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.18429629882863333,
|
||||||
|
"sharpe": 0.18578971215949266,
|
||||||
|
"dsr": 0.022696217108110216,
|
||||||
|
"dsr_pvalue": 0.9773037828918898,
|
||||||
|
"return": 0.03138679502492736,
|
||||||
|
"max_dd": 0.19089436189057732,
|
||||||
|
"n_trades": 90,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.5261711065682141,
|
||||||
|
"sharpe": 1.875154815895858,
|
||||||
|
"dsr": 0.34945842578669783,
|
||||||
|
"dsr_pvalue": 0.6505415742133022,
|
||||||
|
"return": 0.684094224950746,
|
||||||
|
"max_dd": 0.26051011671170043,
|
||||||
|
"n_trades": 108,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.29904777517998976,
|
||||||
|
"sharpe": 0.45027968136531676,
|
||||||
|
"dsr": 0.040236883094469954,
|
||||||
|
"dsr_pvalue": 0.9597631169055301,
|
||||||
|
"return": 0.16192920610625539,
|
||||||
|
"max_dd": 0.25615601205401484,
|
||||||
|
"n_trades": 87,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.06652893772008044,
|
||||||
|
"sharpe": -0.7859068293026578,
|
||||||
|
"dsr": 0.0016949251764253048,
|
||||||
|
"dsr_pvalue": 0.9983050748235747,
|
||||||
|
"return": -0.1801701961968295,
|
||||||
|
"max_dd": 0.3050931306970407,
|
||||||
|
"n_trades": 89,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.2690110295742294,
|
||||||
|
"fitness_oos_min": 0.06652893772008044,
|
||||||
|
"fitness_oos_max": 0.5261711065682141,
|
||||||
|
"fitness_oos_std": 0.16971232602043682,
|
||||||
|
"sharpe_oos_mean": 0.43132934502950243,
|
||||||
|
"sharpe_oos_min": -0.7859068293026578,
|
||||||
|
"robust_score": 0.06652893772008044
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "d98739b2ba8d65e8",
|
||||||
|
"fitness_is": 0.3581811122056351,
|
||||||
|
"sharpe_is": 1.5316294902683918,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.03897301517910094,
|
||||||
|
"sharpe": -1.1213338499931884,
|
||||||
|
"dsr": 0.0007106609032094727,
|
||||||
|
"dsr_pvalue": 0.9992893390967905,
|
||||||
|
"return": -0.18358503193809717,
|
||||||
|
"max_dd": 0.24053109269341416,
|
||||||
|
"n_trades": 65,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.13868820192362147,
|
||||||
|
"sharpe": 0.1139203144076397,
|
||||||
|
"dsr": 0.018885390702584475,
|
||||||
|
"dsr_pvalue": 0.9811146092974156,
|
||||||
|
"return": 0.019694298831973045,
|
||||||
|
"max_dd": 0.1528666578131679,
|
||||||
|
"n_trades": 21,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.43784574830368517,
|
||||||
|
"sharpe": 1.922993791724599,
|
||||||
|
"dsr": 0.36463909799020594,
|
||||||
|
"dsr_pvalue": 0.6353609020097941,
|
||||||
|
"return": 0.31046814355338936,
|
||||||
|
"max_dd": 0.09604869735695161,
|
||||||
|
"n_trades": 48,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.377910610011883,
|
||||||
|
"sharpe": 1.3313322991701542,
|
||||||
|
"dsr": 0.17322722607861918,
|
||||||
|
"dsr_pvalue": 0.8267727739213808,
|
||||||
|
"return": 0.12021252899342505,
|
||||||
|
"max_dd": 0.04712452925993322,
|
||||||
|
"n_trades": 32,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.24835439385457264,
|
||||||
|
"fitness_oos_min": 0.03897301517910094,
|
||||||
|
"fitness_oos_max": 0.43784574830368517,
|
||||||
|
"fitness_oos_std": 0.1647414807695958,
|
||||||
|
"sharpe_oos_mean": 0.5617281388273011,
|
||||||
|
"sharpe_oos_min": -1.1213338499931884,
|
||||||
|
"robust_score": 0.03897301517910094
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "0dd6619fdcbe37f4",
|
||||||
|
"fitness_is": 0.3765498201912705,
|
||||||
|
"sharpe_is": 0.9388498977535525,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.03550929012857722,
|
||||||
|
"sharpe": -1.1093436310362703,
|
||||||
|
"dsr": 0.0005959199839818188,
|
||||||
|
"dsr_pvalue": 0.9994040800160182,
|
||||||
|
"return": -0.24600377155172415,
|
||||||
|
"max_dd": 0.38950670401585935,
|
||||||
|
"n_trades": 122,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.049414033104104804,
|
||||||
|
"sharpe": -0.9995738302518242,
|
||||||
|
"dsr": 0.0007695523975576842,
|
||||||
|
"dsr_pvalue": 0.9992304476024423,
|
||||||
|
"return": -0.15162579158457645,
|
||||||
|
"max_dd": 0.21485725923368693,
|
||||||
|
"n_trades": 79,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.4634730710112187,
|
||||||
|
"sharpe": 1.2076100738049764,
|
||||||
|
"dsr": 0.15231462029944348,
|
||||||
|
"dsr_pvalue": 0.8476853797005566,
|
||||||
|
"return": 0.3072592298707053,
|
||||||
|
"max_dd": 0.15464658494822137,
|
||||||
|
"n_trades": 153,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.1215451856323226,
|
||||||
|
"sharpe": -0.22288474503734051,
|
||||||
|
"dsr": 0.00830898358713792,
|
||||||
|
"dsr_pvalue": 0.9916910164128621,
|
||||||
|
"return": -0.035113534418310444,
|
||||||
|
"max_dd": 0.17145164314561556,
|
||||||
|
"n_trades": 74,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.16748539496905585,
|
||||||
|
"fitness_oos_min": 0.03550929012857722,
|
||||||
|
"fitness_oos_max": 0.4634730710112187,
|
||||||
|
"fitness_oos_std": 0.17398113830545858,
|
||||||
|
"sharpe_oos_mean": -0.28104803313011467,
|
||||||
|
"sharpe_oos_min": -1.1093436310362703,
|
||||||
|
"robust_score": 0.03550929012857722
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "00545b157923dc6b",
|
||||||
|
"fitness_is": 0.34960092770407836,
|
||||||
|
"sharpe_is": 0.9785144736247469,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.027180640826810924,
|
||||||
|
"sharpe": -1.26345444662059,
|
||||||
|
"dsr": 0.00030602669379661417,
|
||||||
|
"dsr_pvalue": 0.9996939733062034,
|
||||||
|
"return": -0.2411006699210636,
|
||||||
|
"max_dd": 0.36676673786660746,
|
||||||
|
"n_trades": 79,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.5208756815430423,
|
||||||
|
"sharpe": 1.770946043023605,
|
||||||
|
"dsr": 0.3128216779179025,
|
||||||
|
"dsr_pvalue": 0.6871783220820975,
|
||||||
|
"return": 0.60240576625387,
|
||||||
|
"max_dd": 0.2331907909757441,
|
||||||
|
"n_trades": 45,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.2959791903863346,
|
||||||
|
"sharpe": 0.3683437692731339,
|
||||||
|
"dsr": 0.033871432018897314,
|
||||||
|
"dsr_pvalue": 0.9661285679811027,
|
||||||
|
"return": 0.134452978611995,
|
||||||
|
"max_dd": 0.19964940601028408,
|
||||||
|
"n_trades": 58,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.15883382666451054,
|
||||||
|
"sharpe": 0.031160944245222175,
|
||||||
|
"dsr": 0.015769276637227145,
|
||||||
|
"dsr_pvalue": 0.9842307233627728,
|
||||||
|
"return": 0.006899603676653765,
|
||||||
|
"max_dd": 0.1947452948903118,
|
||||||
|
"n_trades": 36,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.2507173348551746,
|
||||||
|
"fitness_oos_min": 0.027180640826810924,
|
||||||
|
"fitness_oos_max": 0.5208756815430423,
|
||||||
|
"fitness_oos_std": 0.1826508968673572,
|
||||||
|
"sharpe_oos_mean": 0.2267490774803428,
|
||||||
|
"sharpe_oos_min": -1.26345444662059,
|
||||||
|
"robust_score": 0.027180640826810924
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "eea882db55f8dd5e",
|
||||||
|
"fitness_is": 0.3181543783162782,
|
||||||
|
"sharpe_is": 1.3214317725559044,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.02689139923003529,
|
||||||
|
"sharpe": -1.3020990219857191,
|
||||||
|
"dsr": 0.00036878360260577075,
|
||||||
|
"dsr_pvalue": 0.9996312163973943,
|
||||||
|
"return": -0.22280992288117984,
|
||||||
|
"max_dd": 0.28735423155244094,
|
||||||
|
"n_trades": 69,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.1064185213723357,
|
||||||
|
"sharpe": -0.3110958507357913,
|
||||||
|
"dsr": 0.006879713400940769,
|
||||||
|
"dsr_pvalue": 0.9931202865990593,
|
||||||
|
"return": -0.057958925555868235,
|
||||||
|
"max_dd": 0.19529025657454543,
|
||||||
|
"n_trades": 33,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.37938211463073945,
|
||||||
|
"sharpe": 1.490827385000592,
|
||||||
|
"dsr": 0.2224878866287407,
|
||||||
|
"dsr_pvalue": 0.7775121133712593,
|
||||||
|
"return": 0.2563445845249124,
|
||||||
|
"max_dd": 0.1053935530975972,
|
||||||
|
"n_trades": 59,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.4175480977898098,
|
||||||
|
"sharpe": 1.6336803280087653,
|
||||||
|
"dsr": 0.260079721684657,
|
||||||
|
"dsr_pvalue": 0.739920278315343,
|
||||||
|
"return": 0.157201259896103,
|
||||||
|
"max_dd": 0.04639072483391873,
|
||||||
|
"n_trades": 43,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.23256003325573005,
|
||||||
|
"fitness_oos_min": 0.02689139923003529,
|
||||||
|
"fitness_oos_max": 0.4175480977898098,
|
||||||
|
"fitness_oos_std": 0.16881097094204098,
|
||||||
|
"sharpe_oos_mean": 0.3778282100719617,
|
||||||
|
"sharpe_oos_min": -1.3020990219857191,
|
||||||
|
"robust_score": 0.02689139923003529
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "24a3e592397d4bda",
|
||||||
|
"fitness_is": 0.3181543783162782,
|
||||||
|
"sharpe_is": 1.3214317725559044,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.02689139923003529,
|
||||||
|
"sharpe": -1.3020990219857191,
|
||||||
|
"dsr": 0.00036878360260577075,
|
||||||
|
"dsr_pvalue": 0.9996312163973943,
|
||||||
|
"return": -0.22280992288117984,
|
||||||
|
"max_dd": 0.28735423155244094,
|
||||||
|
"n_trades": 69,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.1064185213723357,
|
||||||
|
"sharpe": -0.3110958507357913,
|
||||||
|
"dsr": 0.006879713400940769,
|
||||||
|
"dsr_pvalue": 0.9931202865990593,
|
||||||
|
"return": -0.057958925555868235,
|
||||||
|
"max_dd": 0.19529025657454543,
|
||||||
|
"n_trades": 33,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.37938211463073945,
|
||||||
|
"sharpe": 1.490827385000592,
|
||||||
|
"dsr": 0.2224878866287407,
|
||||||
|
"dsr_pvalue": 0.7775121133712593,
|
||||||
|
"return": 0.2563445845249124,
|
||||||
|
"max_dd": 0.1053935530975972,
|
||||||
|
"n_trades": 59,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.4175480977898098,
|
||||||
|
"sharpe": 1.6336803280087653,
|
||||||
|
"dsr": 0.260079721684657,
|
||||||
|
"dsr_pvalue": 0.739920278315343,
|
||||||
|
"return": 0.157201259896103,
|
||||||
|
"max_dd": 0.04639072483391873,
|
||||||
|
"n_trades": 43,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.23256003325573005,
|
||||||
|
"fitness_oos_min": 0.02689139923003529,
|
||||||
|
"fitness_oos_max": 0.4175480977898098,
|
||||||
|
"fitness_oos_std": 0.16881097094204098,
|
||||||
|
"sharpe_oos_mean": 0.3778282100719617,
|
||||||
|
"sharpe_oos_min": -1.3020990219857191,
|
||||||
|
"robust_score": 0.02689139923003529
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "7d6636945c3fdee5",
|
||||||
|
"fitness_is": 0.4143633094822953,
|
||||||
|
"sharpe_is": 1.0518304581395579,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.024065408548587387,
|
||||||
|
"sharpe": -1.362275778196952,
|
||||||
|
"dsr": 0.0002459819911643212,
|
||||||
|
"dsr_pvalue": 0.9997540180088357,
|
||||||
|
"return": -0.27317643202118824,
|
||||||
|
"max_dd": 0.283710961847723,
|
||||||
|
"n_trades": 76,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.10523269843210308,
|
||||||
|
"sharpe": -0.32050989428963983,
|
||||||
|
"dsr": 0.006397259401103736,
|
||||||
|
"dsr_pvalue": 0.9936027405988963,
|
||||||
|
"return": -0.058925951660568465,
|
||||||
|
"max_dd": 0.19264026914858506,
|
||||||
|
"n_trades": 115,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.37331175980311637,
|
||||||
|
"sharpe": 0.6268880704230287,
|
||||||
|
"dsr": 0.05821057212982157,
|
||||||
|
"dsr_pvalue": 0.9417894278701784,
|
||||||
|
"return": 0.13285431586579133,
|
||||||
|
"max_dd": 0.11992643530986899,
|
||||||
|
"n_trades": 66,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.058003508089270274,
|
||||||
|
"sharpe": -0.9065054278150867,
|
||||||
|
"dsr": 0.0011919907667399207,
|
||||||
|
"dsr_pvalue": 0.9988080092332601,
|
||||||
|
"return": -0.11553575296643481,
|
||||||
|
"max_dd": 0.21946607715577302,
|
||||||
|
"n_trades": 108,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.14015334371826926,
|
||||||
|
"fitness_oos_min": 0.024065408548587387,
|
||||||
|
"fitness_oos_max": 0.37331175980311637,
|
||||||
|
"fitness_oos_std": 0.13766562991922562,
|
||||||
|
"sharpe_oos_mean": -0.4906007574696624,
|
||||||
|
"sharpe_oos_min": -1.362275778196952,
|
||||||
|
"robust_score": 0.024065408548587387
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "94413564f2f6c03e",
|
||||||
|
"fitness_is": 0.4504680245893446,
|
||||||
|
"sharpe_is": 1.931509193896414,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.1454684156938894,
|
||||||
|
"sharpe": -0.1847503153026734,
|
||||||
|
"dsr": 0.010432618759993285,
|
||||||
|
"dsr_pvalue": 0.9895673812400068,
|
||||||
|
"return": -0.006041376713751601,
|
||||||
|
"max_dd": 0.028928093840880797,
|
||||||
|
"n_trades": 10,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 0.7414755036663777,
|
||||||
|
"dsr": 0.032908166066855475,
|
||||||
|
"dsr_pvalue": 0.9670918339331446,
|
||||||
|
"return": 0.024390796509991652,
|
||||||
|
"max_dd": 0.01848789755136504,
|
||||||
|
"n_trades": 3,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.6298210284045589,
|
||||||
|
"sharpe": 2.8227093941852077,
|
||||||
|
"dsr": 0.783195485997482,
|
||||||
|
"dsr_pvalue": 0.216804514002518,
|
||||||
|
"return": 0.1153800539734966,
|
||||||
|
"max_dd": 0.009172322853563938,
|
||||||
|
"n_trades": 13,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": -0.3705731110916588,
|
||||||
|
"dsr": 0.005298299731142135,
|
||||||
|
"dsr_pvalue": 0.9947017002688578,
|
||||||
|
"return": -0.01618834464316521,
|
||||||
|
"max_dd": 0.050704690156295765,
|
||||||
|
"n_trades": 8,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.1938223610246121,
|
||||||
|
"fitness_oos_min": 0.0,
|
||||||
|
"fitness_oos_max": 0.6298210284045589,
|
||||||
|
"fitness_oos_std": 0.2586344704657744,
|
||||||
|
"sharpe_oos_mean": 0.7522153678643133,
|
||||||
|
"sharpe_oos_min": -0.3705731110916588,
|
||||||
|
"robust_score": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "9deb48ad9a1d6a01",
|
||||||
|
"fitness_is": 0.38499883511982724,
|
||||||
|
"sharpe_is": 1.7309660717184492,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.11865902601061347,
|
||||||
|
"sharpe": -0.33840465028379796,
|
||||||
|
"dsr": 0.006577366557928182,
|
||||||
|
"dsr_pvalue": 0.9934226334420718,
|
||||||
|
"return": -0.012941050841296264,
|
||||||
|
"max_dd": 0.03402877313520886,
|
||||||
|
"n_trades": 17,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 0.5508017623316874,
|
||||||
|
"dsr": 0.028490827818300125,
|
||||||
|
"dsr_pvalue": 0.9715091721816999,
|
||||||
|
"return": 0.01831303651843519,
|
||||||
|
"max_dd": 0.017308885097101046,
|
||||||
|
"n_trades": 7,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 2.1433702644761987,
|
||||||
|
"dsr": 0.4071948898247041,
|
||||||
|
"dsr_pvalue": 0.5928051101752959,
|
||||||
|
"return": 0.10827348451282881,
|
||||||
|
"max_dd": 0.008755897100329497,
|
||||||
|
"n_trades": 8,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 1.0955591683486918,
|
||||||
|
"dsr": 0.07909942404164044,
|
||||||
|
"dsr_pvalue": 0.9209005759583595,
|
||||||
|
"return": 0.01372945300669004,
|
||||||
|
"max_dd": 0.006329669977511941,
|
||||||
|
"n_trades": 5,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.029664756502653367,
|
||||||
|
"fitness_oos_min": 0.0,
|
||||||
|
"fitness_oos_max": 0.11865902601061347,
|
||||||
|
"fitness_oos_std": 0.05138086545675487,
|
||||||
|
"sharpe_oos_mean": 0.862831636218195,
|
||||||
|
"sharpe_oos_min": -0.33840465028379796,
|
||||||
|
"robust_score": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genome_id": "1bb0f36ae3f178ae",
|
||||||
|
"fitness_is": 0.3289012666358953,
|
||||||
|
"sharpe_is": 1.2144322416340778,
|
||||||
|
"folds": [
|
||||||
|
{
|
||||||
|
"fold": 0,
|
||||||
|
"fitness": 0.03325222099260249,
|
||||||
|
"sharpe": -1.0706470661093082,
|
||||||
|
"dsr": 0.0007248785745670455,
|
||||||
|
"dsr_pvalue": 0.999275121425433,
|
||||||
|
"return": -0.09901039935604483,
|
||||||
|
"max_dd": 0.13711458096989376,
|
||||||
|
"n_trades": 27,
|
||||||
|
"test_start": "2022-05-02 12:00:00+00:00",
|
||||||
|
"test_end": "2023-04-02 08:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 1,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 0.12138335573748249,
|
||||||
|
"dsr": 0.018713173174332784,
|
||||||
|
"dsr_pvalue": 0.9812868268256673,
|
||||||
|
"return": 0.00555346714044469,
|
||||||
|
"max_dd": 0.02724874190208475,
|
||||||
|
"n_trades": 7,
|
||||||
|
"test_start": "2023-04-02 09:00:00+00:00",
|
||||||
|
"test_end": "2024-03-02 05:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 2,
|
||||||
|
"fitness": 0.32995249837249846,
|
||||||
|
"sharpe": 0.9733164430116448,
|
||||||
|
"dsr": 0.07297295015940324,
|
||||||
|
"dsr_pvalue": 0.9270270498405968,
|
||||||
|
"return": 0.05047188141942249,
|
||||||
|
"max_dd": 0.02617799182077058,
|
||||||
|
"n_trades": 13,
|
||||||
|
"test_start": "2024-03-02 06:00:00+00:00",
|
||||||
|
"test_end": "2025-01-31 02:00:00+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fold": 3,
|
||||||
|
"fitness": 0.0,
|
||||||
|
"sharpe": 1.3421850442772436,
|
||||||
|
"dsr": 0.05521595540810741,
|
||||||
|
"dsr_pvalue": 0.9447840445918926,
|
||||||
|
"return": 0.06121506651714692,
|
||||||
|
"max_dd": 0.00995276327591354,
|
||||||
|
"n_trades": 3,
|
||||||
|
"test_start": "2025-01-31 03:00:00+00:00",
|
||||||
|
"test_end": "2025-12-31 23:00:00+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fitness_oos_mean": 0.09080117984127524,
|
||||||
|
"fitness_oos_min": 0.0,
|
||||||
|
"fitness_oos_max": 0.32995249837249846,
|
||||||
|
"fitness_oos_std": 0.13873981434768828,
|
||||||
|
"sharpe_oos_mean": 0.34155944422926565,
|
||||||
|
"sharpe_oos_min": -1.0706470661093082,
|
||||||
|
"robust_score": 0.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user