o
    `ïhxN  ã                   @   s¨   d 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m	Z	 ddl
mZmZ ddlZddlZddlZddlmZ G dd	„ d	ƒZed
krRedd�Ze ¡  dS dS )ux   
Service de surveillance et reporting par email
Envoie un rÃ©capitulatif des trades et analyse du marchÃ© toutes les 6h
é    N)ÚMIMEText)ÚMIMEMultipart)ÚdatetimeÚ	timedelta)ÚListÚDict)ÚHyperliquidClientc                
   @   sÌ   e Zd ZdZd%defdd„Zdd„ Zd&d	ed
ee	 fdd„Z
d
ee	 fdd„Zd
efdd„Zdee	 d
e	fdd„Zd
e	fdd„Zde	de	dee	 ded
ef
dd„Zdeded
efdd„Zd d!„ Zd"d#„ Zd$S )'ÚTradingReportMailerz0Service d'envoi de rapports de trading par emailúbinet.benjamin@gmail.comÚrecipient_emailc                 C   s&   || _ tƒ | _d| _d| _|  ¡  d S )Ni`T  r   )r   r   Úhyperliquid_clientÚreport_intervalÚlast_report_timeÚsetup_logger)Úselfr   © r   ú@/var/www/html/HyperOracle/crypto_trader/trading_report_mailer.pyÚ__init__   s
   zTradingReportMailer.__init__c                 C   sR   t  d¡| _| j t j¡ t  ¡ }t  d¡}| |¡ | jjs'| j 	|¡ dS dS )zConfigure le loggingr	   z&%(asctime)s - [%(name)s] - %(message)sN)
ÚloggingÚ	getLoggerÚloggerÚsetLevelÚINFOÚStreamHandlerÚ	FormatterÚsetFormatterÚhandlersÚ
addHandler)r   ÚhandlerÚ	formatterr   r   r   r   !   s   

ÿz TradingReportMailer.setup_loggeré   ÚhoursÚreturnc              
      sÖ   zM| j j | j j¡}|sg W S t|ƒ}|dkr!| j d|› d�¡ tt 	¡ t
|d�  ¡ d ƒ‰ ‡ fdd„|D ƒ}| j dt|ƒ› d	|› d
|› d�¡ |W S  tyj } z| j d|› �¡ g W  Y d}~S d}~ww )u-   RÃ©cupÃ¨re les trades des X derniÃ¨res heuresiÐ  u   âš ï¸�  Limite API atteinte: u    fills rÃ©cupÃ©rÃ©s (max 2000)©r!   iè  c                    s    g | ]}|  d d¡ˆ kr|‘qS )Útimer   )Úget)Ú.0Úfill©Úcutoff_timer   r   Ú
<listcomp>?   s
    ÿz9TradingReportMailer.get_recent_trades.<locals>.<listcomp>u   ðŸ“Š Fills rÃ©cupÃ©rÃ©s: z
 dans les zh (sur z total)u   Erreur rÃ©cupÃ©ration trades: N)r   ÚinfoÚ
user_fillsÚaccount_addressÚlenr   ÚwarningÚintr   Únowr   Ú	timestampÚ	ExceptionÚerror)r   r!   r,   Útotal_fillsÚrecent_fillsÚer   r(   r   Úget_recent_trades-   s(   ÿ
ÿ$€þz%TradingReportMailer.get_recent_tradesc              
   C   sV   z| j  ¡ }|r|W S g W S  ty* } z| j d|› �¡ g W  Y d}~S d}~ww )u"   RÃ©cupÃ¨re les positions actuellesu!   Erreur rÃ©cupÃ©ration positions: N)r   Úget_positionsr3   r   r4   )r   Ú	positionsr7   r   r   r   Úget_current_positionsM   s   
€þz)TradingReportMailer.get_current_positionsc              
   C   sx   z| j j | j j¡}|rd|v rt|d  dd¡ƒ}|W S W dS  ty; } z| j d|› �¡ W Y d}~dS d}~ww )u   RÃ©cupÃ¨re la balance du compteÚmarginSummaryÚaccountValuer   g        u   Erreur rÃ©cupÃ©ration balance: N)	r   r+   Ú
