
    i                     *   d Z ddlZdej                  d<   ddlZddlZddlZddlZddlZddlZddl	Z
ddlmZmZ ddlmZ ddlmZmZmZmZ ddlmZ ej,                  j.                  d	k7  r. ej0                  ej,                  j2                  d	d
      e_        ej4                  j.                  d	k7  r. ej0                  ej4                  j2                  d	d
      e_        dZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*h dZ+dZ,g dZ- G d d      Z.de/d e/d!e0d"e0d#ee   f
d$Z1d%ee   d#ee/e
jd                  f   fd&Z3d'ee/   d(e0d#ee/ee/e
jd                  f   f   fd)Z4d* Z5 G d+ d,      Z6 G d- d.      Z7 G d/ d0      Z8dRd'ee/   d(e0d1e9fd2Z:	 	 	 dSd3e8d4ed5ed6ed(e0d1e9d7e0d8e0fd9Z;d3e8d6ed(e0fd:Z<e=d;k(  rD ej|                  d<=      Z?e?j                  d>d?dd@A       e?j                  dBe0edCe dDE       e?j                  dFeAedGe dDE       e?j                  dHdIdJK       e?j                  dLdIdMK       e?j                         ZCeCj                  ek7  reCj                  ZeCj                  xs e-ZEeCj                  r[	  eeG      j                  dNz  ZI eJeI      5 ZK ej                  eK      j                  d'e-      ZEddd        eNdO eOeE       dP        e:eEeCj                  eCj                  Q       yy# 1 sw Y   <xY w# eP$ r e-ZEY 6w xY w)Tu  
═══════════════════════════════════════════════════════════════════════════════
 CRASH-TEST LSTM REVERSAL PREDICTOR — Backtest sur 2 semaines
═══════════════════════════════════════════════════════════════════════════════

Module INDÉPENDANT du bot de trading.
Télécharge les données historiques 5m des 14 derniers jours via l'API Binance,
exécute le LSTM Reversal Predictor sur chaque bougie, simule des trades et
produit un rapport de rentabilité détaillé.

Métriques:
  - Win rate, P&L total, P&L moyen par trade
  - Sharpe ratio, max drawdown, profit factor
  - Comparaison LSTM seul vs Buy & Hold
  - Analyse par symbole, par heure, par classe de signal
  - Courbe d'equity en ASCII

Usage:
    python backtest_lstm_reversal.py
    python backtest_lstm_reversal.py --symbols ETHUSDT BTCUSDT SOLUSDT
    python backtest_lstm_reversal.py --days 7

Auteur: IA Trading Bot — Crash Test Module
Date: 01/03/2026
    N CUDA_VISIBLE_DEVICES)datetime	timedelta)Path)DictListOptionalTuple)defaultdictutf-8replace)encodingerrorszhttps://api.binance.com5m   g     @g      @   g?g      ?g      @g     @P@g      ?g     Q@0   g?>         r   T)BTCUSDTETHUSDTSOLUSDTBNBUSDTADAUSDTAVAXUSDTLINKUSDTXLMUSDTSEIUSDTJUPUSDTDASHUSDTAPTUSDTICPUSDTINJUSDTc                   4    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zy)Cz[92mz[91mz[93mz[94mz[96mz[95mz[97mz[2mz[1mz[0mN)__name__
__module____qualname__GRYBCYMWDIMBOLDEND     ./backtest_lstm_reversal.pyr&   r&   h   s4    AAAA	BAA
CD
Cr5   r&   symbolintervalstart_msend_msreturnc           
         t          d}g }|}||k  r}| |||dd}	 t        j                  ||d      }|j                          |j	                         }	|	s	 |S |j                  |	       |	d   d   dz   }t        j                  d	       ||k  r}|S # t        $ r=}
t        d
t        j                   d|  d|
 t        j                          Y d}
~
|S d}
~
ww xY w)uN   Télécharge les klines depuis Binance API publique (pas de clé nécessaire).z/api/v3/klines  )r7   r8   	startTimeendTimelimit   )paramstimeout      g{Gz?  u   ✗ Erreur API z: N)BASE_URLrequestsgetraise_for_statusjsonextendtimesleep	Exceptionprintr&   r+   r3   )r7   r8   r9   r:   url
all_klinescurrentrB   respklineses              r6   fetch_klinesrX   y   s    Jn
%CJG
F
  
	<<FB?D!!#YY[F  f%Rjma'GJJt! F
* 	  	Bqsse?6("QCw?@		s   :B 1B 	C2CCrawc                    | si S t        |       }t        j                  | D cg c]  }t        |d          c}      t        j                  | D cg c]  }t        |d          c}      t        j                  | D cg c]  }t        |d          c}      t        j                  | D cg c]  }t        |d          c}      t        j                  | D cg c]  }t        |d          c}      t        j                  | D cg c]  }t	        |d          c}      d}|S c c}w c c}w c c}w c c}w c c}w c c}w )zKParse klines brutes en arrays numpy (close, high, low, volume, timestamps).rF      r   r   r   r   )openhighlowclosevolume	timestamp)lennparrayfloatint)rY   nkdatas       r6   parse_klinesrj      s    	CAXXC8quQqT{89XXC8quQqT{89XXC8quQqT{89XXC8quQqT{89XXC8quQqT{89hh37aAaD	78D K 988887s#   D)D.
?D3-D8D=	Esymbolsdaysc                 $   t        t        j                         j                         dz        }t        t        j                         t	        |      z
  j                         dz        }t        t	        d      j                         dz        }||z
  }t        |       }i }t        dt        j                   dt        j                          t        dt        j                  |dz        ddt        j                  |dz        d       t        d	t         d
| d       t        | d      D ]  \  }}	t        ||z  dz        }
d|
dz  z  dd|
dz  z
  z  z   }t        d| d|
