Files
ahad-quant/AHAD_QUANT_Colab_Training.ipynb
T

59 KiB
Raw Blame History

🧠 AHAD QUANT V4 — Entraînement Complet sur Google Colab

GPU recommandé : Runtime → Modifier le type de Runtime → T4 GPU (gratuit)

📋 Étapes

# Étape Durée estimée
1 Upload du projet + installation ~5 min
2 Téléchargement données Forex ~5 min
3 Entraînement ML (LGB + XGB + RF + TFT + TGRU) ~45 min
4 Entraînement RL (PPO) ~60 min
5 Export modèle unifié + téléchargement ~2 min

⚠️ Garde cet onglet actif — Colab déconnecte après 90 min d'inactivité. En cas de déconnexion : relancer depuis la cellule 4.2 avec --resume.

📦 ÉTAPE 1 — Upload & Installation

In [13]:
# ── 1.1 Upload du ZIP AHAD QUANT ──────────────────────────────────────────────
from google.colab import files
import os, zipfile, shutil

print('📁 Sélectionne le fichier ahad_quant_v32_FINAL_updated_v4.zip ...')
uploaded = files.upload()

zip_name = list(uploaded.keys())[0]
print(f'\n✅ Reçu : {zip_name} ({os.path.getsize(zip_name)/1024/1024:.1f} MB)')

# Extraire dans /content/ahad_quant
os.makedirs('/content/ahad_quant', exist_ok=True)
with zipfile.ZipFile(zip_name, 'r') as z:
    z.extractall('/content/ahad_quant')

# Trouver le dossier extrait
subdirs = [d for d in os.listdir('/content/ahad_quant') if os.path.isdir(f'/content/ahad_quant/{d}')]
PROJECT_DIR = f'/content/ahad_quant/{subdirs[0]}'
print(f'📂 Projet extrait dans : {PROJECT_DIR}')
os.chdir(PROJECT_DIR)
print('✅ Répertoire de travail configuré')
📁 Sélectionne le fichier ahad_quant_v32_FINAL_updated_v4.zip ...
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.
Saving ahad_quant_v32_CLEAN.zip to ahad_quant_v32_CLEAN.zip

✅ Reçu : ahad_quant_v32_CLEAN.zip (0.2 MB)
📂 Projet extrait dans : /content/ahad_quant/ahad_quant_v32_fixed
✅ Répertoire de travail configuré
In [14]:
# ── 1.2 Installation des dépendances ─────────────────────────────────────────
print('📦 Installation des packages...')

# Packages standards depuis PyPI
!pip install -q lightgbm xgboost scikit-learn optuna yfinance stable-baselines3[extra] gymnasium shimmy python-dotenv

# Torch GPU (CUDA 11.8) depuis l'index PyTorch dédié
!pip install -q torch torchvision --index-url https://download.pytorch.org/whl/cu118

print('\n✅ Packages installés')
📦 Installation des packages...

✅ Packages installés
In [16]:
# ── 1.3 Configuration GPU + variables d'environnement ────────────────────────
import torch, os

GPU_OK = torch.cuda.is_available()
if GPU_OK:
    gpu_name = torch.cuda.get_device_name(0)
    gpu_mem  = torch.cuda.get_device_properties(0).total_memory / 1024**3
    print(f'✅ GPU détecté : {gpu_name} ({gpu_mem:.1f} GB)')
else:
    print('⚠️  Pas de GPU — entraînement plus lent (CPU). Active le GPU dans Runtime → Modifier le type de Runtime.')

# Variables d'env pour AHAD QUANT
os.environ.update({
    'DATA_SOURCE'           : 'yfinance',     # source données (gratuit)
    'EXCHANGE'              : 'paper',         # pas de broker réel
    'PAPER_MODE'            : 'true',
    'PAPER_INITIAL_BALANCE' : '10000',
    # Mémoire : RAM SYSTÈME Colab (~12 Gi), indépendante de la VRAM du GPU
    'MAX_SEQ_PER_PAIR'      : '4000',
    # Batch size TFT/TGRU — GPU peut prendre 512, CPU limité
    'AHAD_QUANT_BATCH_SIZE'  : '512'   if GPU_OK else '128',
    'AHAD_QUANT_MAX_EPOCHS'  : '20'    if GPU_OK else '10',
})

print('\n📋 Config active :')
for k in ['DATA_SOURCE','PAPER_MODE','MAX_SEQ_PER_PAIR','AHAD_QUANT_BATCH_SIZE','AHAD_QUANT_MAX_EPOCHS']:
    print(f'   {k} = {os.environ[k]}')
✅ GPU détecté : Tesla T4 (14.6 GB)

