Pular para conteúdo

Retreino de Modelos

Quando retreinar

Situação Frequência
Mudança em model.yaml (gates, hiperparâmetros) Imediato
Drift detectado pelo CUSUM Auto-rollback (não retreina, troca champion)
Performance forward degradou Manual, investigar primeiro
Mudança em features Imediato (todos os modelos)
Rotina semanal Schtask QuantFX-Retrain-Semanal (segunda 03:00)

Comando básico

# Treina todos os ativos × TFs (~3h)
.venv\Scripts\python.exe scripts\run_training.py

# Apenas 1 ativo
.venv\Scripts\python.exe scripts\run_training.py --symbol EURUSD

# Apenas 1 par símbolo+TF
.venv\Scripts\python.exe scripts\run_training.py --symbol EURUSD --tf H1

# Subset de TFs
.venv\Scripts\python.exe scripts\run_training.py --tfs H1 H4

Flags úteis

# Dry-run (não promove, só calcula)
--dry-run

# Force promotion bypass gates (DANGER)
--force-promote

# Reset de modelos existentes
--clean

# Verbose
--verbose

Output esperado

[01/56] Treinando EURUSD H1...
  [features] 13428 amostras, 47 features
  [labels] take=32.1%, stop=29.4%, timeout=38.5%
  [CPCV] 6 folds × 15 paths
  [LGBM] AUC=0.612, ECE=0.21, PF=1.34
  [XGB]  AUC=0.598, ECE=0.23, PF=1.28
  [CAT]  AUC=0.595, ECE=0.20, PF=1.31
  [ensemble] AUC=0.621, ECE=0.18, PF=1.42
  [gates] AUC>=0.58 ✓ | AUC_p5>=0.55 ✓ | ECE<=0.25 ✓ | PF>=0.95 ✓
  [PROMOTED] lgbm_EURUSD_H1_v85b52764.pkl

[02/56] Treinando GBPUSD H1...
  ...
  [gates] AUC>=0.58 ✗ (0.547)  [REJEITADO]

Como interpretar metadata (.meta.json)

{
  "model_v":         "lgbm_EURUSD_H1_v85b52764",
  "symbol":          "EURUSD",
  "timeframe":       "H1",
  "trained_at":      "2026-05-27T03:14:00Z",
  "features":        ["atr_14", "slope_ema_20", ...],
  "wf_metrics": {
    "auc":           0.621,
    "auc_p5":        0.582,
    "ece":           0.18,
    "pf":            1.42,
    "n_test":        1500,
    "n_paths":       15
  },
  "ensemble_weights": {
    "lgbm": 0.5,
    "xgb":  0.3,
    "cat":  0.2
  },
  "conformal_alpha": 0.15,
  "labels_config": {
    "atr_take": 1.5,
    "atr_stop": 1.0,
    "horizon": 8
  },
  "is_active":       true,
  "approved":        true
}

Campos críticos:

  • approved: false → modelo não passou gates, não está em produção
  • is_active: false → demotido manualmente (champion antigo)
  • wf_metrics.pf < 1.0 → perdedor em backtest (rejeição automática)

MLflow tracking

URL local: http://localhost:5000

Estrutura:

  • Experiment por símbolo+TF (ex: EURUSD_H1)
  • Run por versão de modelo (hash)
  • Metrics: AUC, ECE, PF, brier, log_loss
  • Artifacts: pickle + meta.json + feature_importance plot
  • Params: hiperparâmetros, configs/model.yaml snapshot
# Listar experiments
docker exec forex_mlflow mlflow experiments list

# Comparar 2 runs
# (usar UI em localhost:5000 — comparação visual é melhor)

Re-screening (aplicar novos gates)

Após mudar promotion.* em model.yaml:

# Dry-run: mostra quantos seriam demotidos
.venv\Scripts\python.exe scripts\rescreen_champions.py --dry-run

# Apply: marca approved=false em quem não passa
.venv\Scripts\python.exe scripts\rescreen_champions.py --apply

Sync para VPS depois (ver Deploy §4).

Auto-retrain

scripts/auto_retrain.py é chamado pelo schtask. Lógica:

  1. Lista models com drift_score > threshold
  2. Re-treina apenas esses (não todos)
  3. Se novo modelo passa gates → promove
  4. Se não passa → mantém champion atual + alerta Telegram

Log:

docker logs forex_worker --tail 100 | grep -i auto_retrain

Quando NÃO retreinar

  • Mercado em evento extremo (NFP, FOMC, guerra) — esperar normalizar
  • Modelo recém-promovido (<1 semana) — dar tempo de provar forward
  • Hot-fix de bug em features — primeiro corrige, valida, depois retreina

Tempo médio (PC dev)

Escopo Tempo
1 modelo (LGBM+XGB+CAT) ~3-5 min
1 ativo × 4 TFs ~15-20 min
14 ativos × 4 TFs ~3-4h
Re-screening (sem retreino) ~30s
Drift check diário ~5 min