
    )i5                        d Z ddlZddlmZ ddlmc mZ ddlZddl	m
Z
  G d dej                        Z G d dej                        Z G d d	ej                        Zg d
Z ee      ZdddddZ	 ddddedede
ej(                     fdZ	 ddee   dededeej(                  ej(                  ej(                  f   fdZy)u
  
SPY Optimizer — Deep Learning Model (GPU)
Architecture LSTM + Temporal Attention pour prédire la rentabilité des signaux de surge.

Conçu pour être entraîné sur GPU (RTX 3060+) et exporté pour inference CPU sur le serveur.

Architecture:
  Input (seq_len × n_features) → LSTM bidirectionnel → Temporal Attention → FC → sigmoid

Le modèle prend en entrée une SÉQUENCE de features (ex: 60 minutes de données 1m),
pas un vecteur plat comme LightGBM. Cela lui permet de capturer les patterns temporels.
    N)Optionalc                   ~     e Zd ZdZdef fdZdej                  deej                  ej                  f   fdZ	 xZ
S )TemporalAttentionuE   Attention mechanism pour pondérer les timesteps les plus importants.hidden_sizec                     t         |           t        j                  t        j                  ||dz        t        j
                         t        j                  |dz  d            | _        y )N      )super__init__nn
SequentialLinearTanh	attention)selfr   	__class__s     ;/home/ubuntu/crypto_trading_bot/spy_optimizer/deep_model.pyr   zTemporalAttention.__init__   sM    IIk;!#34GGIIIkQ&*
    lstm_outputreturnc                     | j                  |      j                  d      }t        j                  |d      }t	        j
                  |j                  d      |      j                  d      }||fS )u   
        Args:
            lstm_output: (batch, seq_len, hidden_size)
        Returns:
            context: (batch, hidden_size) — weighted sum
            weights: (batch, seq_len) — attention weights
        r	   dim)r   squeezeFsoftmaxtorchbmm	unsqueeze)r   r   scoresweightscontexts        r   forwardzTemporalAttention.forward   s^     ,44R8))F*))G--a0+>FFqIr   )__name__
__module____qualname____doc__intr   r   Tensortupler$   __classcell__r   s   @r   r   r      s;    O
C 
 5<<  E%,,:T4U  r   r   c                        e Zd ZdZ	 	 	 	 	 ddedededededef fdZd	 Z	 dd
ej                  dej                  de
defdZ xZS )SurgePredictoru   
    LSTM bidirectionnel + Attention Temporelle pour prédire si un surge sera rentable.

    Le modèle reçoit une séquence temporelle de features (klines pré-processées)
    et produit une probabilité de trade profitable.
    
n_featuresr   
num_layersdropoutn_surge_typessurge_embed_dimc                    t         |           || _        || _        || _        t        j                  t        j                  ||      t        j                  |      t        j                         t        j                  |dz              | _        t        j                  |||dd|dkD  r|nd      | _        t        |dz        | _        t        j                   |dz   |      | _        |dz  |z   }t        j                  t        j                  ||      t        j                  |      t        j                         t        j                  |      t        j                  ||dz        t        j                         t        j                  |dz        t        j                  |dz  d            | _        | j'                          y )N      ?Tr	   r   )
input_sizer   r1   batch_firstbidirectionalr2   r   )r
   r   r0   r   r1   r   r   r   	LayerNormGELUDropout
