
    bAjn                         d Z ddlmZmZ ddlmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZ  ee      ZdZdZd	Zd
Z G d d      Z e       Zy)z-Circuit breakers and automatic trading pause.    )datetimetimezone)AnyOptional)
get_logger)	get_redisset_emergency_stop)CircuitBreakerReasonztrading:circuit_breakerzbot:heartbeat:zbinance:ws_last_seenzflash:price:c                   t   e Zd ZdZej
                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  d	iZddedee   dd
fdZdeeee   f   fdZdedd
fdZdedd
fdZddededefdZ	 ddededededef
dZd dedefdZy
)!CircuitBreakerServicez]
    Automatic trading pause on critical conditions.
    Requires explicit manual reset.
    zDaily loss limit reachedzToo many consecutive losseszWebSocket disconnected too longzReconciliation discrepancyzAbnormal order latencyzFlash crash detectedzBinance API ban (418)zManual circuit breakerNreasoncontextreturnc                   K   t                d {   }|j                  |xs i t        j                  t        j
                        j                         dd}|j                  t        t        d      j                  |             d {    t        d       d {    t        j                  d|j                  |       y 7 7 <7 +w)NT)r   r   triggered_atactivejsoncircuit_breaker_triggered)r   r   )r   valuer   nowr   utc	isoformatsetCIRCUIT_BREAKER_KEY
__import__dumpsr	   loggercritical)selfr   r   rpayloads        FC:\xampp\htdocs\tradingbinance\backend\app\services\circuit_breaker.pytriggerzCircuitBreakerService.trigger#   s     +ll}"$LL6@@B	
 ee'F);)A)A')JKKK &&&3FLLRYZ  	L&s4   CCA9C
CCC	(CC	Cc                    K   t                d {   }|j                  t               d {   }|syt        d      j	                  |      }|j                  dd      |fS 7 R7 7w)N)FNr   r   F)r   getr   r   loads)r   r    rawdatas       r"   	is_activezCircuitBreakerService.is_active/   s\     +EE-..&!'',xx%($.. .s   A'A#A'A%6A'%A'reset_byc                    K   t                d {   }|j                  t               d {    t        d       d {    t        j                  d|       y 7 L7 17  w)NFcircuit_breaker_reset)by)r   deleter   r	   r   info)r   r*   r    s      r"   resetzCircuitBreakerService.reset7   sO     +hh*+++ '''+9 +'s1   A#AA#AA# A!A#A#!A#worker_namec                    K   t                d {   }|j                  t         | t        j                  t
        j                        j                         d       d {    y 7 X7 w)Nx   ex)r   r   HEARTBEAT_KEY_PREFIXr   r   r   r   r   )r   r1   r    s      r"   record_heartbeatz&CircuitBreakerService.record_heartbeat=   s_     +ee#$[M2LL&002  
 	
 	
 	
s"   A-A)AA-#A+$A-+A-max_age_secondsc                   K   t                d {   }|j                  t         |        d {   }|syt        j                  |      }t        j
                  t        j                        |z
  j                         }||k  S 7 v7 Ww)NF)	r   r%   r6   r   fromisoformatr   r   r   total_seconds)r   r1   r8   r    tslastages          r"   check_heartbeatz%CircuitBreakerService.check_heartbeatE   sv     +5501+?@@%%b)||HLL)D0??Ao%% @s    BB BB	AB	Bsymbolcurrent_pricethreshold_pctwindow_minutesc                 v  K   t                d{   }t         | }ddl}|j                  |       d{   }t	        j
                  t        j                        }	|r|j                  |      ng }
|
j                  ||	j                         d       |
dd }
|j                  ||j                  |
      d       d{    t        |
      dk  ry|
d   }|d	   dk  ryt        ||d	   z
        |d	   z  d
z  }||k\  r-| j                  t         j"                  |||d       d{    yy7  7 7 s7 w)z7Return True if flash crash detected (triggers breaker).Nr   )pricer<   iiX  r4      FrE   d   )r@   
change_pct
window_minT)r   FLASH_CRASH_KEY_PREFIXr   r%   r   r   r   r   r&   appendr   r   r   lenabsr#   r
   FLASH_CRASH)r   r@   rA   rB   rC   r    keyr   history_rawr   historyoldestrH   s                r"   check_flash_crashz'CircuitBreakerService.check_flash_crashN   s3     +'(1EE#J&ll8<<(-8$**[)bcmmoFG#$-eeCG,e555w<!'?a89F7OKcQ
&,,$00!>Z   1  '
 	6sE   D9D0&D9D3B	D9D5A'D9)D7*D93D95D97D9max_disconnect_secondsc                 n  K   t                d {   }|j                  t               d {   }|syt        j                  |      }t        j
                  t        j                        |z
  j                         }||kD  r+| j                  t        j                  d|i       d {    yy7 7 7 
w)NTdisconnect_secondsF)r   r%   WS_LAST_SEEN_KEYr   r:   r   r   r   r;   r#   r
   WS_DISCONNECTED)r   rT   r    r=   	last_seenr>   s         r"   check_ws_healthz%CircuitBreakerService.check_ws_healthl   s     +UU+,,**40	||HLL)I5DDF'',,$44%s+    ,s2   B5B/B5B1A:B5(B3)B51B53B5)N)Z   )g      @   )<   )__name__
__module____qualname____doc__r
   
DAILY_LOSSCONSECUTIVE_LOSSESrX   RECONCILIATION_FAILEDORDER_LATENCYrN   API_BANMANUALTRIGGERSr   dictr#   tupleboolr)   strr0   r7   intr?   floatrS   rZ        r"   r   r      s6    	'')C//1N,,.O224P**,D((*@$$&=##%=	H
[$8 
[8D> 
[]a 
[/tXd^';!< /:C :D :
# 
$ 
& &s &TX & de*/@E]`	<C  rp   r   N)ra   r   r   typingr   r   app.core.loggingr   app.core.redis_clientr   r	   
app.modelsr
   r^   r   r   r6   rW   rJ   r   circuit_breakerro   rp   r"   <module>rv      sP    3 '   ' ? +	H	/ ' ) ' g gT ()rp   