📋 Config active :
   DATA_SOURCE = yfinance
   PAPER_MODE = true
   MAX_SEQ_PER_PAIR = 4000
   AHAD_QUANT_BATCH_SIZE = 512
   AHAD_QUANT_MAX_EPOCHS = 20
In [17]:
# ── 1.4 (Optionnel) Montage Google Drive pour sauvegarde auto ────────────────
USE_DRIVE = True  # ← Mettre False si tu ne veux pas utiliser Drive

DRIVE_SAVE_DIR = None
if USE_DRIVE:
    from google.colab import drive
    drive.mount('/content/drive')
    DRIVE_SAVE_DIR = '/content/drive/MyDrive/AhadQuant_Models'
    os.makedirs(DRIVE_SAVE_DIR, exist_ok=True)
    print(f'✅ Drive monté — sauvegarde dans : {DRIVE_SAVE_DIR}')
else:
    print('️  Drive désactivé — les modèles seront téléchargés en fin de notebook')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
✅ Drive monté — sauvegarde dans : /content/drive/MyDrive/AhadQuant_Models

📊 ÉTAPE 2 — Téléchargement des données Forex

In [18]:
# ── 2.1 Download 730 jours de données 1h pour les 25 paires ─────────────────
import subprocess, sys

print('📡 Téléchargement des données historiques Forex (Yahoo Finance)...')
print('   25 paires × 730 jours × 1h ≈ 17 000 bougies/paire\n')

result = subprocess.run(
    [sys.executable, 'download_data.py'],
    capture_output=False,
    text=True
)

if result.returncode == 0:
    data_files = [f for f in os.listdir('data') if f.endswith('.json')] if os.path.exists('data') else []
    print(f'\n✅ Données téléchargées : {len(data_files)} fichiers dans data/')
else:
    print(f'\n❌ Erreur download (code {result.returncode})')
📡 Téléchargement des données historiques Forex (Yahoo Finance)...
   25 paires × 730 jours × 1h ≈ 17 000 bougies/paire


✅ Données téléchargées : 25 fichiers dans data/

🤖 ÉTAPE 3 — Entraînement ML (Ensemble + Deep Learning)

In [19]:
# ── 3.1 Entraînement du pipeline ML complet (version diagnostic) ────────────
import subprocess, sys, time, os

print('🧠 Lancement entraînement ML...')
print('   LightGBM + XGBoost + RF + TFT + TransformerGRU + Meta-learner\n')

t0 = time.time()
with open('train_log.txt', 'w') as logfile:
    proc = subprocess.Popen(
        [sys.executable, '-u', 'train.py'],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
        bufsize=1,
    )
    for line in proc.stdout:
        print(line, end='')
        logfile.write(line)
        logfile.flush()
    proc.wait()

elapsed = (time.time() - t0) / 60
if proc.returncode == 0:
    print(f'\n✅ Entraînement ML terminé en {elapsed:.1f} min')
else:
    print(f'\n❌ Échec entraînement ML (code {proc.returncode}) — {elapsed:.1f} min')
    print('\n--- Dernières lignes du log ---')
    with open('train_log.txt') as f:
        lines = f.readlines()
    print(''.join(lines[-40:]))
🧠 Lancement entraînement ML...
   LightGBM + XGBoost + RF + TFT + TransformerGRU + Meta-learner

[DL] PyTorch 2.11.0+cu128 detected — TFT + TGRU enabled
=================================================================
  AHAD QUANT — Ensemble Training Pipeline  (V5)
  LightGBM + XGBoost + RF + TFT + TransformerGRU + Meta-learner
=================================================================

[0/7] Données disponibles : 25 fichiers dans data/

[1/7] Loading data and building tabular features...
  ✅ EURUSD   — 17,222 samples (719 jours)
  ✅ GBPUSD   — 17,223 samples (719 jours)
  ✅ USDJPY   — 17,109 samples (714 jours)
  ✅ USDCHF   — 17,163 samples (716 jours)
  ✅ AUDUSD   — 17,321 samples (723 jours)
  ✅ NZDUSD   — 17,314 samples (723 jours)
  ✅ USDCAD   — 17,326 samples (723 jours)
  ✅ EURGBP   — 17,248 samples (720 jours)
  ✅ EURJPY   — 17,234 samples (719 jours)
  ✅ EURCAD   — 17,249 samples (720 jours)
  ✅ EURCHF   — 17,233 samples (719 jours)
  ✅ EURAUD   — 17,247 samples (720 jours)
  ✅ EURNZD   — 17,240 samples (720 jours)
  ✅ GBPJPY   — 17,233 samples (719 jours)
  ✅ GBPCAD   — 17,313 samples (723 jours)
  ✅ GBPCHF   — 17,230 samples (719 jours)
  ✅ GBPAUD   — 17,309 samples (723 jours)
  ✅ AUDCAD   — 17,318 samples (723 jours)
  ✅ AUDNZD   — 17,315 samples (723 jours)
  ✅ AUDJPY   — 17,234 samples (719 jours)
  ✅ AUDCHF   — 17,283 samples (722 jours)
  ✅ CADJPY   — 17,237 samples (720 jours)
  ✅ CHFJPY   — 17,221 samples (719 jours)
  ✅ NZDJPY   — 17,230 samples (719 jours)
  ✅ NZDCAD   — 17,309 samples (723 jours)

  Total: 431,361 samples | 62 features | 50.40% long labels

