Ë
    šå®j0  ã                  ó¸  — d Z ddlmZ ddlZddlZddlZddlZddlZddl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 ddlmZ  ej(                  dd«      Z e ej(                  d	d
«      «      Z ej(                  dd«      j1                  d«      D � cg c]1  } | j3                  «       sŒ| j3                  «       j5                  «       ‘Œ3 c} Z ee«      j:                  Z edddd¬«      Zd d!d„Z d d!d„Z!d"d„Z"d#d„Z#d#d„Z$d#d„Z% G d„ de«      Z&e'dk(  rD eeefe&«      Z( e)de› de› �«        e)ddjU                  e«      › �«       e(jW                  «        yyc c} w )$z7Local, read-only Kraken market and portfolio dashboard.é    )ÚannotationsN)ÚBaseHTTPRequestHandlerÚThreadingHTTPServer)ÚPath)ÚPaperTraderÚKRAKEN_DASHBOARD_HOSTz	127.0.0.1ÚKRAKEN_DASHBOARD_PORTÚ8765ÚKRAKEN_PAIRSzXBT/USD,ETH/USD,SOL/USDú,i'  é   é   g      Ð?)ÚcashÚfast_windowÚslow_windowÚ
allocationc                óâ  — t         j                  j                  |xs i «      }d| › �|rd|› �ndz   }t         j                  j	                  |ddi¬«      }t         j                  j                  |d¬«      5 }t        j                  |j                  «       j                  d	«      «      }d d d «       j                  d
«      rt        dj                  |d
   «      «      ‚|d   S # 1 sw Y   Œ<xY w)Núhttps://api.kraken.comú?Ú ú
User-Agentúlocal-kraken-dashboard/1.0)Úheadersé   ©Útimeoutúutf-8Úerrorú; Úresult)ÚurllibÚparseÚ	urlencodeÚrequestÚRequestÚurlopenÚjsonÚloadsÚreadÚdecodeÚgetÚRuntimeErrorÚjoin)ÚpathÚparamsÚqueryÚurlr$   ÚresponseÚpayloads          úkraken_dashboard.pyÚkraken_requestr5      sÑ   € Ü�L‰L×"Ñ" 6¢<¨RÓ0€EØ" 4 &Ð
)¹E¨q°°©[ÀrÑ
J€CÜ�n‰n×$Ñ$ S°<ÐA]Ð2^Ð$Ó_€GÜ	�‰×	Ñ	 °Ð	Ó	4ð >¸Ü—*‘*˜XŸ]™]›_×3Ñ3°GÓ<Ó=ˆ÷>à‡{�{�7ÔÜ˜4Ÿ9™9 W¨WÑ%5Ó6Ó7Ð7Ø�8ÑÐ÷	>ð >ús   Á73C%Ã%C.c                ó  — t        j                  d«      }t        j                  d«      }|r|st        d«      ‚dt        t	        j
                  «       dz  «      i|xs i ¥}t        j                  j                  |«      }| j                  «       t        j                  |d   |z   j                  «       «      j                  «       z   }t        j                  t        j                   |«      |t        j"                  «      j                  «       }t        j$                  j'                  d| › �|j                  «       |t        j(                  |«      j+                  «       ddœ¬	«      }t        j$                  j-                  |d
¬«      5 }	t/        j0                  |	j3                  «       j+                  d«      «      }
d d d «       
j5                  d«      rt        dj7                  |
d   «      «      ‚|
d   S # 1 sw Y   Œ<xY w)NÚKRAKEN_API_KEYÚKRAKEN_API_SECRETz)Kraken API credentials are not configuredÚnoncei@B r   r   )zAPI-KeyzAPI-Signr   )Údatar   r   r   r   r   r   r    )ÚosÚgetenvr,   ÚstrÚtimeÚtime_nsr!   r"   r#   ÚencodeÚhashlibÚsha256ÚdigestÚhmacÚnewÚbase64Ú	b64decodeÚsha512r$   r%   Ú	b64encoder*   r&   r'   r(   r)   r+   r-   )r.   r/   ÚkeyÚsecretr:   ÚencodedÚmessageÚ	signaturer$   r2   r3   s              r4   Úprivate_kraken_requestrO   $   s‘  € Ü
�)‰)Ð$Ó
%€CÜ�Y‰YÐ*Ó+€FÙ‘fÜÐFÓGÐGØ”SœŸ™›¨9Ñ4Ó5ÐH¸&º,ÀBÐH€DÜ�l‰l×$Ñ$ TÓ*€GØ�k‰k‹mœgŸn™n¨d°7©m¸gÑ.E×-MÑ-MÓ-OÓP×WÑWÓYÑY€GÜ—‘œ×)Ñ)¨&Ó1°7¼G¿N¹NÓK×RÑRÓT€IÜ�n‰n×$Ñ$Ø
   Ð'Ø�^‰^ÓØ¬V×-=Ñ-=¸iÓ-H×-OÑ-OÓ-QÐa}Ñ~ð %ó €Gô
 