user_stater-   Úfloatr%   r3   r   r4   )r   r>   Úbalancer7   r   r   r   Úget_account_balanceV   s   ÿ€þz'TradingReportMailer.get_account_balanceÚtradesc                 C   sÜ   |sddddddddœS d}d}d}d}d}|D ]'}t | dd¡ƒ}|dkr?||7 }|dkr7|d7 }||7 }q|d7 }||7 }q|| }	|	dkrN||	 d nd}
|dkrX|| nd}|dkrb|| nd}|	||||
||dœS )u/   Analyse les trades et gÃ©nÃ¨re des statistiquesr   )Útotal_tradesÚwinning_tradesÚlosing_tradesÚ	total_pnlÚwin_rateÚavg_winÚavg_lossÚ	closedPnlé   éd   ©r?   r%   )r   rB   rF   rD   rE   Útotal_win_pnlÚtotal_loss_pnlr'   Ú
closed_pnlrC   rG   rH   rI   r   r   r   Úanalyze_tradesg   sH   ù

€ùz"TradingReportMailer.analyze_tradesc           	   
   C   sà   zNddl m} |ƒ }| ddd¡}|rt|ƒdk r ddddœW S t|d d	 ƒ}t|d
 d	 ƒ}|| | d }|dkr?d}n	|dk rFd}nd}|||dœW S  tyo } z| j d|› �¡ ddddœW  Y d}~S d}~ww )u   Analyse le marchÃ© actuelr   )ÚBinanceDataProviderÚBTCÚ1hé   é   ÚUNKNOWN)Úbtc_change_24hÚ	btc_trendÚ	btc_priceÚcloseéÿÿÿÿrL   u   BULLISH ðŸ“ˆéþÿÿÿu   BEARISH ðŸ“‰u
   RANGE ðŸ“Š)rZ   rX   rY   u   Erreur analyse marchÃ©: N)Úbinance_data_providerrR   Úget_candlesr.   r?   r3   r   r4   )	r   rR   ÚbinanceÚbtc_dataÚbtc_price_24h_agoÚbtc_price_nowrX   Útrendr7   r   r   r   Úget_market_analysis˜   s.   ý€þz'TradingReportMailer.get_market_analysisÚtrades_statsÚmarket_analysisr:   Úaccount_balancec                 C   sh  t  ¡  d¡}i }ztddƒ�}t |¡}W d  ƒ n1 sw   Y  W n   Y d}| jdd�}	dd	„ |	D ƒ}