[1b/7] Building sequence dataset (SEQ_LEN=168)...
    → sampled 4,000 / 17,051 sequences (RAM cap)
  [EURUSD  ]   4,000 sequences
    → sampled 4,000 / 17,052 sequences (RAM cap)
  [GBPUSD  ]   4,000 sequences
    → sampled 4,000 / 16,938 sequences (RAM cap)
  [USDJPY  ]   4,000 sequences
    → sampled 4,000 / 16,992 sequences (RAM cap)
  [USDCHF  ]   4,000 sequences
    → sampled 4,000 / 17,150 sequences (RAM cap)
  [AUDUSD  ]   4,000 sequences
    → sampled 4,000 / 17,143 sequences (RAM cap)
  [NZDUSD  ]   4,000 sequences
    → sampled 4,000 / 17,155 sequences (RAM cap)
  [USDCAD  ]   4,000 sequences
    → sampled 4,000 / 17,077 sequences (RAM cap)
  [EURGBP  ]   4,000 sequences
    → sampled 4,000 / 17,063 sequences (RAM cap)
  [EURJPY  ]   4,000 sequences
    → sampled 4,000 / 17,078 sequences (RAM cap)
  [EURCAD  ]   4,000 sequences
    → sampled 4,000 / 17,062 sequences (RAM cap)
  [EURCHF  ]   4,000 sequences
    → sampled 4,000 / 17,076 sequences (RAM cap)
  [EURAUD  ]   4,000 sequences
    → sampled 4,000 / 17,069 sequences (RAM cap)
  [EURNZD  ]   4,000 sequences
    → sampled 4,000 / 17,062 sequences (RAM cap)
  [GBPJPY  ]   4,000 sequences
    → sampled 4,000 / 17,142 sequences (RAM cap)
  [GBPCAD  ]   4,000 sequences
    → sampled 4,000 / 17,059 sequences (RAM cap)
  [GBPCHF  ]   4,000 sequences
    → sampled 4,000 / 17,138 sequences (RAM cap)
  [GBPAUD  ]   4,000 sequences
    → sampled 4,000 / 17,147 sequences (RAM cap)
  [AUDCAD  ]   4,000 sequences
    → sampled 4,000 / 17,144 sequences (RAM cap)
  [AUDNZD  ]   4,000 sequences
    → sampled 4,000 / 17,063 sequences (RAM cap)
  [AUDJPY  ]   4,000 sequences
    → sampled 4,000 / 17,112 sequences (RAM cap)
  [AUDCHF  ]   4,000 sequences
    → sampled 4,000 / 17,066 sequences (RAM cap)
  [CADJPY  ]   4,000 sequences
    → sampled 4,000 / 17,050 sequences (RAM cap)
  [CHFJPY  ]   4,000 sequences
    → sampled 4,000 / 17,059 sequences (RAM cap)
  [NZDJPY  ]   4,000 sequences
    → sampled 4,000 / 17,138 sequences (RAM cap)
  [NZDCAD  ]   4,000 sequences

  Total : 100,000 sequences | shape X_seq=(100000, 168, 62) | 50.00% long labels
  Sequence samples : 100,000 | shape: (100000, 168, 62)
  Seq splits: train=70,000 | val=15,000 | test=15,000

[2/7] Walk-forward cross-validation (tabular)...

  Walk-forward CV (4 windows):
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[500]	valid_0's binary_logloss: 0.537108
    Window 1: train=215,680  test=53,920  acc=0.7102
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[500]	valid_0's binary_logloss: 0.536396
    Window 2: train=269,600  test=53,920  acc=0.7090
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[500]	valid_0's binary_logloss: 0.529891
    Window 3: train=323,520  test=53,920  acc=0.7125
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[500]	valid_0's binary_logloss: 0.530677
    Window 4: train=377,440  test=53,920  acc=0.7138
  CV accuracy: 0.7114 ± 0.0019

  Tabular splits: train=301,952 | val=64,704 | test=64,705

