Example #1
0
    def __init__(self, application, request, **kwargs):
        super(WebSocketHandler, self).__init__(application, request, **kwargs)
        self.remote_ip = request.headers.get(
            'X-Forwarded-For',
            request.headers.get('X-Real-Ip', request.remote_ip))
        application.log('INFO', 'CONNECTION_OPEN', self.remote_ip)

        self.trade_client = TradeClient(self.application.zmq_context,
                                        self.application.trade_in_socket,
                                        options.trade_pub)
        self.md_subscriptions = {}
        self.sec_status_subscriptions = {}

        self.user_response = None
Example #2
0
    def __init__(self, application, request, **kwargs):
        super(WebSocketHandler, self).__init__(application, request, **kwargs)
        self.remote_ip = request.headers.get(
            'X-Forwarded-For',
            request.headers.get(
                'X-Real-Ip',
                request.remote_ip))
        application.log('INFO', 'CONNECTION_OPEN', self.remote_ip )

        self.trade_client = TradeClient(
            self.application.zmq_context,
            self.application.trade_in_socket,
            options.trade_pub)
        self.md_subscriptions = {}
        self.sec_status_subscriptions = {}

        self.user_response = None
Example #3
0
class WebSocketHandler(websocket.WebSocketHandler):

    def __init__(self, application, request, **kwargs):
        super(WebSocketHandler, self).__init__(application, request, **kwargs)
        self.remote_ip = request.headers.get(
            'X-Forwarded-For',
            request.headers.get(
                'X-Real-Ip',
                request.remote_ip))
        application.log('INFO', 'CONNECTION_OPEN', self.remote_ip )

        self.trade_client = TradeClient(
            self.application.zmq_context,
            self.application.trade_in_socket,
            options.trade_pub)
        self.md_subscriptions = {}
        self.sec_status_subscriptions = {}

        self.user_response = None

    def on_trade_publish(self, message):
        self.write_message(str(message[1]))

    def open(self):
        try:
            self.trade_client.connect()
            self.trade_client.on_trade_publish = self.on_trade_publish
            self.application.register_connection(self)

        except TradeClientException as e:
            self.write_message(
                '{"MsgType":"ERROR", "Description":"Error establishing connection with trade", "Detail": "' +
                str(e) +
                '"}')
            self.trade_client.close()
            self.close()

    def write_message(self, message, binary=False):
        self.application.log('OUT', self.trade_client.connection_id, message )
        super(WebSocketHandler, self).write_message(message, binary)

    def close(self):
      self.application.log('DEBUG', self.remote_ip, 'WebSocketHandler.close() invoked' )
      super(WebSocketHandler, self).close()

    def on_message(self, raw_message):
        if not self.trade_client.isConnected():
            return

        try:
            req_msg = JsonMessage(raw_message)
        except InvalidMessageException as e:
            self.write_message(
                '{"MsgType":"ERROR", "Description":"Invalid message", "Detail": "' +
                str(e) +
                '"}')
            self.application.unregister_connection(self)
            self.trade_client.close()
            self.close()
            return


        if req_msg.isUserRequest():
            if req_msg.has('Password'):
                raw_message = raw_message.replace(req_msg.get('Password'), '*')
            if req_msg.has('NewPassword'):
                raw_message = raw_message.replace(req_msg.get('NewPassword'), '*')

            self.application.log('IN', self.trade_client.connection_id ,raw_message )
        else:
            self.application.log('IN', self.trade_client.connection_id, raw_message )


        if req_msg.isTestRequest() or req_msg.isHeartbeat():
            dt = datetime.datetime.now()
            response_msg = {
                'MsgType'           : '0',
                'TestReqID'         : req_msg.get('TestReqID'),
                'ServerTimestamp'   : int(mktime(dt.timetuple()) + dt.microsecond/1000.0 )
            }

            sendTime = req_msg.get('SendTime')
            if sendTime:
                response_msg['SendTime'] = sendTime


            self.write_message(str(json.dumps(response_msg, cls=JsonEncoder)))
            return


        if req_msg.isTradeHistoryRequest():  # Trade History request
            self.on_trade_history_request(req_msg)
            return

        if req_msg.isMarketDataRequest():  # Market Data Request
            self.on_market_data_request(req_msg)

            if not self.trade_client.isConnected():
                self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()' )
                self.application.unregister_connection(self)
                self.trade_client.close()
                self.close()
            return

        if req_msg.isSecurityStatusRequest():
            self.on_security_status_request(req_msg)
            return

        if req_msg.isDepositRequest():
            if not req_msg.get('DepositMethodID') and not req_msg.get('DepositID'):

                currency = req_msg.get('Currency')

                secret = uuid.uuid4().hex
                cold_wallet = self.get_broker_wallet('cold', currency)
                callback_url = options.callback_url + secret
                if not cold_wallet:
                    return

                parameters = urllib.urlencode({
                    'method': 'create',
                    'address': cold_wallet,
                    'callback': callback_url,
                    'currency': currency
                })


                try:
                    url_payment_processor = options.url_payment_processor + '?' + parameters
                    print "invoking .. ", url_payment_processor
                    response = urllib2.urlopen(url_payment_processor)
                    data = json.load(response)
                    req_msg.set('InputAddress', data['input_address'])
                    req_msg.set('Destination', data['destination'])
                    req_msg.set('Secret', secret)
                except urllib2.HTTPError as e:
                    self.write_message(json.dumps({
                        'MsgType': 'ERROR',
                        'ReqID': req_msg.get('DepositReqID'),
                        'Description': 'Blockchain.info is not available at this moment, please try again within few minutes',
                        'Detail': str(e)
                    }))
                    return
                except Exception as e:
                    self.write_message(json.dumps({
                        'MsgType': 'ERROR',
                        'ReqID': req_msg.get('DepositReqID'),
                        'Description': 'Error retrieving a new deposit address from Blockchain.info. Please, try again',
                        'Detail': str(e)
                    }))
                    return

        try:
            resp_message = self.trade_client.sendMessage(req_msg)
            if resp_message:
                self.write_message(resp_message.raw_message)

            if resp_message and resp_message.isUserResponse():
                self.user_response = resp_message

            if not self.trade_client.isConnected():
                self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()' )
                self.application.unregister_connection(self)
                self.trade_client.close()
                self.close()
        except TradeClientException as e:
            exception_message = {
                'MsgType': 'ERROR',
                'Description': 'Invalid message',
                'Detail': str(e)
            }
            self.write_message(json.dumps(exception_message))
            self.application.unregister_connection(self)
            self.trade_client.close()
            self.close()

    def is_user_logged(self):
        if not self.user_response:
            return False
        return self.user_response.get('UserStatus') == 1

    def get_broker_wallet(self, type, currency):
        if not self.user_response:
            return

        broker = self.user_response.get('Broker')
        if not broker:
            return

        if 'CryptoCurrencies' not in broker:
            return

        broker_crypto_currencies = broker['CryptoCurrencies']
        for crypto_currency in broker_crypto_currencies:
            if crypto_currency['CurrencyCode'] == currency:
                for wallet in crypto_currency['Wallets']:
                    if wallet['type'] == type:
                        return wallet['address']

    def on_close(self):
        self.application.log('DEBUG', self.trade_client.connection_id, 'WebSocketHandler.on_close' )
        self.application.unregister_connection(self)
        self.trade_client.close()

    def on_trade_history_request(self, msg):
        page        = msg.get('Page', 0)
        page_size   = msg.get('PageSize', 100)
        filter      = msg.get('Filter')

        offset      = page * page_size

        columns = [ 'TradeID'           , 'Market',  'Side', 'Price', 'Size', 
                    'Buyer'             , 'Seller', 'Created' ]

        trade_list = generate_trade_history(page_size, offset)

        response_msg = {
            'MsgType'           : 'U33', # TradeHistoryResponse
            'TradeHistoryReqID' : msg.get('TradeHistoryReqID'),
            'Page'              : page,
            'PageSize'          : page_size,
            'Columns'           : columns,
            'TradeHistoryGrp'   : trade_list
        }

        self.write_message(str(json.dumps(response_msg, cls=JsonEncoder)))

    def on_security_status_request(self, msg):
        # Generate a FullRefresh
        req_id = msg.get('SecurityStatusReqID')

        # Disable previous Snapshot + Update Request
        if int(msg.get('SubscriptionRequestType')) == 2:
            if req_id in self.sec_status_subscriptions:
                del self.sec_status_subscriptions[req_id]
            return

        instruments = msg.get('Instruments')

        if int(msg.get('SubscriptionRequestType')) == 1:  # Snapshot + Updates
            if req_id not in self.sec_status_subscriptions:
                self.sec_status_subscriptions[req_id] = []

        for instrument in instruments:
            ss = generate_security_status(
                instrument,
                req_id)
            self.write_message(str(json.dumps(ss, cls=JsonEncoder)))

            # Snapshot + Updates
            if int(msg.get('SubscriptionRequestType')) == 1:
                self.sec_status_subscriptions[req_id].append(
                    SecurityStatusPublisher(
                        req_id,
                        instrument,
                        self.on_send_json_msg_to_user))


    def on_market_data_request(self, msg):
        # Generate a FullRefresh
        req_id = msg.get('MDReqID')

        # Disable previous Snapshot + Update Request
        if int(msg.get('SubscriptionRequestType')) == 2:
            if req_id in self.md_subscriptions:
                del self.md_subscriptions[req_id]
            return

        market_depth = msg.get('MarketDepth')
        instruments = msg.get('Instruments')
        entries = msg.get('MDEntryTypes')

        if int(msg.get('SubscriptionRequestType')) == 1:  # Snapshot + Updates
            if req_id not in self.md_subscriptions:
                self.md_subscriptions[req_id] = []

        for instrument in instruments:
            md = generate_md_full_refresh(
                instrument,
                market_depth,
                entries,
                req_id)
            self.write_message(str(json.dumps(md, cls=JsonEncoder)))

            # Snapshot + Updates
            if int(msg.get('SubscriptionRequestType')) == 1:
                self.md_subscriptions[req_id].append(
                    MarketDataPublisher(
                        req_id,
                        market_depth,
                        entries,
                        instrument,
                        self.on_send_json_msg_to_user))

    def on_send_json_msg_to_user(self, sender, json_msg):
        s = json.dumps(json_msg, cls=JsonEncoder)
        self.write_message(s)
