コード例 #1
0
 def create_websocket(self):
     self.ws = BitExThreadedClient(self.blinktrade_ws_url)
     self.ws.signal_connection_open.connect(self.on_ws_open)
     self.ws.signal_connection_closed.connect(self.on_ws_closed)
     self.ws.signal_heartbeat.connect(self.on_blinktrade_heartbeat)
     self.ws.signal_logged.connect(self.on_blinktrade_connected)
     self.ws.signal_balance.connect(self.on_blinktrade_balance)
     self.ws.signal_execution_report.connect(
         self.on_blinktrade_execution_report)
     self.ws.signal_send.connect(self.on_blinktrade_send)
     self.ws.signal_recv.connect(self.on_blinktrade_recv)
コード例 #2
0
    def __init__(self, bitex_username, bitex_password, bitex_ws_url):

        self.ws = BitExThreadedClient(bitex_ws_url)
        self.bitex_username = bitex_username
        self.bitex_password = bitex_password

        self.usd_balance = 0
        self.btc_balance = 0
        self.bitex_broker = None
        self.bitex_profile = None

        self.last_bid = None
        self.last_ask = None

        self.best_bid = []
        self.best_ask = []
コード例 #3
0
ファイル: arbitrator.py プロジェクト: bitbuyercho/bitex
 def create_websocket(self):
     self.ws = BitExThreadedClient(self.blinktrade_ws_url)
     self.ws.signal_connection_open.connect(self.on_ws_open)
     self.ws.signal_connection_closed.connect(self.on_ws_closed)
     self.ws.signal_heartbeat.connect(self.on_blinktrade_heartbeat)
     self.ws.signal_logged.connect(self.on_blinktrade_connected)
     self.ws.signal_balance.connect(self.on_blinktrade_balance)
     self.ws.signal_execution_report.connect(self.on_blinktrade_execution_report)
     self.ws.signal_send.connect(self.on_blinktrade_send)
     self.ws.signal_recv.connect(self.on_blinktrade_recv)
コード例 #4
0
ファイル: main.py プロジェクト: RodrigoChagass/bitex
def main():
    while True:
        try:
            ws = BitExThreadedClient('wss://test.bitex.com.br:8449/trade')

            def on_login(sender, msg):
                ws.sendMsg({'MsgType': 'S0', 'EmailReqID': '0'})

            def on_message(sender, msg):
                if msg['MsgType'] == 'C':
                    try:
                        sender = u'BitEx Suporte <*****@*****.**>'
                        send_email(sender, msg['To'], msg['Subject'],
                                   msg['Body'])
                    except Exception as ex:
                        print "Error: unable to send email to " + str(
                            msg['To']) + ' - ' + str(ex)

                else:
                    print 'received ', msg
                    print ''

            ws.signal_logged.connect(on_login)
            ws.signal_recv.connect(on_message)

            ws.connect()

            # TODO: get the user and password from a configuration file
            ws.login('mailer', 'abc123$%')

            ws.run_forever()

        except KeyboardInterrupt:
            print 'Exiting'
            ws.close()
            break

        except Exception, e:
            print 'Error ', e
            print 'reconnecting in 1 sec'
            time.sleep(1)
コード例 #5
0
ファイル: main.py プロジェクト: RodrigoChagass/bitex
 def connect_bitex(self):
     ws = BitExThreadedClient('wss://%s:%s/trade' %
                              (self.config.om_host, self.config.om_port))
     ws.signal_recv.connect(self.on_message)
     ws.connect()
     ws.login(self.config.om_user, self.config.om_pwd)
     return ws
コード例 #6
0
ファイル: robot.py プロジェクト: Anderson-Juhasc/bitex
  def __init__(self, bitex_username, bitex_password,  bitex_ws_url):

    self.ws = BitExThreadedClient( bitex_ws_url )
    self.bitex_username = bitex_username
    self.bitex_password = bitex_password

    self.usd_balance = 0
    self.btc_balance = 0
    self.bitex_broker = None
    self.bitex_profile = None

    self.last_bid = None
    self.last_ask = None

    self.best_bid = []
    self.best_ask = []
