Ejemplo n.º 1
0
class GetMarketTrx(object):

    def __init__(self):
        config_file = os.getenv("HOME") + "/.python-bts/bts_client.json"
        fd_config = open(config_file)
        self.config_bts = json.load(fd_config)["client_default"]
        fd_config.close()

        config_bts = self.config_bts
        self.client = BTS(config_bts["user"], config_bts["password"],
                          config_bts["host"], config_bts["port"])
        self.market = BTSMarket(self.client)
        self.height = -1

    def display_deal_trx(self, deal_trx):
        for trx in deal_trx:
            if trx["type"] == "bid":
                deal_type = "buy"
            else:
                deal_type = "sell"
            sys.stdout.write("\n%s %s %s %s %s at price %.4g %s/%s" % (
                trx["timestamp"], trx["block"], deal_type,
                trx["volume"], trx["base"], trx["price"],
                trx["quote"], trx["base"]))

    def display_place_trx(self, place_trx):
        trx_id = ""
        for trx in place_trx:
            if trx_id == trx["trx_id"]:
                sys.stdout.write(".")
                continue
            trx_id = trx["trx_id"]
            if trx["type"] == "cover":
                sys.stdout.write("\n%s %s %s %s %s %s" % (
                    trx["timestamp"], trx["block"], trx["trx_id"], trx["type"],
                    trx["amount"], trx["quote"]))
            elif trx["type"] == "add_collateral":
                sys.stdout.write("\n%s %s %s %s %s %s" % (
                    trx["timestamp"], trx["block"], trx["trx_id"], trx["type"],
                    trx["amount"], trx["base"]))
            else:
                if trx["type"] == "bid":
                    volume = trx["amount"] / trx["price"]
                else:
                    volume = trx["amount"]
                order_type = trx["type"]
                if trx["cancel"]:
                    order_type = "cancel " + trx["type"]
                if trx["price"]:
                    price_str = "%.4g" % trx["price"]
                else:
                    price_str = "unlimited"
                sys.stdout.write("\n%s %s %s %s %s %s at price %s %s/%s" % (
                    trx["timestamp"], trx["block"], trx["trx_id"], order_type,
                    volume, trx["base"], price_str,
                    trx["quote"], trx["base"]))

    def excute(self):
        client_info = self.client.get_info()
        height_now = int(client_info["blockchain_head_block_num"])
        if self.height == -1:
            self.height = height_now - 1000
        while self.height < height_now:
            self.height += 1
            trxs = self.client.get_block_transactions(self.height)
            recs = self.market.get_order_deal_rec(self.height)
            self.display_deal_trx(recs)
            recs = self.market.get_order_place_rec(trxs)
            self.display_place_trx(recs)
            self.market.update_order_owner(recs)
