From f85bf4972ad915066d0587c9b45daf7c5bbaaa28 Mon Sep 17 00:00:00 2001 From: caty21 Date: Sun, 28 Jun 2026 14:55:49 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20TvChart=20container=5Fid=20pour=20corrig?= =?UTF-8?q?er=20le=20symbole=20Apple=20+=20redesign=20COT=20ax=C3=A9=20sur?= =?UTF-8?q?=20l'=C3=A9volution=20hebdomadaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TvChart: container_id unique par instance → widget TradingView trouve son conteneur → corrige le bug où tous les charts affichaient Apple Inc au lieu du bon symbole - CurrencyCard COT: nouveau design centré sur l'évolution vs semaine précédente · ② Qui pilote (AM hedge vs HF spécu) · ③ Delta hebdo AM (net Δ) + HF (Δ longs / Δ shorts séparés) · ④ Barre de dominance + signal de convergence/divergence/retournement Co-Authored-By: Claude Sonnet 4.6 --- components/CurrencyCard.tsx | 161 +++++++++++++++++------------------- components/TvChart.tsx | 8 +- 2 files changed, 82 insertions(+), 87 deletions(-) diff --git a/components/CurrencyCard.tsx b/components/CurrencyCard.tsx index 4fd00dd..02a8ea8 100644 --- a/components/CurrencyCard.tsx +++ b/components/CurrencyCard.tsx @@ -1602,100 +1602,91 @@ export default function CurrencyCard({ )} - {/* ② Signal de synthèse — lecture immédiate en premier */} - {(() => { - const hfSignalColor = - (hfLongsGrowing && hfIsShort) || (hfShortsReducing && hfIsShort) - ? "text-emerald-400 border-emerald-500/20 bg-emerald-500/5" - : (hfShortsGrowing && !hfIsShort) || (hfLongsReducing && !hfIsShort) - ? "text-red-400 border-red-500/20 bg-red-500/5" - : "text-slate-300 border-slate-600/30 bg-slate-800/30"; - return ( -
-
- → HF {hfIsShort ? "net short" : "net long"} — {hfTrend} -
-
- {amDominates - ? `AM domine le flux · ${cot.amNet > 0 ? "hedge haussier" : "hedge baissier"} (${dFmt(cot.amNet)})` - : `HF domine le flux · net ${dFmt(cot.net)}` - } -
-
- ); - })()} + {/* ② Qui pilote la devise ? */} +
+ {amDominates + ? <>AM pilote ({amPct}%) · hedge {cot.amNet > 0 ? "haussier" : "baissier"} — institutionnel / carry + : <>HF pilote ({hfPct}%) · spéculation {hfIsShort ? "baissière" : "haussière"} + } +
- {/* ③ Flux hebdomadaire HF — ΔL/ΔS en priorité */} -
-
Mouvement HF · semaine
-
-
-
Δ Longs
-
0 ? "text-emerald-400" : "text-red-400" - }`}> - {cot.longsDelta !== null - ? `${cot.longsDelta > 0 ? "+" : ""}${(cot.longsDelta/1000).toFixed(1)}k${cot.longsDelta > 0 ? "↑" : "↓"}` - : "—" - } -
-
{(cot.hfLongs/1000).toFixed(1)}k acc.
-
-
-
-
Δ Shorts
-
0 ? "text-red-400" : "text-emerald-400" - }`}> - {cot.shortsDelta !== null - ? `${cot.shortsDelta > 0 ? "+" : ""}${(cot.shortsDelta/1000).toFixed(1)}k${cot.shortsDelta > 0 ? "↑" : "↓"}` - : "—" - } -
-
{(cot.hfShorts/1000).toFixed(1)}k acc.
-
+ {/* ③ Évolution hebdomadaire — le delta est la vraie lecture */} +
+
Évolution cette semaine
+ + {/* AM delta */} +
+ AM (hedge) + + 0 ? "text-emerald-400" : "text-red-400"}`}> + {cot.amNet > 0 ? "LONG" : "SHORT"} {dFmt(cot.amNet)} + + {cot.amNetDelta !== null && ( + 0 ? "text-emerald-400" : cot.amNetDelta < 0 ? "text-red-400" : "text-slate-500"}`}> + Δ{dFmt(cot.amNetDelta)}{cot.amNetDelta > 0 ? "↑" : cot.amNetDelta < 0 ? "↓" : ""} + + )} + +
+ + {/* HF delta — Δlongs / Δshorts séparés : c'est ici que se lit l'accumulation */} +
+ HF (spécu) + + 0 ? "text-emerald-400" : "text-red-400"}`}> + {cot.net > 0 ? "LONG" : "SHORT"} {dFmt(cot.net)} + + + {cot.longsDelta !== null && ( + 0 ? "text-emerald-400" : "text-red-400"}> + L {cot.longsDelta > 0 ? "+" : ""}{(cot.longsDelta/1000).toFixed(1)}k{cot.longsDelta > 0 ? "↑" : "↓"} + + )} + {cot.shortsDelta !== null && ( + 0 ? "text-red-400" : "text-emerald-400"}> + S {cot.shortsDelta > 0 ? "+" : ""}{(cot.shortsDelta/1000).toFixed(1)}k{cot.shortsDelta > 0 ? "↑" : "↓"} + + )} + +
- {/* ④ Dominance AM vs HF — poids + direction explicite */} + {/* ④ Barre de dominance + signal de convergence */}
- {/* Barre de poids */} -
+
- {/* AM */} -
- AM · {amPct}% du flux - - 0 ? "bg-emerald-500/15 text-emerald-400" : "bg-red-500/15 text-red-400"}`}> - {cot.amNet > 0 ? "LONG" : "SHORT"} - - 0 ? "text-emerald-400" : "text-red-400"}`}> - {dFmt(cot.amNet)} - - {cot.amNetDelta !== null && ( - Δ{dFmt(cot.amNetDelta)}{cot.amNetDelta > 0 ? "↑" : "↓"} - )} - -
- {/* HF */} -
- HF · {hfPct}% du flux - - 0 ? "bg-emerald-500/15 text-emerald-400" : "bg-red-500/15 text-red-400"}`}> - {cot.net > 0 ? "LONG" : "SHORT"} - - 0 ? "text-emerald-400" : "text-red-400"}`}> - {dFmt(cot.net)} - - {cot.netDelta !== null && ( - Δ{dFmt(cot.netDelta)}{cot.netDelta > 0 ? "↑" : "↓"} - )} - +
+ AM {amPct}% + HF {hfPct}%
+ + {/* Signal de convergence : est-ce que les deux groupes convergent ? */} + {(() => { + const amBull = cot.amNet > 0; + const convergeBull = amBull && (hfLongsGrowing || hfShortsReducing); + const convergeBear = !amBull && (hfShortsGrowing || hfLongsReducing); + const hfFlipping = hfIsShort && hfLongsGrowing && hfShortsReducing; + const txt = hfFlipping + ? `↻ HF retournement potentiel — longs ↑ & shorts ↓ malgré position short` + : convergeBull + ? `▲ Convergence haussière — AM long + HF ${hfTrend}` + : convergeBear + ? `▼ Convergence baissière — AM short + HF ${hfTrend}` + : `→ Divergence — AM ${cot.amNet > 0 ? "long" : "short"} / HF ${hfTrend}`; + const cls = hfFlipping || convergeBull + ? "text-emerald-400/80 bg-emerald-500/5 border-emerald-500/15" + : convergeBear + ? "text-red-400/80 bg-red-500/5 border-red-500/15" + : "text-slate-400 bg-slate-800/30 border-slate-700/20"; + return ( +
+ {txt} +
+ ); + })()}
); diff --git a/components/TvChart.tsx b/components/TvChart.tsx index c8e2e9d..5dc7321 100644 --- a/components/TvChart.tsx +++ b/components/TvChart.tsx @@ -29,11 +29,13 @@ function mountEmbedWidget( widgetDiv.className = "tradingview-widget-container__widget"; widgetDiv.style.width = "100%"; widgetDiv.style.height = `${height}px`; + // container_id permet au widget de trouver son propre conteneur parmi plusieurs instances + if (config.container_id) widgetDiv.id = String(config.container_id); wrapper.appendChild(widgetDiv); const script = document.createElement("script"); script.type = "text/javascript"; - script.async = false; // false = exécution ordonnée → document.currentScript correctement défini + script.async = false; // false → document.currentScript défini lors de l'exécution script.src = scriptSrc; script.text = JSON.stringify(config); wrapper.appendChild(script); @@ -65,6 +67,7 @@ export function TvAdvancedChart({ if (initialized.current || !wrapperRef.current) return; initialized.current = true; + const containerId = `tv_adv_${instanceId.current}`; mountEmbedWidget( wrapperRef.current, `https://s3.tradingview.com/external-embedding/embed-widget-advanced-chart.js?t=${instanceId.current}`, @@ -76,7 +79,7 @@ export function TvAdvancedChart({ interval, timezone: "Europe/Paris", theme: "dark", - style: "1", // bougies japonaises + style: "1", locale: "fr", backgroundColor: "rgba(8,12,20,0)", gridColor: "rgba(30,45,61,0.5)", @@ -88,6 +91,7 @@ export function TvAdvancedChart({ isTransparent: true, save_image: true, drawings_access: { type: "all", tools: [{ name: "Regression Trend" }] }, + container_id: containerId, }, height );