o
    j×íi|  ã                   @   s   d Z ddlZddlZddlZddlZddlmZmZm	Z	 ddl
m
Z
mZmZ ddlmZ ddlmZ ddlmZ e e¡Zd	ZG d
d„ dƒZdS )uÄ   
Binance å®žæ—¶æ•°æ®æ‹‰å–æ¨¡å—

ä¸Ž binance_downloader.py ä¸åŒï¼Œè¿™ä¸ªæ¨¡å—è´Ÿè´£:
- æ¯å°æ—¶å¢žé‡æ‹‰å–æœ€æ–°Kçº¿
- ç»´æŠ¤æœ¬åœ°æ•°æ®åº“çš„æœ€æ–°çŠ¶æ€
- å¤„ç†APIé™æµå’Œé”™è¯¯é‡è¯•
é    N)ÚOptionalÚDictÚList)ÚdatetimeÚtimezoneÚ	timedeltaé   )ÚCOINS)ÚDatabase)Úprepare_all_timeframesz%https://api.binance.com/api/v3/klinesc                	   @   s®   e Zd ZdZddedefdd„Z		dd	ed
ededej	fdd„Z
d	edefdd„Zdeeef fdd„Zdd	edefdd„Zddefdd„Zd	edeeej	f fdd„ZdS )ÚBinanceLiveFetcheruÚ   
    å®žæ—¶Kçº¿æ•°æ®æ‹‰å–å™¨

    ç”¨æ³•:
        fetcher = BinanceLiveFetcher(db)
        fetcher.update_all()  # æ›´æ–°æ‰€æœ‰å¸ç§
        data = fetcher.get_all_timeframes('BTCUSDT')  # èŽ·å–å¤šå‘¨æœŸæ•°æ®
    é   ÚdbÚmax_retriesc                 C   s&   || _ || _t ¡ | _d| jjd< d S )NzLangLangAI/1.0z
User-Agent)r   r   ÚrequestsÚSessionÚsessionÚheaders)Úselfr   r   © r   ú /opt/langlang_ai/live/fetcher.pyÚ__init__$   s   
zBinanceLiveFetcher.__init__Ú1héô  ÚsymbolÚintervalÚlimitÚreturnc                 C   sÚ  | j  ||¡}|||dœ}|r"ttj|dd ¡ d ƒd }||d< t| jƒD ]´}z€| jj	t
|dd}| ¡  | ¡ }	|	sDt ¡ W   S tj|	g d	¢d
}
tj|
d ddd|
d< dD ]}|
|  t¡|
|< q[|
g d¢ }
tjjdd}|dkr~| d¡}n|dkrˆ| d¡}n| d¡}|
|
d |k  }
t dt|
ƒ› d|› d|› ¡ |
W   S  tjjyÛ } z$t d|d › d|› d|› ¡ || jd k rÑt d| ¡ W Y d}~q'd}~ww t d|› d| j› d¡ t ¡ S ) uq   
        æ‹‰å–æœ€æ–°Kçº¿æ•°æ®ï¼ˆå¢žé‡ï¼‰

        è‡ªåŠ¨ä»Žæ•°æ®åº“æœ€æ–°æ—¶é—´æˆ³ä¹‹åŽå¼€å§‹æ‹‰å–
        )r   r   r   ÚUTC©Útzéè  é   Ú	startTimeé   ©ÚparamsÚtimeout©Ú	open_timeÚopenÚhighÚlowÚcloseÚvolumeÚ