| j d
t	|
ƒ› �¡ |
D ]Ä}| 
dd¡}| 
dd¡}t| 
dd¡ƒ}t| 
dd¡ƒ}t| 
dd¡ƒ}d}| ¡ dkrwd}nd}|dkrdnd}|dkr‡dnd}|| }|dkr—|| d nd}|› d|› �|› d|› �|› d�|› d�g}d}|D ]}||v rÇ||  
dd¡}|dkrÇ nq³|dkrÒ|d›d�nd}|d|› d |dkrßd!nd"› d#|› d$|d%›d&|d%›d |dkródnd'› d#|› d |› d#|› d(|d)›d*|d›d+�7 }qF|
�sd,}|d- dk�rdnd}|d- dk�r$dnd}|d. d/k�r/dn
|d. d0k�r8d'nd}d g d1‘|› ‘d2‘|d3›‘d4‘| 
d5d¡d3›‘d6‘| 
d7d¡dk�r_dnd› ‘d8‘| 
d7d¡d9›‘d:‘| 
d;d<¡› ‘d=‘|d> › ‘d?‘|› ‘d@‘|d. dA›‘dB‘|› ‘d@‘|› ‘d(‘|d- d)›‘dC‘|dD › ‘dE‘|dF › ‘dG‘|› ‘dH‘¡}|S )Iu   GÃ©nÃ¨re le rapport HTMLú%Y-%m-%d %H:%Mzposition_peaks.jsonÚrNÚ r    r#   c                 S   s$   g | ]}t | d d¡ƒdkr|‘qS )rJ   r   rM   )r&   Útr   r   r   r*   Î   s   $ z:TradingReportMailer.format_html_report.<locals>.<listcomp>u.   ðŸ“‹ Trades fermÃ©s trouvÃ©s pour le rapport: ÚcoinÚdirrJ   r   ÚpxÚszÚbuyÚSHORTÚLONGÚgreenÚredú+rL   Ú_Ú_LONGÚ_SHORTÚpeak_pnl_percentz+.1fú%ú-z&
            <tr>
                <td>z(</td>
                <td style="color: z#0066ccz#cc6600z; font-weight: bold;">z</td>
                <td>$z.4fz</td>
                <td>Úorangeú$ú.2fz (z&%)</td>
            </tr>
            uY   <tr><td colspan="6" style="text-align: center; color: #888;">Aucun trade fermÃ©</td></tr>rF   rG   é2   é(   uq  
        <!DOCTYPE html>
        <html>
        <head>
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <style>
                * { margin: 0; padding: 0; box-sizing: border-box; }
                body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; background: #f5f5f5; padding: 10px; font-size: 14px; }
                .container { max-width: 600px; margin: 0 auto; background: white; padding: 15px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
                h1 { color: #333; font-size: 18px; border-bottom: 2px solid #4CAF50; padding-bottom: 8px; margin-bottom: 15px; }
                h2 { color: #555; font-size: 16px; margin: 20px 0 10px 0; border-left: 3px solid #2196F3; padding-left: 8px; }
                .stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 10px 0; }
                .stat-card { background: #f9f9f9; padding: 10px; border-radius: 6px; border-left: 3px solid #4CAF50; }
                .stat-label { font-size: 10px; color: #888; text-transform: uppercase; margin-bottom: 4px; }
                .stat-value { font-size: 18px; font-weight: bold; color: #333; }
                table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 12px; }
                th { background: #4CAF50; color: white; padding: 8px 4px; text-align: left; font-size: 11px; }
                td { padding: 6px 4px; border-bottom: 1px solid #eee; }
                .footer { margin-top: 20px; padding-top: 15px; border-top: 1px solid #ddd; text-align: center; color: #888; font-size: 11px; }
                @media (max-width: 600px) {
                    body { padding: 5px; }
                    .container { padding: 10px; }
                    h1 { font-size: 16px; }
                    h2 { font-size: 14px; }
                    .stat-value { font-size: 16px; }
                    table { font-size: 11px; }
                    th, td { padding: 6px 2px; }
                }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>ðŸ“Š Trading Report - u9  </h1>

                <h2>ðŸ’¼ Balance & MarchÃ©</h2>
                <div class="stats">
                    <div class="stat-card" style="border-left-color: #FF9800;">
                        <div class="stat-label">Balance Compte</div>
                        <div class="stat-value" style="color: #FF9800;">$z,.2fz¾</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">BTC Prix</div>
                        <div class="stat-value">$rZ   zÔ</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">BTC Variation 24h</div>
                        <div class="stat-value" style="color: rX   z ;">
                            z+.2fzð%
                        </div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">Tendance</div>
                        <div class="stat-value" style="font-size: 16px;">rY   rW   u?  </div>
                    </div>
                </div>

                <h2>ðŸ’° Performance des 6 derniÃ¨res heures</h2>
                <div class="stats">
                    <div class="stat-card">
                        <div class="stat-label">Total Trades</div>
                        <div class="stat-value">rC   zË</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">Win Rate</div>
                        <div class="stat-value" style="color: z;">z.1fzÍ%</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">PnL Total</div>
                        <div class="stat-value" style="color: zö</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label">Trades Gagnants / Perdants</div>
                        <div class="stat-value" style="font-size: 18px; color: green;">rD   z? <span style="color: #888;">/</span> <span style="color: red;">rE   u3  </span></div>
                    </div>
                </div>

                <h2>ðŸ“‹ Historique 6h</h2>
                <table>
                    <thead>
                        <tr>
                            <th>Symbole</th>
                            <th>Side</th>
                            <th>Prix</th>
                            <th>Taille</th>
                            <th>Peak</th>
                            <th>PnL Final</th>
                        </tr>
                    </thead>
                    <tbody>
                        uB  
                    </tbody>
                </table>

                <div class="footer">
                    <p>ðŸ¤– Rapport gÃ©nÃ©rÃ© automatiquement par Crypto Trading Bot</p>
                    <p>Prochain rapport dans 6 heures</p>
                </div>
            </div>
        </body>
        </html>
        )r   r1   ÚstrftimeÚopenÚjsonÚloadr8   r   r+   r.   r%   r?   ÚlowerÚjoin)r   rf   rg   r:   rh   r1   Ú
peaks_dataÚfÚclosed_trades_htmlÚrecent_tradesÚclosed_onlyÚtraderm   Ú	directionÚpnlÚpriceÚsizeÚside_displayÚ	pnl_colorÚpnl_signÚposition_valueÚfinal_pnl_pctÚpeak_key_optionsÚpeak_pnl_pctÚkeyÚpeak_displayÚwr_colorÚhtmlr   r   r   Úformat_html_report¼   sÈ   ÿ€ü€þýýüûúúùùùù(
 à&
Ú
*
Ö.Ò
/
Ñ
4Ì<Ä@À@
ÀD¼D¼D
¼H¸H¸Y§fz&TradingReportMailer.format_html_reportÚsubjectÚhtml_contentc           
   
   C   s&  zvddl }ddl}|jdddd��}| |¡ |j}W d  ƒ n1 s$w   Y  dd|d	d
d	d| jg}t|dƒ�}|j||dddd�}W d  ƒ n1 sNw   Y  t 	|¡ |j
dkrj| j d| j› �¡ W dS | j d|j› �¡ W dS  ty’ }	 z| j d|	› �¡ W Y d}	~	dS d}	~	ww )u,   Envoie l'email via la commande mail systÃ¨mer   NÚwz.htmlF)ÚmodeÚsuffixÚdeleteÚmailz-sz-az&Content-Type: text/html; charset=UTF-8z)From: Bot Hyperliquid <server@codeben.fr>rj   Té   )ÚstdinÚcapture_outputÚtextÚtimeoutu"   âœ… Email envoyÃ© avec succÃ¨s Ã  u   â�Œ Erreur mail: u   â�Œ Erreur envoi email: )Ú
subprocessÚtempfileÚNamedTemporaryFileÚwriteÚnamer   rƒ   ÚrunÚosÚunlinkÚ
returncoder   r+   r4   Ústderrr3   )
r   rž   rŸ   rª   r«   r‰   Ú	html_fileÚcmdÚresultr7   r   r   r   Ú
send_email}  sB   
þûûÿ


