@@ -85,6 +85,9 @@ def __init__(self, client, user_timeout=DEFAULT_USER_TIMEOUT):
8585 self ._user_timer = None
8686 self ._user_listen_key = None
8787 self ._user_callback = None
88+ self ._margin_timer = None
89+ self ._margin_listen_key = None
90+ self ._margin_callback = None
8891 self ._client = client
8992 self ._user_timeout = user_timeout
9093
@@ -447,6 +450,24 @@ def start_user_socket(self, callback):
447450 conn_key = self ._start_user_socket (user_listen_key , callback )
448451 return conn_key
449452
453+ def start_margin_socket (self , callback ):
454+ """Start a websocket for margin data
455+
456+ https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md
457+
458+ :param callback: callback function to handle messages
459+ :type callback: function
460+
461+ :returns: connection key string if successful, False otherwise
462+
463+ Message Format - see Binance API docs for all types
464+ """
465+ # Get the user margin listen key
466+ margin_listen_key = self ._client .margin_stream_get_listen_key ()
467+ # and start the socket with this specific key
468+ conn_key = self ._start_margin_socket (margin_listen_key , callback )
469+ return conn_key
470+
450471 def _start_user_socket (self , user_listen_key , callback ):
451472 # With this function we can start a user socket with a specific key
452473 if self ._user_listen_key :
@@ -461,14 +482,34 @@ def _start_user_socket(self, user_listen_key, callback):
461482 if conn_key :
462483 # start timer to keep socket alive
463484 self ._start_user_timer ()
485+ return conn_key
464486
487+ def _start_margin_socket (self , margin_listen_key , callback ):
488+ # With this function we can start a user margin socket with a specific key
489+ if self ._margin_listen_key :
490+ # cleanup any sockets with this key
491+ for conn_key in self ._conns :
492+ if len (conn_key ) >= 60 and conn_key [:60 ] == self ._margin_listen_key :
493+ self .stop_socket (conn_key )
494+ break
495+ self ._margin_listen_key = margin_listen_key
496+ self ._margin_callback = callback
497+ conn_key = self ._start_socket (self ._margin_listen_key , callback )
498+ if conn_key :
499+ # start timer to keep socket alive
500+ self ._start_margin_timer ()
465501 return conn_key
466502
467503 def _start_user_timer (self ):
468504 self ._user_timer = threading .Timer (self ._user_timeout , self ._keepalive_user_socket )
469505 self ._user_timer .setDaemon (True )
470506 self ._user_timer .start ()
471507
508+ def _start_margin_timer (self ):
509+ self ._margin_timer = threading .Timer (self ._user_timeout , self ._keepalive_margin_socket )
510+ self ._margin_timer .setDaemon (True )
511+ self ._margin_timer .start ()
512+
472513 def _keepalive_user_socket (self ):
473514 user_listen_key = self ._client .stream_get_listen_key ()
474515 # check if they key changed and
@@ -481,6 +522,18 @@ def _keepalive_user_socket(self):
481522 # Restart timer only if the user listen key is not changed
482523 self ._start_user_timer ()
483524
525+ def _keepalive_margin_socket (self ):
526+ margin_listen_key = self ._client .stream_get_listen_key ()
527+ # check if they key changed and
528+ if margin_listen_key != self ._margin_listen_key :
529+ # Start a new socket with the key received
530+ # `_start_margin_socket` automatically cleanup open sockets
531+ # and starts timer to keep socket alive
532+ self ._start_margin_socket (margin_listen_key , self ._margin_callback )
533+ else :
534+ # Restart timer only if the margin listen key is not changed
535+ self ._start_margin_timer ()
536+
484537 def stop_socket (self , conn_key ):
485538 """Stop a websocket given the connection key
486539
@@ -501,6 +554,10 @@ def stop_socket(self, conn_key):
501554 if len (conn_key ) >= 60 and conn_key [:60 ] == self ._user_listen_key :
502555 self ._stop_user_socket ()
503556
557+ # or a margin stream socket
558+ if len (conn_key ) >= 60 and conn_key [:60 ] == self ._margin_listen_key :
559+ self ._stop_margin_socket ()
560+
504561 def _stop_user_socket (self ):
505562 if not self ._user_listen_key :
506563 return
@@ -509,6 +566,14 @@ def _stop_user_socket(self):
509566 self ._user_timer = None
510567 self ._user_listen_key = None
511568
569+ def _stop_margin_socket (self ):
570+ if not self ._margin_listen_key :
571+ return
572+ # stop the timer
573+ self ._margin_timer .cancel ()
574+ self ._margin_timer = None
575+ self ._margin_listen_key = None
576+
512577 def run (self ):
513578 try :
514579 reactor .run (installSignalHandlers = False )
0 commit comments