
    i              
       	   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ZddlmZ ddlmZ ddlmZ ddlmZmZ ddlmZmZmZmZ ddlmZmZmZ dd	lmZ dd
lm Z m!Z! 	 ejD                  dk(  rbddl#Z# e#jH                  ejJ                  jL                  ddd      e_%         e#jH                  ejN                  jL                  ddd      e_'        dejP                  d<   ejR                  jU                  ejR                  jW                  ejR                  jY                  e-            d      Z. ej^                  ej`                  dd ejb                  ejJ                         ejd                  e.d      g        ejf                  e4      Z5dZ6ejR                  jW                  ejR                  jY                  e-            Z7 ejp                  e7       ejD                  dk(  rejR                  jU                  e7ddd      Z9nejR                  jU                  e7ddd      Z9ejR                  ju                  e9      sejv                  Z9	 ddl<m=Z=m>Z> dZ?	 dd lBmCZCmDZD dZEe5j                  d!       	 dd#lHmIZImJZJ dZKe5j                  d$        ee7      ZL ed&d'(      ZM eeLeM      ZN ee7      ZO ee7      ZP ee7      ZQ ee7eOePeQeN      ZReLj                         ZTe5j                  d)       e5j                  d*e6        e5j                  d+e7        e5j                  d,e6 d-       e5j                  d.eTdd/  d0       e5j                  d1        G d2 d3ej                  j                        ZWd4 ZXd5 ZYd6 ZZd7 Z[d8e\d9e\d:e]d;e^fd<Z_d= Z`d> Zad? Zbe4d@k(  rddlcZcdA Zd ej                  edddBC      Zfefj                           ej                  eYdD      Zhehj                           ej                  e`dD      Zieij                           ej                  ebdD      Zjejj                           ej                  eadD      Zkekj                           eX        yy#  Y xY w# e@$ r dZ?e5j                  d       Y +w xY w# e@$ r!ZGdZEe5j                  d"eG        Y dZG[G4dZG[Gww xY w# e@$ r!ZGdZKe5j                  d%eG        Y dZG[GAdZG[Gww xY w)Eu  
Dashboard API Server v2.0
==========================
Version améliorée avec architecture modulaire, sécurité renforcée et async/await

Améliorations:
- Architecture modulaire (séparation des responsabilités)
- Validation des inputs avec Pydantic
- Rate limiting et authentification renforcée
- Opérations async pour meilleure performance
- Gestion d'erreurs robuste
- Code testable
    N)datetime)urlparse)Optional)TradingConfigOptimizationRequest)TokenManagerRateLimiterAuthMiddlewareSecurityValidator)ConfigServiceTradingService
BotService)RouteHandler)load_json_filesave_json_filewin32utf-8replaceT)encodingerrorsline_buffering1PYTHONUNBUFFEREDzdashboard_log.txtz1%(asctime)s [%(levelname)s] %(name)s: %(message)sz%H:%M:%Sr   )levelformatdatefmthandlersi"  .venvScriptsz
python.exebinpython3)get_fetcherCryptoDataFetcherFz!crypto_data_fetcher not available)get_ai_predictorget_surveillance_serviceu   ✅ Module AI Predictor chargézAI Predictor non disponible: )get_realtime_servicestart_realtime_serviceu   ✅ Module AI Realtime chargézAI Realtime non disponible: i  <   )max_requestswindow_secondszDashboard API Server v2.0zPort: zDirectory: zURL: http://localhost:/dashboard.htmlzAPI Token:    z*... (set DASHBOARD_API_TOKEN to customize)zPress Ctrl+C to stopc                        e Zd ZdZdZ fdZ fdZd ZdefdZ	d Z
defd	Z fd
Zd Zddededee   fdZdefdZdefdZdefdZd Z xZS )DashboardAPIHandlerz0Handler HTTP moderne avec architecture modulaire   c                 B    t               | _        t        |   |i | y N)r   	validatorsuper__init__)selfargskwargs	__class__s      dashboard_api_server.pyr5   zDashboardAPIHandler.__init__   s    *,$)&)    c                 B   | j                  dd       | j                  dd       | j                  dd       | j                  dd       | j                  d	d
       | j                  dd       | j                  dd       | j                  dd       t        | 	          y)u"   Ajouter headers CORS et sécuritézAccess-Control-Allow-Origin*zAccess-Control-Allow-MethodszGET, POST, OPTIONSzAccess-Control-Allow-HeaderszContent-Type, AuthorizationCache-Controlz#no-store, no-cache, must-revalidatezX-Content-Type-OptionsnosniffzX-Frame-OptionsDENY
Connection
keep-alivez
Keep-Aliveztimeout=30, max=100N)send_headerr4   end_headers)r6   r9   s    r:   rD   zDashboardAPIHandler.end_headers   s    6<79MN79VW*OP19=*F3|4'<=r;   c                 F    | j                  d       | j                          y)u   Gérer preflight CORS   N)send_responserD   )r6   s    r:   
do_OPTIONSzDashboardAPIHandler.do_OPTIONS   s    3r;   returnc                     | j                   d   }| j                  j                         D ci c]  \  }}||
 }}}t        j	                  ||      \  }}|st
        j                  d| d|        |S c c}}w )u   Vérifier l'authentificationr   zUnauthorized request from : )client_addressheadersitemsauth_middleware