[3/7] Hyperparameter search (30 Optuna trials)...
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[306]	valid_0's binary_logloss: 0.531696
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[256]	valid_0's binary_logloss: 0.536046
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.531071
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[176]	valid_0's binary_logloss: 0.534405
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[320]	valid_0's binary_logloss: 0.532699
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.529014
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.533946
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[997]	valid_0's binary_logloss: 0.531701
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[540]	valid_0's binary_logloss: 0.535239
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[519]	valid_0's binary_logloss: 0.530513
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[996]	valid_0's binary_logloss: 0.530435
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[725]	valid_0's binary_logloss: 0.529296
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[998]	valid_0's binary_logloss: 0.528426
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[987]	valid_0's binary_logloss: 0.529308
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[998]	valid_0's binary_logloss: 0.528884
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.529866
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[815]	valid_0's binary_logloss: 0.528147
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[469]	valid_0's binary_logloss: 0.530574
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.532568
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[897]	valid_0's binary_logloss: 0.528453
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.528905
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[695]	valid_0's binary_logloss: 0.529934
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[833]	valid_0's binary_logloss: 0.529049
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.52851
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[761]	valid_0's binary_logloss: 0.531103
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.529707
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.531528
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.529486
Training until validation scores don't improve for 30 rounds
Did not meet early stopping. Best iteration is:
[1000]	valid_0's binary_logloss: 0.532756
Training until validation scores don't improve for 30 rounds
Early stopping, best iteration is:
[310]	valid_0's binary_logloss: 0.531737
  Best LightGBM accuracy (Optuna): 0.7147

[4/7] Training tabular base models (LightGBM + XGBoost + RF)...
  Training LightGBM...
Training until validation scores don't improve for 50 rounds
[200]	valid_0's binary_logloss: 0.537594
[400]	valid_0's binary_logloss: 0.532418
[600]	valid_0's binary_logloss: 0.530308
[800]	valid_0's binary_logloss: 0.529119
[1000]	valid_0's binary_logloss: 0.528434
Early stopping, best iteration is:
[1018]	valid_0's binary_logloss: 0.528387
  Training XGBoost...
  Training RandomForest...

[4b/7] Training Deep Learning models (TFT + TransformerGRU)...
  Training Temporal Fusion Transformer...
  [TFT] device=cuda | train=70,000 val=15,000 samples
  [TFT] parameters: 669,305
/content/ahad_quant/ahad_quant_v32_fixed/tft_model.py:280: FutureWarning: `torch.cuda.amp.GradScaler(args...)` is deprecated. Please use `torch.amp.GradScaler('cuda', args...)` instead.
  scaler_amp = torch.cuda.amp.GradScaler(enabled=torch.cuda.is_available())
/content/ahad_quant/ahad_quant_v32_fixed/tft_model.py:297: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  with torch.cuda.amp.autocast(enabled=torch.cuda.is_available()):
  [TFT] epoch   1/30  train=0.6950  val=0.6942  val_acc=0.5015  (82s)
  [TFT] epoch   2/30  train=0.6936  val=0.6953  val_acc=0.5015  (163s)
  [TFT] epoch   3/30  train=0.6935  val=0.6931  val_acc=0.5053  (243s)
  [TFT] epoch   4/30  train=0.6934  val=0.6935  val_acc=0.5007  (324s)
  [TFT] epoch   5/30  train=0.6931  val=0.6934  val_acc=0.5003  (405s)
  [TFT] epoch   6/30  train=0.6934  val=0.6940  val_acc=0.5033  (486s)
  [TFT] epoch   7/30  train=0.6932  val=0.6936  val_acc=0.5002  (566s)
  [TFT] epoch   8/30  train=0.6929  val=0.6938  val_acc=0.5059  (647s)
  [TFT] epoch   9/30  train=0.6926  val=0.6932  val_acc=0.5073  (728s)
  [TFT] early stopping at epoch 9
  [TFT] training complete — best val_loss=0.6931

  Training TransformerGRU...
  [TGRU] device=cuda | train=70,000 val=15,000 samples
  [TGRU] parameters: 588,033
/content/ahad_quant/ahad_quant_v32_fixed/transformer_gru_model.py:275: FutureWarning: `torch.cuda.amp.GradScaler(args...)` is deprecated. Please use `torch.amp.GradScaler('cuda', args...)` instead.
  scaler_amp = torch.cuda.amp.GradScaler(enabled=torch.cuda.is_available())
