
    i3                        d 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ZddlZddl	Z
ddlmZmZ ddlmZ ej                  j                   r`ej                  j                   j#                         dv r:ej                  j%                  dd       ej&                  j%                  dd       ej(                  j+                  ej(                  j-                  e            Zej(                  j3                  ed	      Zej(                  j3                  ed
      ZdZh dZddhZg dZi ddddddddddddddddddd d!d"dd#dd$d%d&d'd(d)d*d+d,d-ed.d/d-d0d1Z e jC                         D  ci c]  \  } }| |
 c}} Z"e"jG                  d2dd-d3d3ddd4d5dd6d7       dHd8Z$d9 Z%dId:Z&d; Z'd< Z(d= Z)d> Z*d? Z+dJd@Z,dA Z-dKdBZ.dKdCZ/dD Z0dE Z1dF Z2e3dGk(  r e2        yyc c}} w )Lu  
spy_crashtest_30d.py  —  Crash-test complet du Market SPY sur 30 jours réels
═══════════════════════════════════════════════════════════════════════════════

Télécharge les klines 1m Binance Production pour les N paires les plus actives,
simule EXACTEMENT la logique de market_spy.py (détection surge, confirmation,
gestion de position) et calcule le P&L total sur la période.

Permet de :
  - Comparer paramètres ANCIENS vs ACTUELS (FIX 15/03)
  - Identifier les types de surges les plus rentables
  - Optimiser les seuils (--optimize)
  - Mesurer l'impact de chaque correctif (anti-mèche, instant-reversal, etc.)

Usage:
  python spy_crashtest_30d.py                  # 30 jours, top 30 paires
  python spy_crashtest_30d.py --days 7         # 7 jours uniquement
  python spy_crashtest_30d.py --pairs 50       # Top 50 paires
  python spy_crashtest_30d.py --no-cache       # Re-télécharger les données
  python spy_crashtest_30d.py --optimize       # Recherche params optimaux
  python spy_crashtest_30d.py --verbose        # Afficher chaque trade simulé
═══════════════════════════════════════════════════════════════════════════════
    N)datetime	timedelta)defaultdict)cp1252cp850asciiutf-8replace)encodingerrorszspy_crash_cache.pklzspy_crash_report.jsonzhttps://api.binance.com>
   DAIUSDTEURUSDTGBPUSDTBUSDUSDTTUSDUSDTUSDCUSDTUSDPUSDTUSTCUSDT	FDUSDUSDT	PYUSDUSDTZECUSDT
BANANAUSDT))      ?333333?)      ?r   )       @ffffff?)      @      ?)      @g?)g      $@g      @)g      .@g      @)  r    surge_flash_pct皙?surge_build_pctg?surge_trend_pctr   surge_accel_pctflash_spike_facvol_ratio_minr   	green_min   mom_min皙?wick_max_pct333333?live_retrace_pct皙?hard_sl_pctearly_sl_pctearly_sl_secx   early_sl_maxpnl皙?instant_rev_sec-   instant_rev_trigg      trail_activationr      
     )trail_tiersmax_hold_minstag_minstag_pnl_minposition_usdtg?g     8@   r   g     8)r"   r$   r&   r-   r/   r1   r2   r3   r5   r7   r9   c           
         t        d|  d       t        j                  t         dd      }|j	                          |j                         }|D cg c]  }|d   j                  d      rr|d   t        vrg|d   t        vr\t        |j                  dd	            d
k\  r>t        |j                  dd	            dk\  r t        |j                  dd	            dk  r| }}|j                  d d       |d|  D cg c]  }|d   	 }}t        dt        |       ddj                  |dd        d       |S c c}w c c}w )u7   Récupère les N meilleures paires USDT par volume 24h.u     📋 Récupération top z paires USDT...z/api/v3/ticker/24hrr;   )timeoutsymbolUSDTquoteVolumer   i@KL 	lastPricegMb@?iP  c                 8    t        | j                  dd            S )NrH   r   )floatgetxs    ./spy_crashtest_30d.py<lambda>z!get_top_symbols.<locals>.<lambda>   s    aeeM1&= >     TkeyreverseN     ✅ z	 paires: z,    z...)printrequestsrL   PROD_APIraise_for_statusjsonendswithSTABLECOINS	BLACKLISTrK   sortlenjoin)nresptickerstfilteredsymbolss         rO   get_top_symbolsrh   z   s>   	&qc
9:<<8*$78"EDiikG hK  ((;.(9,aeeM1-.);aeeK+,6aeeK+,6 	
H  MM>MM$,RaL1qq{1G1	F3w<.	$))GBQK*@)A
EFN 2s   BD9<D>c                    t        |j                         dz        }t        |j                         dz        }g }|}||k  r| d|t        |dz   |      dd}	 |j                  t         d|d      }	|	j                         }
|
rt        |
t              rn@|j                  |
       t        |
d   d	         d
z   }t        j                  d       ||k  r|s%t        j                  dt        j                        S t        j                   |D cg c]_  }t#        |d	         t#        |d         t#        |d         t#        |d         t#        |d         t#        |d         t#        |d         ga c}t        j                        }|S # t        $ r0}t        d|  d|        t        j                  d       Y d}~d}~ww xY wc c}w )u   
    Télécharge les klines 1m pour un symbole sur la période demandée.
    Retourne un np.array [N, 7]: [open_time, open, high, low, close, volume, taker_buy_vol]
      1mi)rF   interval	startTimeendTimelimitz/api/v3/klinesr;   )paramsrE   r   i`  gQ?u   
    ⚠️ : r*   N)r      )dtype            r<   )int	timestampminrL   rY   r[   
isinstancedictextendtimesleep	ExceptionrW   npemptyfloat64arrayrK   )rF   start_dtend_dtsessionstart_msend_msrowscurrp   rdataekarrs                 rO   fetch_klines_1mr      s   
 8%%'$./H6##%$./FDC
