
    iF                        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mZmZ ddl	m
Z
 ej                  j                  ej                  j                  e            Zej                  j!                  ed      Zej                  j!                  ed      Zg dg dg d	g d
g dg dg ddZddddddddZddddddddZd"dZd Zd Zd#dZd Zd Zd Zd  Zed!k(  r e       \  ZZ yy)$u-  
🧪 SPY BACKTESTER - Simule différents paramètres sur les trades récents
============================================================================
Télécharge les klines 1m réels de Binance pour chaque trade historique
et simule la stratégie de sortie avec différents jeux de paramètres.
    N)datetime	timedelta)productzespion_history.jsonzspy_backtest_cache.json)      ?皙?      ?g333333?      ?)r	          @      @      @)r   r         @)r   r	   r
   r   )r   r   r   )         )   <   x      )
trail_base
trail_widetrail_largehard_sltrail_activationmomentum_candlesmax_holdr   r   r   r	   r   r   r   r   r   -   c                    	 t        j                  |      }t        |j                         dz        dz
  }||dz  dz  z   }d}g }|}||k  r| d|t	        |dz   |      dd}	t        j                  ||	d	
      }
|
j                  dk7  r	 |S |
j                         }|s	 |S |j                  |       |d   d   dz   }t        j                  d       ||k  r|S # t        $ r}t        d|  d|        g cY d}~S d}~ww xY w)uJ   Télécharge les klines 1min depuis l'entrée du trade + X minutes après.  `  r   z%https://api.binance.com/api/v3/klines1mii  )symbolinterval	startTimeendTimelimit
   )paramstimeout   r   g333333?u     ❌ Erreur fetch z: N)r   fromisoformatint	timestampminrequestsgetstatus_codejsonextendtimesleep	Exceptionprint)r!   entry_time_strlookforward_minutesentry_dtstart_msend_msurl
all_klinescurrent_startr'   rklineses                ./spy_backtest.pyfetch_klines_for_traderD   @   s3   )).9x))+d23e;025<=5
 f$  *}{:FCF S<A}}#  VVXF
 	 f%"2JqME1MJJt! f$$  #F82aS12	s0   BC C  6C C 	C?"C:4C?:C?c           	      l   i }t         j                  j                  t              r/	 t	        t        d      5 }t        j                  |      }ddd       d}| D ]n  }|d    d|d    }||vst        d|d    d|d   dd	  d
       t        |d   |d         }|r |||<   d}t        dt        |       d       dt        d       p |rGt	        t        d      5 }t        j                  ||       ddd       t        dt        |       d       |S # 1 sw Y   xY w#  i }Y xY w# 1 sw Y   8xY w)u6   Charge les klines depuis le cache ou les télécharge.r@   NFr!   _
entry_timeu"     📡 Téléchargement klines 1m z (   z)...Tu	        ✅ u    klines récupéréesu        ⚠️ Pas de klineswu     💾 Cache sauvegardé (z trades))ospathexistsKLINES_CACHEopenr2   loadr7   rD   lendump)tradescachefupdatedtradekeyrA   s          rC   load_or_fetch_klinesrX   c   sP   E	ww~~l#	lC( %A		!%
 G 
4x!5#6"78e6uX6Gr%P\J]^a_aJbIccghi+E(OU<=PQF#c
	#f+.CDE13
4 ,$ 	 IIeQ	 *3u:,h?@L/% %	E 	  	 s.   D! DD! D*DD! !D'*D3c                 2   t        j                  |      }t        |j                         dz        }d}d}d}|}	| D ]*  }
|
d   }||k  rt	        |
d         }t	        |
d         }t	        |
d         }||z
  dz  }||z
  |z  d	z  }||z
  |z  d	z  }||z
  |z  d	z  }t        ||      }||d
    k  rt        |d
    |      }|||dfc S ||d   k\  rd}|rW|dkD  rR|dk\  rd}n3|dk\  r|j                  dd      }n|dk\  r|d   }n|dk\  r|d   }n|d   }||z
  }||k\  r||z
  }|||dfc S ||d   k\  r|dk  r|||dfc S ||	k  r|dz  }nd}||d   k\  r|dk  r|||dfc S |}	- | rt	        | d   d         n|}||z
  |z  d	z  }||t        |       dfS ) u~   
    Simule la stratégie de sortie sur des klines 1m réels.
    Retourne: (pnl_pct, max_pnl, hold_minutes, exit_reason)
    r   g        Fr   r      r   r   d   r   HARD_SLr   Tg      .@g      @g      $@trail_ultrar   r   r
   r   r   TRAILINGr   r   MAX_HOLD   r   MOMENTUM_EXITr*   END_OF_DATA)r   r+   r,   r-   floatmaxr0   rP   )rA   entry_pricer8   r'   r:   entry_msmax_pnltrailing_activatedconsecutive_drops
