Ejemplo n.º 1
0
    def processAlerts(self):
        if 'alerts' not in self.db:
            return
        higher = 'HIGHER'
        lower = 'LOWER'
        alerts = self.db['alerts']
        toRemove = []
        print(alerts)
        for chatId in alerts:
            for fsym in alerts[chatId]:
                ops = alerts[chatId][fsym]
                for op in ops:
                    tsyms = ops[op]
                    for tsym in tsyms:
                        targets = tsyms[tsym]
                        price = self.repository.get_price_if_valid(fsym, tsym)
                        for target in targets:
                            self.log.info(
                                f"{chatId} {fsym}{tsym} = {price} target {op} {target} "
                            )
                            if op == lower and price < target or op == higher and price > target:
                                self.api.sendMessage(
                                    '{} is {} {} at {} {}'.format(
                                        self.repository.get_symbols()[fsym],
                                        'below' if op == lower else 'above',
                                        format_price(target),
                                        format_price(price), tsym), chatId)
                                toRemove.append(
                                    (fsym, tsym, target, chatId, op))

        for tr in toRemove:
            self.removeAlert(tr[0], tr[1], tr[2], tr[3], tr[4])
Ejemplo n.º 2
0
    def price(self, chatId, command):
        parts = command.split()
        if len(parts) > 3:
            self.sendMessage("Invalid command, enter 2 symbols, eg: BTC USD", chatId)
            return

        fsym = TgBot.DEFAULT_COIN
        if len(parts) >1:
            fsym = parts[1].upper()

        tsym = self.DEFAULT_FIAT
        if len(parts) > 2:
            tsym = parts[2].upper()

        if not self.repository.isPricePairValid(fsym, tsym):
            self.sendMessage("Invalid symbols {} {}".format(fsym,tsym), chatId)
            return

        price = self.get_price(fsym, tsym)
        resp = '1 {} = {} {}'.format(self.get_symbols()[fsym], format_price(price),tsym)
        chartFile = self.repository.get_chart_near(fsym, tsym)
        if chartFile != None:
            self.sendPhoto(chartFile, resp, chatId)
        else:
            self.sendMessage(resp, chatId)
Ejemplo n.º 3
0
    def chart(self, chatId, command):
        parts = command.split()
        if len(parts) > 4:
            self.sendMessage("Invalid command, enter 2 symbols, eg: BTC USD", chatId)
            return

        fsym = TgBot.DEFAULT_COIN
        if len(parts) > 1:
            fsym = parts[1].upper()

        tsym = self.DEFAULT_FIAT
        tf = CandleInterval.ONE_HOUR
        if len(parts) > 2:
            tsym = parts[2].upper()                
            if len(parts) > 3 and CandleInterval.has_value(parts[3]):
                tf = CandleInterval(parts[3])


        chartFile = self.repository.get_chart(fsym, tsym, tf)
        if chartFile != None:
            price = self.get_price(fsym, tsym)
            if self.repository.isPricePairValid(fsym, tsym):
                resp = '1 {} = {} {}'.format(self.get_symbols()[fsym], format_price(price),tsym)
            else:
                resp = "Enjoy the binance chart!"
            self.sendPhoto(chartFile, resp, chatId)
        else:
            self.sendMessage(f"no chart for {fsym} {tsym} {tf}", chatId)
Ejemplo n.º 4
0
    def draw_chart_frame(self, draw, minVal, maxVal, symbol):
        color = (255, 255, 255)
        left = self.CHART_MARGIN_LEFT
        right = self.IMG_WIDTH
        bottom = self.IMG_HEIGHT - self.CHART_MARGIN_BOTTOM
        top = 0
        MARGIN = 2
        font = ImageFont.truetype(self.FONT_PATH, 14)
        # valStr = "{:.1f}".format(minVal)
        # size = draw.textsize(str(valStr), font)
        # draw.text((left-size[0]-MARGIN, bottom - size[1]- self.CHART_PADDING - MARGIN), str(valStr), color, font)

        # length = int(math.floor(math.log10(math.floor(maxVal))+1)) if maxVal>=1 else 0
        # precision = 8 - length

        color_bg = (100, 100, 100)
        LINES = 12
        for i in range(0, LINES + 1):
            y = bottom - (
                i / LINES) * (bottom - top - self.CHART_MARGIN_TOP -
                              self.CHART_PADDING * 2) - self.CHART_PADDING
            draw.line([(left, y), (right, y)], color_bg, 1)
            x = left + (i / LINES) * (right - left)
            draw.line([(x, top), (x, bottom)], color_bg, 1)
            val = minVal + (i / LINES) * (maxVal - minVal)
            valStr = format_price(val)
            size = draw.textsize(valStr, font)
            draw.text((left - size[0] - MARGIN, y - size[1] - MARGIN), valStr,
                      color, font)

        draw.line([(left, bottom), (right, bottom)], color, 1)
        draw.line([(left, top), (left, bottom)], color, 1)
        #draw legend
        font_legend = ImageFont.truetype(self.FONT_PATH, 18)
        draw.text((left, top), symbol, (255, 255, 0), font_legend)
