
    qWi                         d dl Z d dlmZmZ d dlmZmZmZ d dlmZm	Z	 d dl
mZ d dlmZmZmZ d dlmZmZmZmZmZ  e j        e          Z G d d	          Z e            ZdS )
    N)datetime	timedelta)ListDictAny)selectfunc)AsyncSession)TradeTradeStatusTradeResult)calculate_sharpe_ratiocalculate_max_drawdowncalculate_profit_factorcalculate_expectancycalculate_rr_ratioc            
           e Zd ZdZdedeeef         fdZdede	eeef                  fdZ
dede	eeef                  fdZ	 ddedede	eeef                  fd	Zdeeef         fd
ZdS )PerformanceEnginez1Aggregates trading statistics from closed trades.dbreturnc                 d  K   |                     t          t                                        t          j        t
          j        k                         d{V }|                                                                }|s| 	                                S t          |          }t          d |D                       }t          d |D                       }|dk    r||z  nd}d |D             }t          |          }	t          d |D                       }
t          t          d |D                                 }t          |
|          }|dk    r|
|z  nd}|dk    r||z  nd}t          |||          }g }d}t          |d	 
          D ]#}||j        pdz  }|                    |           $|rt%          |          nd}t'          d |D                       }g }|D ]b}|j        rYt          |j                  dk    rAt+          |j        |j        |j        d                   }|dk    r|                    |           c|rt          |          t          |          z  nd}|||t1          |dz  d          t1          |	d          t1          |d          t1          |d          |||d
S )z'Return overall bot performance metrics.Nc              3   D   K   | ]}|j         t          j        k    d V  dS    Nresultr   WIN.0ts     =/var/www/html/crypto-bot/backend/app/analytics/performance.py	<genexpr>z5PerformanceEngine.get_global_stats.<locals>.<genexpr>!   s0      DDKO(C(C1(C(C(C(CDD    c              3   D   K   | ]}|j         t          j        k    d V  dS r   )r   r   LOSSr   s     r!   r"   z5PerformanceEngine.get_global_stats.<locals>.<genexpr>"   s1      GG1!(k6F*F*FQ*F*F*F*FGGr#   r           c                 *    g | ]}|j         	|j         S Npnl_percentager   s     r!   
<listcomp>z6PerformanceEngine.get_global_stats.<locals>.<listcomp>%   s#    QQQQA4D4P 4P4P4Pr#   c              3   &   K   | ]}|d k    |V  dS r   N r   ps     r!   r"   z5PerformanceEngine.get_global_stats.<locals>.<genexpr>(   s&      44a!ee1eeee44r#   c              3   &   K   | ]}|d k     |V  dS r-   r.   r/   s     r!   r"   z5PerformanceEngine.get_global_stats.<locals>.<genexpr>)   s&      661AQ66r#   c                 6    | j         pt          j                    S r(   )	closed_atr   utcnowxs    r!   <lambda>z4PerformanceEngine.get_global_stats.<locals>.<lambda>3   s    ak.NX_=N=N r#   )keyc                 0    g | ]}|j         	|j         d z  S )d   r)   r   s     r!   r+   z6PerformanceEngine.get_global_stats.<locals>.<listcomp>8   s)    (d(d(dASTSc(d)9C)?(d(d(dr#   r:         
total_tradeswinning_tradeslosing_tradeswin_rate	total_pnlmax_drawdownavg_rr_ratiosharpe_ratioprofit_factor
expectancy)executer   r   wherestatusr   CLOSEDscalarsall_empty_statslensumabsr   r   sortedr*   appendr   r   take_profit_levelsr   entry_price	stop_lossround)selfr   r   tradestotalwinslossesrA   pnlsrB   gross_profit
gross_lossrF   avg_winavg_lossrG   equity_curverunningr    max_ddsharpe	rr_ratiosrravg_rrs                           r!   get_global_statsz"PerformanceEngine.get_global_stats   s	     zz5MM0B BCC
 
 
 
 
 
 
 
 %nn..2244 	'$$&&&FDDfDDDDDGGGGGGG#(1994%<<#QQ&QQQII	44d44444666666677
/jII+/!88<$&&,2QJJJ''C)(GXFF
 $N$NOOO 	) 	)Aq'.3.G((((9EN'5553'(d(d(d(d(dee 	 	) 	)A# )A,@(A(AA(E(E'q{ADXYZD[\\66$$R(((4=FY#i..003 ""#hna00y!,,!&!,,!&!,,"*$
 
 	
r#   c                   K   |                     t          t                                        t          j        t
          j        k                         d{V }|                                                                }i }|D ]H}|j	        pi 
                    dd          }|                    |g                               |           Ig }|                                D ]\  }}t          |          }	t          d |D                       }