/content/ahad_quant/ahad_quant_v32_fixed/transformer_gru_model.py:292: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  with torch.cuda.amp.autocast(enabled=torch.cuda.is_available()):
  [TGRU] epoch   1/30  train=0.6419  val=0.5863  val_acc=0.6751  (32s)
  [TGRU] epoch   2/30  train=0.5910  val=0.5618  val_acc=0.6897  (64s)
  [TGRU] epoch   3/30  train=0.5722  val=0.5608  val_acc=0.6885  (96s)
  [TGRU] epoch   4/30  train=0.5620  val=0.5450  val_acc=0.7002  (128s)
  [TGRU] epoch   5/30  train=0.5493  val=0.5325  val_acc=0.7067  (160s)
  [TGRU] epoch   6/30  train=0.5413  val=0.5278  val_acc=0.7097  (192s)
  [TGRU] epoch   7/30  train=0.5334  val=0.5214  val_acc=0.7157  (224s)
  [TGRU] epoch   8/30  train=0.5262  val=0.5349  val_acc=0.7007  (255s)
  [TGRU] epoch   9/30  train=0.5193  val=0.5043  val_acc=0.7247  (287s)
  [TGRU] epoch  10/30  train=0.5138  val=0.4947  val_acc=0.7262  (319s)
  [TGRU] epoch  11/30  train=0.5041  val=0.4924  val_acc=0.7249  (351s)
  [TGRU] epoch  12/30  train=0.4999  val=0.4847  val_acc=0.7306  (383s)
  [TGRU] epoch  13/30  train=0.4940  val=0.4821  val_acc=0.7277  (415s)
  [TGRU] epoch  14/30  train=0.4866  val=0.4807  val_acc=0.7303  (447s)
  [TGRU] epoch  15/30  train=0.4838  val=0.4750  val_acc=0.7301  (479s)
  [TGRU] epoch  16/30  train=0.4791  val=0.4762  val_acc=0.7289  (511s)
  [TGRU] epoch  17/30  train=0.4743  val=0.4713  val_acc=0.7335  (543s)
  [TGRU] epoch  18/30  train=0.4716  val=0.4662  val_acc=0.7378  (575s)
  [TGRU] epoch  19/30  train=0.4677  val=0.4707  val_acc=0.7357  (606s)
  [TGRU] epoch  20/30  train=0.4647  val=0.4677  val_acc=0.7347  (639s)
  [TGRU] epoch  21/30  train=0.4622  val=0.4695  val_acc=0.7347  (670s)
  [TGRU] epoch  22/30  train=0.4592  val=0.4632  val_acc=0.7383  (702s)
  [TGRU] epoch  23/30  train=0.4566  val=0.4646  val_acc=0.7373  (734s)
  [TGRU] epoch  24/30  train=0.4544  val=0.4650  val_acc=0.7395  (766s)
  [TGRU] epoch  25/30  train=0.4532  val=0.4667  val_acc=0.7361  (798s)
  [TGRU] epoch  26/30  train=0.4521  val=0.4632  val_acc=0.7394  (830s)
  [TGRU] epoch  27/30  train=0.4504  val=0.4662  val_acc=0.7381  (862s)
  [TGRU] epoch  28/30  train=0.4497  val=0.4646  val_acc=0.7389  (894s)
  [TGRU] epoch  29/30  train=0.4478  val=0.4644  val_acc=0.7387  (926s)
  [TGRU] epoch  30/30  train=0.4488  val=0.4646  val_acc=0.7397  (958s)
  [TGRU] training complete — best val_loss=0.4632

❌ Échec entraînement ML (code -9) — 88.7 min

--- Dernières lignes du log ---
  [TFT] training complete — best val_loss=0.6931

  Training TransformerGRU...
  [TGRU] device=cuda | train=70,000 val=15,000 samples
  [TGRU] parameters: 588,033
/content/ahad_quant/ahad_quant_v32_fixed/transformer_gru_model.py:275: FutureWarning: `torch.cuda.amp.GradScaler(args...)` is deprecated. Please use `torch.amp.GradScaler('cuda', args...)` instead.
  scaler_amp = torch.cuda.amp.GradScaler(enabled=torch.cuda.is_available())
