o
    d\ïh¤7  ã                   @   sp   d Z ddl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
mZ G dd„ dƒZdadefd	d
„ZdS )u�   
SystÃ¨me de tracking de performance des trades pour amÃ©lioration continue
Stocke chaque trade avec ses conditions d'entrÃ©e et son rÃ©sultat
é    N)ÚdatetimeÚ	timedelta)ÚDictÚListÚOptional)ÚLockc                   @   sÀ   e Zd ZdZd!defdd„Zdd„ Zded	efd
d„Z	dedede
de
de
ded	efdd„Z		d"dededed	efdd„Zd#deded	efdd„Zd#ded	ee fdd„Zd$defdd „ZdS )%ÚTradePerformanceDBu>   Base de donnÃ©es SQLite pour tracker la performance des tradesúdata/trade_performance.dbÚdb_pathc                 C   s<   || _ tƒ | _t d¡| _tjtj 	|¡dd� |  
¡  d S )Nr   T)Úexist_ok)r
   r   ÚlockÚloggingÚ	getLoggerÚloggerÚosÚmakedirsÚpathÚdirnameÚ_init_database)Úselfr
   © r   útrade_performance_db.pyÚ__init__   s
   zTradePerformanceDB.__init__c                 C   sŒ   | j �9 t | j¡}| ¡ }| d¡ | d¡ | d¡ | d¡ | ¡  | ¡  | j 	d| j› �¡ W d  ƒ dS 1 s?w   Y  dS )u(   CrÃ©e les tables si elles n'existent pasu�  
                CREATE TABLE IF NOT EXISTS trades (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    symbol TEXT NOT NULL,
                    side TEXT NOT NULL,
                    entry_price REAL NOT NULL,
                    exit_price REAL,
                    size REAL NOT NULL,
                    leverage INTEGER NOT NULL,

                    -- Conditions d'entrÃ©e
                    regime TEXT,
                    rsi REAL,
                    macd_signal TEXT,
                    trend_score REAL,
                    momentum_score REAL,
                    volatility_score REAL,
                    volume_score REAL,
                    signal_score REAL,
                    quality_score REAL,

                    -- RÃ©sultat
                    win INTEGER,
                    pnl_pct REAL,
                    pnl_usd REAL,
                    duration_minutes INTEGER,
                    close_reason TEXT,

                    -- Timestamps
                    entry_time TIMESTAMP NOT NULL,
                    exit_time TIMESTAMP,

                    UNIQUE(symbol, side, entry_time)
                )
            ze
                CREATE INDEX IF NOT EXISTS idx_regime
                ON trades(regime)
            zp
                CREATE INDEX IF NOT EXISTS idx_symbol_side
                ON trades(symbol, side)
            zm
                CREATE INDEX IF NOT EXISTS idx_entry_time
                ON trades(entry_time)
            u   Base de donnÃ©es initialisÃ©e: N)
r   Úsqlite3Úconnectr
   ÚcursorÚexecuteÚcommitÚcloser   Úinfo)r   Úconnr   r   r   r   r      s   

%

"Äz!TradePerformanceDB._init_databaseÚ
trade_dataÚreturnc                 C   s*  zx| j �j t | j¡}| ¡ }| d|d |d |d |d |d | dd¡| d	¡| d
¡| d¡| d¡| d¡| d¡| d¡| d¡t ¡ f¡ | 	¡  | 
¡  | j d|d › d|d › �¡ 	 W d  ƒ W dS 1 sqw   Y  W dS  ty” } z| j d|› �¡ W Y d}~dS d}~ww )a]  
        Log l'ouverture d'un trade

        Args:
            trade_data: {
                'symbol': 'BTC',
                'side': 'LONG',
                'entry_price': 64000,
                'size': 0.01,
                'leverage': 10,
                'regime': 'BEAR_VOLATILE',
                'rsi': 35,
                'macd_signal': 'bullish',
                'trend_score': 0.6,
                'momentum_score': 0.7,
                'volatility_score': 0.5,
                'volume_score': 0.8,
                'signal_score': 0.45,
                'quality_score': 0.65
            }
        a™  
                    INSERT OR IGNORE INTO trades (
                        symbol, side, entry_price, size, leverage,
                        regime, rsi, macd_signal, trend_score, momentum_score,
                        volatility_score, volume_score, signal_score, quality_score,
                        entry_time
                    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                ÚsymbolÚsideÚentry_priceÚsizeÚleverageÚregimeÚUNKNOWNÚrsiÚmacd_signalÚtrend_scoreÚmomentum_scoreÚvolatility_scoreÚvolume_scoreÚsignal_scoreÚquality_scoreu   Trade ouvert loggÃ©: ú NTzErreur log trade open: F)r   r   r   r
   r   r   Úgetr   Únowr   r   r   r   Ú	ExceptionÚerror)r   r!   r    r   Úer   r   r   Úlog_trade_open[   s@   
ñù (ß#€þz!TradePerformanceDB.log_trade_openr#   r$   Ú
exit_priceÚpnl_pctÚpnl_usdÚclose_reasonc                 C   s^  z’| j �„ t | j¡}| ¡ }| d||f¡ | ¡ }	|	s7| j d|› d|› �¡ | 	¡  	 W d  ƒ W dS |	\}
}}t
 ¡ }t
 |¡}t||  ¡ d ƒ}|dkrUdnd}| d	||||||||