コード例 #7
0
ファイル: arbitrator.py プロジェクト: bitbuyercho/bitex
class BlinkTradeArbitrator(object):
    def __init__(
        self,
        blinktrade_username,
        blinktrade_password,
        blinktrade_ws_url="wss://api.blinktrade.com/trade/",
        symbol="BTCUSD",
    ):
        self.fiat_currency = symbol[3:]
        self.crypto_currency = symbol[:3]
        self.fiat_balance = 0
        self.crypto_balance = 0
        self.latency = 0
        self.blinktrade_ws_url = blinktrade_ws_url
        self.blinktrade_username = blinktrade_username
        self.blinktrade_password = blinktrade_password
        self.blinktrade_broker = None
        self.blinktrade_profile = None

        self.order_book_bid_processor = OrderBookProcessor("1", symbol)
        self.order_book_ask_processor = OrderBookProcessor("2", symbol)
        self.order_book_bid_processor.send_new_order_signal.connect(self.on_send_buy_new_order)
        self.order_book_ask_processor.send_new_order_signal.connect(self.on_send_sell_new_order)
        self.order_book_bid_processor.cancel_order_signal.connect(self.on_send_cancel_order)
        self.order_book_ask_processor.cancel_order_signal.connect(self.on_send_cancel_order)

        # Signals
        self.signal_connected = Signal()
        self.signal_disconnected = Signal()
        self.signal_logged = Signal()
        self.signal_order = Signal()

        self.create_websocket()

    def create_websocket(self):
        self.ws = BitExThreadedClient(self.blinktrade_ws_url)
        self.ws.signal_connection_open.connect(self.on_ws_open)
        self.ws.signal_connection_closed.connect(self.on_ws_closed)
        self.ws.signal_heartbeat.connect(self.on_blinktrade_heartbeat)
        self.ws.signal_logged.connect(self.on_blinktrade_connected)
        self.ws.signal_balance.connect(self.on_blinktrade_balance)
        self.ws.signal_execution_report.connect(self.on_blinktrade_execution_report)
        self.ws.signal_send.connect(self.on_blinktrade_send)
        self.ws.signal_recv.connect(self.on_blinktrade_recv)

    def is_connected(self):
        return self.ws.is_connected

    def is_logged(self):
        return self.ws.is_logged

    def on_ws_open(self, sender, msg):
        self.signal_connected(self)
        self.ws.login(self.blinktrade_username, self.blinktrade_password)

    def on_ws_closed(self, sender, code_reason):
        self.signal_disconnected(self, code_reason)

    def reconnect(self):
        del self.ws
        self.create_websocket()
        self.connect()

    def connect(self):
        from ws4py.exc import HandshakeError

        try:
            self.ws.connect()
        except HandshakeError, e:
            print datetime.datetime.now(), "ERROR", "connection error: ", e
            raise