check_authloggerwarning)r6   	client_ipkvrM   
authorizederrors          r:   rP   zDashboardAPIHandler.check_auth   sy    ''*	$(LL$6$6$89DAq1a499+66w	J
ENN7	{"UGLM :s   A5c                     d}| j                  d       | j                  dd       | j                  dd       | j                  dt        |             | j                          | j                  j                  |       y)	uZ   Envoyer une réponse 401 avec header WWW-Authenticate pour déclencher le popup navigateurs   Authentication requiredi  zWWW-Authenticatez4Basic realm="Trading Bot Dashboard", charset="UTF-8"Content-Typeztext/plain; charset=utf-8Content-LengthN)rG   rC   lenrD   wfilewrite)r6   bodys     r:   send_auth_requiredz&DashboardAPIHandler.send_auth_required   sk    )3+-cd)DE)3t95

r;   c                 J    | j                   d   }t        j                  |      S )u   Vérifier le rate limitr   )rL   rO   check_rate_limit)r6   rS   s     r:   ra   z$DashboardAPIHandler.check_rate_limit   s#    ''*	//	::r;   c                    	 | j                         \  }}}|s| j                  d|id|       yt        | j                        j                  }t        | j                        j                  }|t
        j                  vr!| j                         s| j                          yddl	m
} |r ||      ni }|dk(  rt        j                  |        y|dk(  rt        j                  |        y|dk(  rt        j                  |        y|d	k(  rt        j                  |        y|d
k(  rt        j!                  |        y|dk(  rt        j#                  |        y|dk(  rt        j%                  |        y|dk(  rt        j'                  |        y|dk(  rt        j)                  |        y|dk(  rt        j+                  |        y|dk(  rt        j-                  |        y|dk(  rt        j/                  |        y|dk(  rt        j1                  | |       y|dk(  rt        j3                  |        y|dk(  rt        j5                  |        y|dk(  rt        j7                  |        y|dk(  rt        j9                  | |       y|dk(  rt        j;                  |        y|dk(  rt        j=                  | |       y|dk(  rt        j?                  | |       y|dk(  rt        jA                  | |       y|dk(  rt        jC                  | |       y|dk(  rt        jE                  | |       y|dk(  rt        jG                  |        y|jI                  d      rt        jK                  |        y|dk(  rt        jM                  |        y|d k(  rt        jO                  |        y|d!k(  rt        jQ                  |        y|d"k(  rt        jS                  |        y|d#k(  rt        jU                  |        y|d$k(  rt        jW                  | |       y|d%k(  rt        jY                  |        y|d&k(  rt        j[                  |        y|d'k(  rt        j]                  |        y|d(k(  rt        j_                  |        y|d)k(  rt        ja                  |        y|d*k(  rt        jc                  |        y|d+k(  rt        je                  |        y|d,k(  rt        jg                  |        y|d-k(  r| ji                  d.i        y|d/k(  r| ji                  d0g        ytj        	|           y# tn        tp        tr        f$ r Y ytt        $ rD}tv        jy                  d1|        	 | j                  dd2id3       n#  Y nxY wY d}~yY d}~yd}~ww xY w)4u   Gérer les requêtes GETrW     Nr   )parse_qsz/api/healthz/api/get-configz/api/get-ia-criteriaz/api/rotation-statusz/api/cycle-statusz/api/get-profilesz/api/bot-analysisz/api/crypto-dataz/api/crypto-summaryz/api/crypto-refreshz/api/opportunitiesz/api/ai-surveillancez/api/ai-watchlistz/api/ai-training-infoz/api/auto-updater-statusz/api/market-regimez/api/trade-analysisz/api/get-sltp-configz/api/analysis-logsz/api/positions-livez/api/ai-self-optimizerz/api/technical-analysisz/api/market-analysisz/api/watchdog-statusz/api/bot-logsz/api/monitor-statusz/api/maintenance/healthz/api/maintenance/binance-syncz/api/binance-balancez /api/maintenance/binance-accountz/api/patterns-performancez/api/spy-dataz/api/spy-statusz/api/ia-statusz/api/mobile-summaryz/api/gestion-projectionsz/api/deep-spy-analysisz/api/trend-risk-ratioz/api/crypto-newsz/positions.jsonzpositions.jsonz/trade_history.jsonztrade_history.jsonzGET error: Internal server error  )=ra   send_json_responser   pathqueryr
   PUBLIC_PATHSrP   r_   urllib.parserd   route_handlerhandle_healthhandle_get_confighandle_get_ia_criteriahandle_get_rotation_statushandle_cycle_statushandle_get_profileshandle_bot_analysishandle_crypto_datahandle_crypto_summaryhandle_crypto_refreshhandle_opportunitieshandle_ai_surveillancehandle_ai_watchlisthandle_ai_training_infohandle_auto_updater_statushandle_market_regimehandle_trade_analysishandle_get_sltp_confighandle_analysis_logshandle_positions_livehandle_ai_self_optimizerhandle_technical_analysishandle_market_analysishandle_watchdog_status
startswithhandle_bot_logshandle_monitor_statushandle_maintenance_healthhandle_binance_synchandle_binance_balancehandle_binance_account_detailhandle_patterns_performancehandle_spy_datahandle_spy_statushandle_ia_statushandle_mobile_summaryhandle_gestion_projectionshandle_deep_spy_analysishandle_trend_risk_ratiohandle_crypto_newsserve_json_filer4   do_GETConnectionAbortedErrorConnectionResetErrorBrokenPipeError	ExceptionrQ   rW   )
r6   allowedrW   retry_afterrh   ri   rd   query_paramser9   s
            r:   r   zDashboardAPIHandler.do_GET   s   r	*.*?*?*A'GUK''%(8#{KDII&++DTYY'--E >666(++- ..38E?L }$++D1**//5//44T://88>,,11$7,,11$7,,11$7++006..33D9..33D9--2248//44T:,,11$E0055d;3388>--2248..33D,G//44T:--224F..33D,G1166t\J2277lK//44T<H//44T:1--d3..33D92277=8811$7//44T:;;;;DA4499$M(--d3**//5))..t4..33D93388>1166t<0055d;++006**$$%5r:..$$%92>  &(<oN 	 	LL;qc*+''2I(JCP Q	s7  +T" A0T"  ,T" T" (T" T" T" 9T" T" /T" 
T" %T"  T" T" 6T" T" -T" T" #T" ?T" T" 6T" T" .T" 
T" &T" &T" (T" T" T" 9T" T" /T" T" &T" T" T" 7T" T" -T" T" #T" ;T" T" "V8V U?U.-U?.U20U??Vc                    	 | j                         \  }}}|s| j                  d|id|       yt        | j                        j                  }| j	                         s| j                          yt        | j                  j                  dd            }|dkD  r*| j                  j                  |      j                  d      nd}	 |rt        j                  |      ni }|dk(  rt         j#                  | |       y|dk(  rt         j%                  | |       y|dk(  rt         j'                  | |       y|dk(  rt         j)                  | |       y|dk(  r| j+                  |       y|dk(  rt         j-                  | |       y|dk(  rt         j/                  | |       y|dk(  rt         j1                  | |       y|dk(  rt         j3                  | |       y|dk(  rt         j5                  | |       y|dk(  rt         j7                  | |       y|dk(  rt         j9                  | |       y|dk(  rt         j;                  | |       y|dk(  rt         j=                  |        y|dk(  rt         j?                  |        y|dk(  rt         jA                  | |       y|dk(  rt         jC                  | |       y| j                  ddid       y# t        j                  $ r+}| j                  dd	t        |       d
d       Y d}~yd}~ww xY w# tD        tF        tH        f$ r Y ytJ        $ rD}tL        jO                  d|        	 | j                  dd id!       n#  Y nxY wY d}~yY d}~yd}~ww xY w)"u   Gérer les requêtes POSTrW   rc   NrZ   r   r   z{}FzInvalid JSON: successrW     z/api/apply-configz/api/save-ia-criteriaz/api/execute-rotationz/api/toggle-rotationz/api/run-optimizationz/api/update-settingsz/api/force-closez/api/update-positions-sltpz/api/update-sltp-configz/api/sell-allz/api/reset-dashboardz/api/restart-botz/api/save-watchlistz/api/maintenance/explain-syncz/api/maintenance/fix-syncz /api/maintenance/binance-cleanupz/api/spy-scanzUnknown endpoint  zPOST error: re   rf   )(ra   rg   r   rh   rP   r_   intrM   getrfilereaddecodejsonloadsJSONDecodeErrorstrrl   handle_apply_confighandle_save_ia_criteriahandle_execute_rotationhandle_toggle_rotationhandle_run_optimizationhandle_update_settingshandle_force_closehandle_update_positions_sltphandle_update_sltp_confighandle_sell_allhandle_reset_dashboardhandle_restart_bothandle_save_watchlisthandle_explain_synchandle_fix_synchandle_binance_cleanuphandle_spy_scanr   r   r   r   rQ   rW   )	r6   r   rW   r   rh   content_lengthr^   datar   s	            r:   do_POSTzDashboardAPIHandler.do_POST2  s+   H	*.*?*?*A'GUK''%(8#{KDII&++D ??$'') !!1!12BA!FGNFTWXFX4::??>299'B^bD+/tzz$'R **11$=0055dDA0055dDA//44T4@00,,T2//44T4@++00t<55::4F2277dC(--dD9//44T4@++00t<..33D$?8811$744--d3;;44T4@(--dD9''2D(EsKW '' ''$-c!fX6)  Z '(<oN 	 	LL<s+,''2I(JCP Q	s   +L	 ?L	 .AL	 K L	 :L	 L	 2L	 L	 %L	 L	 L	 9L	 L	 1L	 L	 )L	 L	  L	 ;L	 L	 3L	 L!L<L	 LL	 	M+M+'M& MM&MM&&M+r   statusr   c                    	 t        j                  |d      j                  d      }| j                  |       | j	                  dd       | j	                  dt        |             |r| j	                  dt        |             | j                          | j                  j                  |       y# t        t        t        f$ r Y yw xY w)	u   Envoyer une réponse JSONF)ensure_asciir   rY   application/json; charset=utf-8rZ   zRetry-AfterN)r   dumpsencoderG   rC   r[   r   rD   r\   r]   r   r   r   )r6   r   r   r   responses        r:   rg   z&DashboardAPIHandler.send_json_response~  s    	zz$U;BB7KHv&^-NO-s8}=  K0@AJJX&&(<oN 		s   B,B/ /CCfilenamec                 Z   | j                   j                  |      s| j                  ddid       yt        j                  j                  t        |      }	 t        j                  j                  |      st        ||       t        |dd      5 }|j                         }ddd       | j                  d       | j                  d	d
       | j                  dt        j                  d                   | j                          | j                   j#                  |j                  d             y# 1 sw Y   xY w# t$        t&        t(        f$ r Y yt*        $ rP}t,        j/                  d| d|        	 | j                  dt1        |      id       n#  Y nxY wY d}~yY d}~yd}~ww xY w)zServir un fichier JSONrW   zInvalid filenamer   Nrr   r   rF   rY   r   rZ   zError serving rK   rf   )r3   is_safe_filenamerg   osrh   join
SCRIPT_DIRexistsr   openr   rG   rC   r[   r   rD   r\   r]   r   r   r   r   rQ   rR   r   )r6   r   default_contentfilepathfcontentr   s          r:   r   z#DashboardAPIHandler.serve_json_file  sd    ~~..x8##W.@$A3G77<<
H5	77>>(+x9hg6 #!&&(# s#^-NO-s7>>'3J/KLJJW^^G45# # '(<oN 	 	NN^H:Rs;<''#a&(93? @	sO   9D< D0 BD< 0D95D< <F*F*F%6FF%FF%%F*c                     	 t        dji |}t        j                  d|j                   dt	        |j
                         d       t        j                  j                  t        d      }t        j                  j                  |      s| j                  dddd       y	| j                  d
       | j                  dd       | j                  dd       | j                  dd       | j                          ddddd}|j                  |j                  d      }t	        |j
                        dk\  rd}nTt	        |j
                        dk\  rd}n9dj                  |j
                  D cg c]  }|j!                  dd       c}      }t"        |d|d|dd d!d"g
