""" AHAD QUANT — Déclencheur manuel du cycle quotidien local (léger) ==================================================================== Appelle exactement la même fonction que le thread de fond AutoRetrainer (auto_retrain.py::run_daily_unified_retrain), mais à la demande — utilisé par le bouton "⚡ Cycle quotidien local" du web UI pour forcer un warm-start LightGBM + RL fine-tune 100% réel sans attendre l'intervalle de DAILY_LOCAL_RETRAIN_INTERVAL_HOURS (24h par défaut). N'écrit PAS dans last_daily_local.json à la place du thread de fond — run_daily_unified_retrain() s'en charge déjà lui-même (_save_daily_local_state), donc un déclenchement manuel ici remet aussi le compteur à zéro pour le thread de fond, ce qui est le comportement voulu (pas de double cycle rapproché). Usage : python daily_local_retrain.py """ import sys try: sys.stdout.reconfigure(encoding="utf-8", errors="replace") except AttributeError: pass from auto_retrain import run_daily_unified_retrain def _notify(msg: str): print(msg) if __name__ == "__main__": print("=" * 65) print(" AHAD QUANT — Cycle quotidien local (déclenché manuellement)") print(" ML : warm-start LightGBM (ensemble) | RL : fine-tune 100% réel") print("=" * 65) result = run_daily_unified_retrain(notify_fn=_notify) print("\n" + "=" * 65) print(f" ML mis à jour : {'✅' if result['ml_updated'] else '❌ (inchangé)'}") print(f" RL mis à jour : {'✅' if result['rl_updated'] else '❌ (inchangé ou skip)'}") print("=" * 65) # Marqueur stdout parsable si besoin futur (cohérent avec le format # RL_FINETUNE_RESULT déjà utilisé ailleurs dans le projet). print(f"DAILY_LOCAL_RESULT ml_updated={result['ml_updated']} " f"rl_updated={result['rl_updated']} ran={result['ran']}") sys.exit(0)