td.mono { white-space: nowrap; }
trading-or.html · or-serveur.js · NEAT dans un Web Worker · données Yahoo Finance

L'IA et l'or, le code

D'où viennent les cours et les données économiques, ce que l'IA regarde chaque jour, comment on calcule ce qu'elle aurait gagné, pourquoi on la juge sur une période qu'elle n'a jamais vue, si l'économie ou les bougies l'aident vraiment à prévoir, et comment fonctionnent le temps réel et l'effet de levier.

Simulation pédagogique avec de l'argent fictif, pas un conseil en investissement. Le code est volontairement simple ; les limites sont listées en fin de page.

01Les données

Les cours viennent de Yahoo Finance : le contrat à terme sur l'or du COMEX (symbole GC=F), en dollars l'once. Il y a deux types de données : les clôtures quotidiennes depuis 2000 (6 550 séances) pour l'entraînement, et le cours minute par minute de la séance pour le temps réel.

Un navigateur n'a pas le droit d'interroger Yahoo directement : les sites refusent les requêtes venant d'une autre page (règle CORS). Un petit relais sur rdv-app.fr, serveur/or-serveur.js, fait la requête à sa place et garde la réponse en mémoire, 6 heures pour l'historique et 30 secondes pour le cours en direct. Si Yahoo ne répond pas, il renvoie la dernière valeur connue ; si le relais lui-même est indisponible, la page se rabat sur un fichier statique, or.json.

serveur/or-serveur.js · historique
// Attention : avec range=max, Yahoo renvoie des points mensuels. On demande donc explicitement les dates.
const r = await yahoo(`period1=946684800&period2=${Math.floor(Date.now() / 1000)}&interval=1d`);

Ce commentaire vient d'un vrai piège rencontré : la première version recevait 269 points mensuels au lieu de 6 550 points quotidiens, sans aucune erreur.

02Ce que voit l'IA

Chaque jour, l'IA reçoit au minimum 13 nombres (jusqu'à 33 avec les options « forme des bougies » et « économie », présentées plus bas). Les 10 premiers sont des indicateurs classiques de l'analyse technique, calculés uniquement avec les cours jusqu'à ce jour-là. Utiliser par erreur un cours du lendemain donnerait une IA miraculeuse sur le papier et inutile en vrai.

EntréeCe qu'elle mesureDivisée par
1 à 4Variation du cours sur 1, 5, 20 et 60 jours (en logarithme)1,5 % · 3,5 % · 7 % · 12 %
5 à 7Écart entre le cours et sa moyenne sur 20, 50 et 200 jours4 % · 6 % · 12 %
8Volatilité : ampleur moyenne des variations quotidiennes sur 20 jours1,2 %
9RSI 14 jours : le cours a-t-il surtout monté ou baissé récemment ? (de 0 à 100, centré sur 50)25
10Recul depuis le plus haut des 252 derniers jours (un an de séances)15 %
11 à 13Position actuelle de l'IA : vendeuse, neutre ou acheteuse (une seule vaut 1)–

Chaque indicateur est divisé par une valeur typique, puis borné entre −3 et 3 : le réseau reçoit des nombres de même ordre de grandeur, et un jour de krach ne fait pas « exploser » ses calculs. Les 200 premières séances servent seulement à amorcer les moyennes : l'IA commence à trader en 2001.

trading-or.html · Or.indicateurs() (extrait)
const borne = (v) => Math.max(-3, Math.min(3, v));
f[o]     = borne(lr(i, 1) / 0.015);                 // variation sur 1 jour
f[o + 4] = borne((c[i] / moy(20) - 1) / 0.04);      // écart à la moyenne 20 jours
f[o + 8] = borne((rsi - 50) / 25);                  // RSI centré
f[o + 9] = borne((c[i] / haut - 1) / 0.15);         // recul depuis le plus haut d'un an

03La décision

Le réseau a 3 sorties : vendre, rester neutre, acheter. La plus forte l'emporte. Si la vente à découvert n'est pas autorisée, la sortie « vendre » est simplement ignorée. Donner la position actuelle en entrée permet au réseau d'apprendre à ne pas changer d'avis pour un rien, puisque chaque changement coûte des frais.