prev_closeklinekline_time_msclosehighlowelapsed_min	pnl_closepnl_highpnl_lowactual_exit	trail_pctdrop_from_maxexit_pnl
last_close	final_pnls                            rC   simulate_exitrz      s_   
 %%n5H8%%'$./HGJ ?a8#eAhU1XE!Ho$x/58 k)[8C?	K';6#=+%4; gx( vi(((vi00)<Ki?? f/00!%'A+$	D"JJ}c:	C"=1	C"<0	"<0	#i/M	)"Y.+BB &,,3 ';
BB :" !'9 ::3 ';GG
?D *0vbz!}%[J{*k9S@Igs6{M99    c                 f   g }| D ]  }|d    d|d    }|j                  |g       }|s%t        ||d   |d   |      \  }}	}
}|j                  |d   |d   |j                  dd      t        |d      t        |	d      t        |
d      |t        |	|z
  d      |j                  d	d      d
	        |S )u0   Exécute le backtest pour un jeu de paramètres.r!   rF   rG   re   surge_strengthr   rZ   r`   pnl_pct)	r!   rG   r}   r~   rg   hold_minexit_reasonmissed_gainoriginal_pnl)r0   rz   appendround)rR   klines_cacher'   labelresultsrV   rW   rA   pnlrg   holdreasons               rC   run_backtestr      s    G x!5#6"78!!#r*%2E-(%*=v&
"WdF 	Ho-#ii(8!<S!}Wa(dA! 32!IIi3

 
	* Nr{   c                 <   | sdddddS | D cg c]  }|d   	 }}t        |      }t        d |D              }t        |      |z
  }t        j                  |      }|rt	        |      nd}t        j                  | D cg c]  }|d   	 c}      }|dz  |t        |      z  dz  z   |d	z  z
  |d
z  z   }	t        |d      t        |d      t        |t        |      z  dz  d      ||t        |d      t        |d      t        |	d      t        |       d	S c c}w c c}w )u4   Score composite pour évaluer un jeu de paramètres.r   )	total_pnlavg_pnlwin_ratescorer~   c              3   ,   K   | ]  }|d kD  s	d  yw)r   r`   N ).0ps     rC   	<genexpr>z score_results.<locals>.<genexpr>   s     (Q!a%q(s   
r   r
   r   r   333333?rZ   r[   r`   )	r   r   r   winslossesmax_dd
avg_missedr   n_trades)sumrP   npmeanr.   r   )
r   r@   pnlsr   r   r   r   max_drawdownmissedr   s
             rC   score_resultsr      s5   1!dKK")*QAiL*D*D	I($((DYFggdmG $3t9!LWW81a&89F 	C#d)q
 	!
3,	 
	 
 9a(!$$T*S0!4a(FA&uaL
 
) + 9s   D>Dc                 ~   t        d       t        d       t        d       t        j                         }i }t        j	                         D ]  \  }}t        d| dt        |       d       d}||   }|D ]{  }|j                         }	||	|<   t        | ||	      }
t        |
      }|d   |kD  rd	nd
}t        d| d|dd|d   dd|d   dd|d   dd|d   d|        |d   |kD  su|d   }|}} ||d||<   t        d| d|         |j	                         D ci c]  \  }}||d    }}}||fS c c}}w )u   
    Recherche intelligente: au lieu de tester TOUTES les combinaisons,
    on teste les paramètres un par un autour des valeurs actuelles.
       
══════════════════════════════════════════════════════════════════════uI   🔬 PHASE 1: Test des paramètres individuels (ancrage = params actuels)   ══════════════════════════════════════════════════════════════════════u   
📊 Test de 'z' (z valeurs)...r   r   u    🏆    =z>5u
    → PnL: r   +.2f% | WR: r   z>5.1f% | Missed: r   .2fz% | Score: >6.2f)best_val
best_scoreu      ✅ Meilleur: r   )r7   CURRENT_PARAMScopy
PARAM_GRIDitemsrP   r   r   )rR   r   baseparam_impact
param_namevaluesr   r   valtest_paramsr   statsmarkerkv	optimizeds                   rC   smart_grid_searchr     s   
 

	
UV	* D L(..0 ;
F CF}LIJ

# 	C))+K&)K
#"6<EG!'*E %g ;WFC
|1SHJu[7I$6O Pz*51eL>QRU=V W!'N51&; < W~
*"7^
	 19
#SZ !*Qxj9:+;0 /;.@.@.BCdaAjM!CICl"" Ds   "D9c                    t        d       t        d       t        d       t        d|d   dz
        |d   |d   dz   gt        d|d   dz
        |d   |d   dz   gt        d	|d
   dz
        |d
   |d
   dz   gd}d}d}t        t        |d   |d   |d
               }t        dt	        |       d       |D ]  \  }}}	|j                         }
t        |d      |
d<   t        |d      |
d<   t        |	d      |
d
<   t        | ||
      }t        |      }|d   |kD  se|d   }|
j                         }|}t        d| d| d|	 d|d   dd|d   dd|d   d        |fS )u   
    PHASE 2: Recherche combinatoire ciblée autour des meilleurs paramètres individuels.
    On ne fait varier que les 3 paramètres les plus impactants.
    r   u@   🎯 PHASE 2: Recherche combinatoire ciblée (top 3 paramètres)r   r   r   r   r   r   r   r   )r   r   r   r   Nz   Testing z combinaisons...
r`   r   u      🏆 NEW BEST: trail=/z sl=u	    → PnL:r   r   z% WR:r   z.0fz% Score:r   )	r7   rd   listr   rP   r   r   r   r   )rR   r   base_params
key_paramsr   
best_combocombostbtwslr   r   r   
best_statss                 rC   targeted_grid_searchr   B  s   
 

	
LM	* 3L 9C ?@+lB[]hiu]vy|]|}3L 9C ?@+lB[]hiu]vy|]|}[3c9:K	<RT_`iTjmpTpqJ JJ'*\2J|4LjYbNcdeF	KF}$6
78 Z
B!&&($)"aLL!$)"aLL!!&r1Iv|[Ag&>J&wJ$))+JJ,RD"T"Yu[GYZ^F__dejkuevwzd{  |D  EJ  KR  ES  TW  DX  Y  ZZ z!!r{   c                  ,
   t        d       t        d       t        d       t        t        dd      5 } t        j                  |       }d d d        t        dt               d       t        d       t        |      }t        d	t        |       d
       t        d       t        d       t        d       t        ||t              }t        |      }t        d|d   dd|d   dd|d    d|d    d	       t        d|d   dd|d   dd|d   dd        t        d!|d"   d       t        d       t        d#       t        d       t        ||t              }t        |      }t        d|d   dd|d   dd|d    d|d    d	       t        d|d   dd|d   dd|d   dd        t        d!|d"   d       t        ||      \  }}t        |||      \  }	}
t        d$       t        d%       t        d       t        |||	      }t        |      }d&d'd(d)d*d(d+d*d(d,d*}d-}t        |       t        |       t        d.d'd(|d   d/d0|d   d/d0|d   d/d        t        d1d'd(|d   d2d0|d   d2d0|d   d2d        t        d3d'd(|d   d/d0|d   d/d0|d   d/d        t        d4d'd(|d   d/d0|d   d/d0|d   d/d        t        d5d'd(|d   d6d0|d   d6d0|d   d6d        t        d7d'd(|d"   d6d(|d"   d6d(|d"   d6       t        d8       t        |       t        |	j                               D ]h  \  }}t        j                  |d9      }d&}t!        |t"        t$        f      r!t!        |t"        t$        f      r||k7  rd:| d;}t        d<|d'd=| |        j t        d>       t        |       t        d?d@d(dAdBd(dCdDd(dEdFd(dGdHd(dIdHd(dJdBdK       t        |       |D ]Z  }|dL   }|dM   }||kD  rdNn||k  rdOndP}t        |dQ   d@d(|dR   dSd0|dTd0|dUd0|dV   dWd0|dX   dYd0|dZ   d[d\|d]    d^|        \ t'        j(                         j+                         t        |      t        |t        ||	||d_	}t,        j.                  j1                  t2        d`      }t        |dad      5 } t        j4                  || dbdcd       d d d        t        de       |	|fS # 1 sw Y   xY w# 1 sw Y   %xY w)fNzF======================================================================u9   🧪 SPY BACKTESTER - Optimisation des paramètres d'exitr@   zutf-8)encodingu   
📋 z trades dans l'historiqueu5   
📡 Chargement des données de prix 1m (Binance)...u      ✅ Klines disponibles pour z tradesr   u9   📦 BENCHMARK: Paramètres ANCIENS (avant modifications)r   z   PnL Total: r   r   r   r   z.1fz% (r   zW/r   zL)z   PnL Moyen: r   z% | Max DD: r   r   r   r   %z
   Score: r   u>   📦 BENCHMARK: Paramètres ACTUELS (après nos modifications)zG