,S</8
	xj7PRSA668D:dD1KKd2hqk"V+CJJt ,* xxbjj11
(( 	 !+uQqT{E!A$Kqt
!+uQqT{E!B%L
2 	 jj	C J  	M&A3/0JJqM		s%   =F :F A$G		G&GGc           
         |rt         j                  j                  t              r	 t	        t        d      5 }t        j                  |      }ddd       j                  di       }|j                  d      | k(  r`|j                  d      |k(  rLt        |d         }t        d |d   j                         D              }t        d| d	|d
d| d       |d   S t        d       	 t        dt        |        d| d       t        dt        |       |z  dz   d       t        j                         j                  dd      }	|	t!        |      z
  }
t#        j$                         }|j&                  j)                  ddi       i }d}t+        | d      D ]x  \  }}t        d|ddt        |        d|d d!d"#       t-        ||
|	|      }t        |      r-|||<   |t        |      z  }t        d$t        |      d%d&       nt        d'       z |d(z  d)z  d*z  }t        d+|d
d|d,d-       	 t	        t        d.      5 }t        j.                  | |d/|d0|d12       ddd       t        d3t         j                  j1                  t                      |S # 1 sw Y   MxY w# t        $ r}t        d| d       Y d}~d}~ww xY w# 1 sw Y   mxY w# t        $ r}t        d4|        Y d}~|S d}~ww xY w)5ut   
    Charge depuis le cache pickle ou télécharge depuis Binance.
    Retourne: dict {symbol: np.array [N, 7]}
    rbNmetarg   daysr   c              3   2   K   | ]  }t        |        y wNr`   .0vs     rO   	<genexpr>z#load_or_download.<locals>.<genexpr>   s     DqCFD   u     ✅ Cache chargé:  symboles, ,z
 candles (zj)uS     ℹ️ Cache invalide (différent de la config demandée) → re-téléchargementu     ⚠️ Erreur lecture cache: u    → re-téléchargementu   
  📡 Téléchargement u    × zj de klines 1m...u        Durée estimée: ~rx   z
 secondes
r   )secondmicrosecond)r   z
User-AgentzSpyCrashtest/1.0ru   z  [02d/z] 15 Tendflushu   ✅  z6,z candlesu   ❌  pas de donnéesrs   rV   g    .Au   
  📊 Total: .1fz MB)wb)rg   r   )r   r   rw   )protocolu     💾 Cache sauvegardé → u-     ⚠️ Impossible de sauvegarder le cache: )ospathexists
CACHE_FILEopenpickleloadrL   r`   sumvaluesrW   r   r   utcnowr
   r   rX   Sessionheadersupdate	enumerater   dumpbasename)rg   r   	use_cachefcachedr   n_symtotalr   r   r   r   r   total_candlesirF   r   mbs                     rO   load_or_downloadr      s    RWW^^J/	Qj$' (1Q(::fb)Dxx	"g-$((62Bd2JF6N+DF6N,A,A,CDD-eWKay
SWRXXZ[\f~%kl 
&s7|nD>O
PQ	#CL4$71$<#=[
IJ ((q(AF	t,,H!GOOL*<=>DMw* *	6Ac7!CL>F2;7SMfh@s8 DLSX%ME#c(2h/0()* 
	Q		$B	]1-Z3xt
DEC*d# 	cqKKWd!CTRTU`ab	c-bgg.>.>z.J-KLM K]( (  	Q3A36NOPP	Q<	c 	c  C=aSABBKCse   J% JBJ% J% 0K  K7K J"J% %	K.KKKK 	K9 K44K9c                    t        |       dk  rg S | dddf   | dddf   }| dddf   }|d   dz  }|d   dz  }|d	   dz  }g }d
}t        dt        |       dz
        D ]{  }	|	|z
  dk  r|	   |	dz
     }}
|	dz
     }||	   }|dk  s|dk  r2d}d}|
|z  dz
  dz  }||d   k\  rd}|}n||z  dz
  dz  |d   k\  rd}||z  dz
  dz  }ng|
|z  dz
  dz  |d   k\  r|dkD  rd}|
|z  dz
  dz  }nC|	dk\  r>|	dz
     }|dkD  r1|
|z  dz
  dz  }||z  dz
  dz  }||d	   k\  r|dkD  r|dkD  r	||kD  rd}|}|W|	dk\  rR|	dz
     }|dkD  rE|
