2026-08-03 21:09:33 +02:00
{% extends "base.html" %}
{% block title %}Analyse technique - Bolsa{% endblock %}
{% block header_title %}Analyse technique{% endblock %}
{% block content %}
< div class = "flex flex-col items-center justify-start py-4 px-2 w-full h-full overflow-y-auto" >
<!-- Toasts -->
< div id = "toast-container" class = "fixed top-6 left-1/2 transform -translate-x-1/2 z-50 space-y-3 w-full max-w-md px-4 pointer-events-none" >
{% set messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
< div class = "toast-message pointer-events-auto flex items-center justify-center px-4 py-3 rounded-xl shadow-2xl text-white text-sm font-medium transition-all duration-300
{% if category == 'success' %}bg-emerald-600 border border-emerald-500{% else %}bg-rose-600 border border-rose-500{% endif %}" >
< span > {{ message }}</ span >
</ div >
{% endfor %}
{% endif %}
</ div >
<!-- Barre de recherche ISIN -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
2026-08-09 09:50:49 +02:00
< form method = "GET" action = "{{ url_for('analyse.analyse') }}" class = "flex items-center gap-3 flex-wrap" >
2026-08-03 21:09:33 +02:00
< input type = "hidden" name = "csrf_token" value = "{{ csrf_token() }}" />
< div class = "flex-1 min-w-[200px]" >
< label class = "block text-xs font-medium text-gray-400 mb-1" > Entrer un ISIN</ label >
< input type = "text" name = "isin" id = "input-isin-analyse" required
value = "{{ isin_recherche or '' }}"
placeholder = "Ex : FR0000120271"
class = "w-full bg-gray-950 border border-gray-800 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-blue-500 uppercase" />
</ div >
< button type = "submit" class = "px-5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white text-sm font-semibold rounded-lg transition cursor-pointer self-end" >
< i class = "fa-solid fa-magnifying-glass-chart" ></ i > Analyser
</ button >
< a
2026-08-09 09:50:49 +02:00
href = "{{ url_for('menu.menu') }}"
2026-08-03 21:09:33 +02:00
class = "px-5 py-2.5 bg-gray-800 hover:bg-gray-700 text-gray-200 text-sm font-semibold rounded-lg transition duration-200 cursor-pointer self-end"
>
< i class = "fa-solid fa-house" ></ i > Retour au menu
</ a >
</ form >
</ div >
{% if resultat %}
{% if resultat.erreur %}
<!-- Message d'erreur -->
< div class = "bg-rose-950 border border-rose-800 rounded-xl p-6 text-center w-full max-w-[98%]" >
< i class = "fa-solid fa-triangle-exclamation text-rose-400 text-3xl mb-3" ></ i >
< p class = "text-rose-300 text-sm" > {{ resultat.erreur }}</ p >
{% if resultat.action %}
< p class = "text-gray-400 text-xs mt-2" > Action : {{ resultat.action.company_name }} ({{ resultat.isin }})</ p >
{% endif %}
</ div >
{% else %}
<!-- ===================== EN-TÊTE FICHE ACTION ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-6 mb-4" >
< div class = "flex flex-wrap items-start justify-between gap-4" >
< div >
< h2 class = "text-3xl font-extrabold text-white" > {{ resultat.action.company_name }}</ h2 >
< p class = "text-gray-400 text-sm font-mono mt-1" > {{ resultat.isin }}
{% if resultat.action.ticker %} · {{ resultat.action.ticker }}{% endif %}
</ p >
< div class = "flex items-center gap-4 mt-3" >
< span class = "text-2xl font-bold text-white" > {{ "{:,.2f}".format(resultat.cours) }} {{ resultat.action.currency or '€' }}</ span >
{% set vj = resultat.variation_jour %}
< span class = "text-lg font-semibold {% if vj and vj >= 0 %}text-emerald-400{% elif vj %}text-rose-400{% else %}text-gray-400{% endif %}" >
{% if vj %}{{ "{:+,.2f}".format(vj) }} %{% else %}--{% endif %}
</ span >
</ div >
< p class = "text-gray-500 text-xs mt-1" > Dernier cours : {{ resultat.derniere_date_cours }}</ p >
</ div >
< div class = "text-right" >
< div class = "inline-block bg-gray-950 border border-gray-800 rounded-xl px-5 py-3" >
< p class = "text-xs text-gray-400 uppercase tracking-wider" > Score</ p >
< p class = "text-4xl font-extrabold
{% if resultat.score >= 65 %}text-emerald-400{% elif resultat.score <= 35 %}text-rose-400{% else %}text-amber-400{% endif %}" >
{{ resultat.score }}/100
</ p >
</ div >
< p class = "mt-2 text-sm font-semibold
{% if resultat.tendance == 'haussiere' %}text-emerald-400{% elif resultat.tendance == 'baissiere' %}text-rose-400{% else %}text-amber-400{% endif %}" >
{% if resultat.tendance == 'haussiere' %}🟢 Haussière{% elif resultat.tendance == 'baissiere' %}🔴 Baissière{% else %}🟡 Neutre{% endif %}
</ p >
</ div >
</ div >
</ div >
<!-- ===================== CARTES INDICATEURS ===================== -->
< div class = "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-7 gap-3 w-full max-w-[98%] mb-4" >
<!-- RSI -->
{% set rsi14 = resultat.rsi.RSI14 %}
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > RSI 14</ p >
< p class = "text-2xl font-bold {% if rsi14.valeur and rsi14.valeur < 30 %}text-emerald-400{% elif rsi14.valeur and rsi14.valeur > 70 %}text-rose-400{% else %}text-white{% endif %}" >
{{ rsi14.valeur if rsi14.valeur is not none else '--' }}
</ p >
< p class = "text-[10px] {% if rsi14.zone == 'survente' %}text-emerald-400{% elif rsi14.zone == 'surachat' %}text-rose-400{% else %}text-gray-500{% endif %} uppercase" > {{ rsi14.zone }}</ p >
</ div >
<!-- MACD -->
{% set macd = resultat.macd %}
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > MACD</ p >
< p class = "text-2xl font-bold {% if macd.histogramme and macd.histogramme > 0 %}text-emerald-400{% elif macd.histogramme and macd.histogramme < 0 %}text-rose-400{% else %}text-white{% endif %}" >
{{ "{:+.2f}".format(macd.histogramme) if macd.histogramme is not none else '--' }}
</ p >
< p class = "text-[10px] {% if macd.croisement == 'haussier' %}text-emerald-400{% elif macd.croisement == 'baissier' %}text-rose-400{% else %}text-gray-500{% endif %} uppercase" > {{ macd.croisement }}</ p >
</ div >
<!-- ATR14 -->
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > ATR 14</ p >
< p class = "text-2xl font-bold text-white" > {{ resultat.atr.ATR14 if resultat.atr.ATR14 is not none else '--' }}</ p >
< p class = "text-[10px] text-gray-500" > {{ resultat.atr.ATR14_pct if resultat.atr.ATR14_pct is not none else '--' }}% du cours</ p >
</ div >
<!-- Volatilité -->
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > Volatilité 20j</ p >
< p class = "text-2xl font-bold text-white" > {{ resultat.volatilite.actuelle if resultat.volatilite.actuelle is not none else '--' }}%</ p >
< p class = "text-[10px] text-gray-500" > Moy 1an : {{ resultat.volatilite.moyenne_1an if resultat.volatilite.moyenne_1an is not none else '--' }}%</ p >
</ div >
<!-- Bollinger -->
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > Bollinger</ p >
< p class = "text-2xl font-bold text-white" > {{ resultat.bollinger.position if resultat.bollinger.position is not none else '--' }}%</ p >
< p class = "text-[10px] text-gray-500" > position dans les bandes</ p >
</ div >
<!-- Volume relatif -->
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > Volume relatif</ p >
< p class = "text-2xl font-bold {% if resultat.volumes.exceptionnel %}text-amber-400{% else %}text-white{% endif %}" >
{{ resultat.volumes.volume_relatif if resultat.volumes.volume_relatif is not none else '--' }}x
</ p >
< p class = "text-[10px] {% if resultat.volumes.exceptionnel %}text-amber-400{% else %}text-gray-500{% endif %}" > {% if resultat.volumes.exceptionnel %}Exceptionnel{% else %}Normal{% endif %}</ p >
</ div >
<!-- Drawdown -->
< div class = "bg-gray-900 border border-gray-800 rounded-xl p-3 text-center" >
< p class = "text-xs text-gray-400 uppercase tracking-wider mb-1" > Drawdown</ p >
< p class = "text-2xl font-bold {% if resultat.drawdown.actuel and resultat.drawdown.actuel < -10 %}text-rose-400{% else %}text-white{% endif %}" >
{{ "{:.1f}".format(resultat.drawdown.actuel) if resultat.drawdown.actuel is not none else '--' }}%
</ p >
< p class = "text-[10px] text-gray-500" > Max : {{ "{:.1f}".format(resultat.drawdown.maximum) if resultat.drawdown.maximum is not none else '--' }}%</ p >
</ div >
</ div >
<!-- ===================== GRAPHIQUE PRINCIPAL ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< div class = "flex items-center justify-between mb-3" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider" >< i class = "fa-solid fa-chart-line text-blue-500" ></ i > Cours & Moyennes mobiles</ h3 >
< div class = "flex gap-2 text-xs" >
< label class = "flex items-center gap-1 cursor-pointer" >< input type = "checkbox" id = "toggle-mm20" checked class = "accent-blue-500" > MM20</ label >
< label class = "flex items-center gap-1 cursor-pointer" >< input type = "checkbox" id = "toggle-mm50" checked class = "accent-emerald-500" > MM50</ label >
< label class = "flex items-center gap-1 cursor-pointer" >< input type = "checkbox" id = "toggle-mm200" checked class = "accent-amber-500" > MM200</ label >
</ div >
</ div >
< div style = "height: 380px;" >< canvas id = "chartCours" ></ canvas ></ div >
</ div >
<!-- ===================== GRAPHIQUE VOLUME ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-chart-column text-blue-500" ></ i > Volumes</ h3 >
< div style = "height: 180px;" >< canvas id = "chartVolume" ></ canvas ></ div >
</ div >
<!-- ===================== GRAPHIQUE VOLATILITÉ ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-wave-square text-blue-500" ></ i > Volatilité 20j annualisée</ h3 >
< div style = "height: 180px;" >< canvas id = "chartVolatilite" ></ canvas ></ div >
</ div >
<!-- ===================== SUPPORTS & RÉSISTANCES ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-arrows-up-down text-blue-500" ></ i > Supports & Résistances</ h3 >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-6" >
<!-- Tableau -->
< div >
< table class = "w-full text-sm text-gray-300" >
< thead >< tr class = "text-gray-400 text-xs uppercase border-b border-gray-800" >< th class = "py-2 px-3 text-left" > Fenêtre</ th >< th class = "py-2 px-3 text-right" > Plus Haut</ th >< th class = "py-2 px-3 text-right" > Plus Bas</ th ></ tr ></ thead >
< tbody >
{% for fenetre in ['20j', '50j', '100j', '250j'] %}
< tr class = "border-b border-gray-800/50" >
< td class = "py-2 px-3" > {{ fenetre }}</ td >
< td class = "py-2 px-3 text-right text-emerald-400" > {{ "{:,.2f}".format(resultat.supports_resistances.plus_haut[fenetre]) if resultat.supports_resistances.plus_haut[fenetre] is not none else '--' }}</ td >
< td class = "py-2 px-3 text-right text-rose-400" > {{ "{:,.2f}".format(resultat.supports_resistances.plus_bas[fenetre]) if resultat.supports_resistances.plus_bas[fenetre] is not none else '--' }}</ td >
</ tr >
{% endfor %}
</ tbody >
</ table >
< div class = "mt-3 space-y-1 text-xs" >
< p class = "text-gray-400" > Support proche : < span class = "text-emerald-400 font-bold" > {{ "{:,.2f}".format(resultat.supports_resistances.support_proche) if resultat.supports_resistances.support_proche is not none else '--' }} {{ resultat.action.currency or '€' }}</ span ></ p >
< p class = "text-gray-400" > Résistance proche : < span class = "text-rose-400 font-bold" > {{ "{:,.2f}".format(resultat.supports_resistances.resistance_proche) if resultat.supports_resistances.resistance_proche is not none else '--' }} {{ resultat.action.currency or '€' }}</ span ></ p >
</ div >
</ div >
<!-- Barre visuelle 52 sem -->
< div >
{% set pb52 = resultat.supports_resistances.plus_bas['250j'] %}
{% set ph52 = resultat.supports_resistances.plus_haut['250j'] %}
{% set cours = resultat.cours %}
{% if pb52 is not none and ph52 is not none and ph52 > pb52 %}
{% set pct_pos = ((cours - pb52) / (ph52 - pb52) * 100) | float %}
< div class = "relative h-8 bg-gray-950 rounded-lg border border-gray-800 overflow-hidden" >
< div class = "absolute top-0 left-0 h-full bg-gradient-to-r from-rose-900 via-amber-900 to-emerald-900 opacity-30" style = "width: 100%" ></ div >
< div class = "absolute top-0 h-full w-1 bg-white" style = "left: {{ pct_pos }}%;" ></ div >
</ div >
< div class = "flex justify-between text-xs mt-1" >
< span class = "text-rose-400" > {{ "{:,.2f}".format(pb52) }}</ span >
< span class = "text-gray-400" > Cours : {{ "{:,.2f}".format(cours) }}</ span >
< span class = "text-emerald-400" > {{ "{:,.2f}".format(ph52) }}</ span >
</ div >
{% endif %}
</ div >
</ div >
</ div >
<!-- ===================== ANALYSE DES GAPS ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-arrows-left-right-to-line text-blue-500" ></ i > Analyse des gaps</ h3 >
< div class = "grid grid-cols-1 md:grid-cols-4 gap-3 mb-3" >
< div class = "bg-gray-950 border border-gray-800 rounded-lg p-3 text-center" >
< p class = "text-xs text-gray-400" > Total gaps</ p >
< p class = "text-xl font-bold text-white" > {{ resultat.gap.nb_total }}</ p >
</ div >
< div class = "bg-gray-950 border border-gray-800 rounded-lg p-3 text-center" >
< p class = "text-xs text-gray-400" > Taux comblés</ p >
< p class = "text-xl font-bold text-emerald-400" > {{ resultat.gap.taux_combles }}%</ p >
</ div >
< div class = "bg-gray-950 border border-gray-800 rounded-lg p-3 text-center" >
< p class = "text-xs text-gray-400" > Gap moyen</ p >
< p class = "text-xl font-bold text-white" > {{ resultat.gap.gap_moyen }}%</ p >
</ div >
< div class = "bg-gray-950 border border-gray-800 rounded-lg p-3 text-center" >
< p class = "text-xs text-gray-400" > Plus gros gap</ p >
< p class = "text-xl font-bold text-amber-400" > {{ resultat.gap.plus_gros_gap }}%</ p >
</ div >
</ div >
{% if resultat.gap.derniers %}
< table class = "w-full text-sm text-gray-300" >
< thead >< tr class = "text-gray-400 text-xs uppercase border-b border-gray-800" >
< th class = "py-2 px-3 text-left" > Date</ th >< th class = "py-2 px-3 text-left" > Type</ th >< th class = "py-2 px-3 text-right" > Taille</ th >< th class = "py-2 px-3 text-center" > Comblé</ th >
</ tr ></ thead >
< tbody >
{% for g in resultat.gap.derniers %}
< tr class = "border-b border-gray-800/50" >
< td class = "py-2 px-3" > {{ g.date }}</ td >
< td class = "py-2 px-3 {% if g.type == 'haussier' %}text-emerald-400{% else %}text-rose-400{% endif %}" > Gap {{ g.type }}</ td >
< td class = "py-2 px-3 text-right" > {{ "{:+.2f}".format(g.taille) }}%</ td >
< td class = "py-2 px-3 text-center" > {% if g.comble %}< span class = "text-emerald-400" > ✓ Oui ({{ g.jours_combles }}j)</ span > {% else %}< span class = "text-rose-400" > ✗ Non</ span > {% endif %}</ td >
</ tr >
{% endfor %}
</ tbody >
</ table >
{% else %}
< p class = "text-gray-500 text-sm text-center py-4" > Aucun gap significatif détecté.</ p >
{% endif %}
</ div >
<!-- ===================== SIGNAL SYNTHÉTIQUE ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-clipboard-check text-blue-500" ></ i > Analyse automatique</ h3 >
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4" >
<!-- Points positifs -->
< div class = "bg-emerald-950/30 border border-emerald-800/50 rounded-xl p-4" >
< p class = "text-emerald-400 font-semibold mb-2" > 🟢 Points positifs</ p >
{% if resultat.points_positifs %}
{% for p in resultat.points_positifs %}
< p class = "text-emerald-300 text-sm flex items-start gap-2 mb-1" >< i class = "fa-solid fa-check text-emerald-500 mt-0.5" ></ i > {{ p }}</ p >
{% endfor %}
{% else %}
< p class = "text-gray-500 text-sm" > Aucun point positif détecté.</ p >
{% endif %}
</ div >
<!-- Points négatifs -->
< div class = "bg-rose-950/30 border border-rose-800/50 rounded-xl p-4" >
< p class = "text-rose-400 font-semibold mb-2" > 🔴 Points négatifs</ p >
{% if resultat.points_negatifs %}
{% for n in resultat.points_negatifs %}
< p class = "text-rose-300 text-sm flex items-start gap-2 mb-1" >< i class = "fa-solid fa-xmark text-rose-500 mt-0.5" ></ i > {{ n }}</ p >
{% endfor %}
{% else %}
< p class = "text-gray-500 text-sm" > Aucun point négatif détecté.</ p >
{% endif %}
</ div >
</ div >
<!-- Conclusion -->
< div class = "mt-4 bg-gray-950 border border-gray-800 rounded-xl p-4 text-center" >
< p class = "text-gray-300 text-sm" >
< strong > Conclusion :</ strong >
Tendance
{% if resultat.tendance == 'haussiere' %}< span class = "text-emerald-400 font-bold" > positive</ span >
{% elif resultat.tendance == 'baissiere' %}< span class = "text-rose-400 font-bold" > négative</ span >
{% else %}< span class = "text-amber-400 font-bold" > neutre</ span > {% endif %}
— Score {{ resultat.score }}/100.
{% if resultat.points_negatifs and resultat.points_positifs %}Des signaux contradictoires sont présents, prudence recommandée.{% endif %}
</ p >
</ div >
</ div >
<!-- ===================== DÉTAILS : PERFORMANCES + MOYENNES + SÉRIES ===================== -->
< div class = "grid grid-cols-1 md:grid-cols-2 gap-4 w-full max-w-[98%] mb-4" >
<!-- Performances -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl p-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" > Performances</ h3 >
< table class = "w-full text-sm text-gray-300" >
{% for fenetre, val in resultat.performances.fenetres.items() %}
< tr class = "border-b border-gray-800/50" >
< td class = "py-1.5 px-2" > {{ fenetre }}</ td >
< td class = "py-1.5 px-2 text-right font-bold {% if val and val >= 0 %}text-emerald-400{% elif val %}text-rose-400{% else %}text-gray-500{% endif %}" >
{{ "{:+.2f}".format(val) if val is not none else '--' }}%
</ td >
</ tr >
{% endfor %}
{% if resultat.performances.ytd is not none %}
< tr class = "border-b border-gray-800/50" >
< td class = "py-1.5 px-2" > YTD</ td >
< td class = "py-1.5 px-2 text-right font-bold {% if resultat.performances.ytd >= 0 %}text-emerald-400{% else %}text-rose-400{% endif %}" > {{ "{:+.2f}".format(resultat.performances.ytd) }}%</ td >
</ tr >
{% endif %}
</ table >
</ div >
<!-- Moyennes mobiles + Séries -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl p-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" > Moyennes mobiles & Séries</ h3 >
< table class = "w-full text-sm text-gray-300 mb-3" >
{% for mm, val in resultat.moyennes_mobiles.sma.items() %}
{% if mm.endswith('_distance') %}{% else %}
< tr class = "border-b border-gray-800/50" >
< td class = "py-1.5 px-2" > {{ mm }}</ td >
< td class = "py-1.5 px-2 text-right" > {{ "{:,.2f}".format(val) if val is not none else '--' }}</ td >
< td class = "py-1.5 px-2 text-right text-xs {% if resultat.moyennes_mobiles.sma[mm + '_distance'] and resultat.moyennes_mobiles.sma[mm + '_distance'] >= 0 %}text-emerald-400{% elif resultat.moyennes_mobiles.sma[mm + '_distance'] %}text-rose-400{% else %}text-gray-500{% endif %}" >
{{ "{:+.2f}".format(resultat.moyennes_mobiles.sma[mm + '_distance']) if resultat.moyennes_mobiles.sma.get(mm + '_distance') is not none else '' }}%
</ td >
</ tr >
{% endif %}
{% endfor %}
</ table >
< div class = "border-t border-gray-800 pt-3 space-y-1 text-xs text-gray-400" >
< p > Hausse consécutive : < span class = "text-emerald-400 font-bold" > {{ resultat.series.jours_hausse_consecutifs }}j</ span > · Baisse : < span class = "text-rose-400 font-bold" > {{ resultat.series.jours_baisse_consecutifs }}j</ span ></ p >
< p > Plus forte hausse : < span class = "text-emerald-400" > {{ "{:+.2f}".format(resultat.series.plus_forte_hausse) if resultat.series.plus_forte_hausse is not none else '--' }}%</ span > · Plus forte baisse : < span class = "text-rose-400" > {{ "{:.2f}".format(resultat.series.plus_forte_baisse) if resultat.series.plus_forte_baisse is not none else '--' }}%</ span ></ p >
</ div >
</ div >
</ div >
<!-- ===================== CHANDELIERS JAPONAIS ===================== -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-4 mb-4" >
< h3 class = "text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3" >< i class = "fa-solid fa-chart-simple text-blue-500" ></ i > Chandeliers japonais</ h3 >
< p class = "text-gray-400 text-sm mb-2" > Pattern actuel : < span class = "text-amber-400 font-bold" > {{ resultat.chandeliers.pattern_actuel }}</ span ></ p >
{% if resultat.chandeliers.derniers_detectes %}
< table class = "w-full text-sm text-gray-300" >
< thead >< tr class = "text-gray-400 text-xs uppercase border-b border-gray-800" >< th class = "py-2 px-3 text-left" > Date</ th >< th class = "py-2 px-3 text-left" > Pattern</ th ></ tr ></ thead >
< tbody >
{% for c in resultat.chandeliers.derniers_detectes %}
< tr class = "border-b border-gray-800/50" >< td class = "py-2 px-3" > {{ c.date }}</ td >< td class = "py-2 px-3 text-amber-400" > {{ c.pattern }}</ td ></ tr >
{% endfor %}
</ tbody >
</ table >
{% else %}
< p class = "text-gray-500 text-sm" > Aucun pattern significatif détecté récemment.</ p >
{% endif %}
</ div >
<!-- Données JSON pour les graphiques (passées au JS) -->
< script id = "data-cours" type = "application/json" >{{ resultat . graphique_cours | tojson | safe }}</ script >
< script id = "data-volumes" type = "application/json" >{{ resultat . graphique_volumes | tojson | safe }}</ script >
< script id = "data-volatilite" type = "application/json" >{{ resultat . graphique_volatilite | tojson | safe }}</ script >
{% endif %}
{% else %}
<!-- Message d'accueil quand aucune recherche -->
< div class = "bg-gray-900 border border-gray-800 rounded-2xl shadow-2xl w-full max-w-[98%] p-8 text-center" >
< i class = "fa-solid fa-chart-line text-gray-700 text-5xl mb-4" ></ i >
< h2 class = "text-xl font-bold text-white mb-2" > Analyse technique</ h2 >
< p class = "text-gray-400 text-sm" > Saisissez un ISIN ci-dessus pour afficher la fiche d'analyse complète.</ p >
</ div >
{% endif %}
</ div >
<!-- Chart.js + charts.js -->
< script src = "https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js" ></ script >
< script src = "{{ url_for('static', filename='js/charts.js') }}" ></ script >
< script >
// Disparition des toasts
document . addEventListener ( "DOMContentLoaded" , () => {
document . querySelectorAll ( ".toast-message" ). forEach ( t => setTimeout (() => {
t . style . opacity = "0" ; t . style . transform = "translateY(-10px)" ;
setTimeout (() => t . remove (), 300 );
}, 4000 ));
});
</ script >
{% endblock %}