dd|	ddd       t        |	t        ||      }t        |      }|rt        |d         dkD  r|||	<   |||	   d<   t        dt        j                    d|	 dt        |       d t        j                           t        d!d" d#t        |       d$| d%d&        |S )'u.   Télécharge toutes les données nécessaires.r=   )rl   r   
u1   ═══ TÉLÉCHARGEMENT DES DONNÉES ═══u     Période: z%Y-%m-%d %H:%Mu    → z  Intervalle: z | Symboles: z | Warmup: +5 jours
rF   d      █r      ░!     [] 3dz% 12sr   Tendflushr_      backtest_start_msrG   u   ⚠ u   : pas assez de données (z	 bougies)  uc   █████████████████████████████████u
    100% — /u    symboles chargés                    )rf   r   utcnowra   r   total_secondsrb   rQ   r&   r2   r3   utcfromtimestampINTERVAL	enumeraterX   rj   r,   )rk   rl   r:   r9   	warmup_msfetch_starttotalall_dataidxsympctbarrY   ri   s                 r6   load_all_datar      s   ",,.56FHOO%	t(<<GGIDPQH I1%335<=IY&KLEH	BqvvhGw
OP	L228D=A.QQVW_WpWpqwx|q|W}  M  WN  O  P	N8*M%8M
NOgq) ZS#+#$sax 5BM#::cU"SHBs3i0bE3+v>C CW&, HSM19HSM-.Bqsse4u$=c#hZyQRQVQVPWXYZ 
DJs8}oQug=OPXz
Z[Or5   c                     	 ddl } d| _        | j                         }|j                  |j                  j	                         |_        t        dt        j                   d|j                   dt        j                          |S # t        $ rb}t        dt        j                   d| t        j                          ddl}|j                          t        j                  d       Y d}~yd}~ww xY w)	uZ   Charge le LSTM Reversal Predictor sur CPU (CUDA_VISIBLE_DEVICES='' déjà défini au top).r   Ncpu
  u5   ✓ LSTM Reversal Predictor chargé sur CPU (trained=)u6   ✗ Impossible de charger le LSTM Reversal Predictor: rF   )lstm_reversal_predictorDEVICEget_reversal_predictormodelr   rQ   r&   r*   
is_trainedr3   rP   r+   	traceback	print_excsysexit)lrp	predictorrW   r   s       r6   load_lstm_predictorr      s    -
..0	??&'oo113IOQSSENyOcOcNddefgfkfkelmn QSSEOPQsSTSXSXRYZ[	s   BB 	C/AC**C/c                       e Zd Zg dZd Zy)Position)	r7   entry_price
entry_time	size_usdtqty	max_pricetrailing_active	stop_losstake_profitc                     || _         || _        || _        || _        ||z  | _        || _        d| _        |dt        dz  z
  z  | _        |dt        dz  z   z  | _
        y )NFrF   ro   )r7   r   r   r   r   r   r   STOP_LOSS_PCTr   TAKE_PROFIT_PCTr   )selfr7   r   r   r   s        r6   __init__zPosition.__init__   sg    &$"{*$$$MC,?(?@&!o.C*CDr5   Nr'   r(   r)   	__slots__r   r4   r5   r6   r   r      s    MI	Er5   r   c                       e Zd Zg dZd Zy)Trader7   r   
exit_pricer   	exit_timer   pnl_usdtpnl_pctexit_reasonsignal_confidencesignal_probabilityc                 N    |j                         D ]  \  }}t        | ||        y N)itemssetattr)r   kwargsrh   vs       r6   r   zTrade.__init__   s'    LLN 	 DAqD!Q	 r5   Nr   r4   r5   r6   r   r      s    'I r5   r   c                       e Zd ZdZdefdZedefd       Zedefd       Zdde	de
defd	Z	 dde	d
ede
dedef
dZde	dede
dee   fdZde	dede
dedee   f
dZde	d
ede
de	def
dZdee	ef   de
fdZy)BacktestEnginezDMoteur de backtest avec gestion des positions, trailing stop, frais.initial_capitalc                     || _         || _        i | _        g | _        g | _        g | _        d| _        d| _        d| _        d| _	        d| _
        i | _        y )Nr   )r   capital	positionsclosed_tradesequity_curvesignals_logtotal_reversal_uptotal_reversal_downtotal_neutraltotal_continuationblocked_signalssl_cooldown)r   r   s     r6   r   zBacktestEngine.__init__  sb    .&.0*,57') "##$ "# +-r5   r;   c                 V    t        d | j                  j                         D              S )z4Valeur des positions ouvertes au dernier prix connu.c              3   4   K   | ]  }|j                     y wr   )r   ).0ps     r6   	<genexpr>z,BacktestEngine.open_value.<locals>.<genexpr>  s     @11;;@   )sumr   valuesr   s    r6   
open_valuezBacktestEngine.open_value  s"     @(=(=(?@@@r5   c                 4    | j                   | j                  z   S r   )r   r   r   s    r6   equityzBacktestEngine.equity  s    ||doo--r5   r7   timestamp_msc                    || j                   v ryt        | j                         t        k\  ry|| j                  v r || j                  |   k  ry| j                  |= | j                  t
        dz  z  }|dk  s|| j                  dz  kD  ryy)NFro   
   gffffff?T)r   rb   MAX_OPEN_POSITIONSr   r   POSITION_SIZE_PCT)r   r7   r   sizes       r6   can_open_positionz BacktestEngine.can_open_position  s    T^^#t~~"44T%%%d..v66$$V,||0367"9t||d22r5   price
confidenceprobabilityc           	          | j                   t        dz  z  }|t        dz  z  }| xj                   ||z   z  c_         t        ||||      }|| j                  |<   | j
                  j                  d|||||d       y)zOuvre une position long.ro   BUY)typer7   r   rN   r   r   N)r   r   TRADING_FEE_PCTr   r   r   append)	r   r7   r   r   r   r   r   feeposs	            r6   open_positionzBacktestEngine.open_position,  s     ||0367o+,$vulD9!$v $&!
 	r5   current_pricec                    || j                   vry| j                   |   }||j                  z
  |j                  z  dz  }||j                  kD  r||_        |t        k\  r|j                  sd|_        d}||j
                  z
  }|dz  }|t        k\  rd|dd}nU||j                  k  rd}nC||j                  k\  rd	}n1|j                  r%|j                  d