| j%                  d#d$d%|j                  j'                          d&       | j%                  d'd(d)d*       d+d	l}|j+                         d,t,        d-t.        fd.fd/}	t1        j2                  |	0      }
|
j5                          d+d	l}d1}|j7                         }d2}|j7                         }|
j9                         r|j7                         |z
  |k  r	 j                  d34      }|d5   d'k(  r>t;        ||j                  d'|            }| j%                  |       |j7                         }nC|d5   d#k(  r| j%                  |       n)|d5   d6k(  rnG|d5   d7k(  r| j%                  d#d7|d8   d&       |
j9                         r|j7                         |z
  |k  r|
j                  d(4       | j%                  d'd=d>d*       t        j                  j                  t        d?      }|j>                  xs i }d@dAdBddC}t        j                  j                  |      r	 tA        |      }|rdD|v r|dD   }|j                  dEdF      |j                  dGdH      |j                  dIdJ      |j                  dKdL      |j                  dMdN      |j                  dOdP      |j                  dQdR      |j                  dSdT      |j                  dUdV      d9dW
}dX|v rL|dX   }|j                  dYd@      |j                  dZdA      |j                  d[dB      |j                  d\d      dC}| j%                  d^|d_   |d`   |da   |db   |dcdd       t        j                  de       y	c c}w # |j<                  $ rI |j7                         |z
  d9kD  r/|d:k  r*|d;z  }| j%                  d'|d<d*       |j7                         }Y Ew xY w# tB        $ r"}t        jE                  d]|        Y d	}~d	}~ww xY w# tF        $ r+}| j                  ddft-        |       ddg       Y d	}~y	d	}~wtB        $ r@}t        jE                  dh|        | j                  dt-        |      ddi       Y d	}~y	d	}~ww xY w)ku   
        Endpoint d'optimisation avec SSE (Server-Sent Events)
        Gardé ici car nécessite accès direct au wfile pour streaming
        zOptimization: mode=z, z symbolszai_optimizer.pyFzai_optimizer.py not foundr   r   NrF   rY   ztext/event-streamr>   zno-cacherA   rB   backtestgridgeneticfull)quickr   r   r   2   all   top25,USDT z--modez	--symbolsz	--candles2000z
--interval1hloginfozMode: typer   messageprogress   zStarting...r   r   r   r   linerI   c                    g }| j                         } | r"| j                  d      s| j                  d      r|S d } ||       }d| v r!d| j                         v sd| v r|j                  ddd	| d
       |S d| j                         v r,d| j                         v r|j                  ddd| d
       |S d| j                         v rEd| j                         v sd| v r/|j                  ddd| d
       |j                  dddd       |S d| v sd| j                         v r|j                  ddd| d
       |S d| j                         v r|j                  ddd| d
       |S d| v r/|j                  ddd| d
       |j                  dddd       |S d | v rd!| j                         v sd"| j                         v r|j                  ddd#| d
       |S d$| j                         v sd%| j                         v r|j                  dd&d'| d
       |S |j                  ddd(| d
       |S d)| v r|j                  ddd*| d
       |S d+| v r|j                  ddd,| d
       |S d-| v r|j                  ddd.| d
       |S d/| v r|j                  ddd| d
       |S d0| j                         v rSd1| j                         v sd| j                         v r/|j                  ddd| d
       |j                  dd2d3d       |S d4| v sd5| v r3d6| v r/|j                  ddd7| d
       |j                  dd8d9d       |S d:| v rd;| j                         v sd<| j                         v r/|j                  ddd=| d
       |j                  dd>d?d       |S d@| j                         v sd| j                         v r|j                  dddA| d
       |S dB| j                         v sdC| j                         v r/|j                  dddD| d
       |j                  ddEdFd       |S |j                  ddd| d
       |S dG| v sdH| j	                         v r/|j                  dddI| d
       |j                  ddJdKd       |S dB| j                         v sdC| j                         v r|j                  dddD| d
       |S dL| j                         v s$dM| j                         v sdN| j                         v r|j                  ddd| d
       |S dO| j                         v r>dP| j                         v sdQ| j                         v r|j                  dddR| d
       |S dS| j                         v r,t        dT | D              r|j                  dddI| d
       |S dU| j                         v s$dV| j                         v sdW| j                         v r/|j                  ddd#| d
       |j                  ddXdYd       |S dZ| v s$d[| j                         v sd\| j                         v r|j                  dd[d]|  d
       |S d^| v sd_| v r|j                  dd&d'| d
       |S d`| v sd| j                         v r,da| v r(|j                  ddd.| j                          d
       |S db| v sdc| v sdd| v r|j                  ddd| d
       |S )euA   Parse une ligne de sortie et retourne les messages SSE à envoyer+|c                 p    d| v r#| j                  dd      d   j                         S | j                         S )N]   )splitstrip)ls    r:   extract_contentzbDashboardAPIHandler.handle_run_optimization.<locals>.parse_optimizer_line.<locals>.extract_content  s3    ax wwsAr288::779$r;   z[DB]historical_data