|z  dz
  dz  }||d   k\  r2|dkD  r-t        fdt        |	dz
  |	dz         D              }|dk\  rd}|}|1|j                  |	| |	df   |t	        |d      t        |
      t        |      t        ||	dz            d       |	}~ |S )u  
    Simule la détection de surges à partir de klines 1m.

    Chaque kline 1m ≈ 6 scans de 10s. On détecte:
      FLASH       : close[i]/close[i-1] ≥ surge_flash%   (hausse rapide close-to-close)
      FLASH_SPIKE : high[i]/close[i-1]  ≥ surge_flash%   (pic intra-candle, close peut retomber)
      BUILDING    : close[i]/close[i-2] ≥ surge_build%   avec close[i] > close[i-1]
      ACCELERATING: hausse successive sur 2 deltas, minimum accel_min%
      TRENDING    : hausse soutenue sur 8 candles (≥1%), majorité upward

    Prix d'entrée = open[i+1]
    (après détection + confirmation, on achète à l'ouverture de la bougie suivante)
       Nrw   r*   ru   r"   d   r$   r&   r;   r           FLASHFLASH_SPIKEr6   BUILDINGrv   g333333?r   ACCELERATINGrV   r%   c              3   @   K   | ]  }|   |d z
     k\  sd   ywru   N )r   jclosess     rO   r   z detect_surges.<locals>.<genexpr>E  s'     UAF1IPQRSPS<TaUs   rx   TRENDING)idxtime_ms
surge_typesurge_strengthdetect_pricespike_priceentry_price)r`   ranger   appendroundrK   )r   rp   highsopenssurge_flashsurge_buildsurge_accelsurgeslast_surge_endr   c0c1c2h0r   r   flash_ccc3	delta_now
delta_prevc8change_8upsr   s                          @rO   detect_surgesr      s    3x"}	AYFAYEAYE*+c1K*+c1K*+c1KFN2s3x!|$ @~!)VAaC[B!A#;87bAg
 GaK3&v/00$J%N 2gkS F+<$==*J 2gkS0N 2gkS F+<$==(S.'J 2gkS0N !V!BAv 2gkS0	 2gkS0
(9!::&-$sN%
2%3J%.N !q&!BAvGaK3.v&788X\UqsAaCUUCax)3
)1!MM!"!$QT!+"'":!&r!&r!&uQqSz!2  NA@D MrQ   c                   %& |d   }|dk  s|t        |       k\  rdddgifS | t        d|dz
        |dz    }|d	d	df   %|d	d	df   &|d	d	d
f   }|d	d	df   }|d	d	df   }|d	d	df   }|d   }	t        |      dkD  r|d   n|	}
t        |      dkD  rt        j                  |d	d       n|	}|dk  rd}|	|z  }|
|z  }t        ||      }|d   dkD  r|d   |d   z  nd}t        |      dkD  r|d   dkD  r|d   |d   z  nd}t        ||      }|dk\  }|dk  xr |dkD  }t        %      dk\  rt	        %&fdt        dd      D              nd}t        %      dk\  r%d   dkD  r%d   %d   z  dz
  dz  nd}|d   }|d   }|d   }|dkD  r|%d   z
  |z  dz  nd}|dkD  r||z
  |z  dz  nd}t        |      dk\  rt        |dd       n|d   }t        |      dkD  rt        |d	d       n|d   }|dkD  r||z  dz
  dz  nd}|d   dv xr |d   dk\  }|d   dv xr |d   d k\  }g } |rdn|d!   }!||!k  r#|r||!d"z  k\  s| j                  d#|d$d%|! d&       |rdn|d'   }"||"k  r| j                  d(| d)       |s%||d*   k  r| j                  d+|d,d-|d*    d.       n|r|d/k  r| j                  d0|d,d.       |r|s| j                  d1|d2d3       |d   d4k(  rd5nd6}#||#k  r|s| j                  d7|d$d.       |j                  d8d9      d:k  r&|s$||d8   kD  r| j                  d;|d$d<|d8    d.       |j                  d=d9      d:k  r$||d=   kD  r| j                  d>|d$d<|d=    d.       t        |       dk(  }$|$t        |d
      |t        |d      t        |d
      t        |d      t        |d      t        |d
      | |$d?	fS )@u   
    Simule confirm_surge() de market_spy.py.
    Vérifie: volume, bougies vertes, momentum, taker buy, anti-mèche, V-bounce.
    Retourne (confirmed: bool, details: dict)
    r   rx   F	rejectioninsufficient_datar   rw   ru   Nr*   rv      rq   r   r   gףp=
?gffffff?r   c              3   :   K   | ]  }|   |   kD  sd   ywr   r   )r   r   r   r   s     rO   r   z confirm_surge.<locals>.<genexpr>  s      BVAYq-A!Bs   r   r   r   r   r   r   )r   r   r   r   r(   r   zvol_low(r   zx<zx)r)   znot_bullish(z/3)r+   z	mom_weak(z.2fz%<%)g      z
mom_crash(zsell_press(buy=z.0%)r   g      g      zv_bounce(drop=r-   r!   c   u   wick_trap(mèche=z%>r/   zlive_retrace()		vol_ratiogreen_3mom_3	buy_ratiowick_pctlive_retracev_dropr   	confirmed)
r`   maxr   meanr   r   r{   r   rL   r   )'r   surgerp   r   slice_cr   lowsvolsbvolscurrent_volprev_volavg_volr   prev_vol_ratiobest_vol_ratiocur_buyprev_buybest_buy
strong_buy
sell_pressr   r   r   r   r   r  r  min_lowmax_oldr  	is_strongis_very_strreasons_rej
vol_thresh	min_greenv_threshr  r   r   s'                                        @@rO   confirm_surger  ]  s    	eA1uSX{%8$9::: #a1+ac"GQT]FQT]EQT]EQT]DQT]DQT]E r(K!$i!m$r(H(+D	A"''$s)$;G!| 7*I7*NN3N (,Bx!|uRy48#G'*4y1}bAuRy48#3H7H%Hd"JT/:ns&:J GJ&kUVFVcBU2q\BB\]G 47v;!3Cr
UVVBZ&*$q(C/\_E 'K(L'KGRUVkF2J.+=C\_HJVYZJZl[0L@3F`cL $'t9>s42;tBxG$'JNs5":b	G07!'!A%,F%)AAdeL\F]adFdI%)AAdeL\F]adFdKK "vo'>J
"~c1AA.)=R
|2NO F;$7I\'#67 	!22YuSkF94E3FbIJ	ut|Zc{"56 )_XcN!<= \*j8tdH^F3<r:; zz.#&+Kf^,,!28C.6.CYBZZ\]^ zz$c*R/&!344|C.@6J\C]B^^`abK A%Ina0eQh*h*lA.fa(#!
 
 
rQ   c                 8    |D ]  \  }}| |k  s|c S  |d   d   S )u=   Retourne le % de trail à appliquer selon le P&L max atteint.rq   ru   r   )max_pnltiers	thresholdtrails       rO   
_get_trailr%    s3    ! 	5YL 9Q<rQ   c           	         |t        |       k\  s|dk  ry| dddf   }| dddf   }| dddf   }|}d}d}	d}
d}|}|d|d	   d
z  z
  z  }|d   }t        ||d   z   dz   t        |             }t        ||      D ]  }||   }||   }||   }||z
  }|dz  }||z  dz
  d