f¡ | ¡  | 	¡  | j d
|› d|› d|d›d�¡ 	 W d  ƒ W dS 1 s‹w   Y  W dS  ty® } z| j d|› �¡ W Y d}~dS d}~ww )a=  
        Log la fermeture d'un trade

        Args:
            symbol: Symbole du trade
            side: LONG ou SHORT
            exit_price: Prix de sortie
            pnl_pct: PnL en pourcentage
            pnl_usd: PnL en USD
            close_reason: Raison de fermeture (STOP_LOSS, TAKE_PROFIT, etc.)
        zù
                    SELECT id, entry_time, entry_price
                    FROM trades
                    WHERE symbol = ? AND side = ? AND exit_time IS NULL
                    ORDER BY entry_time DESC
                    LIMIT 1
                u    Aucun trade ouvert trouvÃ© pour r2   NFé<   r   é   ae  
                    UPDATE trades
                    SET exit_price = ?,
                        win = ?,
                        pnl_pct = ?,
                        pnl_usd = ?,
                        duration_minutes = ?,
                        close_reason = ?,
                        exit_time = ?
                    WHERE id = ?
                u   Trade fermÃ© loggÃ©: z - PnL: z.2fú%TzErreur log trade close: )r   r   r   r
   r   r   Úfetchoner   Úwarningr   r   r4   ÚfromisoformatÚintÚtotal_secondsr   r   r5   r6   )r   r#   r$   r9   r:   r;   r<   r    r   ÚresultÚtrade_idÚ
entry_timer%   Ú	exit_timeÚentry_dtÚduration_minutesÚwinr7   r   r   r   Úlog_trade_close™   sN   úî

øö"(È:€þz"TradePerformanceDB.log_trade_closeNé   r(   Údaysc           
   
   C   sR  zˆ| j �z t | j¡}| ¡ }d}|g}|r|d7 }| |¡ |r*|d7 }| |¡ | ||¡ | ¡ }| ¡  |rm|d dkrm|d pEd|d pJd|d pOd|d	 pTdt	|d pZdƒt	|d
 padƒdœW  d  ƒ W S dddddddœW  d  ƒ W S 1 s�w   Y  W dS  t
y¨ }	 z| j d|	› �¡ dddœW  Y d}	~	S d}	~	ww )u  
        RÃ©cupÃ¨re les performances par pattern

        Args:
            regime: Filtrer par rÃ©gime (BULL_STABLE, BEAR_VOLATILE, etc.)
            side: Filtrer par side (LONG, SHORT)
            days: Nombre de jours d'historique

        Returns:
            {
                'win_rate': 0.65,
                'avg_pnl_pct': 2.3,
                'avg_pnl_winners': 3.5,
                'avg_pnl_losers': -1.8,
                'total_trades': 150,
                'avg_duration_minutes': 45
            }
        ad  
                    SELECT
                        AVG(CASE WHEN win = 1 THEN 1.0 ELSE 0.0 END) as win_rate,
                        AVG(pnl_pct) as avg_pnl_pct,
                        AVG(CASE WHEN win = 1 THEN pnl_pct END) as avg_pnl_winners,
                        AVG(CASE WHEN win = 0 THEN pnl_pct END) as avg_pnl_losers,
                        COUNT(*) as total_trades,
                        AVG(duration_minutes) as avg_duration
                    FROM trades
                    WHERE exit_time IS NOT NULL
                    AND entry_time > datetime('now', '-' || ? || ' days')
                z AND regime = ?z AND side = ?é   r   ç        r>   é   é   é   )Úwin_rateÚavg_pnl_pctÚavg_pnl_winnersÚavg_pnl_losersÚtotal_tradesÚavg_duration_minutesNç      à?z Erreur get pattern performance: ©rT   rX   )r   r   r   r
   r   Úappendr   r@   r   rC   r5   r   r6   )