コード例 #8
0
ファイル: robot.py プロジェクト: Anderson-Juhasc/bitex
class BitexBot(object):
  def __init__(self, bitex_username, bitex_password,  bitex_ws_url):

    self.ws = BitExThreadedClient( bitex_ws_url )
    self.bitex_username = bitex_username
    self.bitex_password = bitex_password

    self.usd_balance = 0
    self.btc_balance = 0
    self.bitex_broker = None
    self.bitex_profile = None

    self.last_bid = None
    self.last_ask = None

    self.best_bid = []
    self.best_ask = []

  def on_bitex_execution_report(self, sender, msg):
    if msg['ExecType'] == '0' or msg['ExecType'] == '4': # cancel
      return

    print msg

  def on_bitex_balance(self, sender, msg):
    if str(self.bitex_broker['BrokerID']) in msg:
      if 'USD' in msg[str(self.bitex_broker['BrokerID'])]:
        self.usd_balance = msg[str(self.bitex_broker['BrokerID'])]['USD']
      if 'BTC' in msg[str(self.bitex_broker['BrokerID'])]:
        self.btc_balance = msg[str(self.bitex_broker['BrokerID'])]['BTC']

  def on_bitex_error(self, sender, msg):
    print 'error blinktrade: ', msg

  def on_bitex_error_login(self, sender, msg):
    self.ws.close()
    print 'login error on blinktrade: ', msg['UserStatusText']
    sys.exit(-1)

  def on_bitex_connected(self, sender, msg):
    print 'connected to blinktrade'
    self.bitex_broker   = msg['Broker']
    self.bitex_profile  = msg['Profile']

    self.ws.send(json.dumps({ 'MsgType':'F'}))  # Cancel all open orders for this user
    self.ws.requestBalances()
    self.ws.requestMarketData('1', ['BTCUSD'], ['0','1', '2'] )


  def on_send_buy_new_order(self,sender, msg):
    print datetime.datetime.now(), msg
    self.ws.sendMsg(msg)

  def on_send_sell_new_order(self,sender, msg):
    print datetime.datetime.now(), msg
    self.ws.sendMsg(msg)

  def on_send_cancel_order(self,sender, msg):
    print datetime.datetime.now(), msg
    self.ws.sendMsg(msg)

  def on_book_clear_ask(self, sender, msg):
    self.best_ask = []

  def on_book_ask_new_order(self, sender, msg):
    self.best_ask.insert( msg['MDEntryPositionNo']-1, msg['MDEntryPx']/1e8 )
    self.on_tick()

  def on_book_ask_delete_order(self, sender, msg):
    del self.best_ask[ msg['MDEntryPositionNo']-1 ]
    self.on_tick()

  def on_book_ask_update_order(self, sender, msg):
    self.best_ask[ msg['MDEntryPositionNo']-1 ] = ( msg['MDEntryPx']/1e8 )
    self.on_tick()

  def on_book_ask_delete_thru(self, sender, msg):
    idx = (msg['MDEntryPositionNo']-1)
    while --idx :
      self.best_ask.pop()

  def on_book_clear_bid(self, sender, msg):
    self.best_bid = []

  def on_book_bid_new_order(self, sender, msg):
    self.best_bid.insert( msg['MDEntryPositionNo']-1, msg['MDEntryPx']/1e8 )
    self.on_tick()

  def on_book_bid_update_order(self, sender, msg):
    self.best_bid[ msg['MDEntryPositionNo']-1 ] = ( msg['MDEntryPx']/1e8 )
    self.on_tick()

  def on_book_bid_delete_order(self, sender, msg):
    del self.best_bid[ msg['MDEntryPositionNo']-1 ]
    self.on_tick()

  def on_book_bid_delete_thru(self, sender, msg):
    idx = (msg['MDEntryPositionNo']-1)
    while --idx :
      self.best_bid.pop()


  def on_tick(self):
    if len(self.best_bid) > 0 and len(self.best_ask) > 0:

      tick = False
      if self.last_ask != self.best_ask[0]:
        self.last_ask = self.best_ask[0]
        tick = True

      if self.last_bid != self.best_bid[0]:
        self.last_bid = self.best_bid[0]
        tick = True

      if tick:
        print 'bid: %f ask %f spread %f' % ( self.last_bid, self.last_ask, self.last_ask - self.last_bid )

  def run(self):

    self.ws.signal_logged.connect(self.on_bitex_connected)
    self.ws.signal_error_login.connect(self.on_bitex_error_login)
    self.ws.signal_error.connect(self.on_bitex_error)

    self.ws.signal_balance.connect(self.on_bitex_balance )
    self.ws.signal_execution_report.connect(self.on_bitex_execution_report)

    self.ws.signal_book_bid_new_order.connect(self.on_book_bid_new_order)
    self.ws.signal_book_bid_update_order.connect(self.on_book_bid_update_order)
    self.ws.signal_book_bid_delete_order.connect(self.on_book_bid_delete_order)
    self.ws.signal_book_bid_delete_thru.connect(self.on_book_bid_delete_thru)

    self.ws.signal_book_bid_clear.connect(self.on_book_clear_bid)

    self.ws.signal_book_offer_new_order.connect(self.on_book_ask_new_order)
    self.ws.signal_book_offer_update_order.connect(self.on_book_ask_update_order)
    self.ws.signal_book_offer_delete_order.connect(self.on_book_ask_delete_order)
    self.ws.signal_book_offer_delete_thru.connect(self.on_book_ask_delete_thru)

    self.ws.signal_book_offer_clear.connect(self.on_book_clear_ask)


    self.ws.connect()
    self.ws.login(self.bitex_username, self.bitex_password )


    try:
      self.ws.run_forever()
    except Exception, e:
      self.ws.send(json.dumps({'MsgType':'F'}))  # Cancel all open orders for this user
      self.ws.close()
      pass