z  }||z  dz
  d
z  }||z  dz
  d
z  }||kD  r|}||kD  r|}|j                  dd      }|j                  dd      }|dkD  r!||k  r|dk  r||k  rt	        |||d||      c S ||k  rt	        |d	    ||d||      c S ||d   k\  r#||d   k  r||d    k  rt	        |||d||      c S ||d   k\  rd}	|	r7t        ||      }|d|d
z  z
  z  }
||
k  r||z
  }t	        |||d| d||      c S ||d   k\  r|dk  rt	        |||d||      c S ||d   k\  r#||d    k  r||d    kD  rt	        |||d!||      c S ||k  r|dz  }nd}|dk\  r d|cxk  rd"k  rn nt	        |||d#||      c S |dk\  r|d$k  r|d%k  rt	        |||d&||      c S |} t        ||d   z   t        |       dz
        }| |df   |z  dz
  d
z  }t	        |||d   d'||      S )(u+  
    Simule une position ouverte au prix entry_price à partir de start_idx.
    Applique dans l'ordre: INSTANT_REVERSAL → HARD_SL → EARLY_SL → TRAILING → MAX_HOLD → STAGNATION → REVERSAL

    Retourne un dict avec pnl_pct, max_pnl, hold_min, exit_reason, pnl_usdt, missed_gain_pct.
    r   Nrw   r*   rv   r   Fru   r1   r   r>   r?      <   r7   r9   r   g?INSTANT_REVERSALHARD_SLr3   r5   r2   EARLY_SLr:   Tz
TRAILING(-r   r   MAX_HOLDr@   rA   
STAGNATIONr    MOMENTUM_EXITg       @r   REVERSALEND_MAX_HOLD)r`   r{   r   rL   _mkr%  )r   	start_idxr   rp   r   r   r
  	max_pricer!  trailing_activetrailing_stopconsec_drops
prev_closehard_sl_pricer>   max_idxr   highlowclosehold_mhold_spnl_hpnl_lpnl_cir_secir_trig	trail_pctexit_pnl	pnl_finals                                 rO   simulate_positionrG    s    CHq 0AYFAYEAYD!IGOML!J!Q)>)D%DEMm,K )f^44r93s8DG9g& B(q')i-2+$q(C/$q(C/$q(C/ )I7?G **.3**/6A:&F*w~%7BRw1C[RXYY -}--w	;X^__ ~..f%677vn555ugvz;OO f/00"O&w<I%Y_)<=Mm#"Y.8Wf
9+R6PR]_eff VN++ugvz;OO fZ((F>22VN333ugv|[&QQ :ALL1USugvVTT c>gmugvz;OO
EBJ 	I~..C1=AQT[(1,3Iy'6.#9>;X^__rQ   c           
         |j                  dd      }|| z  dz  }t        d|| z
        }t        t        |       d      t        t        |      d      t	        |      |t        t        |      d      t        t        |      d      dS )u,   Construire le dict résultat d'une position.rB   r=   r   r   rv   r*   )pnl_pctr!  hold_minexit_reasonpnl_usdtmissed_gain_pct)rL   r  r   rK   ry   )	rI  r!  rJ  reasonr   rp   pos_usdtrL  misseds	            rO   r1  r1  <  s~    

?C0H7"S(HC7*+Fg3g!4h- h!4 v!4 rQ   c                    g }g }| j                         D ]n  \  }}t        |      dk  rt        ||      }d}|D ]E  }	|	d   }
|
|k  rt        ||	|      \  }}|s-|j	                  ||	d   |	d   |j                  dg       d       Nt        ||
dz   |	d	   |      }|e|j                  ||	d   |	d   |
t        j                  ||
d
f   dz        j                  d      |j                  dd
      |j                  dd
      |j                  dd
      d       |j	                  |       |
dz   |d   z   }|s|d   d
kD  rdnd}t        d| d|dd|	d   dd|	d   dd|d   dd|d   dd|d   dd |d!    d"       H q ||fS )#u   
    Lance le backtest complet sur tous les symboles.
    Simule au maximum SPY_MAX_POSITIONS positions simultanées (approximation).

    Retourne: (trades: list, rejected: list)
    r'  rq   r   r   r   r   )rF   r   strengthreasonsru   r   r   rj   z%m-%d %H:%Mr   r  r  )rF   r   r   	entry_idx
entry_timer   r  r  rJ  rI  u   ✅u   ❌    r   12z str=z5.2fz% PnL=z+6.2fz% max=r!  z% hold=3zm (rK  r   )itemsr`   r   r  r   rL   rG  r   r   utcfromtimestampstrftimerW   )r   rp   verbosetradesrejectedrF   r   r   
open_untilr  r   r  detailsresultemojis                  rO   run_backtestrc  O  s%    FHzz| 74s8b=!#v.
 0	4E,C j  "/sE6!BIw"("'"5"'(8"9")++k2">	!   'sC!GU=5I6RF~MM"("'"5"'(8"9"%"*";";&)#q&kD&8#$$,H]$;")++k1"=")++k1"=")++j!"<  MM&! q6*#55J!'	!2Q!6EUG1VBKq|1DR0H I"#34T: ;#I.u5 6#I.u5 6$Z03 4 /03 4W0	474r 8rQ   c                 .   | si S | D cg c]  }|d   	 }}| D cg c]  }|d   	 }}| D cg c]  }|d   dkD  s| }}| D cg c]  }|d   dk  s| }}|r/t        t        j                  |D cg c]  }|d   	 c}            nd}|r/t        t        j                  |D cg c]  }|d   	 c}            nd}|dk7  rt        ||z        nd}t	        t
              }	t	        t
              }