trading-or.html · Or.decider()
const e = Array.from(f.subarray(i * NF, i * NF + NF));
e.push(pos === -1 ? 1 : 0, pos === 0 ? 1 : 0, pos === 1 ? 1 : 0);
const o = activer(e);
let k = 1;                              // neutre par défaut
if (o[2] > o[k]) k = 2;                 // acheter
if (vente && o[0] > o[k]) k = 0;        // vendre, seulement si autorisé
return k - 1;                           // -1, 0 ou 1

04Le portefeuille

La règle est simple et prudente : l'IA décide à la clôture du jour i, avec les cours connus ce jour-là, et sa position s'applique jusqu'à la clôture du lendemain. Elle ne profite donc jamais d'un mouvement qu'elle n'aurait pas pu anticiper.

À chaque changement de position, on prélève les frais (0,1 % par défaut, le double pour passer directement d'acheteur à vendeur). Le portefeuille suit ensuite le cours : multiplié par la variation de l'or si l'IA est acheteuse, divisé si elle est vendeuse, inchangé si elle est neutre. On note au passage la pire chute depuis un sommet.

trading-or.html · Or.simuler()
for (let i = a; i < b; i++) {
  const p = decider(activer, f, i, pos, vente);
  if (p !== pos) { eq *= 1 - frais * Math.abs(p - pos); trades++; pos = p; }
  eq *= Math.exp(pos * Math.log(c[i + 1] / c[i]));   // la position joue jusqu'à la clôture suivante
  if (eq > haut) haut = eq;
  dd = Math.max(dd, 1 - eq / haut);                  // pire chute depuis un sommet
}

Les rendements sont ramenés à une moyenne annuelle (252 séances par an) pour pouvoir comparer des périodes de longueurs différentes.

05La fitness

La note d'une IA est le logarithme de ce qu'elle a multiplié son capital pendant l'entraînement, moins la moitié de sa pire chute :

trading-or.html · Web Worker · evaluer()
const r = simuler(reseau(versCerveau(g)), C, F, A, S, FRAIS, VENTE);   // A → S : entraînement seulement
g.fitness = Math.log(r.eq) - 0.5 * r.dd;

Le logarithme met les gains et les pertes à égalité (doubler puis diviser par deux ramène à zéro). La pénalité de chute écarte les IA qui gagnent beaucoup en prenant des risques énormes : à rendement égal, celle qui a moins chuté en cours de route est préférée.

Le reste est le même NEAT que dans les autres jeux, exécuté dans un Web Worker : réseaux qui grandissent par mutation, espèces, élitisme, relance de diversité après 40 générations sans progrès. Une génération de 60 IA prend environ une demi-seconde.

06Entraînement et test

La sélection n'utilise que la période d'entraînement (de A à S). Après chaque génération, le Worker rejoue la meilleure IA sur la période de test (de S à aujourd'hui), en partant d'une position neutre, et envoie ce résultat à la page sans jamais s'en servir pour choisir. C'est la condition pour que le test soit un vrai examen.

trading-or.html · Web Worker · boucle() (extrait)
pop.forEach(evaluer);                                   // notes sur l'entraînement uniquement
const best = [...pop].sort((a, b) => b.fitness - a.fitness)[0];
const test = simuler(reseau(versCerveau(best)), C, F, S, B, FRAIS, VENTE);   // examen, pour information

Résultat mesuré avec un entraînement de 2001 à 2018 (100 IA, 150 générations) : la meilleure IA passe de 9 % à 21 % par an sur l'entraînement, mais ne fait que 7 à 14 % par an sur 2019-2026, alors qu'acheter et garder rapportait 16,4 %. La courbe par génération de la page montre ce décrochage : c'est le surapprentissage, expliqué en détail sur la page elle-même.

Si l'on déplace la fin de l'entraînement après coup, les IA déjà entraînées sont effacées : leurs chiffres auraient été calculés avec une autre coupure et ne seraient plus comparables.

07L'économie et la géopolitique

En option, l'IA reçoit aussi le contexte économique américain et géopolitique. Le script scripts/maj_marche.py rassemble tout dans un seul fichier, or-macro.json, aligné jour par jour sur les séances de l'or. Le relais le reconstruit toutes les 12 heures et le sert à la page (/or-api/macro).

DonnéeSourceRythme
Taux à 10 ans, bon du Trésor à 3 mois (suit le taux de la Fed), dollar, VIX, pétrole, S&P 500Yahoo Financequotidien
Inflation (indice des prix CPI-U, sur un an) et taux de chômageBLS, l'office statistique américainmensuel
Créations d'emplois américaines (emploi salarié non agricole)BLSmensuel
Argent métalYahoo Finance (SI=F)quotidien
Risque géopolitique mondial, avec les grands événements datésCaldara et Iacoviello (Réserve fédérale), indice calculé à partir de la pressequotidien
Tensions par région : Moyen-Orient (Israël, Arabie saoudite, Égypte, Turquie), Russie-Ukraine, Chine-TaïwanCaldara et Iacoviello, indices par pays (part des articles qui évoquent des tensions impliquant chaque pays)mensuel

La difficulté est de ne jamais donner à l'IA une information qu'elle n'aurait pas eue à l'époque. L'inflation de mars, par exemple, n'est publiée que vers le 15 avril : utiliser ce chiffre fin mars reviendrait à tricher. Chaque valeur n'est donc rendue disponible qu'à partir de sa date de publication.

scripts/maj_marche.py · publication et alignement
def publication(annee, mois):
    #Les chiffres du mois M sont publiés vers le 15 du mois suivant
    a, m = (annee + 1, 1) if mois == 12 else (annee, mois + 1)
    return datetime.date(a, m, 15).isoformat()

def aligner(dates, serie, decalage_jours=1):
    #Valeur connue à chaque date : la dernière observation antérieure d'au moins `decalage_jours`
    ...
DonnéeUtilisée à partir du
Cours de marché, risque géopolitique quotidienlendemain
Inflation et chômage du mois M15 du mois M+1
Créations d'emplois du mois M (publiées le premier vendredi)8 du mois M+1
Tensions par région du mois M5 du mois M+1

Exemple vérifié : le 20 mars 2020, en pleine panique du Covid, le chômage vu par l'IA est encore 3,5 % (le chiffre de février). L'envolée à près de 15 % n'apparaît qu'à sa publication, en mai.

Trois pièges rencontrés :

  • FRED, la base de données de la Fed de Saint-Louis, refuse les requêtes venant de serveurs : d'où le passage par le BLS et Yahoo.
  • Le BLS publie « - » pour les mois sans chiffre : la dernière valeur connue reste alors en vigueur.
  • Sans clé d'inscription, le BLS n'accepte que 25 requêtes par jour, et ne renvoie que 10 ans par requête. Les séries sont donc gardées dans scripts/cache/ : une mise à jour ne redemande que les deux dernières années, et si le BLS refuse, les chiffres précédents sont conservés.

08Quinze critères économiques

Avec l'option « économie », l'IA reçoit 15 critères de plus, en plus des indicateurs du cours et de sa position. Comme pour le cours, chaque critère est ramené à une échelle comparable et borné entre −3 et 3.

CritèreCalculEffet habituel sur l'or
Taux à 10 ansévolution sur un moisdes taux qui montent pèsent sur l'or
Taux réeltaux à 10 ans moins l'inflation (approximation)l'or ne rapporte rien : il attire moins quand le taux réel est élevé
Taux de la Fedévolution du taux à 3 mois sur 3 moisles hausses de la Fed pèsent souvent sur l'or
Dollarévolution sur un moisdollar fort, or souvent en baisse
Peur des marchés (VIX)niveau (20 = normal)valeur refuge lors des crises
Inflationniveau sur un anprotection contre l'inflation
Chômageévolution sur six moisannonce souvent des baisses de taux
Risque géopolitiqueniveau (100 = moyenne 1985-2019)guerres et tensions poussent vers les refuges
Pétrole, actions américainesévolution sur un moisinflation, appétit pour le risque
Créations d'emploisdernier mois publié (0 si pas encore connu)un marché du travail faible fait espérer des baisses de taux
Tensions Moyen-Orient, Russie-Ukraine, Chine-Taïwanniveau mensuel par régionrefuge ; achats d'or des banques centrales après 2022
Argent métalévolution sur un moisles deux métaux évoluent souvent ensemble
trading-or.html · Or.indicateurs() (extrait)
f[o + 11] = b((v("taux10", i) - v("inflation", i) - 1) / 1.5);        // taux réel : taux moins inflation
f[o + 13] = b(lrm("dollar", 20) / 0.02);                              // le dollar se renforce-t-il ?
f[o + 17] = b((v("geopolitique", i) - 100) / 60);                     // risque géopolitique

Un bug instructif rencontré en écrivant ce code : dans la boucle, une variable de comptage portait le même nom (m) que les séries économiques, et les masquait. Le paramètre s'appelle désormais macro.

Le résultat mesuré

Quatre entraînements par cas (60 IA, 120 générations), comparés sur la période de test jamais vue (mesure faite avec les 10 premiers critères) :

Période de testCours seulCours + économieAcheter et garder
2019-202614,9 %/an (14,1 à 16,1)12,1 %/an (8,2 à 17,2)16,4 %/an
2013-20265,7 %/an (5,0 à 6,7)3,8 %/an (2,5 à 7,2)6,8 %/an

Avec l'économie, l'IA réussit mieux sur l'entraînement (15,7 % au lieu de 14,0 % par an pour la première coupure), mais moins bien sur le test, et de façon plus irrégulière. Plus d'informations, c'est aussi plus de façons d'apprendre le passé par cœur : le surapprentissage augmente.

Le panneau de contexte de la page mesure le « lien observé » : la corrélation entre les variations sur 21 séances de chaque indicateur et celles de l'or, de 2001 à aujourd'hui. Seuls l'argent métal (+0,70) et le dollar (−0,45) ont un lien net et régulier ; le taux de la Fed suit de loin (−0,18). L'inflation, le VIX, le pétrole, le chômage et les tensions géopolitiques, régionales comprises, n'en ont presque pas mois par mois : leur effet existe lors de certaines crises, pas de façon régulière. Et un lien n'est pas une prévision : l'argent et le dollar bougent en même temps que l'or, pas avant.

09Ce qui guide l'IA

Un réseau de neurones ne dit pas pourquoi il décide. On peut l'interroger de l'extérieur : sur chaque jour de la période de test, on « neutralise » un critère à la fois (on le remet à sa valeur moyenne, 0) et on regarde si la décision change. La part des jours où elle change mesure l'importance du critère.

trading-or.html · majInfluence() (extrait)
const base = choix(act(e), evo.vente);
for (let k = 0; k < nf; k++) {
  const e2 = e.slice(); e2[k] = 0;                         // critère neutralisé
  if (choix(act(e2), evo.vente) !== base) changes[k]++;    // la décision change-t-elle ?
}

L'avis du jour utilise la même idée sur la dernière séance : l'IA donne sa décision (acheter, rester à l'écart, vendre), et les critères dont le retrait réduit le plus l'avance de cette décision sur les autres sont présentés avec les vrais chiffres du jour (« or 12 % sous son plus haut d'un an », « taux de la Fed 4,02 % »…). C'est un avis appris sur le passé, accompagné de son résultat sur la période de test, pas un conseil.

10Les bougies

Une bougie résume une période avec quatre prix : ouverture, plus haut, plus bas, clôture. Le script récupère ces quatre valeurs pour chaque séance ; quand Yahoo ne les a pas (752 séances anciennes, surtout avant 2010), la bougie se réduit à un trait au cours de clôture.

Pour afficher des bougies par semaine ou par mois, on regroupe les séances : la première ouverture, le plus haut des plus hauts, le plus bas des plus bas, la dernière clôture. La semaine est repérée par son lundi.

trading-or.html · construireBougies() (extrait)
const k = cle(H.dates[i]), b = bougies[bougies.length - 1];
if (b && b.k === k) { b.i1 = i; b.h = Math.max(b.h, HAU[i]); b.l = Math.min(b.l, BAS[i]); b.c = C[i]; }
else bougies.push({ k, i0: i, i1: i, o: OUV[i], h: HAU[i], l: BAS[i], c: C[i] });

Le cours en direct complète la bougie du jour : toutes les 30 secondes, les cours minute par minute de la séance donnent l'ouverture, le plus haut et le plus bas, et le dernier cours sert de clôture provisoire. Si la séance n'est pas encore dans l'historique (reconstruit toutes les 12 heures), la bougie est ajoutée au bout du graphique, entourée en or et marquée « en direct ». En simulation, les cours minute par minute sont aussi regroupés en bougies de 5 minutes.

11Les bougies prédisent-elles ?

Deux façons de poser la question, avec deux réponses différentes.

Les figures classiques : non

L'analyse technique donne des noms à certaines formes de bougies : le marteau (longue mèche basse, censé annoncer une hausse), l'étoile filante (longue mèche haute, censée annoncer une baisse), l'avalement (une bougie qui « englobe » la précédente), le doji (ouverture et clôture presque égales)… La page les détecte sur chaque séance, puis compare ce que fait l'or le lendemain avec un jour ordinaire, sur 2010-2018 puis sur 2019-2026.

trading-or.html · majFigures() (extrait)
["Marteau", "hausse", (i) => Math.abs(corps(i)) > 0 && mb(i) >= 2 * Math.abs(corps(i)) && mh(i) <= 0.3 * Math.abs(corps(i))],
// … pour chaque figure et chaque période : nombre de cas, variation moyenne le lendemain, part de hausses,
// et écart avec un jour ordinaire rapporté à sa marge d'erreur (« t »).
const stable = Math.sign(p1.t) === Math.sign(p2.t) && Math.abs(p1.t) > 2 && Math.abs(p2.t) > 2;
FigureCensée annoncerLendemain 2010-2018Lendemain 2019-2026
Marteauhausse−0,47 % (67 cas)+0,55 % (19 cas)
Avalement baissierbaisse−0,24 % (84 cas)+0,19 % (103 cas)
Étoile filantebaisse+0,34 % (64 cas)+0,56 % (16 cas)
Doji, avalement haussier, 3 vertes, 3 rouges…–comme un jour ordinaire

Aucune figure ne tient sur les deux périodes : le marteau et l'avalement baissier changent de sens, l'étoile filante fait l'inverse de ce qu'elle annonce, sur peu de cas. Avec une quarantaine de mesures, quelques écarts « remarquables » apparaissent de toute façon par hasard. La carte « Les bougies prédisent-elles l'avenir ? » de la page refait ce calcul en direct sur les données à jour.

La forme brute, donnée à l'IA : un peu

Plutôt que des figures toutes faites, l'option « forme des bougies » donne à l'IA cinq mesures brutes de la bougie du jour, et la laisse les combiner avec le reste :

CritèreCalcul
Corps(clôture − ouverture) / amplitude : de −1 (toute rouge) à +1 (toute verte)
Mèche haute, mèche bassetaille de chaque mèche, en part de l'amplitude
Écart à l'ouvertureouverture du jour comparée à la clôture de la veille (le « gap »)
Amplitude du jour(plus haut − plus bas) / cours, comparée à la volatilité habituelle
trading-or.html · Or.indicateurs() (extrait)
const O = bg.ouverture[i], Hh = bg.haut[i], L = bg.bas[i], amp = Hh - L;
if (amp > 0) {                                                     // bougie sans ouverture/haut/bas connus : zéros
  f[q] = borne((c[i] - O) / amp);                                  // corps
  f[q + 1] = borne(((Hh - Math.max(O, c[i])) / amp) * 2 - 1);      // mèche haute
  f[q + 2] = borne(((Math.min(O, c[i]) - L) / amp) * 2 - 1);       // mèche basse
  f[q + 4] = borne((amp / c[i]) / (vol || 0.01) - 1.5);            // amplitude du jour
}
if (i > 0) f[q + 3] = borne((O / c[i - 1] - 1) / 0.005);           // écart à l'ouverture

Résultat sur 48 entraînements (60 IA, 120 générations), quatre coupures différentes, rendement par an sur la période de test jamais vue :

Période de testCours seulCours + forme des bougiesAcheter et garder
2013-2026 (8 essais par cas)5,4 %6,2 %6,8 %
2016-2026 (4 essais)11,2 %12,5 %13,4 %
2019-2026 (8 essais)13,5 %16,7 %16,4 %
2021-2026 (4 essais)12,6 %15,8 %14,1 %

La forme des bougies améliore le résultat sur la période de test pour les quatre coupures : l'écart moyen avec acheter et garder passe de −1,7 à −0,4 point par an. Et ce n'est pas du surapprentissage : le résultat sur l'entraînement, lui, ne monte pas (il baisse même légèrement). L'information sert donc pour l'avenir, pas seulement pour le passé.

Mais restons mesurés : une troisième série de 16 essais donne un écart de −1,6 point par an au lieu de −0,4. L'apport des bougies est réel mais modeste, et une partie de l'écart vient du hasard des entraînements. En moyenne, l'IA ne bat toujours pas acheter et garder : elle s'en approche, certains essais le battent, d'autres non.

Bougies et économie ensemble : non

Dernière question : en donnant à l'IA à la fois la forme des bougies et les 15 critères économiques, prédit-elle mieux ? Seize essais par cas :

Période de testBougies seulesBougies + économieAcheter et garder
2013-20265,5 %4,0 %6,8 %
2016-202610,6 %3,9 %13,4 %
2019-202613,9 %10,2 %16,4 %
2021-202614,2 %4,8 %14,1 %
Écart moyen avec le marché−1,6 point/an−7,0 points/an

Avec l'économie en plus, le résultat sur l'entraînement monte (15,7 % au lieu de 14,6 % par an), mais il s'effondre sur la période de test : aucun des 16 essais ne bat le marché. Avec 33 entrées pour quelques milliers de séances, l'IA trouve dans le passé des coïncidences entre l'or et l'économie qui ne se reproduisent pas. Plus d'informations n'est pas toujours mieux : c'est la leçon centrale de cette page. D'où les réglages par défaut : forme des bougies cochée, économie décochée.

12PPO, l'autre façon d'apprendre

NEAT fait évoluer une population de réseaux et ne leur donne qu'une note : le rendement sur toute la période d'entraînement. PPO (Proximal Policy Optimization, apprentissage par renforcement) fait apprendre un seul réseau par gradient, et juge chaque décision : la récompense du jour est ce que la position a rapporté jusqu'au lendemain, moins les frais. « Proximale » : à chaque mise à jour, la politique ne change que légèrement, ce qui rend l'apprentissage stable.

Le script scripts/ppo_or.py (PyTorch) reprend exactement les conditions de la page : mêmes 15 indicateurs (cours + forme des bougies, recopiés à l'identique de JavaScript — vérifié : écart nul sur les 6 550 séances), même position en entrée, mêmes frais, mêmes coupures. Il s'entraîne sur des fenêtres d'un an tirées au hasard dans la période d'entraînement, 16 à la fois.

scripts/ppo_or.py · la récompense d'une journée
p = positions[act[t, e]]
r = -FRAIS * abs(p - pos[e]) + p * math.log(c[jour[e] + 1] / c[jour[e]])   # ce que la position a rapporté
rec[t, e] = r * 100                                                     # en %, pour le gradient

Résultat sur la période de test jamais vue, 4 essais par coupure (400 000 décisions d'entraînement chacun, environ 30 secondes) :

Période de testAcheter et garderNEAT (moyenne)PPO (moyenne)PPO bat le marché
2013-20266,8 %5,9 %7,0 %3/4
2016-202613,5 %11,6 %14,7 %3/4
2019-202616,5 %15,8 %15,8 %2/4
2021-202614,3 %15,0 %16,9 %4/4
Écart moyen avec le marché−0,7 point/an+0,8 point/an12/16

PPO fait mieux que NEAT sur trois coupures sur quatre, et un peu mieux que le marché en moyenne. Son comportement explique pourquoi : il reste à l'achat 90 à 98 % du temps et ne sort du marché que quelques jours par an. Il a surtout appris qu'acheter et garder l'or fonctionne, avec quelques sorties. Il surapprend aussi moins : sur l'entraînement, il fait moins que NEAT (par exemple 22-23 % par an contre 25 % pour la coupure 2012), mais mieux sur la suite.

Avec la vente à découvert autorisée, l'écart moyen monte à +1,4 point par an, mais devient très irrégulier (de 3,9 % à 27,7 % par an pour la même coupure) : parier sur la baisse de l'or a rarement payé sur 25 ans.

La page refait les calculs du réseau PPO en JavaScript à partir de ses poids exportés (or-ppo.json) : on peut afficher chacune des 16 IA PPO sur les graphiques, lire son avis du jour et la faire jouer en temps réel. Vérifié : ses décisions dans le navigateur sont identiques à celles de Python sur les 6 349 séances.

13Le temps réel

La page interroge le relais toutes les 30 secondes. Pour décider, l'IA a besoin de ses 10 indicateurs « du jour » : on prend l'historique et on remplace la clôture d'aujourd'hui par le cours en direct, comme si la séance se terminait maintenant.

trading-or.html · decisionIA()
const cours = Array.from(C);
if (H.dates[N - 1] === auj) cours[N - 1] = prix; else cours.push(prix);   // clôture provisoire
const f = Or.indicateurs(cours.slice(-300));
return Or.decider(Or.reseau(directEtat.cerveau), f, Math.min(cours.length, 300) - 1, directEtat.ia.pos, directEtat.vente);

Par défaut, l'IA décide une fois par jour, à la première mise à jour d'une nouvelle séance, comme pendant son entraînement. L'option « à chaque mise à jour » la fait réagir toutes les 30 secondes : plus spectaculaire, mais elle n'a jamais été entraînée à ce rythme et risque de payer beaucoup de frais.

L'état de la simulation (positions, gains, journal, courbe) est gardé dans votre navigateur : la simulation reprend à chaque visite. Pendant que la page est fermée, rien ne tourne ; au retour, les portefeuilles rattrapent d'un coup la variation du cours.

14Le levier

En temps réel, on ne raisonne plus en « capital multiplié » mais en euros gagnés ou perdus sur une exposition fixe, comme chez un courtier. Avec 1 000 000 € d'exposition et un levier ×20, le courtier bloque 50 000 € de marge ; à ×100, seulement 10 000 €. Le gain ou la perte, lui, dépend uniquement de l'exposition :

trading-or.html · appliquer()
p.pnl += directEtat.expo * p.pos * (prix / p.prix - 1);      // gain ou perte depuis la dernière mise à jour
if (p.pnl <= -directEtat.expo / directEtat.levier) {          // les pertes ont mangé toute la marge
  p.liquide = true; p.pos = 0;                                // appel de marge : position fermée
}
Exposition 1 000 000 €MargeMouvement de l'or qui efface la marge
Levier ×5200 000 €20 %
Levier ×2050 000 €5 %
Levier ×10010 000 €1 %

Le gain ou la perte de chaque journée se calcule en retenant le résultat cumulé au premier cours de chaque nouvelle séance : la différence avec la séance suivante (ou avec maintenant) donne la journée. Sur l'historique, la page fait le même calcul pour chaque jour de la période de test et affiche la pire et la meilleure journée. Avec 1 000 000 € exposés, la pire journée récente dépasse −100 000 € : plus que la marge entière à ×20.

15Les limites

SimplificationDans la réalité
Ordres exécutés exactement au cours de clôtureLe prix obtenu s'écarte un peu (glissement), surtout les jours agités.
Un seul frais fixe par changement de positionÉcart achat-vente variable, commissions, et frais de financement chaque nuit sur les positions à levier.
Contrat à terme continu (GC=F)Les contrats expirent et sont « roulés » sur le suivant, ce qui crée de petits sauts de prix.
Montants en euros sans taux de changeL'or est coté en dollars : un investisseur en euros subit aussi les variations de l'euro-dollar.
Cours différé de quelques minutesLes courtiers donnent le cours en temps réel.
Taux réel calculé comme taux à 10 ans moins l'inflation passéeLes professionnels utilisent le rendement des obligations indexées sur l'inflation (TIPS).
Des dates de publication fixes (le 5, le 8, le 15 du mois suivant)Les dates réelles varient de quelques jours.
Chiffres économiques dans leur version actuelleInflation et surtout créations d'emplois sont révisées après coup : le chiffre connu à l'époque différait parfois de celui utilisé ici.
Figures de bougies définies par des seuils simplesLes manuels d'analyse technique en donnent des définitions variables, souvent avec le contexte (tendance précédente).
Une seule période de testUn résultat sérieux se vérifie sur plusieurs découpages et plusieurs entraînements, pas un seul.

16Les fichiers

FichierContenu
web/trading-or.htmlLa page : indicateurs, réseau, simulation, NEAT (Web Worker), graphiques, temps réel et levier
serveur/or-serveur.jsRelais Yahoo Finance avec cache, et données économiques (/or-api/macro) (service pm2 or-temps-reel, port 3078, route nginx /or-api/)
scripts/maj_marche.pyConstruit web/or-macro.json (or en bougies, économie, emplois, géopolitique par région, argent métal) et web/or.json ; lancé par le relais toutes les 12 h
scripts/ppo_or.pyEntraînement PPO (PyTorch, environnement .venv-shinobi) et export des 16 IA dans web/or-ppo.json
scripts/cache/Séries du BLS déjà téléchargées (limite de 25 requêtes par jour)
scripts/maj_or.pyAncienne version, cours de l'or seul
terminal
pm2 restart or-temps-reel      # relancer le relais après une modification
.venv/bin/python scripts/maj_marche.py   # reconstruire les données (or, économie, géopolitique)
./deploy.sh                    # publier les pages sur rdv-app.fr