input_projLSTMlstmr   r   	Embeddingsurge_embedding
classifier_init_weights)	r   r0   r   r1   r2   r3   r4   classifier_inputr   s	           r   r   zSurgePredictor.__init__5   sa    	$&$ --IIj+.LL%GGIJJw}%	
 GG"#!)A~G1
	 +;?;  "||MA,=O '?_<--II&4LL%GGIJJwIIk;!#34GGIJJw}%IIkQ&*	
 	r   c                     | j                         D ]`  \  }}d|v r3|j                         dk\  r t        j                  j	                  |       =d|v sBt        j                  j                  |       b y)z7Xavier initialization pour une convergence plus rapide.weightr   biasN)named_parametersr   r   initxavier_uniform_zeros_)r   nameparams      r   rC   zSurgePredictor._init_weightsj   s\    002 	&KD%4EIIK1$4''.4u%		&r   x
surge_typereturn_attentionr   c                 N   | j                  |      }| j                  |      \  }}| j                  |      \  }}| j                  |      }	t	        j
                  ||	gd      }
| j                  |
      j                  d      }t	        j                  |      }||d}|r||d<   |S )uR  
        Args:
            x: (batch, seq_len, n_features) — séquence temporelle
            surge_type: (batch,) — index du type de surge (0-3)
            return_attention: si True, retourne aussi les poids d'attention

        Returns:
            dict avec 'logits', 'probability', et optionnellement 'attention_weights'
        r	   r   r   )logitsprobabilityattention_weights)	r=   r?   r   rA   r   catrB   r   sigmoid)r   rN   rO   rP   	projectedlstm_out_r#   attn_weights	surge_embcombinedrR   probresults                 r   r$   zSurgePredictor.forwardr   s      OOA&	 ii	*! !%x 8 ((4	 99gy1q9*2226}}V$"48*6F&'r   )   r   g333333?      )F)r%   r&   r'   r(   r)   floatr   rC   r   r*   booldictr$   r,   r-   s   @r   r/   r/   -   s      33 3 	3
 3 3 3j& "'	#<<# LL# 	#
 
#r   r/   c                   x     e Zd ZdZdef fdZdej                  dej                  dej                  fdZ xZ	S )SurgePredictorExportWrapperu{   
    Wrapper pour exporter le modèle avec TorchScript.
    Simplifie l'interface pour l'inference CPU sur le serveur.
    modelc                 0    t         |           || _        y )N)r
   r   rg   )r   rg   r   s     r   r   z$SurgePredictorExportWrapper.__init__   s    
r   rN   rO   r   c                 4    | j                  ||d      }|d   S )u<   Retourne uniquement la probabilité (pour inference simple).F)rP   rS   )rg   )r   rN   rO   r^   s       r   r$   z#SurgePredictorExportWrapper.forward   s!    AzEBm$$r   )
r%   r&   r'   r(   r/   r   r   r*   r$   r,   r-   s   @r   rf   rf      s:    
n % %5<< %ELL %r   rf   )r   high_low_rangeclose_positionvolume_normquote_volume_normbuy_pressurenum_trades_norm
body_ratio
upper_wick
lower_wick	ema7_dist
ema21_distrsi_normbb_positionr	   r   r`   )FLASH_SURGEBREAKOUT_SURGEMOMENTUM_SURGEUNKNOWNdfzpd.DataFrametimestamp_msseq_lenr   c                 X
   ddl }d}|||z   dz  dz  z
  }| d   |k\  | d   |k  z  }| j                  |   j                         }t        |      |dz   k  ry|d   j                  }|d	   j                  }	|d
   j                  }
|d   j                  }|d   j                  }|d   j                  }|d   j                  }|d   j                  }t        |      }t        j                  |      }|d   |d<   d}t        d|      D ]  }|||   z  d|z
  ||dz
     z  z   ||<    t        j                  |      }|d   |d<   d}t        d|      D ]  }|||   z  d|z
  ||dz
     z  z   ||<    t        j                  ||d         }t        j                  |dkD  |d      }t        j                  |dk  | d      }t        j                  |      }t        j                  |      }|d   |d<   |d   |d<   d}t        d|      D ]6  }|||   z  d|z
  ||dz
     z  z   ||<   |||   z  d|z
  ||dz
     z  z   ||<   8 t        j                  |dkD  ||z  d      }ddd|z   z  z
  }t        j                  |      }t        j                  |      }t        |      D ]O  }t        d|dz
        } || |dz    }!|!j                         ||<   t        |!      dkD  r|!j                         nd||<   Q |d|z  z   }"|d|z  z
  }#t        j                  |t        j                  d      dz  d      }$t        j                  |j                  t               t        j                  d      dz  d      }%t        j                  |t"        f      }&||z
  }'t        |      D ]  }|'|z   }(||(   })|	|(   }*|