| D ]X  }|d   j                  d      d   j                         }|	|   j                  |d          |
|d      j                  |d          Z i d	t        |       d
t        |      dt        |      d| r$t        t        |      t        |       z  dz  d      nddt        t        t        j                  |            d      dt        t        t        |            d      dt        t        t        |            d      dt        |d      dt        |d      dt        |d      dt        t        |      d      dt        t        |      d      dt        t        t        j                  | D cg c]  }|d   	 c}            d      dt        t        t        j                  | D cg c]  }|d   	 c}            d      dt        t        t        j                  | D cg c]  }|d   	 c}            d      d|	j                         D ci c]:  \  }}|t        |      t        t        t        j                  |            d      d < c}}d!|
j                         D ci c]d  \  }}|t        |      t        t        t        j                  |            d      t        t        d" |D              t        |      z  dz  d      d#f c}}S 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}}w c c}}w )$u@   Calcule un dict complet de statistiques sur les trades simulés.rI  rL  r   r   g     X@rK  (r   n_tradesn_winsn_losseswin_rater   ru   avg_pnlrv   total_pnl_pctr*   total_pnl_usdtavg_winavg_lossprofit_factormax_pnl_trademin_pnl_tradeavg_max_pnlr!  
avg_missedrM  avg_hold_minrJ  by_exit)countrj  by_surgec              3   ,   K   | ]  }|d kD  s	d  yw)r   ru   Nr   )r   ps     rO   r   z compute_stats.<locals>.<genexpr>  s     -DAa!ea-Ds   
)rv  rj  wr_pct)rK   r   r  absr   listsplitstripr   r`   r   r   r  r{   rY  )r]  re   pnlsrL  winslossesrm  rn  pfru  rw  rS   r   r   s                 rO   compute_statsr    s   	)/0A!I,0D0)/0A!J-0H0#8q|a'7!8D8#9q|q'8!9F9CGrwwd;);<=sGCIrwwf=)=>?sH,4MWx'(tBT"GT"H 7$$S)!,224AiL)<!((967
3v;3t9 	3v; 	f5TS[!83!>BRS	
 	5rwwt}!5q9 	5s4y!115 	5s8}!5q9 	51- 	51- 	5Q< 	5TA. 	5TA. 	5rwwf/M)/M'N!OQRS 	5rwwf/U2C0D/U'V!WYZ[ 	5rwwv/N!*/N'O!PRST  	!(2A #a&U5;La5PQQ 2!$ 	 "*!13 A #a&$)%
*;Q$?$)#-D-D*Ds1v*MPS*SUV$WY Y 3% ! 1089;=. 0N/U/N23sK   OO#O(O(O-O-3O2&O75O</P)P?P
0A)P
c                 n   d}t        dd        t        d|         t        d        |st        d       yt        |      t        |      z   }|rt        |      |z  dz  nd}t        d	       t        |       t        d
|d       t        dt        |      dd|dd       t        dt        |      ddd|z
  dd       t        d|d   dd|d    d|d    d       t        |       t        d|d   dd       t        d|d   dd       t        d|d    d!d"|d#   d$d%       t        d&|d'   d!d       t        d(|d)   d!d       t        d*|d+   dd       t        d,|d-   dd       t        d.|d/   d0       t        d1|d2   dd3       t        d4|d5   dd6       t        d7       t        |       t        |d8   j                         d9 :      D ]7  \  }}	d;t	        d<|	d=         z  }
t        d|d>d?|	d=   d@dA|	d   dBdC|
        9 t        dD       t        |       t        |dE   j                         dF :      D ]*  \  }}	t        d|dGd?|	d=   d@dA|	d   dBdH|	dI   dJd	       , t        |dK dLM      }t        dN       t        |       |ddO D ]6  }t        d|dP   dQdR|dS   dQd|dT    dU|dV   dBdW|dX   dBdY|dZ    d[       8 t        d\       t        |       |d]d D ]/  }t        d|dP   dQdR|dS   dQd|dT    dU|dV   dBdY|dZ    d[       1 y)^u5   Affiche un rapport détaillé d'un jeu de résultats.   ────────────────────────────────────────────────────────────────────
   ════════════════════════════════════════════════════════════════════  u7     ⚠️  Aucun trade simulé pour cette configuration.Nr   r   u   
  📊 RÉSUMÉu     Surges détectés   : z>6u     Surges confirmés  : z  (z.0fz% taux confirmation)u     Surges rejetés    : u   % filtrés)u     Trades simulés    : rf  rg  zW / rh  zL)z  Win Rate          : ri  z>6.1f%z  P&L moyen / trade : rj  z>+7.3fz  P&L total         : rk  z>+7.2fz%  / rl  z>+8.2fu   €z  Meilleur trade    : rp  z  Pire trade        : rq  z  Gain moyen (W)    : rm  z  Perte moyenne (L) : rn  z  Profit Factor     : ro  z>7.2fu     Gains manqués     : rs  z%  avg/tradez  Hold moyen        : rt  z  minu   
  📉 PAR TYPE DE SORTIEru  c                 &    t        | d   d          S Nru   rv  )r{  rM   s    rO   rP   zprint_report.<locals>.<lambda>  s    C!W,>+> rQ   rS   u   █r;   rv  z>18rr   4zx  avg=z>+6.2fz%  u   
  ⚡ PAR TYPE DE SURGErw  c                     | d   d    S r  r   rM   s    rO   rP   zprint_report.<locals>.<lambda>  s    1Q4=. rQ   z>14z%  WR=rz  z3.0fc                     | d   S )NrI  r   )re   s    rO   rP   zprint_report.<locals>.<lambda>  s
    9 rQ   TrR   u   
  🏆 TOP 5 MEILLEURS TRADESrx   rF   rW  r   r   rU  z  PnL=rI  z%  max=r!  z%  (rK  r   u   
  ⚠️  TOP 5 PIRES TRADESr   )rW   r`   sortedrY  r{   )titler]  r^  statsrp   sepn_totalconfirm_raterN  dbarstypetrades_sortedre   s                 rO   print_reportr    sL   