t        dz  z
  z  }	||	k  rd|dd}|r| j                  ||||      S y)uR   Met à jour une position et vérifie SL/TP/trailing. Retourne Trade si clôturée.Nro   Ti zMAX_HOLD_6H (z+.1f%)	STOP_LOSSTAKE_PROFITrF   zTRAILING_STOP ()r   r   r   TRAILING_ACTIVATION_PCTr   r   MAX_HOLDING_CANDLESr   r   TRAILING_STOP_PCT_close_position)
r   r7   r   r   r   r   r   
holding_msholding_candlestrailing_levels
             r6   update_positionzBacktestEngine.update_position>  s"   'nnV$ 3??2cooEK 3==()CM --c6I6I"&C "CNN2
$611)'$r:K cmm+%K coo-'K    ]]a2Cc2I.IJN. /~R@''|[YYr5   c                     || j                   vry| j                   |   }||j                  z
  |j                  z  dz  }|dk  r| j                  |||d|dd      S y)z4Ferme une position sur signal REVERSAL_DOWN du LSTM.Nro   g?zLSTM_DANGER (conf=.0fr   )r   r   r   )r   r7   r   r   r   r   r   s          r6   close_on_dangerzBacktestEngine.close_on_dangerh  ss     'nnV$ 3??2cooEK
 S=''|+=j=MR)PR Rr5   reasonc                    | j                   j                  |      }|j                  |z  }|t        dz  z  }||z
  }||j                  z
  }	||j
                  z
  |j
                  z  dz  }
| xj                  |z  c_        |dk(  r|dz   | j                  |<   t        ||j
                  ||j                  ||j                  |	|
|dd      }| j                  j                  |       |S )Nro   r   i6 r   r   )r   popr   r   r   r   r   r   r   r   r   r   )r   r7   r   r   r   r   gross_valuer   	net_valuer   r   trades               r6   r   zBacktestEngine._close_positionx  s    nn  (ggo_s23#%	s}},3??*coo=C	! [ '36H'HDV$~~"mm 
 	!!%(r5   pricesc                     t        | j                  j                               D ]  }||v s| j                  |||   |d         y)z6Ferme toutes les positions ouvertes (fin de backtest).END_OF_BACKTESTN)listr   keysr   )r   r  r   r   s       r6   force_close_allzBacktestEngine.force_close_all  sE    ++-. 	XCf}$$S&+|EVW	Xr5   N)r   )r   r   )r'   r(   r)   __doc__re   r   propertyr   r   strrf   boolr   r   r
   r   r   r   r   r   r  r4   r5   r6   r   r      s6   N. ." AE A A . . . 3 t " CDC  S "':?$(c (% (s (W_`eWf (Tc % s $).6uo c % s  #(-@Xd3:&6 Xc Xr5   r   use_aic                    |rdnd}t        dt        j                   d| d| dt        j                   d	       d}d}d}t	        d	       }|r	 d
t
        j                  d<   ddl}|j                  j                  }	d |j                  _	        ddl