/content/ahad_quant/ahad_quant_v32_fixed/transformer_gru_model.py:292: FutureWarning: `torch.cuda.amp.autocast(args...)` is deprecated. Please use `torch.amp.autocast('cuda', args...)` instead.
  with torch.cuda.amp.autocast(enabled=torch.cuda.is_available()):
  [TGRU] epoch   1/30  train=0.6419  val=0.5863  val_acc=0.6751  (32s)
  [TGRU] epoch   2/30  train=0.5910  val=0.5618  val_acc=0.6897  (64s)
  [TGRU] epoch   3/30  train=0.5722  val=0.5608  val_acc=0.6885  (96s)
  [TGRU] epoch   4/30  train=0.5620  val=0.5450  val_acc=0.7002  (128s)
  [TGRU] epoch   5/30  train=0.5493  val=0.5325  val_acc=0.7067  (160s)
  [TGRU] epoch   6/30  train=0.5413  val=0.5278  val_acc=0.7097  (192s)
  [TGRU] epoch   7/30  train=0.5334  val=0.5214  val_acc=0.7157  (224s)
  [TGRU] epoch   8/30  train=0.5262  val=0.5349  val_acc=0.7007  (255s)
  [TGRU] epoch   9/30  train=0.5193  val=0.5043  val_acc=0.7247  (287s)
  [TGRU] epoch  10/30  train=0.5138  val=0.4947  val_acc=0.7262  (319s)
  [TGRU] epoch  11/30  train=0.5041  val=0.4924  val_acc=0.7249  (351s)
  [TGRU] epoch  12/30  train=0.4999  val=0.4847  val_acc=0.7306  (383s)
  [TGRU] epoch  13/30  train=0.4940  val=0.4821  val_acc=0.7277  (415s)
  [TGRU] epoch  14/30  train=0.4866  val=0.4807  val_acc=0.7303  (447s)
  [TGRU] epoch  15/30  train=0.4838  val=0.4750  val_acc=0.7301  (479s)
  [TGRU] epoch  16/30  train=0.4791  val=0.4762  val_acc=0.7289  (511s)
  [TGRU] epoch  17/30  train=0.4743  val=0.4713  val_acc=0.7335  (543s)
  [TGRU] epoch  18/30  train=0.4716  val=0.4662  val_acc=0.7378  (575s)
  [TGRU] epoch  19/30  train=0.4677  val=0.4707  val_acc=0.7357  (606s)
  [TGRU] epoch  20/30  train=0.4647  val=0.4677  val_acc=0.7347  (639s)
  [TGRU] epoch  21/30  train=0.4622  val=0.4695  val_acc=0.7347  (670s)
  [TGRU] epoch  22/30  train=0.4592  val=0.4632  val_acc=0.7383  (702s)
  [TGRU] epoch  23/30  train=0.4566  val=0.4646  val_acc=0.7373  (734s)
  [TGRU] epoch  24/30  train=0.4544  val=0.4650  val_acc=0.7395  (766s)
  [TGRU] epoch  25/30  train=0.4532  val=0.4667  val_acc=0.7361  (798s)
  [TGRU] epoch  26/30  train=0.4521  val=0.4632  val_acc=0.7394  (830s)
  [TGRU] epoch  27/30  train=0.4504  val=0.4662  val_acc=0.7381  (862s)
  [TGRU] epoch  28/30  train=0.4497  val=0.4646  val_acc=0.7389  (894s)
  [TGRU] epoch  29/30  train=0.4478  val=0.4644  val_acc=0.7387  (926s)
  [TGRU] epoch  30/30  train=0.4488  val=0.4646  val_acc=0.7397  (958s)
  [TGRU] training complete — best val_loss=0.4632

In [ ]:
import os, shutil

if os.path.exists('model_ensemble.pkl'):
    print(f"model_ensemble.pkl : {os.path.getsize('model_ensemble.pkl')/1024/1024:.1f} MB")
    if DRIVE_SAVE_DIR:
        shutil.copy('model_ensemble.pkl', f'{DRIVE_SAVE_DIR}/model_ensemble.pkl')
        print(f"💾 Sauvegardé sur Drive : {DRIVE_SAVE_DIR}/model_ensemble.pkl")
else:
    print("⚠️ model_ensemble.pkl non trouvé")

Nouvelle section

In [ ]:
# ── 3.2 Résultats ML (backtest rapide) ───────────────────────────────────────
import json

# Lire les résultats de l'entraînement
results_files = ['last_retrain.json', 'backtest_results.json']
for rf in results_files:
    if os.path.exists(rf):
        with open(rf) as f:
            data = json.load(f)
        print(f'\n📊 {rf}:')
        for k, v in list(data.items())[:15]:
            print(f'   {k}: {v}')

🎮 ÉTAPE 4 — Entraînement RL (PPO Agent)

💡 En cas de déconnexion Colab : remonte Drive, retourne dans le dossier projet, puis relance la cellule 4.2 avec --resume — l'entraînement reprend depuis le dernier checkpoint automatiquement.

In [ ]:
# ── 4.1 Vérification pré-RL ──────────────────────────────────────────────────
import os, json

print('🔍 Vérification des prérequis RL...')
checks = {
    'model_ensemble.pkl' : 'Modèle ML',
    'data/'              : 'Données Forex',
}
ok = True
for path, label in checks.items():
    exists = os.path.exists(path)
    print(f'   {"" if exists else ""} {label} ({path})')
    if not exists:
        ok = False

if ok:
    print('\n✅ Tous les prérequis sont présents — tu peux lancer l\'entraînement RL')
else:
    print('\n❌ Lance d\'abord les étapes 2 et 3 !')

