o
    JZïh *  ã                   @   sl   d Z ddlZddlZddlmZmZ ddlmZmZmZ ddl	Z	G dd„ dƒZ
dd„ Zed	kr4eƒ  dS dS )
uu   
Gestionnaire de cooldown pour Ã©viter les fermetures/rÃ©ouvertures rapides
qui gÃ©nÃ¨rent des pertes dues aux frais
é    N)ÚdatetimeÚ	timedelta)ÚDictÚOptionalÚSetc                   @   sÐ   e Zd ZdZd"defdd„Zd#dedefd	d
„Zdefdd„Zdede	fdd„Z
dededefdd„Zdedede	fdd„Zdedee fdd„Zdefdd„Zdd„ Zdedefdd„Zdedefdd „Zd!S )$ÚCooldownManageruG   GÃ¨re les cooldowns pour Ã©viter le overtrading sur les mÃªmes symbolesé   Údefault_cooldown_minutesc                 C   sL   t  d¡| _|| _dddddddœ| _i | _i | _t ¡ | _	d| _
d| _d S )Nr   é
   r   é   é   )ÚBTCÚETHÚBNBÚSOLÚDOGEÚDEFAULTr   )ÚloggingÚ	getLoggerÚloggerr	   Úsymbol_cooldownsÚlast_close_timesÚrecent_opensÚ	threadingÚLockÚlockÚcooldown_blocksÚovertrading_prevention)Úselfr	   © r   úQ/var/www/html/HyperOracle/crypto_trader/simple_trading_system/cooldown_manager.pyÚ__init__   s   ú


zCooldownManager.__init__Ú ÚsymbolÚreasonc              
   C   s�   | j �; t ¡ }|| j|< | j d|› d|  ||¡ d¡› �¡ |r6| j d|› d|› �¡ W d  ƒ dS W d  ƒ dS 1 sAw   Y  dS )z&Enregistre la fermeture d'une positionú	Position u%    fermÃ©e - Cooldown activÃ© jusqu'Ã  ú%H:%M:%SzRaison fermeture ú: N)	r   r   Únowr   r   ÚinfoÚ_get_cooldown_endÚstrftimeÚdebug)r   r#   r$   Ú
close_timer   r   r    Úrecord_position_close(   s   
&ù"úz%CooldownManager.record_position_closec              	      s¨   | j �G t ¡ }|| jvrg | j|< | j|  |¡ |tdd� ‰ ‡ fdd„| j| D ƒ| j|< | j d|› dt| j| ƒ› d�¡ W d  ƒ dS 1 sMw   Y  dS )	z%Enregistre l'ouverture d'une positioné   ©Úhoursc                    ó   g | ]}|ˆ kr|‘qS r   r   ©Ú.0Út©Úcutoff_timer   r    Ú
<listcomp>A   ó
    ÿz8CooldownManager.record_position_open.<locals>.<listcomp>r%   z ouverte - u#    ouvertures dans la derniÃ¨re heureN)	r   r   r(   r   Úappendr   r   r)   Úlen)r   r#   Ú	open_timer   r6   r    Úrecord_position_open4   s   


ÿ&"ñz$CooldownManager.record_position_openÚreturnc           	   	      s”  | j �½ t ¡ ‰ || jv rA| j| }|  ||¡}ˆ |k rA|ˆ  }t| ¡ d ƒ}|  jd7  _dd|› d|› d�fW  d  ƒ S || jv rŸt	| j| ƒ}|dkrj|  j
d7  _
dd	|› d
|› d�fW  d  ƒ S ‡ fdd„| j| D ƒ}t	|ƒdkrŸ|  j
d7  _
dd|› dtˆ |d   ¡ d ƒ› d�fW  d  ƒ S |  |ˆ ¡}|d s²|W  d  ƒ S dd|› �fW  d  ƒ S 1 sÃw   Y  dS )u   
        VÃ©rifie si on peut ouvrir une position sur ce symbole

        Returns:
            Tuple: (allowed, reason)
        é<   r/   FzCooldown actif pour ú - zmin restantesNé   u    Trop d'ouvertures rÃ©centes sur z (z/h - max 3)c                    s    g | ]}ˆ |   ¡ d k r|‘qS )iX  )Útotal_secondsr3   ©r(   r   r    r8   i   s
    ÿz5CooldownManager.can_open_position.<locals>.<listcomp>u   Ouverture trop rÃ©cente sur u    (derniÃ¨re il y a éÿÿÿÿzmin - attendre 10min)r   Tu   Ouverture autorisÃ©e pour )r   r   r(   r   r*   ÚintrB   r   r   r;   r   Ú_check_volatility_cooldown)	r   r#   Ú
last_closeÚcooldown_endÚ	remainingÚremaining_minutesÚrecent_countÚvery_recentÚvolatility_cooldownr   rC   r    Úcan_open_positionH   s<   