�‰×	Ñ	 °Ð	Ó	4ð >¸Ü—*‘*˜XŸ]™]›_×3Ñ3°GÓ<Ó=ˆ÷>à‡{�{�7ÔÜ˜4Ÿ9™9 W¨WÑ%5Ó6Ó7Ð7Ø�8ÑÐ÷	>ð >ús   Æ3G6Ç6G?c                óF   — | j                  dd«      j                  dd«      S )Nú/r   ÚBTCÚXBT)Úreplace)Úpairs    r4   Únormalize_pairrV   9   s    € Ø�<‰<˜˜RÓ ×(Ñ(¨°Ó6Ð6ó    c                 ó  — g } t         D ]Ú  }t        ddt        |«      i«      }t        t	        |j                  «       «      «      }| j                  |t        |d   d   «      t        |d   d   «      t        |d   d   «      t        |d   d   «      t        |d	   d   «      t        |d
   d   «      t        |d   d   «      dœ«       t        j                  || d   d   «       ŒÜ t        t        j                  «       «      | dœS )Nz/0/public/TickerrU   Úcr   ÚbÚaÚhé   ÚlÚvÚp)rU   ÚlastÚbidÚaskÚhighÚlowÚvolumeÚvwapéÿÿÿÿra   )ÚupdatedÚtickers)ÚPAIRSr5   rV   ÚnextÚiterÚvaluesÚappendÚfloatÚPAPER_TRADERÚstepÚintr>   )ÚassetsÚ	requestedÚtickerrn   s       r4   Úpublic_snapshotrw   =   sù   € Ø€FÜò 9ˆ	ÜÐ 2°V¼^ÈIÓ=VÐ4WÓXˆÜ”d˜6Ÿ=™=›?Ó+Ó,ˆØ�‰ØÜ˜& ™+ a™.Ó)Ü˜ ™ Q™Ó(Ü˜ ™ Q™Ó(Ü˜& ™+ a™.Ó)Ü˜ ™ Q™Ó(Ü˜F 3™K¨™NÓ+Ü˜& ™+ a™.Ó)ñ	
ô 		ô 	×Ñ˜) V¨B¡Z°Ñ%7Õ8ð9ô œ4Ÿ9™9›;Ó'°FÑ;Ð;rW   c                 óz   — t        «       } t        j                  | d   D �ci c]  }|d   |d   “Œ c}«      S c c}w )Nrj   rU   ra   )rw   rq   Úsnapshot)Úmarketrv   s     r4   Úpaper_snapshotr{   P   s<   € ÜÓ€FÜ× Ñ ÈvÐV_ÑO`Ö!aÀV &¨¡.°&¸±.Ñ"@Ò!aÓbÐbùÒ!as   ¡8c            	     ó¦   — t        d«      } d| j                  «       D ��cg c]"  \  }}t        |«      dkD  sŒ|t        |«      dœ‘Œ$ c}}dœS c c}}w )Nz/0/private/BalanceTr   )ÚassetÚamount)Ú
configuredÚbalances)rO   Úitemsrp   )r€   rJ   Úvalues      r4   Úportfolio_snapshotrƒ   U   sn   € Ü%Ð&:Ó;€HØÐfn×ftÑftÓfv÷  -LÑXbÐX[Ð]bÔzð  AFó  {Gð  JKó  {K°sÄeÈEÃlÓ-Só  -Lñ  Mð  Mùó  -Ls
    A·Ac                  ó&   — e Zd Zdd„Zddd„Zdd„Zy)	ÚHandlerc                 ó   — y ©N© )ÚselfÚformatÚargss      r4   Úlog_messagezHandler.log_message[   s   € ØrW   c                óR  — t        j                  |«      j                  «       }| j                  |«       | j	                  dd«       | j	                  dd«       | j	                  dt        t        |«      «      «       | j                  «        | j                  j                  |«       y )NúContent-Typezapplication/jsonzCache-Controlzno-storeúContent-Length)