Ejemplo n.º 2
0
class PublishMarket(object):
    def __init__(self):
        self.pusher = None
        self.order_book = {}
        self.order_book_brief = {}
        self.load_config()
        self.init_market()

    def load_config(self):
        config_file = os.getenv("HOME")+"/.python-bts/publish_market.json"
        fd_config = open(config_file)
        self.config = json.load(fd_config)
        fd_config.close()

    def init_market(self):
        config_file = os.getenv("HOME") + "/.python-bts/bts_client.json"
        fd_config = open(config_file)
        config_bts = json.load(fd_config)[self.config["bts_client"]]
        fd_config.close()

        self.bts_client = BTS(config_bts["user"], config_bts["password"],
                              config_bts["host"], config_bts["port"])
        self.market = BTSMarket(self.bts_client)
        client_info = self.bts_client.get_info()
        self.height = int(client_info["blockchain_head_block_num"])

    def myPublish(self, topic, event):
        if self.pusher:
            self.pusher.publish(topic, event, c=topic)

    def publish_deal_trx(self, deal_trx):
        for trx in deal_trx:
            if trx["type"] == "bid":
                deal_type = "buy"
            else:
                deal_type = "sell"
            prefix = get_prefix(trx["quote"], trx["base"])
            format_trx = [prefix, trx["block"], trx["timestamp"],
                          deal_type, trx["price"], trx["volume"]]
            self.myPublish(
                u'bts.orderbook.%s.trx' % (format_trx[0]), format_trx[1:])
            self.myPublish(u'bts.orderbook.trx', format_trx)
            print(format_trx)

    def publish_place_trx(self, place_trx):
        trx_id = ""
        for trx in place_trx:
            if trx_id == trx["trx_id"]:
                continue
            prefix = get_prefix(trx["quote"], trx["base"])
            trx_id = trx["trx_id"]
            if trx["cancel"]:
                trx["type"] = "cancel " + trx["type"]
            format_trx = [prefix, trx["block"], trx["timestamp"],
                          trx["type"], trx["price"], trx["amount"]]
            self.myPublish(
                u'bts.orderbook.%s.order' % (format_trx[0]), format_trx[1:])
            self.myPublish(u'bts.orderbook.order', format_trx)
            print(format_trx)

    def publish_order_book(self):
        market_list = self.config["market_list"]
        for quote, base in market_list:
            prefix = get_prefix(quote, base)
            order_book = self.market.get_order_book(
                quote, base, cover=True)
            order_book["bids"] = order_book["bids"][:10]
            order_book["asks"] = order_book["asks"][:10]
            if (prefix not in self.order_book or
               self.order_book[prefix] != order_book):
                self.order_book[prefix] = order_book
                self.myPublish(
                    u'bts.orderbook.%s' % prefix, order_book)
                self.publish_order_book_brief(quote, base, order_book)

    def publish_order_book_brief(self, quote, base, order_book):
        prefix = get_prefix(quote, base)
        order_book_brief = {"quote": quote, "base": base,
                            "ask1": None, "bid1": None}
        if order_book["bids"]:
            order_book_brief["bid1"] = order_book["bids"][0][0]
        if order_book["asks"]:
            order_book_brief["ask1"] = order_book["asks"][0][0]
        if (prefix not in self.order_book_brief or
           self.order_book_brief[prefix] != order_book_brief):
            self.order_book_brief[prefix] = order_book_brief
            self.myPublish(
                u'bts.orderbook.%s.brief' % prefix, order_book_brief)

    def execute(self):
        client_info = self.bts_client.get_info()
        height_now = int(client_info["blockchain_head_block_num"])
        if(self.height < height_now):
            time_stamp = client_info["blockchain_head_block_timestamp"]
            self.myPublish(u'bts.blockchain.info',
                           {"height": height_now, "time_stamp": time_stamp})
            self.publish_order_book()
        while self.height < height_now:
            self.height += 1
            trxs = self.bts_client.get_block_transactions(
                self.height)
            recs = self.market.get_order_deal_rec(self.height)
            self.publish_deal_trx(recs)
            recs = self.market.get_order_place_rec(trxs)
            self.publish_place_trx(recs)
            self.market.update_order_owner(recs)