コード例 #9
0
ファイル: blockscore.py プロジェクト: Anderson-Juhasc/bitex
def main():
  candidates = [ 'verification.ini' ,'blockscore.ini']
  if len(sys.argv) > 1:
    candidates.append(sys.argv[1])

  config = ConfigParser.SafeConfigParser({
    'websocket_url': 'wss://127.0.0.1/trade/',
    'username': '',
    'password': '',
    'api_key': '',
  })
  config.read( candidates )

  websocket_url = config.get('blockscore', 'websocket_url')
  username      = config.get('blockscore', 'username')
  password      = config.get('blockscore', 'password')
  api_key       = config.get('blockscore', 'api_key')


  blockscore_client = blockscore.Client({'api_key':api_key})

  def on_verify_customer(sender, msg):
    print msg
    verification = blockscore_client.verification.create(
      date_of_birth = msg.get('VerificationData')['date_of_birth'],
      identification = {
        'ssn': msg.get('VerificationData')['ssn']
      },
      name = {
        'first': msg.get('VerificationData')['name']['first'],
        'middle': msg.get('VerificationData')['name']['middle'],
        'last': msg.get('VerificationData')['name']['last'],
      },
      address = {
        'street1': msg.get('VerificationData')['address']['street1'],
        'street2': msg.get('VerificationData')['address']['street2'],
        'city': msg.get('VerificationData')['address']['city'],
        'state': msg.get('VerificationData')['address']['state'],
        'postal_code': msg.get('VerificationData')['address']['postal_code'],
        'country_code': msg.get('VerificationData')['address']['country_code'],
      }
    )

    verification = verification.body

    print verification


  ws = BitExThreadedClient( websocket_url )
  ws.signal_verify_customer_update.connect(on_verify_customer)
  ws.connect()
  ws.login(username, password)

  while True:
    try:
      sleep(30)
      if ws.is_connected:
        ws.testRequest()
      else:
        try:
          ws.close()
        except HandshakeError,e:
          del ws
          ws = BitExThreadedClient( websocket_url )
          ws.signal_verify_customer_update.connect(on_verify_customer)
          ws.connect()
          ws.login(username, password)

    except KeyboardInterrupt:
      ws.close()
      break