Chargementr   r   u   📂 r   klinesdepuisr   u   📊 cryptosu	   chargées/u   ✅ r      u   Données chargéesr   Gapu   récupérationu   🔄 u	   ajoutéesu   ➕ z[FETCH]u   📡    u   Chargement données...z[CACHE]u   chargévalideu   💾 	incompletu   téléchargementwarnu   ⚠️ u   📦 z[MODE]u   ⚙️ Mode: z
[INTERVAL]u   ⏱️ z	[SYMBOLS]u   🪙 z[DATA]bougieschargeesr0   u   Données prêtesz[GPU]GPUPretu   🚀 #   u	   GPU prêtz[GRID]explorationcombinaisonsu   🔍 (   zExploration GRID...testu   ⏳ meilleurbestu   🏆 P   u   Meilleur trouvé!z[TEST]BACKTESTu   📈 -   zBacktesting...win_ratezwin ratewinrateprofitfactorpnlu   💰 tradesc              3   <   K   | ]  }|j                           y wr2   )isdigit).0cs     r:   	<genexpr>z\DashboardAPIHandler.handle_run_optimization.<locals>.parse_optimizer_line.<locals>.<genexpr>G  s     5Paaiik5Ps   
sauvegardesavedsavingZ   zSauvegarde...z[ERROR]rW   erreuru   ❌ z[WARN]u   ⚠️z	Symboles:zTop:z[OK]u   [✓]u   ✅)r   r   lowerappendupperany)r   messagesr   r   s       r:   parse_optimizer_linezIDashboardAPIHandler.handle_run_optimization.<locals>.parse_optimizer_line  s   zz|ts3ts7K#O%
 *$/ T>(DJJL8LD<P V[\c[dTe(fgH  G "TZZ\1h$**,6N Y^_f^gWh(ijD  C #djjl2tzz|8SWZ^bWb Y]^e]fWg(hi Xl(mn~  } $*:djjl*J V[\c[dTe(fgz  y %

4 Y]^e]fWg(hiv  q $&OOUVRWX_W`Pa$bcOOZRTl$mnl  g $& DJJL0H

4L Y^_f^gWh(ijb  a %

48Jdjjl8Z V]^e]fTg(hi^  [ !V[\c[dTe(fgZ  U %OOUVR_`g_hPi$jkR  O "T)OOUVRYZaYbPc$deL  I !D(OOUVRWX_W`Pa$bcF  C %OOUVRWX_W`Pa$bc@  { $**,.J$**,4NR]aeakakamRmOOUYUYZaYbSc$deOOZRTf$ghv  q _$6T>OOUVRWX_W`Pa$bcOOZRT_$`al  g %$

4$**,8V V[\c[dTe(fg Xm(no`  _  4::</:3M VZ[bZcTd(ef\  [ $tzz|3v7M Y^_f^gWh(ij Xk(lmV  S !V[\c[dTe(fgR  M %tzz|)COOUVRWX_W`Pa$bcOOZRTd$efH  C  4::</6TZZ\3IOOUYUZ[bZcSd$ef@  =  4::</:3MQZ^b^h^h^jQjOOUYUZ[bZcSd$ef:  7 -8tzz|3KuX\XbXbXdOdOOUYUZ[bZcSd$ef4  1 -#5P45P2POOUVRWX_W`Pa$bc.  ) "TZZ\1W

5LPX\`\f\f\hPhOOUYUZ[bZcSd$efOOZRTc$de$   $&'TZZ\*AXQUQ[Q[Q]E]OOUWSWX\W]Q^$_`   %T)9OOUVRYZaYbPc$de   !D(Y$**,-F6UY>OOUVRWX\XbXbXdWePf$gh   t^w$%4-OOUYUYZaYbSc$der;   c                  n   	 t         j                  j                         } d| d<   d| d<   t        j                  t        j
                  t        j                  dt        ddd| 	      }g }t        |j                  j                  d	      D ]F  }|s|j                         }|j                  |        	|      }|D ]  }
j                  |        H |j                          
j                  d
||j                  d       y # t         $ r'}
j                  dt#        |      d       Y d }~y d }~ww xY w)Nr   PYTHONIOENCODINGr   
PYTHONUTF8Tr   r   )stdoutstderrtextcwdbufsizer   r   envr   done)r   outputcoderW   )r   r   )r   environcopy
subprocessPopenPIPESTDOUTr   iterr+  readliner   r#  putwait
returncoder   r   )r0  processr2  r   line_strippedr&  msgr   cmdr'  result_queues           r:   run_optimizerzBDashboardAPIHandler.handle_run_optimization.<locals>.run_optimizera  s   K**//+C.5C*+(+C%(..JOOJ<M<M!z1!(	G  F $W^^%<%<b A 6,0JJLM"MM-8 (<M'JH'/ 6 , 0 0 566 LLN $$fPWPbPb%cd  K $$g#a&%IJJKs   BD A2D 	D4D//D4)target
   i,  g333333?)timeoutr   r1  rW   r      U   r   zCalcul en cours..._   zFinalizing...zoptimization_results.jsong      N@g      ?g      $@)winRateprofitFactortotalPnLr  best_params	stop_lossg      @take_profitg333333@