r'   Údumpsr@   Úsend_responseÚsend_headerr=   ÚlenÚend_headersÚwfileÚwrite)r‰   r3   ÚstatusÚbodys       r4   Ú	send_jsonzHandler.send_json^   s   € Ü�z‰z˜'Ó"×)Ñ)Ó+ˆØ×Ñ˜6Ô"Ø×Ñ˜Ð);Ô<Ø×Ñ˜¨*Ô5Ø×ÑÐ)¬3¬s°4«y«>Ô:Ø×ÑÔØ�
‰
×Ñ˜ÕrW   c                óâ  — | j                   dk(  r	 | j                  t        «       «       y | j                   dk(  r	 | j                  t        «       «       y | j                   dk(  r	 | j                  t        «       «       y | j                   d	v rŠt        d
z  j                  «       }| j                  d«       | j                  dd«       | j                  dt	        t        |«      «      «       | j                  «        | j                  j                  |«       y | j!                  d«       y # t        $ r'}| j                  dt	        |«      id«       Y d }~y d }~ww xY w# t        $ r'}| j                  dt	        |«      dœ«       Y d }~y d }~wt        $ r(}| j                  dt	        |«      dœd«       Y d }~y d }~ww xY w# t        $ r'}| j                  dt	        |«      id«       Y d }~y d }~ww xY w)Nz/api/marketr   iö  z/api/portfolioF)r   r   Tz
/api/paper)rQ   z/index.htmlzkraken_dashboard.htmléÈ   rŽ   ztext/html; charset=utf-8r�   i”  )r.   r™   rw   Ú	Exceptionr=   rƒ   r,   r{   ÚROOTÚ
read_bytesr‘   r’   r“   r”   r•   r–   Ú
send_error)r‰   Úexcr˜   s      r4   Údo_GETzHandler.do_GETg   s°  € Ø�9‰9˜Ò%ð9Ø—‘œÓ0Ô1ð Ø�9‰9Ð(Ò(ðMØ—‘Ô1Ó3Ô4ð
 Ø�9‰9˜Ò$ð9Ø—‘œ~Ó/Ô0ð Ø�9‰9Ð,Ñ,ÜÐ2Ñ2×>Ñ>Ó@ˆDØ×Ñ˜sÔ#Ø×Ñ˜^Ð-GÔHØ×ÑÐ-¬s´3°t³9«~Ô>Ø×ÑÔØ�J‰J×Ñ˜TÔ"ØØ�‰˜Õøô3 ò 9Ø—‘ ¬¨S«Ð2°C×8Ð8Øûð9ûô  ò IØ—‘¨e¼cÀ#»hÑG×HÐHð ûô ò MØ—‘¨d¼SÀ»XÑFÈ×LÐLØûðMûô ò 9Ø—‘ ¬¨S«Ð2°C×8Ð8Øûð9úsR   ‘D) »E Á%F> Ä)	EÄ2EÅEÅ	F;Å%FÆF;ÆF6Æ6F;Æ>	G.ÇG)Ç)G.N)rŠ   r=   ÚreturnÚNone)r›   )r3   Údictr—   rs   r¢   r£   )r¢   r£   )Ú__name__Ú
__module__Ú__qualname__rŒ   r™   r¡   rˆ   rW   r4   r…   r…   Z   s   „ óôôrW   r…   Ú__main__zKraken dashboard: http://ú:z
Watching: z, r‡   )r.   r=   r/   zdict[str, str] | Noner¢   r¤   )rU   r=   r¢   r=   )r¢   r¤   ),Ú__doc__Ú
__future__r   rF   rA   rD   r'   r;   Ú	threadingr>   Úurllib.parser!   Úurllib.requestÚhttp.serverr   r   Úpathlibr   Úpaper_traderr   r<   ÚHOSTrs   ÚPORTÚsplitÚstripÚupperrk   Ú__file__Úparentr�   rq   r5   rO   rV   rw   r{   rƒ   r…   r¥   ÚserverÚprintr-   Úserve_forever)r`   s   0r4   ú<module>r¼      sL  ðá =Ý "ã Û Û Û Û 	Û Û Û Û ß CÝ Ý $à€r‡y�yÐ(¨+Ó6€Ù
ˆ9ˆ2�9‰9Ð,¨fÓ5Ó6€Ø$- B§I¡I¨nÐ>WÓ$X×$^Ñ$^Ð_bÓ$cÖq˜qÐgh×gnÑgnÕgpˆ�‰‹�‰Õ	Òq€ÙˆHƒ~×Ñ€Ù °AÀ2ÐRVÔW€ôôó*7ó<ó&có
Mô
*Ð$ô *ðZ ˆzÒÙ  $¨ ¨wÓ7€FÙ	Ð% d V¨1¨T¨FÐ
3Ô4Ù	ˆJ�t—y‘y Ó'Ð(Ð
)Ô*Ø
×ÑÕð	 ùòg 	rs   ÂEÂ' E