d |D             }|                    ||	|
|	dk    rt!          |
|	z  dz  d          nd	t!          t          |          d
          d           t#          |d d          S )z*Return per-strategy performance breakdown.Nstrategyunknownc              3   D   K   | ]}|j         t          j        k    d V  dS r   r   r   s     r!   r"   z7PerformanceEngine.get_strategy_stats.<locals>.<genexpr>_   0      IIQQX-H-Hq-H-H-H-HIIr#   c                 *    g | ]}|j         	|j         S r(   r)   r   s     r!   r+   z8PerformanceEngine.get_strategy_stats.<locals>.<listcomp>`   #    VVV9I9UA$9U9U9Ur#   r   r:   r;   r&   r<   )rk   r>   r?   rA   rB   c                     | d         S NrB   r.   r5   s    r!   r7   z6PerformanceEngine.get_strategy_stats.<locals>.<lambda>i   
    1[> r#   Tr8   reverse)rH   r   r   rI   rJ   r   rK   rL   rM   strategy_snapshotget
setdefaultrS   itemsrO   rP   rW   rR   )rX   r   r   rY   strategy_mapr    namestatsstradesrZ   r[   r]   s               r!   get_strategy_statsz$PerformanceEngine.get_strategy_statsP   s     zz5MM0B BCC
 
 
 
 
 
 
 
 %nn..2244/1 	8 	8A'-222:yIID##D"--44Q7777)//11 
	 
	MD'LLEII'IIIIIDVVgVVVDLL  %"&<AAIIE$,"4a8883"3t99a00      e!9!94HHHHr#   c                   K   |                     t          t                                        t          j        t
          j        k                         d{V }|                                                                }i }|D ]0}|	                    |j
        g                               |           1g }|                                D ]\  }}t          |          }	t          d |D                       }
d |D             }|                    ||	|
|	dk    rt          |
|	z  dz  d          ndt          t          |          d          d	           t!          |d
 d          S )z&Return per-pair performance breakdown.Nc              3   D   K   | ]}|j         t          j        k    d V  dS r   r   r   s     r!   r"   z3PerformanceEngine.get_pair_stats.<locals>.<genexpr>y   rn   r#   c                 *    g | ]}|j         	|j         S r(   r)   r   s     r!   r+   z4PerformanceEngine.get_pair_stats.<locals>.<listcomp>z   rp   r#   r   r:   r;   r&   r<   )pairr>   r?   rA   rB   c                     | d         S rr   r.   r5   s    r!   r7   z2PerformanceEngine.get_pair_stats.<locals>.<lambda>   rs   r#   Trt   )rH   r   r   rI   rJ   r   rK   rL   rM   rx   r   rS   ry   rO   rP   rW   rR   )rX   r   r   rY   pair_mapr    r|   r   ptradesrZ   r[   r]   s               r!   get_pair_statsz PerformanceEngine.get_pair_statsk   s     zz5MM0B BCC
 
 
 
 
 
 
 
 %nn..2244+- 	6 	6A++2215555%^^-- 
	 
	MD'LLEII'IIIIIDVVgVVVDLL %"&<AAIIE$,"4a8883"3t99a00      e!9!94HHHHr#   DAILYperiodc                   K   |                     t          t                                        t          j        t
          j        k                         d{V }|                                                                }dt          dt          ffd}i }|D ]6} ||          }|
                    |g                               |           7g }	t          |                                          D ]\  }
}t          |          }t          d |D                       }d |D             }|	                    |
|||dk    rt!          ||z  dz  d	          nd
t!          t          |          d          d           |	S )zf
        Return performance bucketed by time period.
        period: DAILY | WEEKLY | MONTHLY
        Ntrader   c                    | j         pt          j                    }dk    r|                    d          S dk    r8|                                d          d|                                d         dS |                    d          S )	Nr   z%Y-%m-%dWEEKLYr   z-Wr   02dz%Y-%m)r3   r   r4   strftimeisocalendar)r   dtr   s     r!   
bucket_keyz4PerformanceEngine.get_time_stats.<locals>.bucket_key   s    5HO$5$5B  {{:...8##..**1-JJ1A1A!1DJJJJ{{7+++r#   c              3   D   K   | ]}|j         t          j        k    d V  dS r   r   r   s     r!   r"   z3PerformanceEngine.get_time_stats.<locals>.<genexpr>   rn   r#   c                 *    g | ]}|j         	|j         S r(   r)   r   s     r!   r+   z4PerformanceEngine.get_time_stats.<locals>.<listcomp>   rp   r#   r   r:   r;   r&   r<   )r   r>   r?   rA   rB   )rH   r   r   rI   rJ   r   rK   rL   rM   strrx   rS   rR   ry   rO   rP   rW   )rX   r   r   r   rY   r   
bucket_mapr    r8   r|   
period_keyr   rZ   r[   r]   s     `            r!   get_time_statsz PerformanceEngine.get_time_stats   s      zz5MM0B BCC
 
 
 
 
 
 
 
 %nn..2244	,e 	, 	, 	, 	, 	, 	, 	, .0
 	5 	5A*Q--C!!#r**11!4444#)**:*:*<*<#=#= 
	 
	JLLEII'IIIIIDVVgVVVDLL$ %"&<AAIIE$,"4a8883"3t99a00      r#   c                     ddddddddddd
S )Nr   r&   r=   r.   )rX   s    r!   rN   zPerformanceEngine._empty_stats   s/     
 
 	
r#   N)r   )__name__
__module____qualname____doc__r
   r   r   r   ri   r   r~   r   r   rN   r.   r#   r!   r   r      s       ;;8
 8
$sCx. 8
 8
 8
 8
tI< IDc3h<P I I I I6I| IT#s(^8L I I I I6 /6( (((+(	d38n	( ( ( (T
d38n 
 
 
 
 
 
r#   r   )loggingr   r   typingr   r   r   
sqlalchemyr   r	   sqlalchemy.ext.asyncior
   app.models.trader   r   r   app.analytics.metricsr   r   r   r   r   	getLoggerr   loggerr   performance_enginer.   r#   r!   <module>r      s.    ( ( ( ( ( ( ( ( " " " " " " " " " " # # # # # # # # / / / / / / < < < < < < < < < <              
	8	$	$h
 h
 h
 h
 h
 h
 h
 h
V '&((   r#   