rsi_period   rsi_oversoldgfffff8@rsi_overboughtgLN@	ema_short   ema_longr   	bb_period   bb_stdg@)
STOP_LOSS_PERCENTTAKE_PROFIT_PERCENT
RSI_PERIODRSI_OVERSOLDRSI_OVERBOUGHT	EMA_SHORTEMA_LONG	BB_PERIODBB_STDREQUIRED_SIGNALSmetricsr  profit_factor	total_pnltotal_tradeszError reading results: resultrK  rL  rM  r  )rK  rL  rM  r  
bestConfig)r   resultszOptimization completedzValidation error: r   zOptimization error: rf    )$r   rQ   r   moder[   symbolsr   rh   r   r   r   rg   rG   rC   rD   r   r   VENV_PYTHON	_send_sser$  queueQueuer   list	threadingThreadstarttimeis_alivemaxEmptycurrentConfigr   r   rW   
ValueError)r6   r   reqoptimizer_pathmode_mapoptimizer_modesymbols_argsrq  rD  threadrw  r   last_progress_timerG  rv  rA  result_filebest_configre  results_dataparamsmr   rB  r'  rC  s                           @@@r:   r   z+DashboardAPIHandler.handle_run_optimization  s   
e	N%--CKK-chhZr#ckk:J9K8TU  WW\\*6GHN77>>.1''$8)   s#^-@A_j9\<8 $$	H &\\#((J?N 3;;2%#S[[!R'%!hhs{{'S!		&"(='ST ^.[VdC NNEFPSPXPXP^P^P`OaGbcdNNJA-XY  ;;=Lv 3 v 4 v pK> %%];FLLN H!%GIIKE//#u)<(G9&**3*7C6{j0#&xX1N#Os+-1YY[*V-s+V.V/TWXaTb'cd //#u)<(G( KKK" NNJB?[\'',,z3NOK++1rK"&Y[\Gww~~k*@#1+#>L#(E!-m!<17K1M39::mS3Q*0**\2*F,2JJ~t,L.4jj9I4.P)/K)C(.