# Config RL
RL_STEPS = 1_000_000  # ← Modifier ici si besoin (500k = rapide, 2M = meilleure qualité)
print(f'\n⚙️  Steps RL configurés : {RL_STEPS:,}')
print(f'   Durée estimée : ~{RL_STEPS/60000:.0f} min (GPU T4)')
In [ ]:
# ── 4.2 Entraînement RL PPO ──────────────────────────────────────────────────
# ⚠️ En cas de reprise après déconnexion : changer --steps en 0 et garder --resume
import subprocess, sys, time, os, shutil

RESUME = os.path.exists('rl_progress.json') and os.path.getsize('rl_progress.json') > 5

if RESUME:
    with open('rl_progress.json') as f:
        prog = json.load(f)
    done = prog.get('steps_done', 0)
    total = prog.get('total_steps', RL_STEPS)
    print(f'♻️  Reprise détectée : {done:,} / {total:,} steps déjà effectués')
    resume_flag = ['--resume']
else:
    print('🆕 Nouvel entraînement RL')
    resume_flag = []

print(f'\n🎮 Lancement PPO ({RL_STEPS:,} steps)...')
print('   Checkpoints sauvegardés toutes les 50k steps dans rl_checkpoints/')
print('   Durée estimée : 45-90 min (GPU T4)\n')

t0 = time.time()
result = subprocess.run(
    [sys.executable, 'rl_train.py', '--steps', str(RL_STEPS)] + resume_flag,
    capture_output=False,
    text=True
)
elapsed = (time.time() - t0) / 60

if result.returncode == 0:
    print(f'\n✅ Entraînement RL terminé en {elapsed:.1f} min')
    for f in ['rl_agent.zip', 'rl_scaler.pkl']:
        if os.path.exists(f):
            print(f'   {f} : {os.path.getsize(f)/1024:.0f} KB')

    # Sauvegarde Drive
    if DRIVE_SAVE_DIR:
        for f in ['rl_agent.zip', 'rl_scaler.pkl']:
            if os.path.exists(f):
                shutil.copy(f, f'{DRIVE_SAVE_DIR}/{f}')
        # Sauvegarder aussi les checkpoints
        if os.path.exists('rl_checkpoints'):
            shutil.copytree('rl_checkpoints', f'{DRIVE_SAVE_DIR}/rl_checkpoints', dirs_exist_ok=True)
        print(f'   💾 Sauvegardé sur Drive : {DRIVE_SAVE_DIR}/')
else:
    print(f'\n❌ Échec RL (code {result.returncode}) — {elapsed:.1f} min')
    print('   ➡️  Relance cette cellule avec --resume pour reprendre')

📦 ÉTAPE 5 — Export modèle unifié & Téléchargement

In [ ]:
# ── 5.1 Export ahad_quant_unified.zip ─────────────────────────────────────────
import subprocess, sys, os, shutil

print('📦 Export du modèle unifié...')
result = subprocess.run(
    [sys.executable, 'export_unified.py'],
    capture_output=False,
    text=True
)

if result.returncode == 0 and os.path.exists('ahad_quant_unified.zip'):
    size_mb = os.path.getsize('ahad_quant_unified.zip') / 1024 / 1024
    print(f'✅ ahad_quant_unified.zip créé ({size_mb:.1f} MB)')

    if DRIVE_SAVE_DIR:
        shutil.copy('ahad_quant_unified.zip', f'{DRIVE_SAVE_DIR}/ahad_quant_unified.zip')
        print(f'💾 Sauvegardé sur Drive : {DRIVE_SAVE_DIR}/ahad_quant_unified.zip')
else:
    print('❌ Export échoué')
In [ ]:
# ── 5.2 Créer un bundle complet avec tous les modèles ────────────────────────
import zipfile, os, datetime, shutil

timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M')
bundle_name = f'ahad_quant_trained_{timestamp}.zip'

FILES_TO_BUNDLE = [
    'ahad_quant_unified.zip',   # modèle unifié complet
    'model_ensemble.pkl',       # modèle ML ensemble
    'rl_agent.zip',             # agent RL PPO
    'rl_scaler.pkl',            # scaler RL
    'backtest_results.json',    # résultats backtest
    'last_retrain.json',        # méta-infos entraînement
]

print(f'📦 Création du bundle {bundle_name}...')
with zipfile.ZipFile(bundle_name, 'w', zipfile.ZIP_DEFLATED) as zf:
    for f in FILES_TO_BUNDLE:
        if os.path.exists(f):
            zf.write(f)
            print(f'   + {f} ({os.path.getsize(f)/1024:.0f} KB)')
        else:
            print(f'   ⚠️  {f} — non trouvé, ignoré')

    # Ajouter les checkpoints RL
    if os.path.exists('rl_checkpoints'):
        for root, dirs, files in os.walk('rl_checkpoints'):
            for file in files:
                fp = os.path.join(root, file)
                zf.write(fp)
        print(f'   + rl_checkpoints/ ({len(os.listdir("rl_checkpoints"))} fichiers)')