m}
  |
       }|	|j                  _	        dt
        j                  d<   t        dt        j                   dt        j                          g d}t        | |      }|s-t        t        j                   dt        j                          yt!               }t#        t$              }t        dt        j                   dt        j                          t        dt$        ddt&         dt(                t        dt*         dt,         dt.         dt0         d	       t        dt2         dt4         dt6                |r-t        dt        j8                   d t        j                          t:        rt        d!t=        t>               d"       t        d#t@         d$t@        d%z  d&z   d'       d}|jC                         D ]  \  }}|d(   }|||k  s|} i }|jC                         D ]'  \  }}i }tE        |d)         D ]
  \  }}|||<    |||<   ) tG               }|jC                         D ]2  \  }}|d)   |k\  }|jI                  |d)   |   jK                                4 t=        |      }tM        |      }d*}|tM        |      z  |z  }t        d+|d,d-|d,d.|d%z   d/       t                t	        d0       }t	        d1       }d2}tO        d3|d4z        } tE        |      D ]P  \  }!}|!| z  dk(  rbtQ        |!|z  d2z        }"d5|"d6z  z  d7d4|"d6z  z
  z  z   }#|jR                  }$tM        |jT                        }%t        d8|# d9|"d:d;|$d<d=|% dd>?       |!| d%z  z  dk(  r'|jV                  jY                  ||jR                  f       |jC                         D ]  \  }}||   }||vr||   }&|d@   |&   }'|dA   |&   }(|dB   |&   })|j[                  ||)|      }*|*|j[                  ||(|      }*|*r~|*j\                  dkD  }+t_        j`                  |*jb                  dCz        jd                  },||,   |+rdDndExx   d3z  cc<   ||   |+rdDndExx   d3z  cc<   ||   dFxx   |*j\                  z  cc<   |&|k  r|!|z  dk7  rtg        |&d3z   dG      }-|&|-z
  d3z   }.|d@   |.|&d3z    }/|dH   |.|&d3z    }0|dA   |.|&d3z    }1|dB   |.|&d3z    }2|ji                  |/|0|1|2      }3|3dI   }4|3dJ   }5|3dK   }6|3dL   }7|3dM   }8|3dN   }9|4dk(  r|xjj                  d3z  c_5        nP|4d3k(  r|xjl                  d3z  c_6        n5|4d6k(  r|xjn                  d3z  c_7        n|4d*k(  r|xjp                  d3z  c_8        |5dOk(  r!|6t4        k\  r|7t6        k\  rt_        j`                  |dCz        jd                  }:t:        r|:t>        v r|xjr                  d3z  c_9        &d};|#	 |d@   |.|&d3z    jK                         }<|dH   |.|&d3z    jK                         }=|ju                  ||<|=      }>|jv                  5  ||>i|_<        ddd       |j{                         }?|?rX|?d   }@|@j}                  dPdQ      };|@j}                  dR|>j~                        }A|@j}                  dSd      }B|@j}                  dTdU      }Cn|>j                  };|>j~                  }Ad}BdU}CBdVk(  xr Cxr |;v xr AdWk\  }D|Ds|d3z  }|xjr                  d3z  c_9        I|d3z  }|j                  ||      ru|j                  ||'||6|7       t_        j`                  |dCz        jd                  },||,   dXxx   d3z  cc<   ||   dXxx   d3z  cc<   |;s|;||   dY<   ||;   dZxx   d3z  cc<   |xjr                  d3z  c_9        |9s|6t        k\  s|7t        k\  s|j                  ||'||6      }*|*s|*j\                  dkD  }+t_        j`                  |*jb                  dCz        jd                  },||,   |+rdDndExx   d3z  cc<   ||   |+rdDndExx   d3z  cc<   ||   dFxx   |*j\                  z  cc<    S i }E|jC                         D ]  \  }}|d@   d[   E|<    |r|d[   nd}F|j                  E|F       |jT                  D ]6  }*|*j                  d\k(  s||*j                     dFxx   |*j\                  z  cc<   8 |jV                  jY                  F|jR                  f       t        d]d^ d_|jR                  d<d=tM        |jT                         d`        t        ||||||||||a
       t        |||       y# t        $ r<}t        dt        j                   d| t        j                          d}Y d}~	'd}~ww xY w# 1 sw Y   gxY w# t        $ r}Y d}~d}~ww xY w)buW   Exécute le crash-test complet. Si use_ai=True, valide chaque signal avec ai_predictor.z + AI PREDICTORr   rn   u  ╔══════════════════════════════════════════════════════════════════════╗
║   🧠 CRASH-TEST LSTM REVERSAL PREDICTORu    — BACKTEST u   J          ║
╚══════════════════════════════════════════════════════════════════════╝Nr   c                      dddddS )Nr           )countwinlosspnlr4   r4   r5   r6   <lambda>zrun_backtest.<locals>.<lambda>  s    Qq!TW+X r5   z-1r   c                       y)NFr4   r4   r5   r6   r  zrun_backtest.<locals>.<lambda>  s    r5   )AIPredictorrG   u>   ✓ AI Predictor chargé (smart_criteria + pattern validation))
CREUX_REBOUNDPULLBACKSQUEEZE_BREAKOUTEARLY_BREAKOUTCONSOLIDATION_BREAKOUTEMA_BULLISHCROSSOVER_IMMINENTVOLUME_REVERSALRSI_REVERSALSTRONG_UPTRENDu!   ✗ AI Predictor non disponible: u%   ✗ Aucune donnée chargée. Abandon.u*   ═══ EXÉCUTION DU BACKTEST ═══z  Capital: r   z USDT | Position: z% | Max positions: z  SL: z% | TP: z% | Trailing: z% (act. r   z	  Frais: u   % | LSTM seuils: conf≥u	   % prob≥uU   🧠 MODE IA: Chaque signal LSTM validé par ai_predictor (smart_criteria + patterns)u     🕐 Filtre horaire: bloqué zh UTCu     ⏱️  Max holding: z
 bougies (r   <   h)r{   ra   r   u     Bougies à traiter: ,u    | LSTM évalué: ~z fois (toutes les zmin)c                      ddddS )Nr   )buyr  r  r4   r4   r5   r6   r  zrun_backtest.<locals>.<lambda>  s    !Aq*I r5   c                      dddddS )Nr   r  )r$  r  r  r  r4   r4   r5   r6   r  zrun_backtest.<locals>.<lambda>  s    AaSV,W r5   ro   rF   2   rp   r[   rq   rs   rt   ru   z% | Equity: ,.0fz$ | Trades: Trw   r_   r]   r^   r=   r  r  r  i,  r`   reversal_classreversal_labelr   reversal_probabilityis_reversal_signalis_danger_signalREVERSAL_UPpatternNEUTRALsmart_scoresmart_signalsmart_eligibleFACHATA   r$  
ai_patternr  rD   r  r|   u   ██████████████████████████████████████████████████z 100% | Equity: r~   )r  ai_predai_validated
ai_blockedai_pattern_stats)KrQ   r&   r2   r3   r   osenvirontorchcudais_availableai_predictorr  r*   rP   r+   r   r   r   INITIAL_CAPITALr   r   r   r   r   r   r   REVERSAL_UP_MIN_CONFIDENCEREVERSAL_UP_MIN_PROBr.   ENABLE_HOUR_FILTERsortedBLOCKED_HOURS_UTCr   r   r   setupdatetolistrb   maxrf   r   r   r   r   r   r   r   r   r   hourminpredictr   r   r   r   r   analyze_symbol_lock	watchlistget_watchlistrJ   scorer.  r   r   REVERSAL_DOWN_MIN_CONFIDENCEREVERSAL_DOWN_MIN_PROBr   r  r   r7   print_reportsave_report_json)Grk   rl   r  ai_mode_strr6  r8  r7  r9  _torch_original_cuda_availabler  BUYABLE_PATTERNSrW   r   r   enginer{   r   ri   ssym_indicests_mapitsall_tsmasktotal_candles
EVAL_EVERY
eval_countsignals_by_hoursignals_by_symbolMIN_HISTORYprogress_stepstepr   r   eqn_tradesr   r   current_highcurrent_lowr   is_winrJ  windowstart_iprices_windowvolumes_windowhighs_windowlows_windowresult	rev_class	rev_labelr   r   is_reversal	is_dangercandle_hourr5  	ai_prices
ai_volumesai_itemenriched_listentryai_scoreai_smart_signalai_smart_eligibleis_ai_validlast_priceslast_tssG                                                                          r6   run_backtestr    sv    (.#2K	  	..9]. OY Z[  Z_  Z_  Y` `  GJL"#XY	 26BJJ-."'-{{'?'?$'4FKK$0!mG (@FKK$13BJJ-.BqsseYZ[Z_Z_Y`ab  Wd+H:155'BC $%I O,F 
Bqvvh@
HI	K,,>?P>QQdewdx
yz	F=//):.IZH[[cd{c||~
  A	Io&&>?Y>ZZcdxcy