C	Bxj/	Bug,	XJGH&kCM)G293v;(3.qL		#J	$WRL
12	#CK#33|C6HH\
]^	#CM"#5S\9I#8Nk
Z[	#E*$5b#9 :Hod5#4"5R9 :	#J	"5#4U";1
=>	"5#3F";1
=>	"5#9&"A B%&v.c3 4	"5#9&"A
CD	"5#9&"A
CD	"5#3F";1
=>	"5#4V"<A
>?	"5#9%"@
AB	#E,$7#?|
LM	"5#8"?u
EF	')	#JE),224!>@ U	c"aj))6#,b7Aga	l65J#cUSTU
 
%'	#J5,224 8: )q5+R'
1~ .y\&) *hK%Q( 	)) 6'=tLM	+-	#J2A '1X;r"!AlOB#7r<! "y\&) *y\&) *M"#1	& 	'' 
*,	#J23 '1X;r"!AlOB#7r<! "y\&) *M"#1& 	''rQ   c           	      p   d}t        dd        t        d       t        d        d-d}ddd	d
ddd
dd}|r	|d
ddz  }t        |       t        dd dd dd d       t        |rdd nd       | r| ni }|r|ni }|}d }	 |d |	|d       |	|d      |r	 |	|d      ndd        |d |	|d       |	|d      |r	 |	|d      ndd        |d |	|d       |	|d      |r	 |	|d      nd        |d |	|d       |	|d      |r	 |	|d      nd        |d  |	|d!       |	|d!      |r	 |	|d!      ndd"        |d# |	|d$       |	|d$      |r	 |	|d$      ndd%        |d& |	|d'       |	|d'      |r	 |	|d'      ndd"d()        |d* |	|d+       |	|d+      |r	 |	|d+      ndd,d()       y).z$Affiche le tableau comparatif final.u   ────────────────────────────────────────────────────────────────────────r  u   ════════════════════════════════════════════════════════════════════════u     📊 TABLEAU COMPARATIF FINALNc                 "   ||j                  |      nd}||j                  |      nd}|d uxr |d uxr |r||kD  n||k  }|rdn||k(  rdnd}	d| dd|dd|d|	 }
|#||kD  rd	nd}|
d|j                  |      d| z  }
t        |
       y )
Nz  N/A u    ✅ u    ❌r  >22    │ >12u    🏆)formatrW   )labelold_vcur_vopt_vfmthigher_betterocbetterflagline	best_flags               rO   rowzprint_comparison.<locals>.row  s    !&!2CJJu!&!2CJJud" 
uD'8 
,UU]55= 	  vEUNbE#;eAc7%#wtf=#(5=bIeCJJu-c29+>>DdrQ   r  u	   Métriquer  r  ANCIENSr  ACTUELSu
   OPTIMISÉSuB   ──────────────────────u	   ─┼─u$   ────────────r  )r   c                 .    | r| j                  |d      S dS )Nr   )rL   )r  r   s     rO   gzprint_comparison.<locals>.g/  s    qa/a/rQ   z	Nb Tradesrf  z{:>+.0f})r  zWin Rate (%)ri  z{:>+.1f}zP&L Total (%)rk  u   P&L Total (€)rl  zAvg P&L (%)rj  z{:>+.3f}zProfit Factorro  z{:>.2f}u   Gains manquésrs  F)r  r  zAvg Hold (min)rt  z{:>.1f})Nz{:>+.2f}T)rW   )