ó
ê
ÿ(ß$Ú($Øz!CooldownManager.can_open_positionr-   c                 C   s"   | j  || j d ¡}|t|d� S )z*Calcule la fin du cooldown pour un symboler   )Úminutes)r   Úgetr   )r   r#   r-   Úcooldown_minutesr   r   r    r*   z   s   z!CooldownManager._get_cooldown_endr(   c                 C   s   |dv r|  ¡ dkrdS dS )u5   VÃ©rifications spÃ©ciales pour les symboles volatiles)r   ÚSHIBÚWIFé   )Tu<   Weekend - pas de restriction supplÃ©mentaire pour meme coins)Tu!   Pas de restriction de volatilitÃ©)Úweekday)r   r#   r(   r   r   r    rF   €   s   z*CooldownManager._check_volatility_cooldownc                 C   sœ   | j �A || jvr	 W d  ƒ dS t ¡ }| j| }|  ||¡}||kr.	 W d  ƒ dS || }tdt| ¡ d ƒƒW  d  ƒ S 1 sGw   Y  dS )z0Retourne le temps de cooldown restant en minutesNr   r?   )r   r   r   r(   r*   ÚmaxrE   rB   )r   r#   r(   rG   rH   rI   r   r   r    Úget_remaining_cooldown‰   s   
þ
÷$ôz&CooldownManager.get_remaining_cooldownc                 C   sÎ   | j �Z t ¡ }i i | j| jdœdœ}| j ¡ D ]\}}|  |¡}|r3|dkr3|| d¡dœ|d |< q| j	 ¡ D ]\}}|rSt
|ƒ|rK|d  d¡ndd	œ|d
 |< q9|W  d  ƒ S 1 s`w   Y  dS )z(Retourne le statut complet des cooldowns)r   r   )Úactive_cooldownsÚrecent_activityÚ
statisticsr   r&   )rJ   rG   rX   rD   N)Úopens_last_hourÚ	last_openrY   )r   r   r(   r   r   r   ÚitemsrW   r+   r   r;   )r   r(   Ústatusr#   rG   rI   Úopensr   r   r    Úget_cooldown_statusš   s.   þý

þ€þ€$äz#CooldownManager.get_cooldown_statusc                    sÜ   | j �a t ¡ }|tdd� ‰ ‡ fdd„| j ¡ D ƒ}|D ]}| j|= qt| j ¡ ƒD ]}‡ fdd„| j| D ƒ| j|< | j| sE| j|= q+|r\| j	 
dt|ƒ› d�¡ W d  ƒ dS W d  ƒ dS 1 sgw   Y  dS )	u8   Nettoie les anciennes donnÃ©es (appelÃ© pÃ©riodiquement)é   r0   c                    s   g | ]
\}}|ˆ k r|‘qS r   r   )r4   r#   r-   r6   r   r    r8   Ã   s
    ÿz4CooldownManager.cleanup_old_data.<locals>.<listcomp>c                    r2   r   r   r3   r6   r   r    r8   Í   r9   u   Nettoyage: supprimÃ© z anciens cooldownsN)r   r   r(   r   r   r]   Úlistr   Úkeysr   r)   r;   )r   r(   Ú
old_closesr#   r   r6   r    Úcleanup_old_data»   s(   
ÿ

ÿ
€è"éz CooldownManager.cleanup_old_datac                 C   sd   | j �% || jv r| j|= | j d|› �¡ 	 W d  ƒ dS 	 W d  ƒ dS 1 s+w   Y  dS )z9Force le reset du cooldown pour un symbole (usage manuel)u   Cooldown forcÃ© Ã  zÃ©ro pour NTF)r   r   r   Úwarning)r   r#   r   r   r    Úforce_reset_cooldownØ   s   
ü$ûz$CooldownManager.force_reset_cooldownrO   c              
   C   sj   | j �( | j || jd ¡}|| j|< | j d|› d|› d|› d�¡ W d  ƒ dS 1 s.w   Y  dS )u/   Modifie le cooldown pour un symbole spÃ©cifiquer   z	Cooldown u    modifiÃ©: u   min â†’ ÚminN)r   r   rP   r   r)   )r   r#   rO   Úold_cooldownr   r   r    Úset_symbol_cooldownâ   s
   
""üz#CooldownManager.set_symbol_cooldownN)r   )r"   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rE   r!   Ústrr.   r=   ÚtuplerN   r   r*   rF   r   rW   r   r`   re   Úboolrg   rj   r   r   r   r    r      s    2	!
r   c               	   C   s˜  t dƒ tdd�} t dƒ |  d¡\}}t d|rdnd› d	|› �ƒ |r)|  d¡ t d
ƒ |  dd¡ |  d¡\}}t d|r@dnd› d	|› �ƒ t dƒ tdƒD ]}|  d¡ qP|  d¡\}}t d|rednd› d	|› �ƒ t dƒ |  ¡ }t dƒ |d  ¡ D ]\}}t d|› d|d › d|d › d�ƒ qt dƒ |d  ¡ D ]\}}t d|› d|d › d|d › d�ƒ q t d|d d › d |d d! › d"�ƒ | S )#z Test du gestionnaire de cooldownz=== TEST COOLDOWN MANAGER ===
rT   )r	   z1. Test ouverture normale:r   u      RÃ©sultat: ÚOKÚBLOQUEr@   z*
2. Test fermeture et activation cooldown:zTest fermeturez 
3. Test protection overtrading:é   r   z
4. Statut global:z   Cooldowns actifs:rX   z     r'   rJ   u   min (fermÃ© Ã  rG   ú)u      ActivitÃ© rÃ©cente:rY   r[   u    ouvertures (derniÃ¨re: r\   z   Statistiques: rZ   r   z blocs, r   u    prÃ©ventions)Úprintr   rN   r=   r.   Úranger`   r]   )ÚmanagerÚallowedr$   Úir^   r#   Údatar   r   r    Útest_cooldown_managerë   s4   

&&&r|   Ú__main__)rn   r   Útimer   r   Útypingr   r   r   r   r   r|   rk   r   r   r   r    Ú<module>   s     `.
ÿ