Ejemplo n.º 3
0
class DelegateWatch(object):

    def __init__(self):
        self.confirm = 2
        self.load_config()
        self.init_bts()
        self.setup_log()
        self.init_watch()
        self.init_contact()

    def load_config(self):
        config_file = os.getenv("HOME")+"/.python-bts/delegate_watch.json"
        fd_config = open(config_file)
        self.config = json.load(fd_config)["delegate_watch"]
        fd_config.close()
        config_file = os.getenv("HOME")+"/.python-bts/bts_client.json"
        fd_config = open(config_file)
        self.config_bts = json.load(fd_config)[self.config["bts_client"]]
        fd_config.close()

    def init_bts(self):
        config_bts = self.config_bts
        self.bts_client = BTS(config_bts["user"], config_bts["password"],
                              config_bts["host"], config_bts["port"])
        self.delegate_num = int(self.bts_client.chain_info["delegate_num"])
        self.period = float(self.bts_client.chain_info["block_interval"])

    def setup_log(self):
        # Setting up Logger
        self.logger = logging.getLogger('bts')
        self.logger.setLevel(logging.INFO)
        formatter = logging.Formatter(
            '%(asctime)s[%(levelname)s]: %(message)s')
        fh = logging.handlers.RotatingFileHandler(
            "/tmp/bts_delegate_watch.log")
        fh.setFormatter(formatter)
        self.logger.addHandler(fh)

    def init_watch(self):
        client_info = self.bts_client.get_info()
        self.height = int(client_info["blockchain_head_block_num"])
        self.round_left = int(client_info["blockchain_blocks_left_in_round"])
        self.active_delegates = self.bts_client.list_active_delegates()
        self.active_offset = self.height
        for delegate in self.active_delegates:
            last_block_num = int(
                delegate["delegate_info"]["last_block_num_produced"])
            if last_block_num == self.height:
                break
            self.active_offset -= 1

    def init_contact(self):
        self.contact = {}
        mail_list = self.config["contact"]
        for mail in mail_list:
            if mail_list[mail]["enable"] == 0:
                continue
            for delegate in mail_list[mail]["delegates"]:
                if delegate not in self.contact:
                    self.contact[delegate] = [mail]
                else:
                    self.contact[delegate].append(mail)

    def process_missed_block(self, height):
        index = (height-self.active_offset) % self.delegate_num
        account = self.active_delegates[index]["name"]
        print("missed", height, account)
        self.logger.info("missed %s", account)
        self.active_offset -= 1
        self.notify(account, height)
        return account

    def get_block_delegate(self, height):
        index = (height-self.active_offset) % self.delegate_num
        account = self.active_delegates[index]["name"]
        print("......", height, account)
        self.logger.info("%d %s", height, account)
        return account

    def check_missed_block(self, height):
        limit = height - self.height + 1
        list_blocks = self.bts_client.list_blocks(height, limit)
        last_timestamp = -1
        for block in reversed(list_blocks):
            timestamp = int(block["timestamp"][-2:])
            block_num = int(block["block_num"])
            if last_timestamp != -1:
                period = (timestamp - last_timestamp + 60) % 60
                while period != self.period:
                    period -= self.period
                    self.process_missed_block(block_num)
                self.get_block_delegate(block_num)
            last_timestamp = timestamp

    def notify(self, account, height):
        if account not in self.contact:
            print("no contact")
            return
        print ("sent notify mail")
        sender = self.config["sender"]
        msg_from = "From: %s <%s>\n" % (self.config["name"], sender)
        msg_to = ""
        for receiver in self.contact[account]:
            msg_to = msg_to+"To: <%s>\n" % receiver

        msg_subject = "Subject: missed block attention for %s\n" % account
        msg_content = "you have missed block %d\n" % height
        message = msg_from+msg_to+msg_subject+msg_content
        print(message)
        smtpObj = smtplib.SMTP('localhost')
        smtpObj.sendmail(sender, self.contact[account], message)

    def execute(self):
        while True:
            try:
                client_info = self.bts_client.get_info()
                height = int(
                    client_info["blockchain_head_block_num"]) - self.confirm
                if height > self.height:
                    round_left = (int(
                        client_info["blockchain_blocks_left_in_round"]
                    ) + self.confirm - 1) % self.delegate_num + 1
                    if round_left > self.round_left:
                        if self.round_left != 1:
                            round_left = 1
                            height = self.height+self.round_left-1
                        else:
                            self.active_delegates = \
                                self.bts_client.list_active_delegates()
                    self.check_missed_block(height)
                    self.height = height
                    self.round_left = round_left
            except Exception as e:
                self.logger.exception(e)
            now = time.time()
            nexttime = int(now/self.period+1)*self.period - now
            time.sleep(nexttime+1)