Example #4
0
    def __init__(self, opt):
        handlers = [
            (r'/', WebSocketHandler),
            (r'/get_deposit(.*)', DepositHandler),
            (r'/_webhook/verification_form', VerificationWebHookHandler),
            (r'/_webhook/deposit_receipt', DepositReceiptWebHookHandler),
            (r'/process_deposit(.*)', ProcessDepositHandler),
            (r'/api/(?P<version>[^\/]+)/(?P<symbol>[^\/]+)/(?P<resource>[^\/]+)', RestApiHandler)
        ]
        settings = dict(
            cookie_secret='cookie_secret'
        )
        tornado.web.Application.__init__(self, handlers, **settings)

        self.replay_logger = logging.getLogger("REPLAY")
        self.replay_logger.setLevel(logging.INFO)
        self.replay_logger.addHandler(input_log_file_handler)
        self.replay_logger.info('START')
        self.log_start_data()


        from models import ENGINE, db_bootstrap
        self.db_session = scoped_session(sessionmaker(bind=ENGINE))
        db_bootstrap(self.db_session)


        self.zmq_context = zmq.Context()

        self.trade_in_socket = self.zmq_context.socket(zmq.REQ)
        self.trade_in_socket.connect(opt.trade_in)

        self.application_trade_client = TradeClient(
            self.zmq_context,
            self.trade_in_socket)
        self.application_trade_client.connect()

        instruments = self.application_trade_client.getSecurityList()
        self.md_subscriber = {}

        for instrument in instruments:
            symbol = instrument['Symbol']
            self.md_subscriber[symbol] = MarketDataSubscriber.get(symbol, self)
            self.md_subscriber[symbol].subscribe(
                self.zmq_context,
                options.trade_pub,
                self.application_trade_client)

        last_trade_id = Trade.get_last_trade_id()
        trade_list = self.application_trade_client.getLastTrades(last_trade_id)

        for trade in trade_list:
            msg = dict()
            msg['id']               = trade[0]
            msg['symbol']           = trade[1]
            msg['side']             = trade[2]
            msg['price']            = trade[3]
            msg['size']             = trade[4]
            msg['buyer_username']   = trade[5]
            msg['seller_username']  = trade[6]
            msg['created']          = trade[7]
            msg['trade_date']       = trade[7][:10]
            msg['trade_time']       = trade[7][11:]
            msg['order_id']         = trade[8]
            msg['counter_order_id'] = trade[9]
            Trade.create( self.db_session, msg)

        all_trades = Trade.get_all_trades(self.db_session)
        for t in all_trades:
          trade_info = dict()
          trade_info['price'] = t.price
          trade_info['size'] = t.size
          trade_info['trade_date'] = t.created.strftime('%Y-%m-%d')
          trade_info['trade_time'] = t.created.strftime('%H:%M:%S')
          self.md_subscriber[ t.symbol ].inst_status.push_trade(trade_info)

        for symbol, subscriber in self.md_subscriber.iteritems():
            subscriber.ready()

        self.connections = {}

        self.heart_beat_timer = tornado.ioloop.PeriodicCallback(
            self.send_heartbeat_to_trade,
            30000)
        self.heart_beat_timer.start()