old_scur_sopt_sr  r  headerovcvos_r  s
             rO   print_comparisonr    s$   
C	Bxj/	
+,	XJ +c"%	#eIc?KFE,s+,,	&M	Bxj	(9XJ
?RH	EIhZ
 r2RBRB
C/Ab,Ab4D7:Ac*-*VAb,Qr*5E8;Ac*-:WAb1Ab4I7:Ac/2Fa#34a;K6L7:Ac"23FAbOAbO7:Ac),*VAb1Ab4I7:Ac/2)UQr,/Qr,5G7:Ac,/e- Ab0Ab4H7:Ac.1U,rQ   c                     | syt        |       }t        |       t        |      z   }|rt        |      |z  nd}|d   dz  |d   dz  z   |d   dz  z   |d	   d
z  z
  |dz  z
  S )z0Score composite pour classer les configurations.g    r   rl  r6   ri  r0   ro  r   rs  r   r<   )r  r`   )r]  r^  sr  filter_rs        rO   _scorer  I  s    fA6{S]*G*1s8}w&qH


#
J-
$%
O

$% L/
$% 
#	$rQ   c                 ~   t        dd        t        d       t        d        g dg dg dg dg dg d	g d
g dg dg dg dg dd}|j                         }i }|j                         D ]  \  }}t        t	        | |       }|j                  |      }|}	t        d| d| ddd       |D ]f  }
|
|j                  |      k(  r|j                         }|
||<   t	        | |      \  }}t        ||      }t        d|
 d|ddd       ||	kD  sc|}	|
}h ||j                  |      k7  r0||   |f||<   |||<   t        d|j                  |       d|        t        d| d        t        d       |r4|j                         D ]  \  }\  }}t        d|dd | d|         ||fS t        d!       ||fS )"u   
    Optimisation par recherche sur une grille de paramètres.
    Teste chaque paramètre indépendamment, puis affine les meilleurs.
    r  r  u#     🔬 OPTIMISATION DES PARAMÈTRES)r   r#   r   333333?r   )r.   r   r#   r   r  )r#   r   r  r   )r0   r   r.   r#   )r(  Z   r4      rC   )r,   r6   r   )r0   r.   r#   r!   )r   r0   r   r!   )r   r   r#   r   )r   r  r   r   )r   rV   r<      )   r;   r'  r8   )r1   r"   r&   r2   r3   r5   r-   r/   r:   r(   r@   r?   u   
  📐 z  (base=r   r  Tr   r  u   →r   rU   u    → u     ➖ inchangé (u2   

  📋 Paramètres modifiés par l'optimisation:rV  z>25rr   uF       Aucun changement — les paramètres actuels sont déjà optimaux.)rW   copyrY  r  rc  rL   )r   base_paramsgridbest_paramsimprovementsparamr   
base_scorebest_valbest_svaltestre   r   r  ry  oldnews                     rO   optimize_parametersr  Y  s   
 
Bxj/	
/0	XJ 65003+0000*,D ""$KL 3v\$<=
 __U+	%
!4"DI 
	Ckooe,,&++-DDK'd3DAq!!Q<ABse3qg&Bd;6z
	 {u--#.u#5x"@L"*KF;??512%zBC%hZq12/32 
@B)//1 	3MAzSD3r#eC512	3
 $$ 	VW$$rQ   c            	      t   t        j                  dt         j                        } | j                  dt        dd       | j                  dt        dd       | j                  d	d
d       | j                  dd
d       | j                  dd
d       | j                  dt
        dd       | j                         }t        d       t        d       t        d       t        d|j                   d       t        d|j                   d       t        d|j                   d       t        d|j                  rdnd        t        d |j                  rd!nd"        t                |j                  t        d#<   |j                  t        d#<   	 t        |j                        }t'        |j                  |j                   &      }|s t        d'       t#        j$                  d%       t)        d( |j+                         D              }t        d)t-        |       d*|d+d,       t        d-       t/        |t        |j0                  .      \  }}t3        |      }t5        d/t-        |       d0t-        |       d1|||t               t        d2       t/        |t        |j0                  .      \  }	}
t3        |	      }t5        d3t-        |	       d0t-        |
       d1|	|
|t               d }g }g }|j                  rwt        d4       t7        |t              \  }}t        d5       t/        |||j0                  .      \  }}t3        |      }t5        d6t-        |       d0t-        |       d1||||       t9        |||       t;        t              }|
D ]8  }|j=                  d7g       D ]!  }||j?                  d8      d9   xx   d%z  cc<   # : |rt        d:d        t        d;       t        d<d=        tA        |jC                         d> ?      D ]  \  }}t        d@|dAdB|dCdD        t        dEt-        |
       dFt)        dG |
D               dH       tE        jF                         jI                         |j                  |j                  |j                  tK        |jM                               dI||dJ}|r||dK<   	 tO        tP        dLdMN      5 }tS        jT                  ||dOtV        P       d d d        t        dQtX        jZ                  j]                  tP                      t        d4d        t        dS       t        d d4       y # t         $ r.}t        d$|        t#        j$                  d%       Y d }~d }~ww xY w# 1 sw Y   xY w# t         $ r}t        dR|        Y d }~d }~ww xY w)TNu7   SPY Crash-test 30 jours — backtest complet Market SPY)descriptionformatter_classz--daysr'  u*   Nombre de jours d'historique (défaut: 30))typedefaulthelpz--pairsu%   Top N paires par volume (défaut: 30)z
--no-cache
store_trueu'   Forcer re-téléchargement des données)actionr  z
--optimizeu*   Rechercher les paramètres optimaux (lent)z	--verboseu!   Afficher tous les trades simulész
--positionr=   u&   Taille de position USDT (défaut: 500)u   
════════════════════════════════════════════════════════════════════u;     🧪 SPY CRASH-TEST 30 JOURS — Market Spy Backtester v2r  z  Historique  : z joursz  Paires      : Top z (volume 24h)z  Position    : z USDTz  Optimisation: z
OUI (lent)NONz  Cache       : u   DÉSACTIVÉu   ACTIVÉrB   u'     ❌ Impossible d'obtenir les paires: ru   )r   u     ❌ Aucune donnée chargée.c              3   2   K   | ]  }t        |        y wr   r   r   s     rO   r   zmain.<locals>.<genexpr>  s     2qCF2r   u   
  ✅ Données: r   r   z candles 1m
u7     ⏳ Backtest ANCIENS paramètres (avant FIX 15/03)...)r\  u   📦 ANCIENS PARAMÈTRES — z
 trades / u	    rejetésu3   

  ⏳ Backtest ACTUELS paramètres (FIX 15/03)...u(   ✅ PARAMÈTRES ACTUELS (FIX 15/03) — r  u   
  ⏳ Backtest OPTIMISÉ...u    🏆 PARAMÈTRES OPTIMISÉS — rS  re  r   z
  u7     🔍 ANALYSE DES FILTRES (raisons de rejet FIX 15/03)r  r  c                     | d    S )Nru   r   rM   s    rO   rP   zmain.<locals>.<lambda>  s    AaD5 rQ   r  z   z>20rr   r  u    surges filtrésu     Total filtré par FIX 15/03: z surges (dont c              3   f   K   | ])  }t        d  |j                  dg       D              s&d + yw)c              3   0   K   | ]  }d |v xs d|v   yw)wickretraceNr   )r   rN   s     rO   r   z!main.<locals>.<genexpr>.<genexpr>   s"     4qWXVq[5RIQRN5R4qs   rS  ru   N)anyrL   )r   r   s     rO   r   zmain.<locals>.<genexpr>   s-     r4q\]\a\abkmo\p4q1q1rs   '11u    anti-mèches))r   pairsrB   rg   )generated_atconfigr  current	optimizedwr	   )r   r*   )indentr  u%   
  💾 Rapport JSON sauvegardé → u%   
  ⚠️ Erreur sauvegarde rapport: u     ✅ Crash-test terminé.)/argparseArgumentParserRawTextHelpFormatteradd_argumentry   rK   
parse_argsrW   r   r  positionoptimizeno_cachePARAMS_CURRENT
PARAMS_OLDrh   r   sysexitr   r   r   r`   rc  r\  r  r  r  r  r   rL   r}  r  rY  r   now	isoformatr|  keysr   REPORT_FILEr[   r   strr   r   r   )parserargsrg   r   r   	n_candles
old_tradesold_rej	old_stats
cur_tradescur_rej	cur_stats	opt_stats
opt_tradesopt_rej
opt_paramsr  cur_reject_typesr   rN  rv  reportr   s                          rO   mainr
    su   $$M 55F 3"J  L
	3"D  F
