a
    Gwj4!                     @  s&  d dl m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mZm	Z	 d dl
mZ d dlmZmZmZmZ d dlmZ G dd	 d	eZeegef Zeegdf Zeegdf Zed
dG dd dZG dd dZG dd dZdd	dddZdddddZddddZddddZdS )     )annotationsN)	dataclass)datetimetimezone)Event)CallableIterableMappingProtocol)Tickc                   @  s8   e Zd ZdddddZdddd	Zddd
dZdS )WebSocketConnectionstrobject)payloadreturnc                 C  s   d S N )selfr   r   r   =/home/opc/hanz-radar/runtime/src/hanz_providers/twelvedata.pysend   s    zWebSocketConnection.sendstr | bytesr   c                 C  s   d S r   r   r   r   r   r   recv   s    zWebSocketConnection.recvc                 C  s   d S r   r   r   r   r   r   close   s    zWebSocketConnection.closeN)__name__
__module____qualname__r   r   r   r   r   r   r   r      s   r   T)frozenc                   @  s   e Zd ZU ded< ded< dZded< dZded< d	Zded
< dZded< dZded< dZ	ded< e
dddddddZddddZdS )TwelveDataConfigr   api_keyztuple[str, ...]symbolsBEImarketTWELVE_DATAsourcez'wss://ws.twelvedata.com/v1/quotes/pricewebsocket_url
   intheartbeat_secondsg      ?floatreconnect_min_secondsg      >@reconnect_max_secondsNzIterable[str] | Nonez'TwelveDataConfig')r!   r#   r   c                 C  sv   t dd }|std|d u rDt dd}dd |dD }ttdd	 |D }|shtd
| |||dS )NZHANZ_TWELVEDATA_API_KEY z#HANZ_TWELVEDATA_API_KEY is requiredZHANZ_TWELVEDATA_SYMBOLSc                 S  s   g | ]}|  r|  qS r   )strip.0itemr   r   r   
<listcomp>4       z-TwelveDataConfig.from_env.<locals>.<listcomp>,c                 s  s   | ]}t | V  qd S r   )r   r.   r/   r   r   r   	<genexpr>6   r3   z,TwelveDataConfig.from_env.<locals>.<genexpr>z+At least one Twelve Data symbol is required)r    r!   r#   )osgetenvr.   
ValueErrorsplittupledictfromkeys)clsr!   r#   r    rawZ
normalizedr   r   r   from_env(   s    zTwelveDataConfig.from_envr   c                 C  s   | j  d| j S )Nz?apikey=)r&   r    r   r   r   r   endpoint@   s    zTwelveDataConfig.endpoint)Nr"   )r   r   r   __annotations__r#   r%   r&   r)   r+   r,   classmethodr?   r@   r   r   r   r   r      s   
  r   c                   @  s>   e Zd ZdZddddddddd	d
dZdddddZdS )TwelveDataMessageParserzBConvert Twelve Data WebSocket messages into normalized HANZ ticks.r"   r$   N)r#   r%   symbol_aliasesr   zMapping[str, str] | NoneNone)r#   r%   rD   r   c                C  s.   || _ || _dd |pi  D | _i | _d S )Nc                 S  s"   i | ]\}}t |t | qS r   )r   upper)r0   keyvaluer   r   r   
<dictcomp>P   s   z4TwelveDataMessageParser.__init__.<locals>.<dictcomp>)r#   r%   itemsrD   _last_cumulative_volume)r   r#   r%   rD   r   r   r   __init__G   s    
z TwelveDataMessageParser.__init__r   zTick | dict | None)r>   r   c                 C  s\  t |tr|d}t|}t|dp6|dp6d }|dv rJ|S |dkrVd S t|dpdd }t	|d}t
|dp|d	p|d
}|r|d u s|dks|d u rd S t	|dp|dp|d}| j|t|}| j|}	|d u r|	pd}
n|	d ur,||	k r,|}
n|}
|d urD|| j|< t|| j||
|| jdS )Nzutf-8eventtyper-   >   	heartbeatzsubscribe-statusstatuspricesymbol	timestampr   timer   Z
day_volumevolumeZ	dayVolume        )rR   r#   rQ   rU   rS   r%   )
isinstancebytesdecodejsonloadsr   getlowerr.   	_to_float_to_timestamprD   _clean_symbolrK   r   r#   r%   )r   r>   r   rM   
raw_symbolrQ   rS   cumulative_volumerR   previousZnormalized_volumer   r   r   parseV   sR    


 