close_timeÚquote_volumeÚtradesÚtaker_buy_volÚtaker_buy_quote_volÚignore©Úcolumnsr)   ÚmsT©ÚunitÚutcÚ	timestamp©r*   r+   r,   r-   r.   ©r;   r*   r+   r,   r-   r.   r   Ú4hÚ1DzFetched z new bars for ú zFetch attempt z failed for ú: r   NzFailed to fetch z after z	 attempts)r   Úget_latest_timestampÚintÚpdÚ	Timestampr;   Úranger   r   ÚgetÚBINANCE_KLINE_URLÚraise_for_statusÚjsonÚ	DataFrameÚto_datetimeÚastypeÚfloatÚnowÚfloorÚloggerÚinfoÚlenr   Ú
exceptionsÚRequestExceptionÚwarningÚtimeÚsleepÚerror)r   r   r   r   Úlatestr&   Ústart_tsÚattemptÚrespÚdataÚdfÚcolrO   Úcurrent_bar_startÚer   r   r   Úfetch_latest_klines*   sP   ýÿ
 
 €üz&BinanceLiveFetcher.fetch_latest_klinesc                 C   s.   |   |d¡}|jrdS | j |d|¡ t|ƒS )ud   
        æ›´æ–°å•ä¸ªå¸ç§çš„1Hæ•°æ®å¹¶å­˜å…¥æ•°æ®åº“

        Returns: æ–°å¢žKçº¿æ•°é‡
        r   r   )rc   Úemptyr   Úsave_klinesrS   )r   r   r_   r   r   r   Úupdate_symbolq   s
   z BinanceLiveFetcher.update_symbolc                 C   sN   i }t D ] }|  |¡}|||< |dkrt d|› d|› d¡ t d¡ q|S )uM   
        æ›´æ–°æ‰€æœ‰12å¸ç§

        Returns: {symbol: n_new_bars}
        r   ú  z: +ú barsgš™™™™™É?)r	   rf   rQ   rR   rW   rX   )r   Úresultsr   Únr   r   r   Ú
update_all~   s   
zBinanceLiveFetcher.update_allém  Údaysc              
   C   sÔ  | j  |d¡}||d krt d|› d|› d¡ dS t d|› d|› d	¡ t |¡}|s0dS |j}tt 	t
j¡ ¡ d
 ƒ}ttj|dd ¡ d
 ƒ}d}|}	|	|k rÜ|d|	d
dœ}
z| jjt|
dd}| ¡  | ¡ }W n" ty } zt d|› d|› ¡ t d¡ W Y d}~qPd}~ww |s”nHtj|g d¢d}tj|d ddd|d< dD ]}||  t¡||< q«|g d¢ }| j  |d|¡ |t|ƒ7 }|d d d }	t d ¡ |	|k sTt d|› d!|› d"¡ dS )#u   
        é¦–æ¬¡è¿è¡Œæ—¶ï¼Œæ‹‰å–åŽ†å²æ•°æ®å¡«å……æ•°æ®åº“

        Args:
            symbol: äº¤æ˜“å¯¹
            days: æ‹‰å–å¤šå°‘å¤©çš„åŽ†å²
        r   é   rg   z: already has z bars, skip initNz  Initializing z (z	 days)...r!   r   r   r   )r   r   r#   r   r$   r%   z  Init error rA   é   r(   r5   r)   r7   Tr8   r;   r<   r=   éÿÿÿÿé   r"   g333333Ó?z: initialized rh   )r   Úget_kline_countrQ   rR   r	   rG   Ú
data_startrC   r   rO   r   r:   r;   rD   rE   r   rH   rI   rJ   Ú	ExceptionrY   rW   rX   rK   rL   rM   rN   re   rS   )r   r   rm   ÚexistingÚcfgÚ
start_dateÚend_tsr[   Úall_barsÚcurrentr&   r]   r^   rb   r_   r`   r   r   r   Úinitialize_history   sT   
ü
€ý
à"z%BinanceLiveFetcher.initialize_historyc                 C   s   t D ]}|  ||¡ qdS )u!   åˆå§‹åŒ–æ‰€æœ‰å¸ç§åŽ†å²æ•°æ®N)r	   r{   )r   rm   r   r   r   r   Úinitialize_allÊ   s   ÿz!BinanceLiveFetcher.initialize_allc                 C   s    | j  |d¡}|jri S t|ƒS )us   
        ä»Žæ•°æ®åº“åŠ è½½å¹¶èšåˆå‡ºæ‰€æœ‰æ—¶é—´å‘¨æœŸ

        Returns: {'1H': df, '4H': df, '1D': df}
        r   )r   Úload_klinesrd   r   )r   r   Údf_1hr   r   r   Úget_all_timeframesÏ   s   z%BinanceLiveFetcher.get_all_timeframesN)r   )r   r   )rl   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   rC   r   ÚstrrD   rK   rc   rf   r   rk   r{   r|   r   r   r   r   r   r      s&    		üþýü
ûG= r   )rƒ   rW   Úloggingr   ÚpandasrD   Útypingr   r   r   r   r   r   Úconfig.coinsr	   Údata.databaser
   Údata.aggregatorr   Ú	getLoggerr€   rQ   rH   r   r   r   r   r   Ú<module>   s    	
