
    qi[=              
       j   U d Z ddlZddlZddlZddlZddlmZ ddlZddl	m	Z	 ddl
mZ ddlmZmZmZmZ ddlmZ ddlZddlmZmZ ddlmZ dd	lmZ ddlZd
ddddddddd	Z ej        ej                    ej        d          Z  G d dej!                  Z" G d dej!                  Z# G d d          Z$ eddd          Z%e%&                    ed gd!d gd g"           da'ee$         e(d#<    G d$ d%e          Z) G d& d'e          Z* G d( d)e          Z+ G d* d+e          Z, e	j-                    Z.e%/                    d,          d-             Z0e%1                    d.e,/          d0             Z2e%1                    d1          d2             Z3e%4                    d3e*/          d4e)fd5            Z5e%4                    d6          d4e+fd7            Z6e%4                    d8          dJd9ee7         fd:            Z8e%1                    d;          d<             Z9e:d=k    r e;d>            e;d?            e;d>            e;d@edA                      e;dBedC                      e;dDedE                      e;d>            ej<        dFedA         edC         dGdHI           dS dS )KaD  
ML Inference Server V7
======================
FastAPI server that loads the trained PyTorch model and provides
inference endpoints for the orchestrator.

Endpoints:
- POST /predict - Get trading signal from model
- GET /health - Health check
- POST /load-model - Load a new model
- GET /model-info - Get current model info
    N)datetime)Path)OptionalListDictAny)deque)FastAPIHTTPException)CORSMiddleware)	BaseModelz0.0.0.0i  z2/var/www/html/bestrading.cuttalo.com/models/btc_v7zmodel_best.pt<               )	hostport	model_dirdefault_modellookbacknum_features
hidden_dim	num_heads
num_layers)levelzml-inferencec                   N     e Zd Zddedef fdZdej        dej        fdZ xZS )	PositionalEncoding  d_modelmax_lenc                    t                                                       t          j        |                              d          }t          j        t          j        d|d          t          j        d           |z  z            }t          j        d||          }t          j	        ||z            |dd d dd df<   t          j
        ||z            |dd d dd df<   |                     d|           d S )N   r      g     @pe)super__init__torcharange	unsqueezeexpnplogzerossincosregister_buffer)selfr    r!   positiondiv_termr%   	__class__s         N/var/www/html/bestrading.cuttalo.com/services/ml-inference/inference_server.pyr'   zPositionalEncoding.__init__:   s    <((221559U\!Wa88RVG__<Lw<VWXX[GW--8h#6771aaaA:8h#6771aaaA:T2&&&&&    xreturnc                 T    || j         d d d |                    d          f         z   S )Nr#   )r%   size)r2   r8   s     r6   forwardzPositionalEncoding.forwardC   s*    47111jqvvayyj=)))r7   )r   )	__name__
__module____qualname__intr'   r(   Tensorr<   __classcell__r5   s   @r6   r   r   9   sv        ' ' 'c ' ' ' ' ' '* *%, * * * * * * * *r7   r   c                   Z     e Zd ZdZdef fdZdej        fdZd	dej        de	fdZ
 xZS )
TradingTransformerz Transformer-based trading model.configc           	         t                                                       || _        |                    dd          dz   }|                    dd          }|                    dd          }t	          j        ||          | _        t          ||          | _        t	          j	        ||                    dd	          |d	z  |                    d
d          d          }t	          j
        ||                    dd                    | _        t	          j        t	          j        ||dz            t	          j                    t	          j        |dz  d                    | _        t	          j        t	          j        ||dz            t	          j                    t	          j        |dz  d                    | _        d S )Nr   r   r#   r   r   r   r   r   r   dropoutg?T)r    nheaddim_feedforwardrH   batch_firstr   r   r$   )r&   r'   rF   getnnLinear
input_projr   pos_encoderTransformerEncoderLayerTransformerEncodertransformer
SequentialReLUpolicy_head
value_head)r2   rF   	input_dimr   r   encoder_layerr5   s         r6   r'   zTradingTransformer.__init__J   s   JJ~r22Q6	ZZc22
::j"--)Iz::-j(CC2**[!,,&NJJy#..
 
 
 0JJ|Q''
 

 =Ij*/22GIIIjAoq))
 
 -Ij*/22GIIIjAoq))
 