======================================================================u7   🏆 RÉSULTAT FINAL - Comparaison des 3 configurationsr   z>20z | ANCIENSz>12ACTUELSu
   OPTIMISÉSzA-----------------------------------------------------------------z	PnL Totalz>+11.2fz% | zWin Ratez>11.1fz	PnL MoyenzMax Drawdownu   Gains Manqués Moyz>11.2fScoreu*   
📊 Paramètres OPTIMISÉS recommandés:?u    ← changé (était )r   z = u$   
📋 Détail par trade (OPTIMISÉ):Symbolez>14Surgez>6zPnL Realz>9zPnL Simz>8MaxPnLz>7MissedHoldz | Exitr   r~   u   ✅u   ❌u   ➖r!   r}   z>+5.1fz>+8.2fz>+7.2frg   z>+6.2fr   r   r   z>5.0fzm | r    )	r-   trades_tested
old_params	old_statscurrent_paramscurrent_statsoptimized_paramsoptimized_statsdetail_resultszspy_backtest_results.jsonrI   rZ   F)indentensure_asciiu<   
💾 Résultats sauvegardés dans spy_backtest_results.json)r7   rN   HISTORY_FILEr2   rO   rP   rX   r   
OLD_PARAMSr   r   r   r   sortedr   r0   
isinstancer,   rc   r   now	isoformatrJ   rK   join
SCRIPT_DIRrQ   )rT   rR   r   old_resultsr   current_resultsr   optimized_p1impactsbest_paramsr   final_resultsfinal_statsheaderssepr   r   	current_vdiffr@   origsimbetteroutputoutput_files                            rC   mainr   j  s   	(O	
EF	(O 
lC'	2 a1 
GCK= 9
:; 

BC'/L	+C,=+>g
FG 

	
EF	*v|Z@Kk*I	N9[1$7x	*@UVY?ZZ]^ghn^o]pprs|  ~F  tG  sH  HJ  K  L	N9Y/5\)HBUVYAZZfgpq}g~  @C  gD  DE  F  G	Jy)#.
/0 

	
JK	*"6<HO!/2M	N=5d;8MR\D]^aCbbefstzf{e||~  @M  NV  @W  X  XZ  [  \	N=3D9mT\F]^aEbbno|  ~J  pK  LO  oP  PQ  R  S	J}W-c2
34 .flCL' 36<VK 
/	
CD	(O {CM.KCIc?#i_CS?QRG
C	'N	#J	[S;!7 @]S^E_`gDhhlmx  zE  nF  GN  mO  OP  Q  R	ZC	* 5f=T-PZB[\bAccghst~h  AG  hH  HI  J  K	[S9!5g >d=QZC[\cBddhitu~i  AH  iI  IJ  K  L	^C Ih$7#@]S[E\]dDeeijuv~j  AH  jI  IJ  K  L	!#&c)L*A&)Im\hNijpMqqu  wB  CO  wP  QW  vX  XY  Z  [	WSMYw/7s=;QRX:YY\]hip]qrx\y
z{	79	#J{((*+ )1"&&q#.	a#u&:i#u+NI~.yk;Ac7#aS'() 
13	#J	YsO3wrl#j_C	"~SQYZ\P]]`aijl`mmpqwxzp{  |C  D  E	#J Q 	l*3:%58S!Q'7%8$@T&MQUVYZ`Uaaefghqfrsyezz~  @A  BO  @P  QV  W  W[  \]  ^h  \i  jo  [p  pt  uv  wD  uE  tF  FG  HN  GO  P  	Q	Q \\^--/V (&'&'
F '',,z+FGK	k3	1 ;Q		&!AE:;	IK##{ r; ;s   S=T
=T
T__main__)i,  )r   )!__doc__r2   rJ   r4   r/   numpyr   r   r   	itertoolsr   rK   dirnameabspath__file__r   r   r   rM   r   r   r   rD   rX   rz   r   r   r   r   r   __name__r   r   r   r{   rC   <module>r     s    	    ( WW__RWW__X67
ww||J(=>ww||J(AB ,&"#'!"
&  
 F>Q:h8#L'#T%"Pc$L zK r{   