Example #5
0
    def __init__(self, opt):
        handlers = [
            (r'/', WebSocketHandler), (r'/get_deposit(.*)', DepositHandler),
            (r'/_webhook/verification_form', VerificationWebHookHandler),
            (r'/_webhook/deposit_receipt', DepositReceiptWebHookHandler),
            (r'/process_deposit(.*)', ProcessDepositHandler),
            (r'/api/(?P<version>[^\/]+)/(?P<symbol>[^\/]+)/(?P<resource>[^\/]+)',
             RestApiHandler)
        ]
        settings = dict(cookie_secret='cookie_secret')
        tornado.web.Application.__init__(self, handlers, **settings)

        self.replay_logger = logging.getLogger("REPLAY")
        self.replay_logger.setLevel(logging.INFO)
        self.replay_logger.addHandler(input_log_file_handler)
        self.replay_logger.info('START')
        self.log_start_data()

        from models import ENGINE, db_bootstrap
        self.db_session = scoped_session(sessionmaker(bind=ENGINE))
        db_bootstrap(self.db_session)

        self.zmq_context = zmq.Context()

        self.trade_in_socket = self.zmq_context.socket(zmq.REQ)
        self.trade_in_socket.connect(opt.trade_in)

        self.application_trade_client = TradeClient(self.zmq_context,
                                                    self.trade_in_socket)
        self.application_trade_client.connect()

        instruments = self.application_trade_client.getSecurityList()
        self.md_subscriber = {}

        for instrument in instruments:
            symbol = instrument['Symbol']
            self.md_subscriber[symbol] = MarketDataSubscriber.get(symbol, self)
            self.md_subscriber[symbol].subscribe(self.zmq_context,
                                                 options.trade_pub,
                                                 self.application_trade_client)

        last_trade_id = Trade.get_last_trade_id()
        trade_list = self.application_trade_client.getLastTrades(last_trade_id)

        for trade in trade_list:
            msg = dict()
            msg['id'] = trade[0]
            msg['symbol'] = trade[1]
            msg['side'] = trade[2]
            msg['price'] = trade[3]
            msg['size'] = trade[4]
            msg['buyer_username'] = trade[5]
            msg['seller_username'] = trade[6]
            msg['created'] = trade[7]
            msg['trade_date'] = trade[7][:10]
            msg['trade_time'] = trade[7][11:]
            msg['order_id'] = trade[8]
            msg['counter_order_id'] = trade[9]
            Trade.create(self.db_session, msg)

        all_trades = Trade.get_all_trades(self.db_session)
        for t in all_trades:
            trade_info = dict()
            trade_info['price'] = t.price
            trade_info['size'] = t.size
            trade_info['trade_date'] = t.created.strftime('%Y-%m-%d')
            trade_info['trade_time'] = t.created.strftime('%H:%M:%S')
            self.md_subscriber[t.symbol].inst_status.push_trade(trade_info)

        for symbol, subscriber in self.md_subscriber.iteritems():
            subscriber.ready()

        self.connections = {}

        self.heart_beat_timer = tornado.ioloop.PeriodicCallback(
            self.send_heartbeat_to_trade, 30000)
        self.heart_beat_timer.start()