size_mb = os.path.getsize(bundle_name) / 1024 / 1024
print(f'\n✅ Bundle créé : {bundle_name} ({size_mb:.1f} MB)')

if DRIVE_SAVE_DIR:
    shutil.copy(bundle_name, f'{DRIVE_SAVE_DIR}/{bundle_name}')
    print(f'💾 Sauvegardé sur Drive : {DRIVE_SAVE_DIR}/{bundle_name}')
In [ ]:
# ── 5.3 Téléchargement direct depuis Colab ───────────────────────────────────
from google.colab import files
import os

# Choisir ce qu'on veut télécharger
TO_DOWNLOAD = [
    bundle_name,             # bundle complet (recommandé)
    # 'ahad_quant_unified.zip', # ou juste le modèle unifié
]

for f in TO_DOWNLOAD:
    if os.path.exists(f):
        size_mb = os.path.getsize(f) / 1024 / 1024
        print(f'⬇️  Téléchargement de {f} ({size_mb:.1f} MB)...')
        files.download(f)
    else:
        print(f'⚠️  {f} non trouvé')

print('\n✅ Terminé ! Place les fichiers .pkl et .zip dans ton dossier ahad_quant_v32_fixed/ sur ta machine.')

🔁 BONUS — Relancer uniquement le RL après déconnexion

Si Colab s'est déconnecté pendant le RL (étape 4), exécute ces cellules dans l'ordre :

In [ ]:
# ── REPRISE RAPIDE (après déconnexion pendant le RL) ─────────────────────────
# 1. Monte Drive
from google.colab import drive
drive.mount('/content/drive')

# 2. Réinstalle les packages
!pip install -q lightgbm xgboost scikit-learn optuna yfinance stable-baselines3[extra] gymnasium shimmy python-dotenv torch --index-url https://download.pytorch.org/whl/cu118

# 3. Remonte le projet depuis Drive
import os, shutil, json
DRIVE_SAVE_DIR = '/content/drive/MyDrive/AhadQuant_Models'
PROJECT_DIR = '/content/ahad_quant_resume'
os.makedirs(PROJECT_DIR, exist_ok=True)

# Copie le ZIP du projet depuis Drive (si tu l'avais mis là)
# OU remonte le ZIP original depuis upload
# from google.colab import files
# uploaded = files.upload()  # ← décommente si besoin

# 4. Copie les modèles existants depuis Drive
for f in ['model_ensemble.pkl', 'rl_agent.zip', 'rl_scaler.pkl', 'rl_progress.json']:
    src = f'{DRIVE_SAVE_DIR}/{f}'
    if os.path.exists(src):
        shutil.copy(src, f'{PROJECT_DIR}/{f}')
        print(f'✅ Restauré : {f}')

if os.path.exists(f'{DRIVE_SAVE_DIR}/rl_checkpoints'):
    shutil.copytree(f'{DRIVE_SAVE_DIR}/rl_checkpoints', f'{PROJECT_DIR}/rl_checkpoints', dirs_exist_ok=True)
    print('✅ Restauré : rl_checkpoints/')

# 5. Affiche la progression
prog_file = f'{PROJECT_DIR}/rl_progress.json'
if os.path.exists(prog_file):
    with open(prog_file) as f:
        prog = json.load(f)
    steps_done = prog.get('steps_done', 0)
    total      = prog.get('total_steps', 1_000_000)
    pct        = steps_done / total * 100
    print(f'\n📊 Progression RL : {steps_done:,} / {total:,} steps ({pct:.1f}%)')
    print('➡️  Maintenant exécute la cellule 4.2 — la reprise sera détectée automatiquement')

📋 RÉCAPITULATIF — Fichiers à récupérer

Après l'entraînement, copie ces fichiers dans ton dossier ahad_quant_v32_fixed/ sur ta machine Windows :

Fichier Description Obligatoire
ahad_quant_unified.zip Modèle complet (ML + RL)
model_ensemble.pkl Ensemble ML seul
rl_agent.zip Agent PPO seul
rl_scaler.pkl Scaler features RL
rl_checkpoints/ Checkpoints intermédiaires Optionnel

Ensuite, depuis le Web UI : lance le bot — il chargera ahad_quant_unified.zip automatiquement.

In [8]:
!free -h
               total        used        free      shared  buff/cache   available
Mem:            12Gi       1.1Gi        10Gi       2.0Mi       785Mi        11Gi
Swap:             0B          0B          0B