:r(B)/K)D&,jj3&?01' !L0(3'(uuZ'>,-EE/3,G()k4(@&'eeNB&?	# NN &y1$+N$; '
 3%h/"-	 	 KK01o (T@ {{ 9yy{%77!;2 A
]q'rs-1YY[*9R ! @LL#:1#!>??@   	## -c!fX6%    	NLL/s34##A$GMM	Ns   BV "C	V +TC;V  A:T	 :V ; T	 &V BV DU$ ;V V 	AU!V  U!!V $	V-V
V 
VV 	X!WX6XXc                    	 dt        j                  |       d}| j                  j                  |j	                  d             | j                  j                          y# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)u   Envoyer un événement SSEzdata: z

r   zSSE error: N)	r   r   r\   r]   r   flushr   rQ   rW   )r6   r   r   r   s       r:   rp  zDashboardAPIHandler._send_sse  sp    	,tzz$/05GJJW^^G45JJ 	,LL;qc*++	,s   AA   	B)BBc                     |r%t        |      dk\  rt        |d         }d|v sd|v ryt        j                  d|r|d   nd        y)	u'   Log HTTP requests (filtrer les succès)rH  r   200304NzHTTP: r   r   )r[   r   rQ   debug)r6   fmtr7   r   s       r:   log_messagezDashboardAPIHandler.log_message  sH    CINa\F%6/vd1g2678r;   )rF   N)__name__
__module____qualname____doc__rG  r5   rD   rH   boolrP   r_   tuplera   r   r   dictr   r   rg   r   r   r   rp  r  __classcell__)r9   s   @r:   r/   r/      s    :G*

D 
;% ;
tlJXt S XVY]   >jND jNX	,d ,9r;   r/   c                     ddl } ddlm} | j                  j	                  d       G fdd|      }d|_        	 	  |d	t        ft              5 }t        j                  d
       t        j                  d       t        j                  d
       t        j                  d       t        j                  d       t        j                  d       t        j                  d       t        j                  d       t        j                  d       t        j                  d       t        j                  d
       |j                          ddd       # 1 sw Y   xY w# t        $ r t        j                  d       Y yt        $ r}dt        |      v sdt        |      v r3t        j                  dt         d       ddl}|j!                  d       n-t        j#                  d|        ddl}|j!                  d       Y d}~d}~wt$        $ r7}t        j#                  d|        ddl}|j!                  d       Y d}~d}~ww xY w)uP   Lancer le serveur avec gestion d'erreurs - VERSION MULTI-THREADED (pool limité)r   N)ThreadingHTTPServerr   )max_workersc                       e Zd ZdZ fdZy).run_server.<locals>.BoundedThreadingHTTPServeru@   ThreadingHTTPServer avec pool de threads borné (max 20 workers)c                     	 j                  | j                  ||       y # t        $ r& | j                  ||       | j	                  |       Y y w xY wr2   )submitprocess_request_threadr   handle_errorshutdown_request)r6   requestrL   _pools      r:   process_requestz>run_server.<locals>.BoundedThreadingHTTPServer.process_request  sK    /T88'>R /!!'>:%%g./s   ! ,AAN)r  r  r  r  r  )r  s   r:   BoundedThreadingHTTPServerr    s    N	/r;   r  Tr   z<============================================================z6API Server v2.0 running! (Thread pool: max 20 workers)z
Endpoints:z+   GET  /api/get-config       - Read configz,   POST /api/apply-config     - Apply configz0   POST /api/run-optimization - Run optimizationz2   POST /api/sell-all         - Sell all positionsz+   POST /api/restart-bot      - Restart botz.   POST /api/save-watchlist   - Save watchlistz 
Server stopped by user (Ctrl+C)zAddress already in use10048zPort z in use, retrying in 5s...r   z	OSError:    zServer error: )concurrent.futureshttp.serverr  futuresThreadPoolExecutorallow_reuse_addressPORTr/   rQ   r   serve_foreverKeyboardInterruptOSErrorr   rR   rw  sleeprW   r   )
concurrentr  r  httpdr   rw  r  s         @r:   
run_serverr    s   / 11b1AE/%8 / 6:2
	+RJ8KL &PUH%TUH%L)IJJKNOPQIJLMH%##%& & & ! 	KK;< 	'3q61WA5Ftf,FGH

1y_-

1 	LL>!-.JJqMM	sC   E C8E	E EE I	?I	A:HI	-II	c                     t         sy	 ddl} | j                  d       t        d      }t        j                  d       t        j                  |j                                t        |j                  j                  di             }t        j                  d| d	       y# t        $ r"}t        j                  d
|        Y d}~yd}~ww xY w)zInitialiser le cache cryptoNr   r   F)use_testnetzInitializing crypto cache...rn  zCache initialized: z cryptoszCache init error: )CRYPTO_FETCHER_AVAILABLErw  r  r#   rQ   r   asynciorunfetch_all_datar[   cacher   r   rR   )rw  fetchercountr   s       r:   init_crypto_cacher     s    #
1