\F  H
\I  K
\@  B
5#E  GD	
	
GH	*	TYYKv
./	 M
:;	T]]O5
12	T]]\F
GH	dmm]K
LM	G '+mmN?#&*mmJ!$**- GTYYdmm:KLD./2DKKM22I	s4ykYqM
OP 

CD&tZNJj)I
'J'8
3w<.PYZGY
 

AB&t^T\\RJj)I
23z?2C:cRYl^[deGY IJG}}d#6t^#L 
L-.*4T\\R
G!*-	.s:.?z#g,W`aJ	
 Y	95 #3' 8eeIr* 	8FV\\#.q12a72	88 XJ GH8*o#$4$:$:$<)8: 	AMFECs|2eAY.>?@	A 	/G~ >rgrrs  tBC 	D
 !002 II JJ!]] -	
 
F '{<+sW5 	8IIfa37	86rww7G7G7T6UVW 
Bxj/	
&'	XJb/w  7s;<f	8 	8  <6qc:;;<sH   U V V
17V 	V#VV
VV 	V7V22V7__main__)r'  )T)Fr   )4__doc__r   r  r[   r   r   r  mathrX   numpyr   r   r   collectionsr   stdoutr   lowerreconfigurestderrr   dirnameabspath__file__
SCRIPT_DIRra   r   r  rY   r]   r^   _TRAIL_TIERSr  rY  r  r   rh   r   r   r   r  r%  rG  r1  rc  r  r  r  r  r  r
  __name__)r   r   s   00rO   <module>r     s  0 3 2 2 2   ( # ::3::..446:VVJJGI>JJGI>ggoobggooh78
ggll:'<=
ggll:'>?'F&		  	
          !" #$ %( )* +. /0 &=D  .3356tq!ad6
 
   .,(V6z^Jkdb`J&CT+dB'J2,r ;%DD zF w 7s   5G#