r   r(   r$   rN   r    r   ÚqueryÚparamsrE   r7   r   r   r   Úget_pattern_performanceå   sJ   





úÞ,ú(Õ4€þz*TradePerformanceDB.get_pattern_performancec              
   C   sö   zZ| j �L t | j¡}| ¡ }| d||f¡ | ¡ }| ¡  |rC|d dkrC|d p,d|d p1dt|d p7dƒdœW  d  ƒ W S ddd	œW  d  ƒ W S 1 sSw   Y  W dS  t	yz } z| j
 d
|› �¡ ddd	œW  Y d}~S d}~ww )u7   RÃ©cupÃ¨re les performances pour un symbole spÃ©cifiquea�  
                    SELECT
                        AVG(CASE WHEN win = 1 THEN 1.0 ELSE 0.0 END) as win_rate,
                        AVG(pnl_pct) as avg_pnl,
                        COUNT(*) as total_trades
                    FROM trades
                    WHERE symbol = ?
                    AND exit_time IS NOT NULL
                    AND entry_time > datetime('now', '-' || ? || ' days')
                rQ   r   rZ   r>   rP   )rT   Úavg_pnlrX   Nr[   zErreur get symbol performance: )r   r   r   r
   r   r   r@   r   rC   r5   r   r6   )r   r#   rN   r    r   rE   r7   r   r   r   Úget_symbol_performance2  s,   	÷

ýí(ç€þz)TradePerformanceDB.get_symbol_performancec              
   C   sª   z7| j �) t | j¡}| ¡ }| d|f¡ | ¡ }| ¡  dd„ |D ƒW  d  ƒ W S 1 s0w   Y  W dS  tyT } z| j	 
d|› �¡ g W  Y d}~S d}~ww )u+   RÃ©cupÃ¨re les stats par rÃ©gime de marchÃ©aá  
                    SELECT
                        regime,
                        COUNT(*) as trades,
                        AVG(CASE WHEN win = 1 THEN 1.0 ELSE 0.0 END) as win_rate,
                        AVG(pnl_pct) as avg_pnl
                    FROM trades
                    WHERE exit_time IS NOT NULL
                    AND entry_time > datetime('now', '-' || ? || ' days')
                    GROUP BY regime
                    ORDER BY trades DESC
                c                 S   s6   g | ]}|d  t |d ƒ|d pd|d pddœ‘qS )r   r>   rQ   rP   rR   )r(   ÚtradesrT   r`   )rC   )Ú.0Úrr   r   r   Ú
<listcomp>k  s    û


üÿz<TradePerformanceDB.get_regime_statistics.<locals>.<listcomp>NzErreur get regime statistics: )r   r   r   r
   r   r   Úfetchallr   r5   r   r6   )r   rN   r    r   Úresultsr7   r   r   r   Úget_regime_statisticsT  s$   õù(ì€þz(TradePerformanceDB.get_regime_statisticsé   c              
   C   sÆ   zF| j �8 t | j¡}| ¡ }| d|f¡ |j}| ¡  | ¡  |dkr2| j	 
d|› d|› d�¡ |W  d  ƒ W S 1 s?w   Y  W dS  tyb } z| j	 d|› �¡ W Y d}~dS d}~ww )z%Nettoie les trades de plus de X joursz„
                    DELETE FROM trades
                    WHERE entry_time < datetime('now', '-' || ? || ' days')
                r   zNettoyage: u    trades supprimÃ©s (>z jours)NzErreur cleanup: )r   r   r   r
   r   r   Úrowcountr   r   r   r   r5   r6   )r   rN   r    r   Údeletedr7   r   r   r   Úcleanup_old_datay  s&   ý(ð€þz#TradePerformanceDB.cleanup_old_data)r	   )NNrM   )rM   )ri   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústrr   r   r   Úboolr8   ÚfloatrL   rC   r_   ra   r   rh   rl   r   r   r   r   r      s0    @>ÿÿÿ
ÿLÿÿ
ÿM"%r   r"   c                   C   s   t du rtƒ a t S )u(   RÃ©cupÃ¨re l'instance singleton de la DBN)Ú_db_instancer   r   r   r   r   Úget_performance_db–  s   ru   )rp   r   r   r   r   r   Útypingr   r   r   Ú	threadingr   r   rt   ru   r   r   r   r   Ú<module>   s       