1%023G**,-GMM%%i45)%9: 1+A3/001s   BB! !	C*CCc            	         ddl } | j                  d       t        j                  j	                  t
        d      }t        j                  j                  |      st        j                  d|        y	 d}d}d}t        j                  d	k(  rXt        j                  t        d
|g||z  |z  t        j                  t        j                  t        j                  dt
               nAt        j                  t        d
|gt        j                  t        j                  t
        d       t        j                  d       y# t         $ r"}t        j                  d|        Y d}~yd}~ww xY w)zLancer le bot de tradingr   Nr   ztrading_bot.pyzBot script not found: i   r-   i   r   z-uT)creationflagsr+  r,  stdinstart_new_sessionr.  r+  r,  r.  r  zTrading bot startedzError starting bot: )rw  r  r   rh   r   r   r   rQ   rR   sysplatformr6  r7  ro  DEVNULLr   r   )rw  
bot_scriptCREATE_NO_WINDOWDETACHED_PROCESSCREATE_NEW_PROCESS_GROUPr   s         r:   start_trading_botr  2  s   JJqMj*:;J77>>*%/
|<=3%%#- <<7"dJ/.1AAD\\!))*2D2D ((D k4<$.$6$6z?Q?Q!+tE 	)* 3-aS1223s   3CD; ;	E&E!!E&c                      ddl } | j                  d       dt         d}t        j	                  d|        t        j                  |       y)z&Ouvrir le dashboard dans le navigateurr   NrH  zhttp://localhost:r,   zOpening browser: )rw  r  r  rQ   r   
webbrowserr   )rw  urls     r:   open_browserr  R  s>    JJqMdV?
3C
KK#C5)*OOCr;   symbolintervallimitrI   c                     ddl }	 d}| ||d}|j                  ||d      }|j                  dk(  r|j                         S g S # t        $ r'}t
        j                  d|  d	|        g cY d}~S d}~ww xY w)
u.   Récupère les klines depuis Binance pour l'IAr   Nz%https://api.binance.com/api/v3/klines)r  r  r  rF  )r  rG  rF   zErreur fetch klines rK   )requestsr   status_coder   r   rQ   rR   )r  r  r  r  r  r  r   r   s           r:   fetch_klines_for_air  [  s}    	5"5I<<FB<?3&==?"	 -fXRs;<	s#   :A A 	A3A.(A3.A3c                     t         st        j                  d       y	 t        j                  j                  t        d      } g }t        j                  j                  |       r<t        | d      5 }t        j                  |      }|j                  dg       }ddd       |sg d}t               }|j                  t               t               }t        |_        |j#                  |       d|_        |j'                          t        j)                  dt+        |       d	       t        j)                  d
       y# 1 sw Y   xY w# t,        $ r"}t        j/                  d|        Y d}~yd}~ww xY w)u&   Démarre le service de surveillance IAu0   ⚠️ Service de surveillance IA non disponibleNzwatchlist.jsonr   rn  )
BTCUSDTETHUSDTBNBUSDTSOLUSDTXRPUSDTDOGEUSDTADAUSDTAVAXUSDTDOTUSDT	MATICUSDTr0   u,   🧠 Service de surveillance IA démarré - z	 symbolesz'   Mode: Polling toutes les 30 secondesu#   Erreur démarrage surveillance IA: )AI_PREDICTOR_AVAILABLErQ   rR   r   rh   r   r   r   r   r   loadr   r%   set_klines_fetcherr  r&   klines_fetcherset_symbolsupdate_intervalrv  r   r[   r   rW   )watchlist_filern  r   r   ai_predictorsurveillancer   s          r:   start_ai_surveillancer  j  s1   !IJ$@j2BC77>>.)nc* 2ayy|((9b12 RG ()''(;< 01&9#  )')$ 	B3w<.PYZ[=?92 2<  @:1#>??@s1   AE /(D9B!E 9E>E 	E0E++E0c                  D   ddl } | j                  d       	 ddl}t        j	                         }d}|j                  ddg      D ]  }	 |j                  d   xs g }dj                  |      j	                         }d|vsd	|vr?|r|d   j	                         nd
}d|v s	d|v s||k(  rb|r7t        j                  d|j                  d    d       |j                          n_d}t        j                  d|j                  d    d       n6t        j                  d|j                  d    d       |j                           |ryt        j                  j                  t        d      }t        j                  j                  |      rt        }	t        j                  j                  t        d      }
t         j"                  dk(  rWt%        |
dd      5 }t'        j(                  |	|gt&        j*                  t&        j,                  z  ||t              }ddd       n7t%        |
dd      5 }t'        j(                  |	|g||t        d      }ddd       t        j                  dj.                   d       t        j                  d       t        j                  d|
        yt        j1                  d       y# |j                  |j                  f$ r Y w xY w# 1 sw Y   xY w# 1 sw Y   xY w# t2        $ r"}t        j5                  d|        Y d}~yd}~ww xY w)uN   S'assure que le Market Spy est en cours d'exécution (UNE SEULE instance VENV)r   Nr-   Fpidcmdline 