z{144&mnonsnsmtuv/7H0I/J%PQ	#$7#8
CVYZCZ^`C`Baac
de ^^% "	T$%$,=(= !" K^^% "	TtK01 	EArF2J	!C	" UF^^% 8	TK $55d;'-44678 F^FKMJX.*<J	"="33FzRSnTfgqrsgsfttx
yz	G ""IJO#$WX K=B./Mf% ^Db-1$d]*S01C3!8$uSAX'>>CB6//0HE#bRRI\(TZ\dhi =1$%*&&FMM':; ") P	DIC %F*C M#.M<,Lu+c*K **3R@E}..sL"E!+001A1AD1HINN%ve6BaGB!#&uFCqHC!#&u-?- [ j A% q#&FFlQ&G M'#':M!(^GC!G<N<a8Lu+gcAg6K &&}nlT_`F/0I/0I-J !78K !56K12I A~$$)$a((A-(a**a/*a))Q.) ]*8833 '77T	BGG%+9J*J**a/*
 "
&/$(M'#'$B$I$I$K	%)(^GC!G%D%K%K%M
 #*"8"8i"T %]] ?14gG-? )0(=(=(?($1!$4E).9i)HJ',yy'NH.3ii.KO05		:JE0R-)0J'.}}H.0O05- ,w6 +-+&*::+ %N	 $  +&!OJ"22a72$$) ++C4((mR[Y#44R$Y?DDD#D)%0A50%c*51Q61!?I)#.|<(4W=B=**a/*  <<!77..sM2zR"^^a/F#44U5E5E5LMRRD#D)6%vF!KF%c*F5G1LG%c*51U^^C1aP	D^DB K^^% -	T=,C-"fRjG
;0%% E 11ell+E2ennD2E
 78	D,V]]4,@SQWQeQeMfLghpgq
rs ?4Etl&9IK V.5k  	Bqsse<QCwGHG	B? ?H % sK   B!g  Ah-1
h ;C h-=h-	h!1hh h*%h--	i<irZ  r   re  rf  r7  r8  c
                 #   | j                   }
t        |
      }t        dt        j                   dt        j
                   d       | j                  }| j                  }||z
  }||z  dz  }|dk\  rt        j                  nt        j                  }t        dt        j                   dt        j
                          t        d|dd	       t        d
| |dd	t        j
                          t        d| |dd|ddt        j
                          |dt        |d      z  z  }t        d| |ddt        j
                          |dk(  rxt        dt        j                   dt        j
                          t        d| j                   d| j                          t        d| j                   d| j                          y|
D cg c]  }|j                   dkD  s| }}|
D cg c]  }|j                   dk  s| }}t        |      }t        |      }|dkD  r||z  dz  nd}|r-t#        j$                  |D cg c]  }|j&                   c}      nd}|r-t#        j$                  |D cg c]  }|j&                   c}      nd}t#        j$                  |
D cg c]  }|j&                   c}      }t#        j(                  |
D cg c]  }|j&                   c}      }t        |
d       }t+        |
d       }|rt-        d |D              nd}|rt/        t-        d  |D                    nd!}|dkD  r||z  n
t1        d"      } |
D cg c]  }|j2                  |j4                  z
  d#z    }!}t#        j$                  |!      }"t        dt        j                   d$t        j
                          t        d%|d&       t        d't        j                   |d&d(|d)dt        j
                          t        d*t        j                   |d&d(d|z
  d)dt        j
                          t        d+t        j                   |d,dt        j
                          t        d-t        j                   |d,dt        j
                          t        d.|d,d       t        d/|d,d       t        d0| d1       t        d2|"d3d4|"d5z  d)d6       t        d7t        j                   |j6                   d8|j&                  ddt        j
                          t        d9t        j                   |j6                   d8|j&                  ddt        j
                          |
D cg c]  }|j&                   }#}t#        j$                  |#      t#        j8                  |#      d:z   z  t#        j:                  t        |#      t        |d      z  d;z        z  }$| j<                  r| j<                  D %&cg c]  \  }%}&|&	 c}&}%n|g}'|'d   }(d})|'D ]  }&|&|(kD  r|&}(|(|&z
  |(z  dz  }*|*|)kD  s|*}) |)dkD  r|t        |)d!      z  n
t1        d"      }+t        dt        j                   d<t        j
                          t        d=|$d1       t        d>t        j                   |)d1dt        j
                          t        d?|+d1       t        d@|t        |d      z  dA       t        dt        j                   dBt        j
                          | j                  | j                  z   | j                  z   | j                  z   },t        dC|,dD       t        dE| j                  dDd(| j                  t        |,d      z  dz  dFd       t        dG| j                  dDd(| j                  t        |,d      z  dz  dFd       t        dH| j                  dDd(| j                  t        |,d      z  dz  dFd       t        dI| j                  dDd(| j                  t        |,d      z  dz  dFd       t        dJ| j>                  dDdK       |r|t        dt        j                   dLt        j
                          ||z   }-t        dM|-dN       t        dOt        j                   |dNt        j
                   d(|t        |-d      z  dz  d)d       t        dPt        j                   |dNt        j
                   d(|t        |-d      z  dz  d)d       |	rEt        dQ       tA        |	jC                         dR       D ]  \  }.}/t        dS|.dTdU|/dV   dW        tE        dX       }0|