zTwelveDataMessageParser.parse)r   r   r   __doc__rL   rd   r   r   r   r   rC   D   s   rC   c                	   @  s   e Zd ZdZdddejddddddd	d
dddZd
dddZd
dddZdd
dddZ	e
dd
dddZdddddZdS )TwelveDataProviderzResilient Twelve Data WebSocket provider.

    The provider supplies normalized ticks to RealtimeGateway. It does not make
    trading decisions and does not expose the API key to dashboard clients.
    N)	on_statusconnection_factoryparsersleepr   TickCallbackzStatusCallback | NonezConnectionFactory | NonezTwelveDataMessageParser | NonezCallable[[float], None]rE   )configon_tickrg   rh   ri   rj   r   c                C  sL   || _ || _|pdd | _|p t| _|p6t|j|jd| _|| _	t
 | _d S )Nc                 S  s   d S r   r   )r   r   r   r   <lambda>   r3   z-TwelveDataProvider.__init__.<locals>.<lambda>)r#   r%   )rl   rm   rg   _default_connectionrh   rC   r#   r%   ri   rj   r   _stop)r   rl   rm   rg   rh   ri   rj   r   r   r   rL      s    

zTwelveDataProvider.__init__r   c                 C  s   | j   d S r   )rp   setr   r   r   r   stop   s    zTwelveDataProvider.stopc                 C  s~  d}| j  szd }z2z| | j }| | d}t }| j  st | | jjkrp| 	| t }|
 }| j|}t|tr| | q@t|tr@| | q@W nf ty } zL|d7 }| d| jj|t|d | j  s| | | W Y d }~n
d }~0 0 W |d urxz|  W n tyF   Y n0 q|d urvz|  W n tyt   Y n0 0 qd S )Nr      zprovider-error)rM   Zproviderattempterror)rp   is_setrh   rl   r@   
_subscriberT   	monotonicr)   
_heartbeatr   ri   rd   rW   r   rm   r;   rg   	Exceptionr%   r   rj   _backoffr   )r   rt   
connectionZlast_heartbeatr>   parsedexcr   r   r   run_forever   sR    





(

zTwelveDataProvider.run_foreverr   )r|   r   c              	   C  s(   | tddd| jjid d S )NZ	subscriber!   r4   )actionparams)r   rZ   dumpsjoinrl   r!   )r   r|   r   r   r   rw      s
    zTwelveDataProvider._subscribec                 C  s   |  tddi d S )Nr   rO   )r   rZ   r   )r|   r   r   r   ry      s    zTwelveDataProvider._heartbeatr(   r*   )rt   r   c                 C  sB   t | jj| jjdt|d d  }t | jj|td|d  S )N   rs   r   rV   g333333?)minrl   r,   r+   maxrandomuniform)r   rt   Zceilingr   r   r   r{      s    zTwelveDataProvider._backoff)r   r   r   re   rT   rj   rL   rr   r   rw   staticmethodry   r{   r   r   r   r   rf      s   +rf   r   )urlr   c              
   C  sJ   zdd l }W n. ty: } ztd|W Y d }~n
d }~0 0 |j| ddS )Nr   z,Install dependency: websocket-client>=1.8,<2   )timeout)	websocketImportErrorRuntimeErrorcreate_connection)r   r   r~   r   r   r   ro      s    ro   )ra   r   c                 C  sF   |    }dD ]}||v r||d }qd|v rB|dd }|S )N):/r   .)rF   r.   r9   )ra   rH   	separatorr   r   r   r`      s    r`   zfloat | Noner   c              	   C  s>   z | d u s| dkrW d S t | W S  ttfy8   Y d S 0 d S )Nr-   )r*   	TypeErrorr8   )rH   r   r   r   r^      s    
r^   zdatetime | Nonec                 C  sZ   z8| d u rW d S t | }|dkr(|d }tj|tjdW S  ttttfyT   Y d S 0 d S )Nl    d(	 g     @@)tz)	r*   r   fromtimestampr   utcr   r8   OSErrorOverflowError)rH   Znumericr   r   r   r_     s    r_   ) 
__future__r   rZ   r6   r   rT   dataclassesr   r   r   	threadingr   typingr   r   r	   r
   Zhanz_realtime.modelsr   r   r   ZConnectionFactoryrk   r;   ZStatusCallbackr   rC   rf   ro   r`   r^   r_   r   r   r   r   <module>   s*   	&Ea

	