market_spypythonr   r   venvu*      🔧 Double VENV market_spy tué (PID: )Tu'   ✅ Market Spy VENV déjà actif (PID: u,      🔧 SYSTEM Python market_spy tué (PID: zmarket_spy.pyzmarket_spy_daemon.logr   ar   r   r  r+  r,  r.  r  u3   🕵️ Market Spy démarré automatiquement (PID: u.      • Scan: toutes les 12s | Max positions: 3      • Logs: u    ⚠️ market_spy.py non trouvéu   Erreur démarrage Market Spy: )rw  r  psutilro  r"  process_iterr   r   rQ   killNoSuchProcessAccessDeniedr   rh   r   r   r  r  r   r6  r7  r  r  r  rR   r   rW   )rw  r  venv_python_lowervenv_spy_runningproccmdline_partsr  exescript_path
python_exe
daemon_loglog_filer   s                r:   ensure_market_spy_runningr    s   JJqM@;'--/ !''	(:; 	D $		) 4 :((=1779w.('2I2?mA&,,.Rc>Vs]c=N6N'&PQUQZQZ[`QaPbbc$de		+/(&MdiiX]N^M__`$ab KK"NtyyY^O_N``a bcIIK%	,  ggll:?77>>+&$Jj2IJJ||w&*cG< %++#[1&0&I&IJLgLg&g''&D  *cG< %++#[1''&*.D KKMdhhZWXYZKKHJKK-
|45NN=>G ((&*=*=>     ;5aS9::;s   0K4 :J:K4 B<J:?K4 BK4 A KK4 *!K(AK4 $K4 :KK4 KK4 K%!K4 (K1-K4 4	L=LLc                     ddl } | j                  d       	 t        j                  j	                  t
        d      }t        j                  j                  |      rt        |d      5 }t        |j                         j                               }ddd       ddl}|j                        r\	 |j                  |      }|j                         r:d|j                         j!                         v rt"        j%                  d| d       yt        j                  j	                  t
        d	      }t        j                  j                  |      rt&        }t        j                  j	                  t
        d
      }t(        j*                  dk(  rXt        |dd      5 }	t-        j.                  ||dgt,        j0                  t,        j2                  z  |	|	t
              }ddd       n8t        |dd      5 }	t-        j.                  ||dg|	|	t
        d      }ddd       t"        j%                  dj4                   d       t"        j%                  d       t"        j%                  d|        yt"        j7                  d       y# 1 sw Y   xY w#  Y xY w# 1 sw Y   xY w# 1 sw Y   xY w# t8        $ r"}
t"        j;                  d|
        Y d}
~
yd}
~
ww xY w)u>   S'assure que le service auto_updater est en cours d'exécutionr   Nr   zauto_updater.pidr   r  u$   ✅ Auto-Updater déjà actif (PID: r  zauto_updater_service.pyzauto_updater_daemon.logr   r  r   r   z--daemonr  Tr  u2   🔄 Auto-Updater démarré automatiquement (PID: u<      • Sync rapide: 1h | MAJ données: 6h | IA training: 24hr  u*   ⚠️ auto_updater_service.py non trouvéu    Erreur démarrage Auto-Updater: )rw  r  r   rh   r   r   r   r   r   r   r   r  
pid_existsProcess
is_runningnamer"  rQ   r   ro  r  r  r6  r7  r  r  r  rR   r   rW   )rw  pid_filer   r  r  r   r  r  r  r  r   s              r:   ensure_auto_updater_runningr    sH   JJqM6=77<<
,>? 77>>(#h$ ,!&&(..*+,   %!>>#.D(X9J9J9L-L&J3%q$QR
 ggll:/HI77>>+&$J j2KLJ||w&*cG< %++#[*=&0&I&IJLgLg&g''&D  *cG< %++#[*=''&*.D KKLTXXJVWXYKKVXKK-
|45NNGH], ,    =7s;<<=s   AJ, &(I?J, ,AJ BJ, AJJ, ."J AJ, )J, ?J	J, JJ, JJ,  J)%J, ,	K5KK__main__c                  p   ddl } 	 ddl}|j                         }	 	 | j	                  d       t        j                          |rT|j                         j                  dz  dz  }|dkD  r/t        j                  d|dd       t        j                  d	       }# t        $ r d}Y w xY w# t        $ r Y w xY w)
uK   Surveille la consommation mémoire et force un gc.collect() si nécessaire.r   Nr)   i   i  u   ⚠️ Mémoire élevée: z.0fu    MB — gc.collect() forcérH  )rw  r  r
  ImportErrorr  gccollectmemory_inforssrQ   rR   r   )rw  r  r   rss_mbs       r:   memory_watchdogr     s    	>>#D 	

2

!--/33d:TAF})CF3<Oj'kl

1   	D	  s#   B A;B) B&%B&)	B54B5MemoryWatchdog)rE  daemonr  )rE  r  )lr  r  httpsocketserverr   r   r  rt  r6  r  r  loggingr   rk   r   typingr   
api.modelsr   r   api.securityr   r	   r
   r   api.servicesr   r   r   
api.routesr   	api.utilsr   r   r  ioTextIOWrapperr+  bufferr,  r4  rh   r   dirnameabspath__file__r  basicConfigINFOStreamHandlerFileHandler	getLoggerr  rQ   r  r   chdirro  r   
executablecrypto_data_fetcherr#   r$   r  r  rR   r  r%   r&   r  r   r   ai_realtime_servicer'   r(   AI_REALTIME_AVAILABLEtoken_managerrate_limiterrO   config_servicetrading_servicebot_servicerl   	get_token	API_TOKENserverSimpleHTTPRequestHandlerr/   r  r  r  r  r   r   rs  r  r  r  r  r  r  ru  
mem_threadrv  crypto_thread	ai_threadupdater_thread
spy_threadrl  r;   r:   <module>rA     s      	 
       !  : U U B B # 4	
||w%R%%JJT

 &R%%JJT

 "%

  77<<(ABDWX   
,,>cjj)Hw7	 
		8	$ WW__RWW__X67
   <<7'',,z7I|LK'',,z7E9EK	ww~~k"..K8B#8G!
KK127P 
KK01 Z(R@ =z* ,$ ##%	 ' ) fTFO  k*& ' $TF/: ; k)BQ-(RS T " #b	9$++>> b	9J2j1$3@ s 3 4 *@ZE;P;=| z, "!!L\]J %I$$,=dKM !	  (=dKIOO &Y%%-HQUVN "!!)B4PJ Lk [	H  8$
NN678  8"
NN21#6778  7!
NN1!5667sO   *A1Q& 
Q. R ;R6 &Q+.R
	R
R3R..R36S;SS