|(   }+||(   },|*|+kD  r|*|+z
  nd}-|(dkD  r!||(dz
     dkD  r|)||(dz
     z  dz
  dz  |&|df<   |)dkD  r|-|)z  dz  nd|&|df<   |-dkD  r|)|+z
  |-z  nd|&|df<   ||(   t        |$|(   d      z  |&|df<   ||(   t        |$|(   d      z  |&|df<   ||(   t        ||(   d      z  |&|df<   ||(   t        |%|(   d      z  |&|df<   |-dkD  r|)|,z
  |-z  nd|&|d f<   |-dkD  r|*t        |)|,      z
  |-z  nd|&|d!f<   |-dkD  rt%        |)|,      |+z
  |-z  nd|&|d"f<   |)dkD  r|)||(   z
  |)z  dz  nd|&|d#f<   |)dkD  r|)||(   z
  |)z  dz  nd|&|d$f<   ||(   dz  |&|d%f<   |"|(   |#|(   z
  }.|.dkD  r|)|#|(   z
  |.z  nd|&|d&f<    |&S )'u  
    Construit une séquence de features normalisées pour le modèle LSTM.

    Contrairement au feature engineering tabular (qui résume 120min en 50 features),
    ici on garde la dimension temporelle: chaque minute = un vecteur de N_SEQUENCE_FEATURES.

    Args:
        df: DataFrame klines avec colonnes standard
        timestamp_ms: timestamp en ms du moment d'analyse
        seq_len: longueur de la séquence (nombre de minutes)

    Returns:
        np.ndarray (seq_len, N_SEQUENCE_FEATURES) ou None si données insuffisantes
    r   N2   <     	open_time   closehighlowopenvolumequote_volume
num_tradestaker_buy_quote_volg      ?r	   gF]tE?)prependg$I$I?d      r   same)modeg:0yE>r6   r`               ra   	   
            )pandasloccopylenvaluesnpzerosrangediffwheremaxmeanstdconvolveonesastyperb   N_SEQUENCE_FEATURESmin)/r{   r|   r}   pdwarmupstart_msmaskwindowr   r   r   opnr   	quote_volr   taker_buy_qvolnema7alpha7iema21alpha21deltagainlossavg_gainavg_loss	alpha_rsirsrsi_valsbb_mid
bb_std_arrstart	window_bbbb_upperbb_lowervol_ma	trades_maseqoffsetidxchlohl_rangebb_ranges/                                                  r   build_sequence_featuresr      s!   &  F& 0B6=>H{Ox'B{O|,KLDVVD\ F
6{Wr\!7O""E&>  D
-

C
.

CH$$F~&--I%,,J1299NFA 88A;DAhDGF1a[ A58#q6zT!a%[&@@QA HHQKEQxE!HG1a[ EU1X%Wa!e(DDaE GGE58,E88EAIua(D88EAIvq)Dxx{Hxx{Hq'HQKq'HQKI1a[ N$q')Q]hq1uo,MM$q')Q]hq1uo,MMN 
(Q,8 3S	9BSAF^#H XXa[F!J1X EAq2v%A&	NN$q	+.y>A+=	1
1	E
 J&HJ&H [[BGGBK"$46BFJ--e4bggbkB6FVTI ((G01
2C[F7^ %Pqj#JIHHE1q5t 7uS1W~)U37^+a/36C1I*+a%HqL3&QAqD	*2T/QUh&sAqD	3K#fSk4"88AqD	cNSd%;;AqD	"3'#ind*CCAqD	sOc)C.$&??AqD	*2T/QUh&qAqD	2:T/QQ]h.qAqD	2:T/SAY]h.qAqD	23a%a$s)mq(3.QArE
34q5a%*n)C/aArE
c]S(ArE
C=8C=07?$a(3-'83CArE
K%PN Jr   trades
klines_dirc           
         ddl }ddlm} g }g }g }d}i }	t        |       D ]  \  }
}|j	                  dd      }|j	                  dd      }|r|s|dz  }5||	vr ||      | dz  }|j                         s\|j                  d	      r|j                  d	d
      n|j                  d
d	      } ||      | dz  }|j                         r|}n|dz  }|j                  |      |	|<   |	|   }	 t        |j                  |      j                         dz        }t        |||      }||dz  }|j                  |       |j	                  dd      }|j                  t        j	                  |d             |j                  t!        |j	                  dd            dkD  rdnd       |
dz   dz  dk(  st#        d|
dz    dt%        |        d| d        t#        dt%        |       d| d       t'        j(                  |t&        j*                        t'        j(                  |t&        j,                        t'        j(                  |t&        j*                        fS # t        $ r	 |dz  }Y Rw xY w)u   
    Construit le dataset séquentiel pour le modèle LSTM.

    Returns:
        X: (n_samples, seq_len, N_SEQUENCE_FEATURES)
        surge_types: (n_samples,) — indices des surge types
        y: (n_samples,) — target profitable (0/1)
    r   N)Pathsymbol 
entry_timer	   z.parquetUSDCUSDTr   rO   rz   r`   pnl_usdtr   z  Processed /z	 trades (z	 skipped)z  Done: z sequences, z skipped)dtype)r   pathlibr   	enumerategetexistsendswithreplaceread_parquetr)   	Timestamp	timestamp	Exceptionr   appendSURGE_TYPE_MAPrb   printr   r   arrayfloat32int64)r   r   r}   r   r   X_list
surge_listy_listskippedloaded_klinesr   trader   r   parquet_path
alt_symbolalt_pathr{   ts_msr   rO   s                        r   build_sequence_datasetr   K  so    FJFGMf% )S58R(YY|R0
ZqLG &
+.AAL&&(!'!8 %nnVV<#)>>&&#A   
+H.EE??$#+LqLG$&OOL$AM&!6"	Z0::<tCDE
 &b%9;qLGcYY|Y7
.,,Z;<5:q!9:Q>aAFES=ALQqVYwiyQRS)SV 
HS[MgYh
?@ 	rzz*
288,
rzz* '  	qLG	s   -+I!!I32I3)r   )r(   r   torch.nnr   torch.nn.functional
functionalr   numpyr   typingr   Moduler   r/   rf   SEQUENCE_FEATURESr   r   r   r)   ndarrayr   listrd   strr+   r    r   r   <module>r     s         		  2hRYY hV%")) %& " +,  	 AAA A bjj	AN GJGG G 2::rzz2::-.	Gr   