€þzTradingReportMailer.send_emailc           
   
   C   sê   zX| j  d¡ | jdd�}|  ¡ }|  ¡ }|  |¡}|  ¡ }|  ||||¡}dt 	¡  
d¡› d|d›d|d	 d›�}|  ||¡}|rPt ¡ | _| j  d
¡ |W S | j  d¡ |W S  tyt }	 z| j  d|	› �¡ W Y d}	~	dS d}	~	ww )u%   GÃ©nÃ¨re et envoie le rapport completu*   ðŸ“Š GÃ©nÃ©ration du rapport de trading...r    r#   u   ðŸ¤– Trading Report - ri   z - Balance: $r   z - PnL 6h: $rF   u    âœ… Rapport envoyÃ© avec succÃ¨su   â�Œ Ã‰chec envoi du rapportu!   â�Œ Erreur gÃ©nÃ©ration rapport: NF)r   r+   r8   r;   rA   rQ   re   r�   r   r1   r‚   r·   r$   r   r4   r3   )
r   rB   r:   rh   rf   rg   rŸ   rž   Úsuccessr7   r   r   r   Úgenerate_and_send_report¨  s*   
(
þ€þz,TradingReportMailer.generate_and_send_reportc              
   C   sÊ   | j  d¡ | j  d| j› �¡ | j  d| jd › d�¡ | j  d¡ |  ¡  	 zt | j¡ |  ¡  W n/ tyD   | j  d¡ Y dS  tyc } z| j  	d	|› �¡ t d
¡ W Y d}~nd}~ww q()zBoucle principale du serviceu#   ðŸš€ Service de reporting dÃ©marrÃ©u   ðŸ“§ Destinataire: u   â�° Intervalle: i  Úhu    ðŸ“¨ Envoi du premier rapport...Tu#   ðŸ›‘ ArrÃªt du service de reportingu   â�Œ Erreur dans la boucle: é<   N)
r   r+   r   r   r¹   r$   ÚsleepÚKeyboardInterruptr3   r4   )r   r7   r   r   r   r¯   É  s$   €þõzTradingReportMailer.runN)r
   )r    )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústrr   r   r0   r   r   r8   r;   r?   rA   rQ   re   r�   Úboolr·   r¹   r¯   r   r   r   r   r	      s    	 	1"$ B+!r	   Ú__main__r
   )r   )rÁ   Úsmtplibr„   r$   Úemail.mime.textr   Úemail.mime.multipartr   r   r   Útypingr   r   r   r°   Úsysr   r   r	   r¾   Úmailerr¯   r   r   r   r   Ú<module>   s(      Q
ý