r7   r8   c                    |                      |          }|                     |          }|                     |          }|d d dd d f         }|                     |          }t	          j        |d d ddf                   }t	          j        |d d ddf         dd          }|                     |          }|||fS )Nr   r#   r$         ?)rO   rP   rS   rV   r(   tanhclamprW   )r2   r8   
policy_outaction_meanaction_log_stdvalues         r6   r<   zTradingTransformer.forwardm   s    OOAQQaaaQQQhK%%a((
jAAAqsF!344Z1Q3%7SAA""NE11r7   Tdeterministicc                    |                      |          \  }}}|r(|                                |                                fS t          j        |          }t          j                            ||          }|                                }t          j        |dd          }|                                |                                fS )zGet action for inference.r[   r#   )r<   squeezer(   r+   distributionsNormalsampler_   )	r2   r8   rd   ra   rb   rc   
action_stddistactions	            r6   
get_actionzTradingTransformer.get_action{   s    -1\\!__*^U 	:&&((%--//99Y~..
"))+zBBVR++~~00r7   )T)r=   r>   r?   __doc__dictr'   r(   rA   r<   boolrm   rB   rC   s   @r6   rE   rE   G   s        **!
t !
 !
 !
 !
 !
 !
F2 2 2 2 21 1EL 1 1 1 1 1 1 1 1 1r7   rE   c                       e Zd ZdZdefdZdedefdZdde	e
         d	e
dej        fd
Zddede
d	e
deeef         fdZddee         fdZdS )InferenceEnginez$Manages model loading and inference.rF   c                 *   || _         t          j        t          j                                        rdnd          | _        d | _        i | _        i | _        |                    dd          | _	        t                              d| j                    d S )Ncudacpur   r   zInferenceEngine initialized on )rF   r(   devicert   is_availablemodel
model_infoprice_buffersrL   r   loggerinfo)r2   rF   s     r6   r'   zInferenceEngine.__init__   s    lUZ-D-D-F-F#Q66ERR37
*, 02

:r22CdkCCDDDDDr7   
model_pathr9   c                 D   	 t           j                            |          st                              d|            dS t          j        || j        d          }|                    d| j	                  }t          |          | _        | j                            |d                    | j                            | j                   | j                                         |                    dd          }t          |d          r|                                }|                    d	d          }t          |d          r|                                }|t#          j                                                    |t)          |t*          t,          f          rt-          |          n|d
 |                                D             d| _        t                              d|            dS # t4          $ r(}t                              d|            Y d}~dS d}~ww xY w)zLoad a PyTorch model.zModel not found: F)map_locationweights_onlyrF   model_state_dictbest_rewardunknownitemepisodec                 R    i | ]$\  }}t          |          |t          |          %S  )callablestr).0kvs      r6   
<dictcomp>z.InferenceEngine.load_model.<locals>.<dictcomp>   s0    YYYAXVW[[Y1c!ffYYYr7   )path	loaded_atr   r   rF   zModel loaded: TFailed to load model: N)osr   existsr{   errorr(   loadrv   rL   rF   rE   rx   load_state_dicttoevalhasattrr   r   now	isoformat
isinstancer@   floatitemsry   r|   	Exception)r2   r}   
checkpointmodel_configr   r   es          r6   
load_modelzInferenceEngine.load_model   s   %	7>>*-- ===>>>uJT[W\]]]J &>>(DK@@L ,L99DJJ&&z2D'EFFFJMM$+&&&JOO %..	BBK{F++ 1)..00 nnY	::Gw'' )!,,.. #%\^^5577"5?cSX\5Z5Zku[111`kYY1C1C1E1EYYY DO KK5556664 	 	 	LL5!5566655555	s   <G-  F+G- -
H7HHr   pricescurrent_positionc           	         t          |          }| j                            dd          }t          j        ||dz   f          }t          j        |          }t          g d          D ]U\  }}||k     rJ||k    rDt          j        |          }	||d         |d|          z
  |d|          z  |	|d<   |	|dd|f<   Vt          g d          D ]\  }}d|z   }
|
|k     r{||k    rut          j        |          }t          ||          D ]G}t          j        t          j	        |||z
  |                   |||z
  |dz
           z            ||<   H||dd|
f<   d|k     r|d	k    rd
dl
}|                    |                              d                                          j        }|                    |                              d	                                          j        }t          j        ||z
  |z            |dddf<   d|k     r|dk    rt          j	        ||d
                   }t          j        |d
k    |d
          }t          j        |d
k     | d
          }d
dl
}|                    |                              d                                          j        }|                    |                              d                                          j        }t          j        ||dz   z            }ddd|z   z  z
  dz  dz
  |dddf<   d|k     r8t          j        t          j	        ||d
                             |z  |dddf<   d|k     rH|dk    rBt          j        |          }|dd         |dd         z
  |dd         z  |dd<   ||dddf<   t          |          D ]d}|dd|f         }t          j        |t          j        |                              }|d