コード例 #10
0
class BitexBot(object):
    def __init__(self, bitex_username, bitex_password, bitex_ws_url):

        self.ws = BitExThreadedClient(bitex_ws_url)
        self.bitex_username = bitex_username
        self.bitex_password = bitex_password

        self.usd_balance = 0
        self.btc_balance = 0
        self.bitex_broker = None
        self.bitex_profile = None

        self.last_bid = None
        self.last_ask = None

        self.best_bid = []
        self.best_ask = []

    def on_bitex_execution_report(self, sender, msg):
        if msg['ExecType'] == '0' or msg['ExecType'] == '4':  # cancel
            return

        print msg

    def on_bitex_balance(self, sender, msg):
        if str(self.bitex_broker['BrokerID']) in msg:
            if 'USD' in msg[str(self.bitex_broker['BrokerID'])]:
                self.usd_balance = msg[str(
                    self.bitex_broker['BrokerID'])]['USD']
            if 'BTC' in msg[str(self.bitex_broker['BrokerID'])]:
                self.btc_balance = msg[str(
                    self.bitex_broker['BrokerID'])]['BTC']

    def on_bitex_error(self, sender, msg):
        print 'error blinktrade: ', msg

    def on_bitex_error_login(self, sender, msg):
        self.ws.close()
        print 'login error on blinktrade: ', msg['UserStatusText']
        sys.exit(-1)

    def on_bitex_connected(self, sender, msg):
        print 'connected to blinktrade'
        self.bitex_broker = msg['Broker']
        self.bitex_profile = msg['Profile']

        self.ws.send(json.dumps({'MsgType':
                                 'F'}))  # Cancel all open orders for this user
        self.ws.requestBalances()
        self.ws.requestMarketData('1', ['BTCUSD'], ['0', '1', '2'])

    def on_send_buy_new_order(self, sender, msg):
        print datetime.datetime.now(), msg
        self.ws.sendMsg(msg)

    def on_send_sell_new_order(self, sender, msg):
        print datetime.datetime.now(), msg
        self.ws.sendMsg(msg)

    def on_send_cancel_order(self, sender, msg):
        print datetime.datetime.now(), msg
        self.ws.sendMsg(msg)

    def on_book_clear_ask(self, sender, msg):
        self.best_ask = []

    def on_book_ask_new_order(self, sender, msg):
        self.best_ask.insert(msg['MDEntryPositionNo'] - 1,
                             msg['MDEntryPx'] / 1e8)
        self.on_tick()

    def on_book_ask_delete_order(self, sender, msg):
        del self.best_ask[msg['MDEntryPositionNo'] - 1]
        self.on_tick()

    def on_book_ask_update_order(self, sender, msg):
        self.best_ask[msg['MDEntryPositionNo'] - 1] = (msg['MDEntryPx'] / 1e8)
        self.on_tick()

    def on_book_ask_delete_thru(self, sender, msg):
        idx = (msg['MDEntryPositionNo'] - 1)
        while --idx:
            self.best_ask.pop()

    def on_book_clear_bid(self, sender, msg):
        self.best_bid = []

    def on_book_bid_new_order(self, sender, msg):
        self.best_bid.insert(msg['MDEntryPositionNo'] - 1,
                             msg['MDEntryPx'] / 1e8)
        self.on_tick()

    def on_book_bid_update_order(self, sender, msg):
        self.best_bid[msg['MDEntryPositionNo'] - 1] = (msg['MDEntryPx'] / 1e8)
        self.on_tick()

    def on_book_bid_delete_order(self, sender, msg):
        del self.best_bid[msg['MDEntryPositionNo'] - 1]
        self.on_tick()

    def on_book_bid_delete_thru(self, sender, msg):
        idx = (msg['MDEntryPositionNo'] - 1)
        while --idx:
            self.best_bid.pop()

    def on_tick(self):
        if len(self.best_bid) > 0 and len(self.best_ask) > 0:

            tick = False
            if self.last_ask != self.best_ask[0]:
                self.last_ask = self.best_ask[0]
                tick = True

            if self.last_bid != self.best_bid[0]:
                self.last_bid = self.best_bid[0]
                tick = True

            if tick:
                print 'bid: %f ask %f spread %f' % (
                    self.last_bid, self.last_ask,
                    self.last_ask - self.last_bid)

    def run(self):

        self.ws.signal_logged.connect(self.on_bitex_connected)
        self.ws.signal_error_login.connect(self.on_bitex_error_login)
        self.ws.signal_error.connect(self.on_bitex_error)

        self.ws.signal_balance.connect(self.on_bitex_balance)
        self.ws.signal_execution_report.connect(self.on_bitex_execution_report)

        self.ws.signal_book_bid_new_order.connect(self.on_book_bid_new_order)
        self.ws.signal_book_bid_update_order.connect(
            self.on_book_bid_update_order)
        self.ws.signal_book_bid_delete_order.connect(
            self.on_book_bid_delete_order)
        self.ws.signal_book_bid_delete_thru.connect(
            self.on_book_bid_delete_thru)

        self.ws.signal_book_bid_clear.connect(self.on_book_clear_bid)

        self.ws.signal_book_offer_new_order.connect(self.on_book_ask_new_order)
        self.ws.signal_book_offer_update_order.connect(
            self.on_book_ask_update_order)
        self.ws.signal_book_offer_delete_order.connect(
            self.on_book_ask_delete_order)
        self.ws.signal_book_offer_delete_thru.connect(
            self.on_book_ask_delete_thru)

        self.ws.signal_book_offer_clear.connect(self.on_book_clear_ask)

        self.ws.connect()
        self.ws.login(self.bitex_username, self.bitex_password)

        try:
            self.ws.run_forever()
        except Exception, e:
            self.ws.send(json.dumps(
                {'MsgType': 'F'}))  # Cancel all open orders for this user
            self.ws.close()
            pass