Example #6
0
class WebSocketHandler(websocket.WebSocketHandler):
    def __init__(self, application, request, **kwargs):
        super(WebSocketHandler, self).__init__(application, request, **kwargs)
        self.remote_ip = request.headers.get(
            'X-Forwarded-For',
            request.headers.get('X-Real-Ip', request.remote_ip))
        application.log('INFO', 'CONNECTION_OPEN', self.remote_ip)

        self.trade_client = TradeClient(self.application.zmq_context,
                                        self.application.trade_in_socket,
                                        options.trade_pub)
        self.md_subscriptions = {}
        self.sec_status_subscriptions = {}

        self.user_response = None

    def on_trade_publish(self, message):
        self.write_message(str(message[1]))

    def open(self):
        try:
            self.trade_client.connect()
            self.trade_client.on_trade_publish = self.on_trade_publish
            self.application.register_connection(self)

        except TradeClientException as e:
            self.write_message(
                '{"MsgType":"ERROR", "Description":"Error establishing connection with trade", "Detail": "'
                + str(e) + '"}')
            self.trade_client.close()
            self.close()

    def write_message(self, message, binary=False):
        self.application.log('OUT', self.trade_client.connection_id, message)
        super(WebSocketHandler, self).write_message(message, binary)

    def close(self):
        self.application.log('DEBUG', self.remote_ip,
                             'WebSocketHandler.close() invoked')
        super(WebSocketHandler, self).close()

    def on_message(self, raw_message):
        if not self.trade_client.isConnected():
            return

        try:
            req_msg = JsonMessage(raw_message)
        except InvalidMessageException as e:
            self.write_message(
                '{"MsgType":"ERROR", "Description":"Invalid message", "Detail": "'
                + str(e) + '"}')
            self.application.unregister_connection(self)
            self.trade_client.close()
            self.close()
            return

        if req_msg.isUserRequest():
            if req_msg.has('Password'):
                raw_message = raw_message.replace(req_msg.get('Password'), '*')
            if req_msg.has('NewPassword'):
                raw_message = raw_message.replace(req_msg.get('NewPassword'),
                                                  '*')

            self.application.log('IN', self.trade_client.connection_id,
                                 raw_message)
        else:
            self.application.log('IN', self.trade_client.connection_id,
                                 raw_message)

        if req_msg.isTestRequest() or req_msg.isHeartbeat():
            dt = datetime.datetime.now()
            response_msg = {
                'MsgType':
                '0',
                'TestReqID':
                req_msg.get('TestReqID'),
                'ServerTimestamp':
                int(mktime(dt.timetuple()) + dt.microsecond / 1000.0)
            }

            sendTime = req_msg.get('SendTime')
            if sendTime:
                response_msg['SendTime'] = sendTime

            self.write_message(str(json.dumps(response_msg, cls=JsonEncoder)))
            return

        if req_msg.isTradeHistoryRequest():  # Trade History request
            self.on_trade_history_request(req_msg)
            return

        if req_msg.isMarketDataRequest():  # Market Data Request
            self.on_market_data_request(req_msg)

            if not self.trade_client.isConnected():
                self.application.log('DEBUG', self.trade_client.connection_id,
                                     'not self.trade_client.isConnected()')
                self.application.unregister_connection(self)
                self.trade_client.close()
                self.close()
            return

        if req_msg.isSecurityStatusRequest():
            self.on_security_status_request(req_msg)
            return

        if req_msg.isDepositRequest():
            if not req_msg.get('DepositMethodID') and not req_msg.get(
                    'DepositID'):

                currency = req_msg.get('Currency')

                secret = uuid.uuid4().hex
                cold_wallet = self.get_broker_wallet('cold', currency)
                callback_url = options.callback_url + secret
                if not cold_wallet:
                    return

                parameters = urllib.urlencode({
                    'method': 'create',
                    'address': cold_wallet,
                    'callback': callback_url,
                    'currency': currency
                })

                try:
                    url_payment_processor = options.url_payment_processor + '?' + parameters
                    print "invoking .. ", url_payment_processor
                    response = urllib2.urlopen(url_payment_processor)
                    data = json.load(response)
                    req_msg.set('InputAddress', data['input_address'])
                    req_msg.set('Destination', data['destination'])
                    req_msg.set('Secret', secret)
                except urllib2.HTTPError as e:
                    self.write_message(
                        json.dumps({
                            'MsgType': 'ERROR',
                            'ReqID': req_msg.get('DepositReqID'),
                            'Description':
                            'Blockchain.info is not available at this moment, please try again within few minutes',
                            'Detail': str(e)
                        }))
                    return
                except Exception as e:
                    self.write_message(
                        json.dumps({
                            'MsgType': 'ERROR',
                            'ReqID': req_msg.get('DepositReqID'),
                            'Description':
                            'Error retrieving a new deposit address from Blockchain.info. Please, try again',
                            'Detail': str(e)
                        }))
                    return

        try:
            resp_message = self.trade_client.sendMessage(req_msg)
            if resp_message:
                self.write_message(resp_message.raw_message)

            if resp_message and resp_message.isUserResponse():
                self.user_response = resp_message

            if not self.trade_client.isConnected():
                self.application.log('DEBUG', self.trade_client.connection_id,
                                     'not self.trade_client.isConnected()')
                self.application.unregister_connection(self)
                self.trade_client.close()
                self.close()
        except TradeClientException as e:
            exception_message = {
                'MsgType': 'ERROR',
                'Description': 'Invalid message',
                'Detail': str(e)
            }
            self.write_message(json.dumps(exception_message))
            self.application.unregister_connection(self)
            self.trade_client.close()
            self.close()

    def is_user_logged(self):
        if not self.user_response:
            return False
        return self.user_response.get('UserStatus') == 1

    def get_broker_wallet(self, type, currency):
        if not self.user_response:
            return

        broker = self.user_response.get('Broker')
        if not broker:
            return

        if 'CryptoCurrencies' not in broker:
            return

        broker_crypto_currencies = broker['CryptoCurrencies']
        for crypto_currency in broker_crypto_currencies:
            if crypto_currency['CurrencyCode'] == currency:
                for wallet in crypto_currency['Wallets']:
                    if wallet['type'] == type:
                        return wallet['address']

    def on_close(self):
        self.application.log('DEBUG', self.trade_client.connection_id,
                             'WebSocketHandler.on_close')
        self.application.unregister_connection(self)
        self.trade_client.close()

    def on_trade_history_request(self, msg):
        page = msg.get('Page', 0)
        page_size = msg.get('PageSize', 100)
        filter = msg.get('Filter')

        offset = page * page_size

        columns = [
            'TradeID', 'Market', 'Side', 'Price', 'Size', 'Buyer', 'Seller',
            'Created'
        ]

        trade_list = generate_trade_history(page_size, offset)

        response_msg = {
            'MsgType': 'U33',  # TradeHistoryResponse
            'TradeHistoryReqID': msg.get('TradeHistoryReqID'),
            'Page': page,
            'PageSize': page_size,
            'Columns': columns,
            'TradeHistoryGrp': trade_list
        }

        self.write_message(str(json.dumps(response_msg, cls=JsonEncoder)))

    def on_security_status_request(self, msg):
        # Generate a FullRefresh
        req_id = msg.get('SecurityStatusReqID')

        # Disable previous Snapshot + Update Request
        if int(msg.get('SubscriptionRequestType')) == 2:
            if req_id in self.sec_status_subscriptions:
                del self.sec_status_subscriptions[req_id]
            return

        instruments = msg.get('Instruments')

        if int(msg.get('SubscriptionRequestType')) == 1:  # Snapshot + Updates
            if req_id not in self.sec_status_subscriptions:
                self.sec_status_subscriptions[req_id] = []

        for instrument in instruments:
            ss = generate_security_status(instrument, req_id)
            self.write_message(str(json.dumps(ss, cls=JsonEncoder)))

            # Snapshot + Updates
            if int(msg.get('SubscriptionRequestType')) == 1:
                self.sec_status_subscriptions[req_id].append(
                    SecurityStatusPublisher(req_id, instrument,
                                            self.on_send_json_msg_to_user))

    def on_market_data_request(self, msg):
        # Generate a FullRefresh
        req_id = msg.get('MDReqID')

        # Disable previous Snapshot + Update Request
        if int(msg.get('SubscriptionRequestType')) == 2:
            if req_id in self.md_subscriptions:
                del self.md_subscriptions[req_id]
            return

        market_depth = msg.get('MarketDepth')
        instruments = msg.get('Instruments')
        entries = msg.get('MDEntryTypes')

        if int(msg.get('SubscriptionRequestType')) == 1:  # Snapshot + Updates
            if req_id not in self.md_subscriptions:
                self.md_subscriptions[req_id] = []

        for instrument in instruments:
            md = generate_md_full_refresh(instrument, market_depth, entries,
                                          req_id)
            self.write_message(str(json.dumps(md, cls=JsonEncoder)))

            # Snapshot + Updates
            if int(msg.get('SubscriptionRequestType')) == 1:
                self.md_subscriptions[req_id].append(
                    MarketDataPublisher(req_id, market_depth, entries,
                                        instrument,
                                        self.on_send_json_msg_to_user))

    def on_send_json_msg_to_user(self, sender, json_msg):
        s = json.dumps(json_msg, cls=JsonEncoder)
        self.write_message(s)