Ejemplo n.º 4
0
class BTSOrderBook(object):
    def __init__(self):
        self.market_list = [
            ["BOTSCNY", "BTS"], ["CNY", "BTS"], ["USD", "BTS"],
            ["GOLD", "BTS"], ["BTC", "BTS"], ["BDR.AAPL", "CNY"],
            ["NOTE", "BTS"]]
        self.init_done = False
        self.pusher = None
        self.order_book = {}
        self.deal_trx = {}
        self.place_trx = {}
        for quote, base in self.market_list:
            prefix = get_prefix(quote, base)
            self.order_book[prefix] = {}
            self.deal_trx[prefix] = []
            self.place_trx[prefix] = []
        self.init_market()
        self.execute()
        self.init_done = True

    def init_market(self):
        config_file = os.getenv("HOME") + "/.python-bts/bts_client.json"
        fd_config = open(config_file)
        config_bts = json.load(fd_config)["client_default"]
        fd_config.close()

        self.bts_client = BTS(config_bts["user"], config_bts["password"],
                              config_bts["host"], config_bts["port"])
        self.market = BTSMarket(self.bts_client)
        client_info = self.bts_client.get_info()
        self.height = int(client_info["blockchain_head_block_num"]) - 180

    def myPublish(self, topic, event):
        if self.pusher and self.init_done:
            self.pusher.emit(topic, event, namespace="")

    def publish_deal_trx(self, deal_trx):
        for trx in deal_trx:
            if trx["type"] == "bid":
                deal_type = "buy"
            else:
                deal_type = "sell"
            prefix = get_prefix(trx["quote"], trx["base"])
            format_trx = [prefix, trx["block"], trx["timestamp"],
                          deal_type, trx["price"], trx["volume"]]
            self.myPublish(
                u'bts.orderbook.%s.trx' % (format_trx[0]), format_trx[1:])
            self.myPublish(u'bts.orderbook.trx', format_trx)
            market = format_trx[0]
            if market not in self.deal_trx:
                self.deal_trx[market] = []
            self.deal_trx[market].append(format_trx[1:])
            print(format_trx)

    def publish_place_trx(self, place_trx):
        trx_id = ""
        for trx in place_trx:
            if trx_id == trx["trx_id"]:
                continue
            prefix = get_prefix(trx["quote"], trx["base"])
            trx_id = trx["trx_id"]
            if trx["cancel"]:
                trx["type"] = "cancel " + trx["type"]
            format_trx = [prefix, trx["block"], trx["timestamp"],
                          trx["type"], trx["price"], trx["amount"]]
            self.myPublish(
                u'bts.orderbook.%s.order' % (format_trx[0]), format_trx[1:])
            self.myPublish(u'bts.orderbook.order', format_trx)
            market = format_trx[0]
            if market not in self.place_trx:
                self.place_trx[market] = []
            self.place_trx[market].append(format_trx[1:])
            print(format_trx)

    def publish_order_book(self):
        for quote, base in self.market_list:
            prefix = get_prefix(quote, base)
            order_book = self.market.get_order_book(
                quote, base)
            order_book["bids"] = order_book["bids"][:10]
            order_book["asks"] = order_book["asks"][:10]
            if (prefix not in self.order_book or
               self.order_book[prefix] != order_book):
                self.order_book[prefix] = order_book
                self.myPublish(
                    u'bts.orderbook.%s' % prefix, order_book)

    def execute(self):
        client_info = self.bts_client.get_info()
        height_now = int(client_info["blockchain_head_block_num"])
        if(self.height < height_now):
            time_stamp = client_info["blockchain_head_block_timestamp"]
            self.myPublish(u'bts.blockchain.info',
                           {"height": height_now, "time_stamp": time_stamp})
            self.publish_order_book()
        while self.height < height_now:
            self.height += 1
            trxs = self.bts_client.get_block_transactions(
                self.height)
            recs = self.market.get_order_deal_rec(self.height)
            self.publish_deal_trx(recs)
            recs = self.market.get_order_place_rec(trxs)
            self.publish_place_trx(recs)
            self.market.update_order_owner(recs)
