#!/usr/bin/env python3 """ CMA-ES Re-Run at Corrected Fees — Establishes real performance baseline. Corrected fees: taker 5.0 bps, maker +2.0 bps (BingX perps). Previous best 15,080 was at WRONG fees (taker 0.5, maker -0.2). Runs 200 evals across multiple assets with the full venue-tagged, order-type-aware system. Produces a JSON report at malkhut/results/cma_rerun_.json. Usage: python -m malkhut.cma_rerun """ from __future__ import annotations import json import os import sys import time _HERE = os.path.dirname(os.path.abspath(__file__)) if _HERE not in sys.path: sys.path.insert(0, _HERE) from malkhut.state import FulfilmentPolicyParams from malkhut.training.cma_trainer import ( ScenarioFactory, CMAESTrainer, CMAParameterCodec, PolicySnapshot, PolicyEvaluator, SelfPlayPool, ) from malkhut.cwm.core import MinimalCryptoLOBCWM def _baseline() -> FulfilmentPolicyParams: return FulfilmentPolicyParams( version="baseline_corrected_fees", ucb_c=1.414, max_sims=256, max_depth=3, rollout_depth=3, root_temperature=0.5, min_root_entropy=0.25, quote_offsets_ticks=(0, 1, 2), quote_size_fractions=(0.1, 0.25, 0.5), passive_ttl_ms=200, aggressive_ttl_ms=50, maker_edge_min_bps=0.5, cross_spread_edge_min_bps=5.0, adverse_toxicity_cancel_threshold=0.5, queue_churn_cancel_threshold=0.5, mae_tail_cut_bps=50.0, mfe_giveback_cut_fraction=0.5, max_time_in_loss_s=300.0, failed_recovery_cut_count=3, recovery_velocity_min_bps_per_s=0.0, max_symbol_notional_fraction=0.20, max_single_order_notional_fraction=0.05, reduce_when_global_up_fraction=0.30, session_profit_lock_fraction=0.02, w_expected_pnl=1.0, w_fill_probability=0.5, w_adverse_selection=2.0, w_queue_priority=0.5, w_inventory_risk=1.5, w_tail_loss=5.0, w_fee_quality=0.5, w_time_decay=0.3, w_policy_entropy=0.5, robust_tail_weight=2.0, toxic_counterparty_weight=3.0, low_liquidity_weight=2.0, latency_stress_weight=1.0, ) def main(): BUDGET_EVALS = 50 SEED = 42 SYMBOLS = ("BTCUSDT",) print("=" * 70) print("CMA-ES RE-RUN AT CORRECTED FEES") print(f" Fees: taker=5.0 bps, maker=+2.0 bps (BingX)") print(f" Budget: {BUDGET_EVALS} evals") print(f" Assets: {', '.join(SYMBOLS)}") print(f" Seed: {SEED}") print("=" * 70) print() t0 = time.time() factory = ScenarioFactory(exchange_id="bingx") scenarios = factory.build_suite(symbols=list(SYMBOLS), steps_per_scenario=10, seed=SEED) print(f"Scenarios: {len(scenarios)} (×{len(SYMBOLS)} assets)") print(f" Tags: {sorted(set(t for s in scenarios for t in s.tags))[:10]}...") print() def cwm_factory(): return MinimalCryptoLOBCWM() evaluator = PolicyEvaluator(cwm_factory=cwm_factory, scoring_mode="fast") codec = CMAParameterCodec() pool = SelfPlayPool() trainer = CMAESTrainer(codec=codec, evaluator=evaluator, pool=pool, workers=0) print("Running CMA-ES optimization...") best = trainer.train( incumbent=_baseline(), scenarios=scenarios, budget_evals=BUDGET_EVALS, seed=SEED, ) duration = time.time() - t0 print() print("=" * 70) print("RESULTS") print("=" * 70) print(f"Duration: {duration:.1f}s ({duration/60:.1f} min)") print(f"Best score: {best.score:.2f}") print(f"Previous: 15,080 (pre-fee-fix, WRONG fees)") print(f"Params: {best.params.version}") if best.evaluation_summary: print(f"Mean PnL: {best.evaluation_summary.get('mean_pnl', 'N/A'):.2f} bps") print(f"Max DD: {best.evaluation_summary.get('max_dd', 'N/A'):.2f} bps") print(f"Evals: {best.evaluation_summary.get('n', 'N/A')}") print("=" * 70) os.makedirs("malkhut/results", exist_ok=True) report = { "timestamp_s": int(time.time()), "duration_s": round(duration, 1), "budget_evals": BUDGET_EVALS, "seed": SEED, "symbols": list(SYMBOLS), "fees": {"taker_bps": 5.0, "maker_bps": 2.0}, "previous_best": 15080, "best_score": best.score, "improvement_pct": round((best.score - 15080) / max(abs(15080), 1) * 100, 1), "evaluation_summary": best.evaluation_summary, "n_scenarios": len(scenarios), } report_path = f"malkhut/results/cma_rerun_{int(time.time())}.json" with open(report_path, "w") as f: json.dump(report, f, indent=2) print(f"\nReport saved: {report_path}") if __name__ == "__main__": main()