k    r#t          j        ||dz  z  dd          |dd|f<   e||dddf<   t          j        |                              t          j                  S )z$Compute features from price history.r   r   r#   )r#            r   N)r   r   r   r      r   r   
   	      )prependg|=d   r]         ir   r[   )lenrF   rL   r,   r.   array	enumeraterangestddiffpandasSeriesrollingmeanvalues
nan_to_numwhereabsisnanclipastypefloat32)r2   r   r   nr   features
prices_arriperiodretidxvoljpd	sma_shortsma_longdeltagainlossavg_gainavg_lossrsret_20colr   s                            r6   compute_featuresz InferenceEngine.compute_features   s   KK{~r::8Qq 0122Xf%%
 ##5#5#566 	% 	%IAv<AJJhqkk *677 3j6'6J JjYa[aZaYaNbbFGG!$A #;;;// 	' 	'IAva%C\!!a&jjhqkkvq)) ` `AVBGJqxz,B$C$CjQRSYQYZ[\]Z]Q]F^$^__CFF#&C  |R		*--55b99>>@@GIyy,,44R88==??FH]I,@H+LMMHQQQTN |BGJ
1>>>E8EAIua00D8EAIvq11Dyy..r227799@Hyy..r227799@Hx8e+;<==B!C1r6N2c9C?HQQQTN  fRWZA%O%O%OPPS]]HQQQUO RXa[[F%bcc?Z-==DSDAQQF233K$HQQQUO |$$ 	A 	AA111a4.C&bhsmm^,--CQww!#a"a!@!@A +B}X&&--bj999r7   pairpricec                 L   | j         ddiS || j        vrt          | j                  | j        |<   | j        |                             |           t          | j        |                   | j        k     rGdddd|||t          | j        |                   dt          | j        |                    d| j         d		S t          | j        |                   }|                     ||          }|| j         d         }t          j	        |          
                    d
                              | j                  }t          j                    5  | j                             |d          \  }}ddd           n# 1 swxY w Y   |                                }	|                                }
|	dk    rd}t!          d|	dz
  dz            }n7|	dk     rd}t!          d|	 dz
  dz            }nd}dt#          |	          dz  z
  }||	||