コード例 #11
0
class BlinkTradeArbitrator(object):
    def __init__(self,
                 blinktrade_username,
                 blinktrade_password,
                 blinktrade_ws_url='wss://api.blinktrade.com/trade/',
                 symbol='BTCUSD'):
        self.fiat_currency = symbol[3:]
        self.crypto_currency = symbol[:3]
        self.fiat_balance = 0
        self.crypto_balance = 0
        self.latency = 0
        self.blinktrade_ws_url = blinktrade_ws_url
        self.blinktrade_username = blinktrade_username
        self.blinktrade_password = blinktrade_password
        self.blinktrade_broker = None
        self.blinktrade_profile = None

        self.order_book_bid_processor = OrderBookProcessor('1', symbol)
        self.order_book_ask_processor = OrderBookProcessor('2', symbol)
        self.order_book_bid_processor.send_new_order_signal.connect(
            self.on_send_buy_new_order)
        self.order_book_ask_processor.send_new_order_signal.connect(
            self.on_send_sell_new_order)
        self.order_book_bid_processor.cancel_order_signal.connect(
            self.on_send_cancel_order)
        self.order_book_ask_processor.cancel_order_signal.connect(
            self.on_send_cancel_order)

        #Signals
        self.signal_connected = Signal()
        self.signal_disconnected = Signal()
        self.signal_logged = Signal()
        self.signal_order = Signal()

        self.create_websocket()

    def create_websocket(self):
        self.ws = BitExThreadedClient(self.blinktrade_ws_url)
        self.ws.signal_connection_open.connect(self.on_ws_open)
        self.ws.signal_connection_closed.connect(self.on_ws_closed)
        self.ws.signal_heartbeat.connect(self.on_blinktrade_heartbeat)
        self.ws.signal_logged.connect(self.on_blinktrade_connected)
        self.ws.signal_balance.connect(self.on_blinktrade_balance)
        self.ws.signal_execution_report.connect(
            self.on_blinktrade_execution_report)
        self.ws.signal_send.connect(self.on_blinktrade_send)
        self.ws.signal_recv.connect(self.on_blinktrade_recv)

    def is_connected(self):
        return self.ws.is_connected

    def is_logged(self):
        return self.ws.is_logged

    def on_ws_open(self, sender, msg):
        self.signal_connected(self)
        self.ws.login(self.blinktrade_username, self.blinktrade_password)

    def on_ws_closed(self, sender, code_reason):
        self.signal_disconnected(self, code_reason)

    def reconnect(self):
        del self.ws
        self.create_websocket()
        self.connect()

    def connect(self):
        from ws4py.exc import HandshakeError
        try:
            self.ws.connect()
        except HandshakeError, e:
            print datetime.datetime.now(), 'ERROR', 'connection error: ', e
            raise
コード例 #12
0
ファイル: main.py プロジェクト: RodrigoSagach/bitex
 def connect_bitex(self):
     ws = BitExThreadedClient("wss://%s:%s/trade" % (self.config.om_host, self.config.om_port))
     ws.signal_recv.connect(self.on_message)
     ws.connect()
     ws.login(self.config.om_user, self.config.om_pwd)
     return ws
コード例 #13
0
ファイル: blockscore.py プロジェクト: treverson/bitex-2
def main():
    candidates = ['verification.ini', 'blockscore.ini']
    if len(sys.argv) > 1:
        candidates.append(sys.argv[1])

    config = ConfigParser.SafeConfigParser({
        'websocket_url': 'wss://127.0.0.1/trade/',
        'username': '',
        'password': '',
        'api_key': '',
    })
    config.read(candidates)

    websocket_url = config.get('blockscore', 'websocket_url')
    username = config.get('blockscore', 'username')
    password = config.get('blockscore', 'password')
    api_key = config.get('blockscore', 'api_key')

    blockscore_client = blockscore.Client({'api_key': api_key})

    def on_verify_customer(sender, msg):
        print msg
        verification = blockscore_client.verification.create(
            date_of_birth=msg.get('VerificationData')['date_of_birth'],
            identification={'ssn': msg.get('VerificationData')['ssn']},
            name={
                'first': msg.get('VerificationData')['name']['first'],
                'middle': msg.get('VerificationData')['name']['middle'],
                'last': msg.get('VerificationData')['name']['last'],
            },
            address={
                'street1':
                msg.get('VerificationData')['address']['street1'],
                'street2':
                msg.get('VerificationData')['address']['street2'],
                'city':
                msg.get('VerificationData')['address']['city'],
                'state':
                msg.get('VerificationData')['address']['state'],
                'postal_code':
                msg.get('VerificationData')['address']['postal_code'],
                'country_code':
                msg.get('VerificationData')['address']['country_code'],
            })

        verification = verification.body

        print verification

    ws = BitExThreadedClient(websocket_url)
    ws.signal_verify_customer_update.connect(on_verify_customer)
    ws.connect()
    ws.login(username, password)

    while True:
        try:
            sleep(30)
            if ws.is_connected:
                ws.testRequest()
            else:
                try:
                    ws.close()
                except HandshakeError, e:
                    del ws
                    ws = BitExThreadedClient(websocket_url)
                    ws.signal_verify_customer_update.connect(
                        on_verify_customer)
                    ws.connect()
                    ws.login(username, password)

        except KeyboardInterrupt:
            ws.close()
            break