D ]j  }|jF                  jI                  d8      d   }1|0|1   dVxx   dz  cc<   |0|1   dYxx   |j                   z  cc<   |j                   dkD  s[|0|1   dZxx   dz  cc<   l t        dt        j                   d[t        j
                          tA        |0jC                         d\       D ]y  \  }1}/|/dZ   t        |/dV   d      z  dz  }2|/dY   dk\  rt        j                  nt        j                  }3t        d]|1d^dU|/dV   dWd_|2d`da|3 |/dY   dbdct        j
                          { tA        |jC                         dd       }4t        dt        j                   det        j
                          |4ddf D ]  \  }5}/|/dg   |/dh   z   }6|/dg   t        |6d      z  dz  }2|/dY   dk\  rt        j                  nt        j                  }3t        d]|5did8|/dj   dWdk|2d`da|3 |/dY   dbdct        j
                           t        |4      dfkD  rt        dt        j                   dlt        j
                          |4dmd D ]  \  }5}/|/dg   |/dh   z   }6|/dg   t        |6d      z  dz  }2|/dY   dk\  rt        j                  nt        j                  }3t        d]|5did8|/dj   dWdk|2d`da|3 |/dY   dbdct        j
                           t        dt        j                   dnt        j
                          tK        do      D ]  }7|7|vr||7   }/|/dg   |/dh   z   }8|8dk(  r|/dg   |8z  dz  }2tM        |8t        dt        dp |jO                         D                    z  dqz        }9dr|9z  }:|2dsk\  rt        j                  nt        j                  }3t        d]|7dtdu|:d^d8|8dWdk|3 |2d`dt        j
                           t        dt        j                   dvt        j
                          g };|jC                         D ]P  \  }5}<|<dw   }=|<dx   |=k\  }>|<dy   |>   }?t        |?      dkD  s*|?dz   |?d   z
  |?d   z  dz  }@|;jQ                  |5|@f       R |;r(t#        j$                  |;D %Acg c]  \  }%}A|A	 c}A}%      nd}B|d|Bdz  z   z  }C|Bdk\  rt        j                  nt        j                  }D|dk\  rt        j                  nt        j                  }Et        d{D Bd|d}Cd~dct        j
                          t        d|E |d|d}|d~dct        j
                          ||Bz
  }F|Fdk\  rt        j                  nt        j                  }Gt        d|G Fd|dt        j
                          | j<                  rSt        | j<                        dkD  r:t        dt        j                   dt        j
                          | j<                  D %&cg c]  \  }%}&|&	 }H}%}&t+        |H      }It        |H      }J|J|Ik7  rJIz
  nd}Kd}Lt+        d5t        H            }Mt        dt        |H      |Mz        }N|Hdd|N   d|M }OtK        |Ldzdz      D ]i  }PI|PLz  Kz  z   }Qd}ROD ]  }S|SQk\  rRdrz  }RRd8z  }R PLk(  rRdJd~dcz  }Rn(Pdk(  rRdId~dcz  }RnPLdz  k(  rRdIJz   dz  d~dcz  }Rt        R       k t        ddt        O      z          t        dt        j                   d t        j
                          |dkD  r.|dskD  r)| dkD  r$t        j                   dt        j
                   }Tnz|dkD  r)|dkD  r$t        j                   dt        j
                   }TnL|dkD  r$t        j                   dt        j
                   }Tn#t        j                   dt        j
                   }Tt        dT        |dk  rbt        dt        jR                   d       t        d       t        d       t        dtT         d       t        dt        j
                          t        dt        j                   d t        j
                   d       yc c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}&}%w c c}A}%w c c}&}%w )z)Affiche le rapport complet du crash-test.rn   u  ╔══════════════════════════════════════════════════════════════════════╗