|||t          | j        |                   dS )z"Get prediction for a trading pair.Nr   No model loaded)maxlenWAIT        zAccumulating data: /)	signalrl   
confidencerc   r   r   r3   history_lengthmessager   T)rd   g333333?LONGg      ?gffffff?g333333ӿSHORTHOLD)r   rl   r   rc   r   r   r3   r   )rx   rz   r	   r   appendr   listr   r(   FloatTensorr*   r   rv   no_gradrm   r   minr   )r2   r   r   r   r   r   r8   rl   rc   
action_val	value_valr   r   s                r6   predictzInferenceEngine.predict  s   :.// t)))',DM'B'B'BDt$ 	4 ''... t!$'((4=88 !,"%d&8&>"?"?`T5G5M1N1N``QUQ^``
 
 
 d(.//((1ABB T]NOO, h''11!4477DD ]__ 	I 	I J11!41HHMFE	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I [[]]
JJLL	 FS:#3s":;;JJ$FSJ;#4";<<JJFs:44J  $(!$"4T":;;	
 	
 		
s    E::E>E>Nc                     |r,|| j         v r!| j         |                                          dS dS | j                                          dS )Clear price history buffer.N)rz   clear)r2   r   s     r6   clear_historyzInferenceEngine.clear_historyG  s]     	't)))"4(..00000 *) $$&&&&&r7   )r   N)r=   r>   r?   rn   ro   r'   r   rp   r   r   r   r,   ndarrayr   r   r   r   r   r   r   r7   r6   rr   rr      s        ..
Et 
E 
E 
E 
E'S 'T ' ' ' 'R>: >:tE{ >:e >:TVT^ >: >: >: >:@?
 ?
C ?
 ?
 ?
tTWY\T\~ ?
 ?
 ?
 ?
B' '(3- ' ' ' ' ' 'r7   rr   zML Inference Server V7zTrading model inference APIz7.0.0)titledescriptionversion*T)allow_originsallow_credentialsallow_methodsallow_headersenginec                   2    e Zd ZU eed<   eed<   dZeed<   dS )PredictRequestr   r   r   r3   N)r=   r>   r?   r   __annotations__r   r3   r   r7   r6   r   r   g  s4         
IIILLLHer7   r   c                       e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   eed<   d	Zee         ed
<   d	Z	ee         ed<   d	S )PredictResponser   rl   r   rc   r   r   r3   r   Nr   r   )
r=   r>   r?   r   r   r   r@   r   r   r   r   r7   r6   r  r  m  s         KKKMMMLLL
IIILLLOOO!GXc]!!!E8C=r7   r  c                       e Zd ZU eed<   dS )LoadModelRequestr}   N)r=   r>   r?   r   r   r   r7   r6   r  r  z  s         OOOOOr7   r  c                   8    e Zd ZU eed<   eed<   eed<   eed<   dS )HealthResponsestatusmodel_loadedrv   uptimeN)r=   r>   r?   r   r   rp   r   r7   r6   r  r  ~  s7         KKKKKKKKKKKr7   r  startupc                    K   t          t                    at          j                            t          d         t          d                   } t          j                            |           r9t                              |            t          	                    d|             dS t          
                    d|             dS )z)Initialize engine and load default model.r   r   zDefault model loaded: zDefault model not found: N)rr   CONFIGr   r   r   joinr   r   r{   r|   warning)r   s    r6   startup_eventr    s       V$$F GLL!4f_6MNNM	w~~m$$ D-(((<]<<=====B=BBCCCCCr7   z/health)response_modelc                     K   dt           rt           j        dundt           rt          t           j                  ndt          t	          j                    t          z
            dS )zHealth check endpoint.healthyNFzN/A)r  r  rv   r	  )r   rx   r   rv   r   r   startup_timer   r7   r6   healthr    s[       4:ED00(.9#fm$$$Ehlnn|344	  r7   z/model-infoc                  L   K   t           rt           j        sddiS t           j        S )zGet current model information.r   r   )r   rx   ry   r   r7   r6   ry   ry     s.        , ,*++r7   z/predictrequestc                    K   t           st          dd          t                               | j        | j        | j                  }d|v rt          d|d                   |S )zGet trading signal prediction.r   Engine not initializedstatus_codedetailr     )r   r   r   r   r   r3   )r  results     r6   r   r     sh        N4LMMMM^^GL'-9IJJF&F7ODDDDMr7   z/load-modelc                    K   t           st          dd          t                               | j                  }|st          dd| j                   dt           j        dS )zLoad a new model.r   r  r  r  r   T)successry   )r   r   r   r}   ry   )r  r  s     r6   r   r     st        N4LMMMM 233G c4aWM_4a4abbbb6+<===r7   z/clear-historyr   c                 x   K   t           st          dd          t                               |            d| pddS )r   r   r  r  Tall)r  cleared)r   r   r   )r   s    r6   r   r     sK        N4LMMMM
666r7   z/modelsc                    K   t           d         } t          j                            |           sg | dS d t          j        |           D             }|| t
          r+t
          j        rt
          j                            d          nddS )zList available models.r   )models	directoryc                 <    g | ]}|                     d           |S )z.pt)endswith)r   fs     r6   
<listcomp>zlist_models.<locals>.<listcomp>  s)    DDDA!**U2C2CDaDDDr7   r   N)r$  r%  current)r  r   r   r   listdirr   ry   rL   )r   r$  s     r6   list_modelsr,    s       {#I7>>)$$ 69555DDI..DDDF4:Zv?PZ6$((000VZ  r7   __main__z<============================================================zML INFERENCE SERVER V7zHost: r   zPort: r   zModel dir: r   zinference_server:appFr|   )r   r   reload	log_levelr   )=rn   r   sysjsonr(   torch.nnrM   numpyr,   r   pathlibr   typingr   r   r   r   collectionsr	   loggingfastapir
   r   fastapi.middleware.corsr   pydanticr   uvicornr  basicConfigINFO	getLoggerr{   Moduler   rE   rr   appadd_middlewarer   r   r   r  r  r  r   r  on_eventr  rL   r  ry   postr   r   r   r   r,  r=   printrunr   r7   r6   <module>rF     s=     
			 



                         , , , , , , , , , , , ,        * * * * * * * * 2 2 2 2 2 2        E$

 

  ', ' ' ' '		>	*	** * * * * * * *@1 @1 @1 @1 @1 @1 @1 @1N' ' ' ' ' ' ' 'L g
"-     %%%     %)! ( ( (    Y   
  
  
  
  
 i 
  
  
     y       Y    x|~~ iD D D >22  32    *_55
> 
 
 
 65
 -
>. 
> 
> 
> 
> 
7 7hsm 7 7 7 7   $ z	E&MMM	E
"###	E&MMM	E
#6&>
#
#$$$	E
#6&>
#
#$$$	E
-{+
-
-...	E&MMMGKF^F^      r7   