Ejemplo n.º 5
0
class BTSOrderBook(object):
    def __init__(self):
        self.market_list = [["BOTSCNY", "BTS"], ["CNY", "BTS"], ["USD", "BTS"],
                            ["GOLD", "BTS"], ["BTC", "BTS"],
                            ["BDR.AAPL", "CNY"], ["NOTE", "BTS"]]
        self.init_done = False
        self.pusher = None
        self.order_book = {}
        self.deal_trx = {}
        self.place_trx = {}
        for quote, base in self.market_list:
            prefix = get_prefix(quote, base)
            self.order_book[prefix] = {}
            self.deal_trx[prefix] = []
            self.place_trx[prefix] = []
        self.init_market()
        self.execute()
        self.init_done = True

    def init_market(self):
        config_file = os.getenv("HOME") + "/.python-bts/bts_client.json"
        fd_config = open(config_file)
        config_bts = json.load(fd_config)["client_default"]
        fd_config.close()

        self.bts_client = BTS(config_bts["user"], config_bts["password"],
                              config_bts["host"], config_bts["port"])
        self.market = BTSMarket(self.bts_client)
        client_info = self.bts_client.get_info()
        self.height = int(client_info["blockchain_head_block_num"]) - 180

    def myPublish(self, topic, event):
        if self.pusher and self.init_done:
            self.pusher.emit(topic, event, namespace="")

    def publish_deal_trx(self, deal_trx):
        for trx in deal_trx:
            if trx["type"] == "bid":
                deal_type = "buy"
            else:
                deal_type = "sell"
            prefix = get_prefix(trx["quote"], trx["base"])
            format_trx = [
                prefix, trx["block"], trx["timestamp"], deal_type,
                trx["price"], trx["volume"]
            ]
            self.myPublish(u'bts.orderbook.%s.trx' % (format_trx[0]),
                           format_trx[1:])
            self.myPublish(u'bts.orderbook.trx', format_trx)
            market = format_trx[0]
            if market not in self.deal_trx:
                self.deal_trx[market] = []
            self.deal_trx[market].append(format_trx[1:])
            print(format_trx)

    def publish_place_trx(self, place_trx):
        trx_id = ""
        for trx in place_trx:
            if trx_id == trx["trx_id"]:
                continue
            prefix = get_prefix(trx["quote"], trx["base"])
            trx_id = trx["trx_id"]
            if trx["cancel"]:
                trx["type"] = "cancel " + trx["type"]
            format_trx = [
                prefix, trx["block"], trx["timestamp"], trx["type"],
                trx["price"], trx["amount"]
            ]
            self.myPublish(u'bts.orderbook.%s.order' % (format_trx[0]),
                           format_trx[1:])
            self.myPublish(u'bts.orderbook.order', format_trx)
            market = format_trx[0]
            if market not in self.place_trx:
                self.place_trx[market] = []
            self.place_trx[market].append(format_trx[1:])
            print(format_trx)

    def publish_order_book(self):
        for quote, base in self.market_list:
            prefix = get_prefix(quote, base)
            order_book = self.market.get_order_book(quote, base)
            order_book["bids"] = order_book["bids"][:10]
            order_book["asks"] = order_book["asks"][:10]
            if (prefix not in self.order_book
                    or self.order_book[prefix] != order_book):
                self.order_book[prefix] = order_book
                self.myPublish(u'bts.orderbook.%s' % prefix, order_book)

    def execute(self):
        client_info = self.bts_client.get_info()
        height_now = int(client_info["blockchain_head_block_num"])
        if (self.height < height_now):
            time_stamp = client_info["blockchain_head_block_timestamp"]
            self.myPublish(u'bts.blockchain.info', {
                "height": height_now,
                "time_stamp": time_stamp
            })
            self.publish_order_book()
        while self.height < height_now:
            self.height += 1
            trxs = self.bts_client.get_block_transactions(self.height)
            recs = self.market.get_order_deal_rec(self.height)
            self.publish_deal_trx(recs)
            recs = self.market.get_order_place_rec(trxs)
            self.publish_place_trx(recs)
            self.market.update_order_owner(recs)