║                  📊 RAPPORT CRASH-TEST LSTM REVERSAL               ║
╚══════════════════════════════════════════════════════════════════════╝ro   r   rG   u   RÉSUMÉ FINANCIERu     ├─ Capital initial:  z>10,.2fz USDTu     ├─ Capital final:    u     ├─ P&L total:        z>+10,.2fz USDT (z+.2fr   im  rF   u     └─ P&L annualisé:    z>+10,.1f%r   uI   ⚠ Aucun trade exécuté. Le LSTM n'a généré aucun signal qualifiant.z  Signaux REVERSAL_UP: z | REVERSAL_DOWN: z  NEUTRAL: z | CONTINUATION: Nc                     | j                   S r   r   ts    r6   r  zprint_report.<locals>.<lambda>  s
    199 r5   )keyc                     | j                   S r   r  r  s    r6   r  zprint_report.<locals>.<lambda>  s
    AII r5   c              3   4   K   | ]  }|j                     y wr   r   r   r  s     r6   r   zprint_report.<locals>.<genexpr>  s     0aqzz0r   c              3   4   K   | ]  }|j                     y wr   r  r  s     r6   r   zprint_report.<locals>.<genexpr>  s     44r   {Gz?infi`  zSTATISTIQUES DE TRADINGu     ├─ Trades total:     z>6du     ├─ Wins:             z (z.1fu     ├─ Losses:           u     ├─ Gain moyen:       z>+6.2fu     ├─ Perte moyenne:    u     ├─ P&L moyen:        u     ├─ P&L médian:       u     ├─ Profit Factor:    z>6.2fu     ├─ Durée moy trade:  z>6.0fz min (r   r!  u     ├─ Meilleur trade:    u     └─ Pire trade:       g:0yE>   zRATIOS DE RISQUEu     ├─ Sharpe Ratio:     u     ├─ Max Drawdown:     u     ├─ Calmar Ratio:     u     └─ Trades/jour:      z>6.1fzSIGNAUX LSTMu     ├─ Total évaluations: z>10,du     ├─ REVERSAL_UP:       z.2fu     ├─ REVERSAL_DOWN:     u     ├─ NEUTRAL:           u     ├─ CONTINUATION:      u     └─ Signaux bloqués:   z (max positions/capital)u   🧠 VALIDATION AI PREDICTORu(     ├─ Signaux LSTM évalués par IA: z>6,du'     ├─ IA VALIDÉS (ACHAT):          u(     ├─ IA BLOQUÉS (non-éligible):   u      └─ Patterns IA autorisés:c                     | d   d    S NrF   r  r4   xs    r6   r  zprint_report.<locals>.<lambda>=  s    aPQdSZm^ r5   u        ├─ 25su    × r  ru   c                      ddddS )Nr   r  )r  r  winsr4   r4   r5   r6   r  zprint_report.<locals>.<lambda>A  s    3'J r5   r  r  zSORTIES PAR RAISONc                     | d   d    S r  r4   r  s    r6   r  zprint_report.<locals>.<lambda>J  s    QqT']N r5   u	     ├─ 20sz | WR: z5.1fz	% | P&L: z>+8.2f$c                     | d   d    S )NrF   r  r4   r  s    r6   r  zprint_report.<locals>.<lambda>P  s    ad5k\ r5   zTOP 10 SYMBOLESr   r  r  rv   r$  z trades | WR: zBOTTOM 5 SYMBOLESzPERFORMANCE PAR HEURE (UTC)   c              3   2   K   | ]  }|d    |d   z     yw)r  r  Nr4   )r   r[  s     r6   r   zprint_report.<locals>.<genexpr>j  s     *bA1U8ai+?*bs      rp   r&  02dzh: zCOMPARAISON BUY & HOLDr{   ra   r_   rD   u     ├─ Buy & Hold (moy):  z>+.2fu   % → r'  u     ├─ LSTM Strategy:     u     └─ Alpha LSTM:        r[   zCOURBE D'EQUITY   u     │u     └u   ─u   ══════════════════════════════════════════════════════════════════════g333333?uG   ✅ RENTABLE — Le LSTM Reversal Predictor génère un alpha positif !-   uI   ⚠️  MARGINALEMENT RENTABLE — Résultats positifs mais à optimiser.uH   ⚠️  NEUTRE — Pas de perte significative mais pas de gain non plus.uQ   ❌ NON RENTABLE — Le modèle nécessite plus d'entraînement ou d'ajustements.z  VERDICT: u   💡 RECOMMANDATIONS:uD        - Le modèle est encore jeune (peu de données d'entraînement)uL        - L'entraînement online va progressivement améliorer les prédictionsz4     - Augmenter la confiance minimum (actuellement z$%) pourrait filtrer les faux signauxzI     - Tester avec un lookback plus long (30 jours) pour plus de contexte)+r   rb   rQ   r&   r2   r3   r   r   r*   r+   rI  r,   r   r   r   r   r   rc   meanr   medianrK  r   absre   r   r   r7   stdsqrtr   r   rD  r   r   r   splitrangerf   r   r   r.   rA  )UrZ  r   re  rf  rl   r  r6  r7  r8  r9  tradesrg   initialfinal	total_pnltotal_pnl_pctcolor
annual_pctr  r  lossesn_winsn_losseswin_rateavg_winavg_lossavg_pnl
median_pnl
best_tradeworst_tradegross_profit
gross_lossprofit_factor	durationsavg_durationreturnssharpe_rj  	eq_valuespeakmax_ddddcalmartotal_signalstotal_aipatstatsexit_reasonsr   wrc_sorted_symbolsr   	total_symhtotal_hbar_lenr   
bh_returnsri   bt_startra  	prices_btbh_retravg_bhbh_portfolioc_bhc_lstmdiffc_diffeq_valsmin_eqmax_eqrange_eqheightwidth	step_sizesampledrow	thresholdlinevalverdictsU                                                                                        r6   rT  rT    s5    !!FFA	  	Y Z[  Z_  Z_  Y` `  $$GMMEI(C/M>ACCqssE	Bqvvh(
01	''8
>?	'wuWoU155'
JK	'wy.B'-X\I]]_`a`e`e_f
gh #D!"45J	(
8/DAaeeW
MNAvQSSEbcdchchbijk'(@(@'AASTZTnTnSopqF0011B6C\C\B]^_ 0!aA0D03A1::?a3F3YF6{H%&U
S H48bgg$/Qqyy/0aG7=rww62a		231Hgg&1Qqyy12Gv6!AII67JV!45Jf"56K4830400aL9?S4V445TJ1;aL:-U5\M @FF!!++,5FIF779%L	D/w
78	'#w
/0	'uVCL8C.155'
RS	'uXcN"S8^C<PPRSTSXSXRY
Z[	'uWV,<AaeeW
EF	'uXf,=Qquug
FG	''7q
9:	(F(;1
=>	'e'<
=>	(e(<F<PR?SVBWWY
Z[	'uZ->->,?qASASTX@YYZ[\[`[`Za
bc	'u[-?-?,@+BUBUVZA[[\]^]b]b\c
de #))Qqyy)G)ggg"&&/D"89RWWS\TWX\^_T`E`cfEf=ggF :@9L9L!4!4525SZR[IQ<DF 9DRi4#%;F 5;QJmc&$//E%LF	D(
01	'u~
67	'uVEN!AEE7
CD	'u~
67	'CaL(8'?
@A 
DQUUG
,-,,v/I/IIFL`L``cic|c||M	)-)>
?@	()A)A%(H6KcKcdghuvwdxKxy|K|  ~A  KB  BD  E  F	()C)CE(J"VMgMghklyz{h|M|  ~A  NA  BE  MF  FH  I  J	()=)=e(DBvG[G[\_`mno\pGpqtGtuxFyy{
|}	()B)B5(IFLeLefijwxyfzLz{~L~  @C  LD  DF  G  H	)&*@*@)GG_
`a '%QVVH8@A*,8$HI7u\$<OPQPUPUwVXYefijrstfuYuvyYyz}X~  A  B  	C8j=NquugUWXbcfgopqcrXrsvXvwzW{{}~46$%5%;%;%=C[\ G
USIT%.1DEFG JKL .$$S)!,VW%*%VU#qzz1#::> (A-(. 
D*155'
23 2 2 4:RS y6]Sw33c9%LA%QSS133	&T%.)<GBt9IVXUYZ_`eZfgmYnnopqpupuovwxy -335;QRN	Dw
/0$Sb) x
U%L5=0	5\C	1--3%LA%QSS133	#c!E%L#4N2d)9UWTXY^_dYeflXmmnopototnuvw	x >RQVVH-aeeW56(- 	|JCeuV}4IuIq 11C7Be)qssBIc#YaeR'8r$iyY[X\]bch]ijp\qqrstsxsxryz{		| 
D3AEE7
;<2Y _O#",v.a<5\G#c)gAs*bI_I_Ia*b'b ccfhhigo"HQSS!##	!CC9Agb\tBt9TUVWV[V[U\]^_ 
D.quug
67J^^% -	T+,K H,M$'	y>Amil2ilBSHFsFm,- 5?RWWJ/DAqa/0AFa&3,./LA+133133D!Q&QSSACCF	(venF<PTBUUVWXW\W\V]
^_	(u0EVERV<WXYZY^Y^X_
`a6!DAIQSS133F	(eAaeeW
EF s6#6#67!;QVVHOAEE734#)#6#67%!R277WW&,&66F?ABG%3w<501	+I+&v.R( 	C#,(!::ID  )#EMDCKD	 
 f}"VDM++"VDM++!#"fvo248::$K	 	ec'l*+,- 
Bqvvhzl155'
*+qX]}s/BSSE`abafaf`gh		x"}SSEbcdchchbij		SSEabcbgbgahiSSEjklkpkpjqr	Ky
!"qQTTF/01TV\^DE_D`  aE  F  	GYZ[Z_Z_Y`ab	Bqvvhzl155'
,-S 13
 0216 G" * 6F 0 8s[   
AF:AF:)AF?>AF?>AG/AG	AGAG#AG(AG5AG"AG(
<AG.c                    | j                   }t        |      }|D cg c]  }|j                  dkD  s| }}t        j                         j                         || j                  t        | j                  d      t        | j                  | j                  z
  d      t        | j                  | j                  z
  | j                  z  dz  d      |t        t        |      t        |d      z  dz  d      |dkD  rBt        t        d |D              t        t        t        d |D                    d      z  d      nd|dkD  r7t        t        j                  |D cg c]  }|j                   c}      d      ndd| j                  | j                   | j"                  | j$                  | j&                  d	|j)                         D ci c]  \  }}||
 c}}|D cg c]  }|j*                  t        |j,                  d
      t        |j.                  d
      t        j0                  |j2                  dz        j                         t        j0                  |j4                  dz        j                         t        |j                  d      t        |j                  d      |j6                  d c}d}	| j8                  rY| j8                  D 
cg c]  \  }
}|	 }}
}|d   }d}|D ]   }||kD  r|}||z
  |z  dz  }t        ||      }" t        |d      |	d<   t;        t<              j>                  dz  }tA        |dd      5 }tC        jD                  |	|ddtF               ddd       tI        dtJ        jL                   d|jN                   tJ        jP                          yc c}w c c}w c c}}w c c}w c c}}
w # 1 sw Y   ^xY w)u4   Sauvegarde le rapport JSON pour analyse ultérieure.r   r[   ro   rF   c              3   4   K   | ]  }|j                     y wr   r  r  s     r6   r   z#save_report_json.<locals>.<genexpr>  s     "<!1::"<r   c              3   T   K   | ]   }|j                   d k  s|j                    " yw)r   Nr  r  s     r6   r   z#save_report_json.<locals>.<genexpr>  s$     JyZ[ijisiswxix1::Jys   ((r  r   )reversal_upreversal_downneutralcontinuationblockedrE   r=   r   )r7   r   r   r   r   r   r   r   )ra   backtest_daysr   final_capitaltotal_pnl_usdtr  total_tradesr  r  avg_pnl_pctmax_drawdown_pctsignals	by_symbolr  r   zbacktest_lstm_report.jsonwr   )r   F)indentensure_asciidefaultNrG   u   📄 Rapport JSON sauvegardé: ))r   rb   r   r   r   	isoformatr   roundr   rI  r   r  rc   r  r   r   r   r   r   r   r   r7   r   r   r   r   r   r   r   r   __file__parentr\   rL   dumpr	  rQ   r&   r.   namer3   )rZ  rf  rl   r  rg   r  r  r   r  reportr  rj  r  r  r  r  out_pathfs                     r6   rU  rU    sk   !!FFA0!aA0D0 __&002!11v}}a00F0F FJ0F0F F&J`J``cffhij#d)c!Qi/#5q9 JK  NO  JOs"<t"<<s3sJy_eJyGyCz  }A  @B   B  DE  F  UVIJQuRWW%@Aaii%@A1ETU!33#77++"55--
 4E3J3J3LMZS%c5jM 
  (($Q]]A6#ALL!4&77t8KLVVX%66q{{T7IJTTV!!**a0 A. }}	
)!FH #)#6#67%!R277qz 	%BDy)t#c)B_F		%
 &+61%5!"H~$$'BBH	hg	. H!		&!AE3GH 
Bqttf3HMM?155'
JKk 1 &A N
" 8H Hs/   NNN$N)CN/
N4>N::O__main__z"Crash-Test LSTM Reversal Predictor)descriptionz	--symbols+u5   Liste de symboles à tester (défaut: 20 top cryptos))nargsr  helpz--daysu&   Nombre de jours de backtest (défaut: r   )r   r  r  z	--capitalu"   Capital initial en USDT (défaut: z--all
store_truez(Tester tous les symboles de la watchlist)actionr  z--aiu>   Activer la validation IA complète (smart_criteria + patterns)zwatchlist.jsonz  Mode --all: z symboles de la watchlist)r  )F)FNr   r   N)Sr  r:  r;  r   rL   rN   iorI   argparsenumpyrc   r   r   pathlibr   typingr   r	   r
   r   collectionsr   stdoutr   TextIOWrapperbufferstderrrH   r   BACKTEST_DAYSr@  r   r   r   r   r   r   rA  rB  rR  rS  r   r   rE  rC  DEFAULT_SYMBOLSr&   r	  rf   rX   ndarrayrj   r   r   r   r   r   r
  r  rT  rU  r'   ArgumentParserparseradd_argumentre   
parse_argsargsr   rk   allr	  r
  wlr\   r  loadrJ   rQ   rb   rP   rl   air4   r5   r6   <module>r-     s  6 
%'

! " 
   	    (  . . # ::'!!!!#**"3"3giXCJ::'!!!!#**"3"3giXCJ %        "    $     
   

 
"  s C DQUJ <d4j T#rzz/%:  49 C Dd3

?>S9S4T J2E E    ]X ]XH_6$s) _63 _6 _6N	 EJHI"&o. o.4 o.$ o.$(o.03o.=Ao.-0o.BEo.d9L^ 9L 9LC 9L@ z$X$$1UVF
3T  V
sMEm_TUV  X
%A/ARRST  V
G  I
|]  _ D||&,,ll-oGxx	&h&&)99Bb GQ#$))A,**9oFGN3w<.0IJK $))DGG4; .G G  	&%G	&s*   L #K<L <LL LL