Ejemplo n.º 5
0
    def higher_lower(self, chatId, command):
        parts = command.upper().split()
        if len(parts) < 3 or len(parts) > 4:
            self.api.sendMessage("Invalid command", chatId)
            return
        op = parts[0]
        fsym = parts[1]
        if not fsym in self.repository.get_symbols().keys():
            self.api.sendMessage('Invalid symbol "{}"'.format(fsym), chatId)
            return
        try:
            target = float(parts[2])
        except ValueError:
            self.api.sendMessage('Invalid number "{}"'.format(parts[2]),
                                 chatId)
            return
        tsym = parts[3] if len(parts) > 3 else config.DEFAULT_FIAT
        if tsym == "SAT" or tsym == "SATS":
            target = target / (100.0 * 1000.0 * 1000.0)
            tsym = "BTC"

        if tsym not in self.repository.TSYMS:
            self.api.sendMessage('Invalid symbol {}'.format(tsym), chatId)
            return

        if 'alerts' not in self.db:
            self.db['alerts'] = {}
        alerts = self.db['alerts'][chatId] if chatId in self.db[
            'alerts'] else {}
        if fsym in alerts:
            alert = alerts[fsym]
            if op in alert and type(alert[op]) is dict:
                opObj = alert[op]
                if tsym in opObj:
                    opObj[tsym].add(target)
                else:
                    opObj[tsym] = set([target])
            else:
                alert[op] = {tsym: set([target])}
        else:
            alerts[fsym] = {op: {tsym: set([target])}}
        self.db['alerts'][chatId] = alerts
        msg = 'Notification set for {} {} {} {}.'.format(
            self.repository.get_symbols()[fsym],
            'below' if op == 'LOWER' else 'above', format_price(target), tsym)
        self.api.sendMessage(msg, chatId)
Ejemplo n.º 6
0
    def processMessage(self, message):
        if "text" not in message:
            print(F"message doesn't have text! \n {message}"
        text = message['text']
        chatId = message['chat']['id']
        if('entities' in message and message['entities'][0]['type'] == 'bot_command'):
            self.dispatchCommand(message)

    def removeAlert(self, fsym, tsym, target, chatId, op):
        alerts = TgBot.db['alerts']
        alerts[chatId][fsym][op][tsym].remove(target)
        if len(alerts[chatId][fsym][op][tsym]) == 0:
            alerts[chatId][fsym][op].pop(tsym)
            if len(alerts[chatId][fsym][op]) == 0:
                alerts[chatId][fsym].pop(op)
                if len(alerts[chatId][fsym]) == 0:
                    alerts[chatId].pop(fsym)
                    if len(alerts[chatId]) == 0:
                        alerts.pop(chatId)

    def processAlerts(self):
        if 'alerts' not in TgBot.db:
            return
        higher = 'HIGHER'
        lower = 'LOWER'
        alerts = TgBot.db['alerts']
        toRemove = []
        for chatId in alerts:
            for fsym in alerts[chatId]:
                ops = alerts[chatId][fsym]
                for op in ops:
                    tsyms = ops[op]
                    for tsym in tsyms:
                        targets = tsyms[tsym]
                        price = self.get_price(fsym, tsym)
                        for target in targets:
                            if op == lower and price < target or op == higher and price > target:
                                self.sendMessage('{} is {} {} at {} {}'.format(self.get_symbols()[fsym],
                                'below' if op == lower else 'above', format_price(target), format_price(price), tsym), chatId)
                                toRemove.append((fsym, tsym, target, chatId, op))

        for tr in toRemove:
            self.removeAlert(tr[0], tr[1], tr[2], tr[3], tr[4])
    
    def getUpdates(self):
        offset = self.last_update+1
        url = self.getTgUrl('getUpdates')
        r = self.request_session.post(
            url=url, data={'offset': offset, 'limit': 100, 'timeout': 9})
        updates = r.json()
        if not 'ok' in updates or not updates['ok']:
            return None
        return updates['result']

    def processUpdates(self, updates):
        for update in updates:
            print('processing {}...'.format(update['update_id']))
            message = update['message'] if 'message' in update else update['edited_message']
            try:
                self.processMessage(message)
                self.last_update = TgBot.db['last_update'] = update['update_id']
            except:
                traceback.print_exc()

    def init(self):
        try:
            with open(TgBot.DB_FILENAME, 'rb') as fp:
                TgBot.db = pickle.load(fp)
        except:
            self.log("error loading db")
            TgBot.db = {}
        #self.log("db at start: {}".format(TgBot.db))
        self.last_update = TgBot.db['last_update'] if 'last_update' in TgBot.db else 0

    def persist_db(self):
        with open(TgBot.DB_FILENAME, 'wb') as fp:
            #self.log(f"db at save: {TgBot.db}")
            pickle.dump(TgBot.db, fp)