Example #1
0
    def get_action(self, bot, update, args):
        base_cur = "USD"
        fiat_symbol = "$"

        if args:
            base_cur = args[0].upper()
            if base_cur == "EUR":
                fiat_symbol = "€"

        if RateLimit.limit_reached(update):
            return

        try:
            market = CoinGecko().get_coins_markets(
                base_cur.lower(),
                per_page=30,
                page=1,
                order="market_cap_desc",
                sparkline=False,
                price_change_percentage=False)
        except Exception as e:
            return self.handle_error(e, update)

        msg = str()

        if market:
            for i in range(30):
                rank = market[i]['market_cap_rank']
                symbol = market[i]['symbol'].upper()
                name = market[i]['name']

                price = market[i]['current_price']
                price = utl.format(price, decimals=4, symbol=base_cur)

                if base_cur == "EUR":
                    price = f"{price} {fiat_symbol}"
                    mcap = f"{utl.format(market[i]['market_cap'])}{fiat_symbol}"
                    vol = f"{utl.format(market[i]['total_volume'])}{fiat_symbol}"
                elif base_cur == "USD":
                    price = f"{fiat_symbol}{price}"
                    mcap = f"{fiat_symbol}{utl.format(market[i]['market_cap'])}"
                    vol = f"{fiat_symbol}{utl.format(market[i]['total_volume'])}"
                else:
                    price = f"{price}"
                    mcap = f"{utl.format(market[i]['market_cap'])}"
                    vol = f"{utl.format(market[i]['total_volume'])}"

                msg += f"{rank}. *{symbol}* ({name}) - {price}\n" \
                       f"` M.Cap.: {mcap}`\n" \
                       f"` Volume: {vol}`\n"

        if msg:
            msg = f"*Top 30 Coins by Market Cap in {base_cur}*\n\n {msg}"
        else:
            msg = f"{emo.ERROR} Can't retrieve toplist"

        update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
Example #2
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        # Set tokens for Twitter access
        tw = twitter.Api(consumer_key=self._consumer_key,
                         consumer_secret=self._consumer_secret,
                         access_token_key=self._access_token_key,
                         access_token_secret=self._access_token_secret)

        coin = args[0].upper()

        # Get coin ID
        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        timeline = None
        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)

                coin_name = data["name"]
                tw_account = data["links"]["twitter_screen_name"]

                if tw_account:
                    timeline = tw.GetUserTimeline(screen_name=tw_account,
                                                  count=3,
                                                  include_rts=False,
                                                  trim_user=True,
                                                  exclude_replies=True)
                break

        if timeline:
            for tweet in [i.AsDict() for i in reversed(timeline)]:
                stats = f"{emo.HEART} {tweet['favorite_count']} " \
                        f"{emo.REPEAT} {tweet['retweet_count']}"

                msg = f"*Tweet from {coin_name}*\n" \
                      f"{tweet['created_at'].split('+')[0]}\n" \
                      f"{stats}\n\n" \
                      f"{tweet['text']}"

                update.message.reply_text(text=msg,
                                          parse_mode=ParseMode.MARKDOWN)
Example #3
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        msg = str()

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    self.handle_error(e, update)

                dev_data = data["developer_data"]

                for k, v in dev_data.items():
                    msg += f"`{k.title().replace('_', ' ')}: {str(v)}`\n"

                gh_links = data["links"]["repos_url"]["github"]

                if not gh_links:
                    break

                msg += "\n`GitHub links:`\n"

                for link in gh_links:
                    title_index = link.rfind("/")
                    msg += f"[{link[title_index+1:len(link)]}]({link})\n"

                break

        if msg:
            msg = f"`GitHub info for {coin}`\n\n" + msg
        else:
            msg = f"{emo.INFO} No developer data found for *{coin}*"

        update.message.reply_text(text=msg.replace("Pull Request", "PR"),
                                  parse_mode=ParseMode.MARKDOWN,
                                  disable_web_page_preview=True)
Example #4
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        data = None

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)
                break

        if not data or not data["description"]["en"]:
            update.message.reply_text(text=f"{emo.INFO} No data for *{coin}*",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        coin_desc = data["description"]["en"]

        if len(coin_desc) > con.MAX_TG_MSG_LEN:
            url = f"https://www.coingecko.com/en/coins/{data['id']}"
            html_link = f'...\n\n<a href="{url}">Read whole description</a>'
            coin_desc = coin_desc[:(con.MAX_TG_MSG_LEN - 27)] + html_link

        update.message.reply_text(text=coin_desc,
                                  parse_mode=ParseMode.HTML,
                                  disable_web_page_preview=True)
Example #5
0
    def get_action(self, bot, update, args):
        kw = utl.get_kw(args)

        limit = kw.get("limit", 5)
        kw.pop("limit", None)

        if RateLimit.limit_reached(update):
            return

        try:
            events = CoinGecko().get_events(**kw)
        except Exception as e:
            return self.handle_error(e, update)

        for i in range(int(limit)):
            if len(events["data"]) <= i:
                break

            event = events["data"][i]

            title = event["title"]
            event_type = event["type"]
            description = event["description"]
            organizer = event["organizer"]
            from_date = event["start_date"]
            to_date = event["end_date"]
            address = event["address"].strip()
            city = event["city"].strip()
            country = event["country"].strip()
            website = event["website"]

            org = f" by {organizer}" if organizer else ""

            msg = f"[{title}]({website})\n" \
                  f"{event_type}{org}\n\n" \
                  f"{utl.esc_md(description)}\n\n" \
                  f"*Date*\nStart {from_date}\nEnd   {to_date}\n\n" \
                  f"*Location*\n{address}\n{city}\n{country}\n\n"

            update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
Example #6
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(
                text=f"Usage:\n{self.get_usage()}",
                parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        data = None

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)
                break

        if not data or not data["description"]["en"]:
            update.message.reply_text(
                text=f"{emo.INFO} No data for *{coin}*",
                parse_mode=ParseMode.MARKDOWN)
            return

        coin_desc = data["description"]["en"]

        for message in utl.split_msg(coin_desc):
            update.message.reply_text(
                text=message,
                parse_mode=ParseMode.HTML,
                disable_web_page_preview=True)
Example #7
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(
                text=f"Usage:\n{self.get_usage()}",
                parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        vs_cur = "usd"

        if "-" in args[0]:
            pair = args[0].split("-", 1)
            vs_cur = pair[1].lower()
            coin = pair[0].upper()
        else:
            coin = args[0].upper()

        data = None

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        # Get coin ID and data
        for entry in response:
            if entry["symbol"].upper() == coin:
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)
                break

        if not data:
            update.message.reply_text(
                text=f"{emo.INFO} No data for *{coin}*",
                parse_mode=ParseMode.MARKDOWN)
            return

        name = data["name"]
        symbol = data["symbol"].upper()

        if data["market_data"]["price_change_percentage_1h_in_currency"]:
            c_1h = data["market_data"]["price_change_percentage_1h_in_currency"][vs_cur]
            c1h = utl.format(float(c_1h), decimals=2, force_length=True)
            h1 = "{:>10}".format(f"{c1h}%")
        else:
            h1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_24h_in_currency"]:
            c_1d = data["market_data"]["price_change_percentage_24h_in_currency"][vs_cur]
            c1d = utl.format(float(c_1d), decimals=2, force_length=True)
            d1 = "{:>10}".format(f"{c1d}%")
        else:
            d1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_7d_in_currency"]:
            c_1w = data["market_data"]["price_change_percentage_7d_in_currency"][vs_cur]
            c1w = utl.format(float(c_1w), decimals=2, force_length=True)
            w1 = "{:>10}".format(f"{c1w}%")
        else:
            w1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_30d_in_currency"]:
            c_1m = data["market_data"]["price_change_percentage_30d_in_currency"][vs_cur]
            c1m = utl.format(float(c_1m), decimals=2, force_length=True)
            m1 = "{:>10}".format(f"{c1m}%")
        else:
            m1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_1y_in_currency"]:
            c_1y = data["market_data"]["price_change_percentage_1y_in_currency"]["usd"]
            c1y = utl.format(float(c_1y), decimals=2, force_length=True)
            y1 = "{:>10}".format(f"{c1y}%")
        else:
            y1 = "{:>10}".format("N/A")

        update.message.reply_text(
            text=f"`"
                 f"{name} ({symbol}) in {vs_cur.upper()}\n\n"
                 f"Hour  {h1}\n"
                 f"Day   {d1}\n"
                 f"Week  {w1}\n"
                 f"Month {m1}\n"
                 f"Year  {y1}\n\n"
                 f"`",
            parse_mode=ParseMode.MARKDOWN,
            disable_web_page_preview=True)
Example #8
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        msg = str()
        top = str()
        coin = str()
        vs_cur = "usd"

        if args[0].lower().startswith("top="):
            top = args[0][4:]

            if not top.isnumeric():
                update.message.reply_text(
                    text=f"{emo.ERROR} Value of `top` has to be a number",
                    parse_mode=ParseMode.MARKDOWN)
                return
            if int(top) > 100:
                update.message.reply_text(
                    text=f"{emo.ERROR} Max value for `top` is `100`",
                    parse_mode=ParseMode.MARKDOWN)
                return
        else:
            if "-" in args[0]:
                pair = args[0].split("-", 1)
                vs_cur = pair[0].lower()
                coin = pair[1].lower()
            else:
                coin = args[0].lower()

        if RateLimit.limit_reached(update):
            return

        # ---------- TOP VOLUME ----------

        if top:
            try:
                data = CoinGecko().get_coins_markets(vs_cur,
                                                     per_page=top,
                                                     page=1,
                                                     order="volume_desc",
                                                     sparkline=False)
            except Exception as e:
                return self.handle_error(e, update)

            count = 0
            for entry in data:
                count += 1

                name = entry["name"]
                symbol = entry["symbol"].upper()
                vol = utl.format(entry["total_volume"])

                msg += f"#{count} {name} ({symbol})\n" \
                       f"{vol} {vs_cur.upper()}\n\n"

            msg = f"Top {top} by Total Volume\n\n{msg}"

        # ---------- TOTAL VOLUME ----------

        else:
            data = None

            try:
                response = APICache.get_cg_coins_list()
            except Exception as e:
                return self.handle_error(e, update)

            # Get coin ID and data
            for entry in response:
                if entry["symbol"] == coin:
                    try:
                        data = CoinGecko().get_coins_markets(
                            vs_cur, ids=entry["id"], order="volume_desc")
                    except Exception as e:
                        return self.handle_error(e, update)
                    break

            if not data:
                update.message.reply_text(
                    text=f"{emo.ERROR} No data for *{coin}*",
                    parse_mode=ParseMode.MARKDOWN)
                return

            name = data[0]["name"]
            vol = utl.format(data[0]["total_volume"])

            msg = f"{name} ({coin.upper()})\n\n" \
                  f"Total Volume:\n" \
                  f"{vol} {vs_cur.upper()}"

        if not msg:
            msg = f"{emo.ERROR} Can't retrieve data for *{coin.upper()}*"

        update.message.reply_text(text=f"`{msg}`",
                                  parse_mode=ParseMode.MARKDOWN)
Example #9
0
    def get_action(self, bot, update, args):
        # TODO: Do this in every plugin
        keywords = utl.get_kw(args)
        arg_list = utl.del_kw(args)

        # TODO: Do this in most other plugins
        if not arg_list:
            if not keywords.get(Keyword.INLINE):
                update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                          parse_mode=ParseMode.MARKDOWN)
            return

        vs_cur = str()

        if "-" in arg_list[0]:
            pair = arg_list[0].split("-", 1)
            vs_cur = pair[1].upper()
            coin = pair[0].upper()
        else:
            coin = arg_list[0].upper()

        exchange = str()
        if len(arg_list) > 1:
            exchange = arg_list[1]

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        coin_id = str()
        coin_name = str()
        for entry in response:
            if entry["symbol"].upper() == coin:
                coin_id = entry["id"]
                coin_name = entry["name"]
                break

        if RateLimit.limit_reached(update):
            return

        cg = CoinGecko()
        msg = str()

        if exchange:
            try:
                result = cg.get_coin_by_id(coin_id)
            except Exception as e:
                return self.handle_error(e, update)

            if result:
                vs_list = list()

                if vs_cur:
                    vs_list = vs_cur.split(",")

                for ticker_len in result["tickers"]:
                    if ticker_len["market"]["name"].upper() == exchange.upper(
                    ):
                        if ticker_len["base"] != coin:
                            base_coin = ticker_len["base"]
                        else:
                            base_coin = ticker_len["target"]

                        if vs_list:
                            if base_coin in vs_list:
                                price = utl.format(ticker_len["last"],
                                                   force_length=True)
                                msg += f"`{base_coin}: {price}`\n"
                        else:
                            price = utl.format(ticker_len["last"],
                                               force_length=True)
                            msg += f"`{base_coin}: {price}`\n"
        else:
            if not vs_cur:
                if coin == "BTC":
                    vs_cur = "ETH,USD,EUR"
                elif coin == "ETH":
                    vs_cur = "BTC,USD,EUR"
                else:
                    vs_cur = "BTC,ETH,USD,EUR"

            try:
                result = cg.get_simple_price(coin_id, vs_cur)
            except Exception as e:
                return self.handle_error(e, update)

            if result:
                for symbol, price in next(iter(result.values())).items():
                    if symbol in utl.get_fiat_list():
                        if decimal.Decimal(
                                str(price)).as_tuple().exponent > -3:
                            price = utl.format(price,
                                               decimals=2,
                                               force_length=True)
                        else:
                            price = utl.format(price, force_length=True)
                    else:
                        price = utl.format(price, force_length=True)

                    msg += f"`{symbol.upper()}: {price}`\n"

        if msg:
            if exchange:
                ticker_len = 0
                for line in msg.split("\n"):
                    length = len(line[:line.find(":")])
                    if ticker_len < length:
                        ticker_len = length

                message = str()
                for line in msg.split("\n"):
                    if line:
                        lst = line.split(" ")
                        index = ticker_len + 2 + len(lst[1]) - len(lst[0])
                        price = "{1:>{0}}".format(index, lst[1])
                        message += f"{lst[0]}{price}\n"

                msg = f"`{coin} ({coin_name}) on {exchange.capitalize()}`\n\n" + message
            else:
                msg = f"`{coin} ({coin_name})`\n\n" + msg

            # Add link to source of data (CoinGecko)
            msg += f"\n[Details on CoinGecko]({self.CG_URL}{coin_id})"
        else:
            msg = f"{emo.ERROR} Can't retrieve data for *{coin}*"

        if keywords.get(Keyword.INLINE):
            return msg

        self.send_msg(msg, update, keywords)
Example #10
0
    def get_action(self, bot, update, args):
        keywords = utl.get_kw(args)
        arg_list = utl.del_kw(args)

        if not arg_list:
            if not keywords.get(Keyword.INLINE):
                update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                          parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = arg_list[0].upper()
        data = None
        cgid = None

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        # Get coin ID and data
        for entry in response:
            if entry["symbol"].upper() == coin:
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)

                cgid = entry["id"]
                break

        if not data:
            update.message.reply_text(text=f"{emo.ERROR} No data for *{coin}*",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        name = data["name"]
        symbol = data["symbol"].upper()

        rank_mc = data["market_cap_rank"]
        rank_cg = data["coingecko_rank"]

        cs = int(float(data['market_data']['circulating_supply']))
        sup_c = f"{utl.format(cs)} {symbol}"

        if data["market_data"]["total_supply"]:
            ts = int(float(data["market_data"]["total_supply"]))
            sup_t = f"{utl.format(ts)} {symbol}"
        else:
            sup_t = "N/A"

        usd = data["market_data"]["current_price"]["usd"]
        eur = data["market_data"]["current_price"]["eur"]
        btc = data["market_data"]["current_price"]["btc"]
        eth = data["market_data"]["current_price"]["eth"]

        p_usd = utl.format(usd, force_length=True)
        p_eur = utl.format(eur, force_length=True, template=p_usd)
        p_btc = utl.format(btc, force_length=True, template=p_usd)
        p_eth = utl.format(eth, force_length=True, template=p_usd)

        p_usd = "{:>12}".format(p_usd)
        p_eur = "{:>12}".format(p_eur)
        p_btc = "{:>12}".format(p_btc)
        p_eth = "{:>12}".format(p_eth)

        # Do not display BTC or ETH price if coin is BTC or ETH
        btc_str = "" if coin == "BTC" else f"BTC {p_btc}\n"
        eth_str = "" if coin == "ETH" else f"ETH {p_eth}\n"

        v_24h = utl.format(
            int(float(data["market_data"]["total_volume"]["usd"])))
        m_cap = utl.format(int(float(
            data["market_data"]["market_cap"]["usd"])))

        if data["market_data"]["price_change_percentage_1h_in_currency"]:
            c_1h = data["market_data"][
                "price_change_percentage_1h_in_currency"]["usd"]
            c1h = utl.format(float(c_1h), decimals=2, force_length=True)
            h1 = "{:>10}".format(f"{c1h}%")
        else:
            h1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_24h_in_currency"]:
            c_1d = data["market_data"][
                "price_change_percentage_24h_in_currency"]["usd"]
            c1d = utl.format(float(c_1d), decimals=2, force_length=True)
            d1 = "{:>10}".format(f"{c1d}%")
        else:
            d1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_7d_in_currency"]:
            c_1w = data["market_data"][
                "price_change_percentage_7d_in_currency"]["usd"]
            c1w = utl.format(float(c_1w), decimals=2, force_length=True)
            w1 = "{:>10}".format(f"{c1w}%")
        else:
            w1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_30d_in_currency"]:
            c_1m = data["market_data"][
                "price_change_percentage_30d_in_currency"]["usd"]
            c1m = utl.format(float(c_1m), decimals=2, force_length=True)
            m1 = "{:>10}".format(f"{c1m}%")
        else:
            m1 = "{:>10}".format("N/A")

        if data["market_data"]["price_change_percentage_1y_in_currency"]:
            c_1y = data["market_data"][
                "price_change_percentage_1y_in_currency"]["usd"]
            c1y = utl.format(float(c_1y), decimals=2, force_length=True)
            y1 = "{:>10}".format(f"{c1y}%")
        else:
            y1 = "{:>10}".format("N/A")

        msg = f"`" \
              f"{name} ({symbol})\n\n" \
              f"USD {p_usd}\n" \
              f"EUR {p_eur}\n" \
              f"{btc_str}" \
              f"{eth_str}\n" \
              f"Hour  {h1}\n" \
              f"Day   {d1}\n" \
              f"Week  {w1}\n" \
              f"Month {m1}\n" \
              f"Year  {y1}\n\n" \
              f"Market Cap Rank: {rank_mc}\n" \
              f"Coin Gecko Rank: {rank_cg}\n\n" \
              f"Volume 24h: {v_24h} USD\n" \
              f"Market Cap: {m_cap} USD\n" \
              f"Circ. Supp: {sup_c}\n" \
              f"Total Supp: {sup_t}\n\n" \
              f"`" \
              f"Stats on [CoinGecko](https://www.coingecko.com/en/coins/{cgid}) & " \
              f"[Coinlib](https://coinlib.io/coin/{coin}/{coin})"

        if keywords.get(Keyword.INLINE):
            return msg

        self.send_msg(msg, update, keywords)
Example #11
0
 def refresh_coingecko_coin_list():
     APICache.cg_coin_list = CoinGecko().get_coins_list()
Example #12
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(
                text=f"Usage:\n{self.get_usage()}",
                parse_mode=ParseMode.MARKDOWN)
            return

        time_frame = 3  # Days
        base_coin = "BTC"

        if "-" in args[0]:
            pair = args[0].split("-", 1)
            base_coin = pair[0].upper()
            coin = pair[1].upper()
        else:
            coin = args[0].upper()

        if coin == "BTC" and base_coin == "BTC":
            base_coin = "USD"

        if coin == base_coin:
            update.message.reply_text(
                text=f"{emo.ERROR} Can't compare *{coin}* to itself",
                parse_mode=ParseMode.MARKDOWN)
            return

        if len(args) > 1 and args[1].isnumeric():
            time_frame = args[1]

        if RateLimit.limit_reached(update):
            return

        cg_thread = threading.Thread(target=self._get_cg_coin_id, args=[coin])
        cmc_thread = threading.Thread(target=self._get_cmc_coin_id, args=[coin])

        cg_thread.start()
        cmc_thread.start()

        cg_thread.join()

        if not self.cg_coin_id:
            update.message.reply_text(
                text=f"{emo.ERROR} Can't retrieve data for *{coin}*",
                parse_mode=ParseMode.MARKDOWN)
            return

        try:
            market = CoinGecko().get_coin_market_chart_by_id(
                self.cg_coin_id,
                base_coin.lower(),
                time_frame)
        except Exception as e:
            self.handle_error(e, update)

        # Volume
        df_volume = DataFrame(market["total_volumes"], columns=["DateTime", "Volume"])
        df_volume["DateTime"] = pd.to_datetime(df_volume["DateTime"], unit="ms")
        volume = go.Scatter(
            x=df_volume.get("DateTime"),
            y=df_volume.get("Volume"),
            name="Volume"
        )

        # Price
        df_price = DataFrame(market["prices"], columns=["DateTime", "Price"])
        df_price["DateTime"] = pd.to_datetime(df_price["DateTime"], unit="ms")
        price = go.Scatter(
            x=df_price.get("DateTime"),
            y=df_price.get("Price"),
            yaxis="y2",
            name="Price",
            line=dict(
                color=("rgb(22, 96, 167)"),
                width=2
            )
        )

        cmc_thread.join()

        if not self.cmc_coin_id:
            update.message.reply_text(
                text=f"{emo.ERROR} Can't retrieve data for *{coin}*",
                parse_mode=ParseMode.MARKDOWN)
            return

        margin_l = 140
        tickformat = "0.8f"

        max_value = df_price["Price"].max()
        if max_value > 0.9:
            if max_value > 999:
                margin_l = 110
                tickformat = "0,.0f"
            else:
                margin_l = 115
                tickformat = "0.2f"

        layout = go.Layout(
            images=[dict(
                source=f"{con.CMC_LOGO_URL_PARTIAL}{self.cmc_coin_id}.png",
                opacity=0.8,
                xref="paper", yref="paper",
                x=1.05, y=1,
                sizex=0.2, sizey=0.2,
                xanchor="right", yanchor="bottom"
            )],
            paper_bgcolor='rgb(233,233,233)',
            plot_bgcolor='rgb(233,233,233)',
            autosize=False,
            width=800,
            height=600,
            margin=go.layout.Margin(
                l=margin_l,
                r=50,
                b=85,
                t=100,
                pad=4
            ),
            yaxis=dict(
                domain=[0, 0.20]
            ),
            yaxis2=dict(
                title=dict(
                    text=base_coin,
                    font=dict(
                        size=18
                    )
                ),                domain=[0.25, 1],
                tickprefix="   ",
                ticksuffix=f"  "
            ),
            title=dict(
                text=coin,
                font=dict(
                    size=26
                )
            ),
            legend=dict(
                orientation="h",
                yanchor="top",
                xanchor="center",
                y=1.05,
                x=0.45
            ),
            shapes=[{
                "type": "line",
                "xref": "paper",
                "yref": "y2",
                "x0": 0,
                "x1": 1,
                "y0": market["prices"][len(market["prices"]) - 1][1],
                "y1": market["prices"][len(market["prices"]) - 1][1],
                "line": {
                    "color": "rgb(50, 171, 96)",
                    "width": 1,
                    "dash": "dot"
                }
            }],
        )

        try:
            fig = go.Figure(data=[price, volume], layout=layout)
        except Exception as e:
            self.handle_error(e, update)

        fig["layout"]["yaxis2"].update(tickformat=tickformat)

        update.message.reply_photo(
            photo=io.BufferedReader(BytesIO(pio.to_image(fig, format="jpeg"))),
            parse_mode=ParseMode.MARKDOWN)
Example #13
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        msg = str()

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    self.handle_error(e, update)

                if "ico_data" not in data:
                    break

                ico_start = data["ico_data"]["ico_start_date"][:10]
                ico_end = data["ico_data"]["ico_end_date"][:10]
                raised = data["ico_data"]["total_raised"]
                raised_cur = data["ico_data"]["total_raised_currency"]

                pre_sale_c = data["ico_data"]["quote_pre_sale_currency"]
                pre_sale_a = data["ico_data"]["base_pre_sale_amount"]
                pre_sale_p = data["ico_data"]["quote_pre_sale_amount"]

                pub_sale_c = data["ico_data"]["quote_public_sale_currency"]
                pub_sale_a = data["ico_data"]["base_public_sale_amount"]
                pub_sale_p = data["ico_data"]["quote_public_sale_amount"]

                kyc_req = data["ico_data"]["kyc_required"]

                raised = utl.format(raised) if raised is not None else raised

                if pre_sale_a:
                    pre_sale_a = utl.format(pre_sale_a, symbol=coin)
                if pre_sale_p:
                    pre_sale_p = utl.format(pre_sale_p, symbol=pre_sale_c)

                if pub_sale_a:
                    pub_sale_a = utl.format(pub_sale_a, symbol=coin)
                if pub_sale_p:
                    pub_sale_p = utl.format(pub_sale_p, symbol=pub_sale_c)

                if pre_sale_a:
                    pre_sale_str = f"{pre_sale_a} {coin} for {pre_sale_p} {pre_sale_c}\n"
                else:
                    pre_sale_str = "None\n"

                if pub_sale_a:
                    pub_sale_str = f"{pub_sale_a} {coin} for {pub_sale_p} {pub_sale_c}\n"
                else:
                    pub_sale_str = "None\n"

                msg = f"`" \
                      f"Start:    {ico_start}\n" \
                      f"End:      {ico_end}\n" \
                      f"Raised:   {raised} {raised_cur}\n" \
                      f"Pre-Sale: {pre_sale_str}" \
                      f"Pub-Sale: {pub_sale_str}" \
                      f"KYC:      {'Yes' if kyc_req == True else 'No'}" \
                      f"`"
                break

        if msg:
            msg = f"`ICO data for {coin}`\n\n" + msg
        else:
            msg = f"{emo.INFO} No ICO data for *{coin}*"

        update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
Example #14
0
    def get_action(self, bot, update, args):
        vs_cur = str()

        if not args:
            if update.message:
                update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                          parse_mode=ParseMode.MARKDOWN)
            return

        if "-" in args[0]:
            pair = args[0].split("-", 1)
            vs_cur = pair[0].upper()
            coin = pair[1].upper()
        else:
            coin = args[0].upper()

        exchange = str()
        if len(args) > 1:
            exchange = args[1]

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            self.handle_error(e, update)

        coin_id = str()
        for entry in response:
            if entry["symbol"].upper() == coin:
                coin_id = entry["id"]
                break

        if RateLimit.limit_reached(update):
            return

        cg = CoinGecko()
        msg = str()

        if exchange:
            try:
                result = cg.get_coin_by_id(coin_id)
            except Exception as e:
                self.handle_error(e, update)

            if result:
                vs_list = list()

                if vs_cur:
                    vs_list = vs_cur.split(",")

                for ticker in result["tickers"]:
                    if ticker["market"]["name"].upper() == exchange.upper():
                        base_coin = ticker["target"]
                        if vs_list:
                            if base_coin in vs_list:
                                price = utl.format(ticker["last"],
                                                   force_length=True)
                                msg += f"`{base_coin}: {price}`\n"
                        else:
                            price = utl.format(ticker["last"],
                                               force_length=True)
                            msg += f"`{base_coin}: {price}`\n"
        else:
            if not vs_cur:
                if coin == "BTC":
                    vs_cur = "ETH,USD,EUR"
                elif coin == "ETH":
                    vs_cur = "BTC,USD,EUR"
                else:
                    vs_cur = "BTC,ETH,USD,EUR"

            try:
                result = cg.get_simple_price(coin_id, vs_cur)
            except Exception as e:
                self.handle_error(e, update)

            if result:
                for symbol, price in next(iter(result.values())).items():
                    if symbol in utl.get_fiat_list():
                        if decimal.Decimal(
                                str(price)).as_tuple().exponent > -3:
                            price = utl.format(price,
                                               decimals=2,
                                               force_length=True)
                        else:
                            price = utl.format(price, force_length=True)
                    else:
                        price = utl.format(price, force_length=True)

                    msg += f"`{symbol.upper()}: {price}`\n"

        if msg:
            if exchange:
                msg = f"`Price of {coin} on {exchange.capitalize()}`\n\n" + msg
            else:
                msg = f"`Price of {coin}`\n\n" + msg
        else:
            msg = f"{emo.ERROR} Can't retrieve data for *{coin}*"

        if update.message:
            update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
        else:
            return msg
Example #15
0
    def get_action(self, bot, update, args):
        keywords = utl.get_kw(args)
        arg_list = utl.del_kw(args)

        if not arg_list:
            if not keywords.get(Keyword.INLINE):
                update.message.reply_text(
                    text=f"Usage:\n{self.get_usage()}",
                    parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        vs_cur = "usd"

        if "-" in arg_list[0]:
            pair = arg_list[0].split("-", 1)
            vs_cur = pair[1].lower()
            coin = pair[0].upper()
        else:
            coin = arg_list[0].upper()

        ath_date = str()
        ath_price = str()
        cur_price = str()
        ath_change = str()

        # Get coin ID
        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    coin_info = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)

                cur_price = coin_info["market_data"]["current_price"]
                ath_price = coin_info["market_data"]["ath"]
                ath_date = coin_info["market_data"]["ath_date"]
                ath_change = coin_info["market_data"]["ath_change_percentage"]
                break

        msg = str()

        for c in vs_cur.split(","):
            if c in ath_price:
                ath_p = format(ath_price[c])
                cur_p = format(cur_price[c], template=ath_p)
                change = format(ath_change[c], decimals=2)

                date_time = ath_date[c]
                date_ath = date_time[:10]
                date_list = date_ath.split("-")
                y = int(date_list[0])
                m = int(date_list[1])
                d = int(date_list[2])

                ath = date(y, m, d)
                now = datetime.date.today()

                ath_p_str = f"Price ATH: {ath_p} {c.upper()}\n"
                cur_p_str = f"Price NOW: {cur_p.rjust(len(ath_p))} {c.upper()}\n"

                msg += f"`" \
                       f"{date_ath} ({(now - ath).days} days ago)\n" \
                       f"{ath_p_str}" \
                       f"{cur_p_str}" \
                       f"Change: {change}%\n\n" \
                       f"`"

        if msg:
            msg = f"`All-Time High for {coin}`\n\n {msg}"
        else:
            msg = f"{emo.ERROR} Can't retrieve data for *{coin}*"

        if keywords.get(Keyword.INLINE):
            return msg

        self.send_msg(msg, update, keywords)
Example #16
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        vs_cur = "btc,eth,usd,eur"

        if "-" in args[0]:
            pair = args[0].split("-", 1)
            vs_cur = pair[0].lower()
            coin = pair[1].upper()
        else:
            coin = args[0].upper()

        if len(args) > 1 and utl.is_number(args[1]):
            qty = args[1]
        else:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        prices = dict()

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        # Get coin ID
        for entry in response:
            if entry["symbol"].upper() == coin:
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)

                prices = data["market_data"]["current_price"]
                break

        try:
            qty_float = float(qty)
        except Exception:
            update.message.reply_text(
                text=f"{emo.ERROR} Quantity '{qty}' not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        msg = str()

        for c in vs_cur.split(","):
            if c in prices:
                value = utl.format(prices[c] * qty_float)
                msg += f"`{c.upper()}: {value}`\n"

        if msg:
            msg = f"`Value of {qty} {coin}`\n\n" + msg
        else:
            msg = f"{emo.ERROR} Can't retrieve data for *{coin}*"

        update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
Example #17
0
 def refresh_coingecko_exchange_list():
     APICache.cg_exch_list = CoinGecko().get_exchanges_list()
Example #18
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        sub_cmd = args[0]

        if not sub_cmd:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        msg = str()

        try:
            res = CoinGecko().get_global()
        except Exception as e:
            return self.handle_error(e, update)

        # ---------- Total Market Capital ----------

        if sub_cmd.lower() == "mcap":
            m_cap_usd = utl.format(res["total_market_cap"]["usd"])
            m_cap_eur = utl.format(res["total_market_cap"]["eur"])

            msg = f"`Total Market Capital`\n" \
                  f"`USD: {m_cap_usd}`\n" \
                  f"`EUR: {m_cap_eur}`"

        # ---------- Total Volume ----------

        elif sub_cmd.lower() == "vol":
            vol_usd = utl.format(res["total_volume"]["usd"])
            vol_eur = utl.format(res["total_volume"]["eur"])

            msg = f"`Total Volume (24h)`\n" \
                  f"`USD: {vol_usd}`\n" \
                  f"`EUR: {vol_eur}`"

        # ---------- Dominance ----------

        elif sub_cmd.lower() == "dom":
            m_cap_per = res["market_cap_percentage"]

            labels = list()
            values = list()

            msg = "`Dominance (Market Capital)`\n"
            for key in sorted(m_cap_per, key=m_cap_per.get, reverse=True):
                labels.append(key.upper())
                values.append(m_cap_per[key])

                value = utl.format(m_cap_per[key],
                                   decimals=2,
                                   force_length=True)
                tst = "{:>13}".format(f"{value}%")
                tst = key.upper() + tst[len(key):]
                msg += f"`{tst}`\n"

            labels.append("[Other]")
            values.append(100 - sum(values))

            layout = go.Layout(paper_bgcolor='rgb(233,233,233)',
                               plot_bgcolor='rgb(233,233,233)',
                               autosize=True,
                               margin=go.layout.Margin(l=20,
                                                       r=20,
                                                       b=20,
                                                       t=20,
                                                       pad=4))

            try:
                trace = go.Pie(labels=labels, values=values)
                fig = go.Figure(data=[trace], layout=layout)
            except Exception as e:
                return self.handle_error(e, update)

            update.message.reply_photo(photo=io.BufferedReader(
                BytesIO(pio.to_image(fig, format="jpeg"))),
                                       caption=msg,
                                       parse_mode=ParseMode.MARKDOWN)

            return

        if not msg:
            msg = f"{emo.ERROR} Can't retrieve global data*"

        update.message.reply_text(text=msg, parse_mode=ParseMode.MARKDOWN)
Example #19
0
 def get_cg_coins_list():
     if APICache.cg_coin_list:
         return APICache.cg_coin_list
     else:
         return CoinGecko().get_coins_list()
Example #20
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        coin_info = None

        volume = False
        if len(args) > 1:
            if args[1].lower().startswith("vol"):
                volume = True

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        # Get coin ID and data
        for entry in response:
            if entry["symbol"].upper() == coin:
                try:
                    coin_info = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)
                break

        if not coin_info or not coin_info["tickers"]:
            update.message.reply_text(text=f"{emo.ERROR} No data for *{coin}*",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        # Sort markets by volume
        if volume:
            data = sorted(coin_info["tickers"],
                          key=lambda k: float(k["volume"]),
                          reverse=True)

            count = len(data)
            if count > 10:
                count = 10

            msg = str()
            for i in range(count):
                vs_cur = data[i]["target"]
                exchange = data[i]["market"]["name"]
                vol_usd = data[i]["converted_volume"]["usd"]
                vol_usd = utl.format(vol_usd, decimals=2, force_length=True)

                msg += f"{exchange} - {vs_cur}\nVolume: {vol_usd} USD\n\n"

            update.message.reply_text(text=f"`Exchanges that trade {coin}`\n"
                                      f"`Top 10 sorted by volume\n\n{msg}`",
                                      parse_mode=ParseMode.MARKDOWN)

        else:
            exchanges = set()
            for ticker in coin_info["tickers"]:
                exchanges.add(ticker['market']['name'])

            exchanges = "\n".join(sorted(exchanges))

            update.message.reply_text(
                text=f"`Exchanges that trade {coin}`\n\n`{exchanges}`",
                parse_mode=ParseMode.MARKDOWN)
Example #21
0
    def get_action(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        if RateLimit.limit_reached(update):
            return

        coin = args[0].upper()
        msg = str()

        try:
            response = APICache.get_cg_coins_list()
        except Exception as e:
            return self.handle_error(e, update)

        for entry in response:
            if entry["symbol"].lower() == coin.lower():
                try:
                    data = CoinGecko().get_coin_by_id(entry["id"])
                except Exception as e:
                    return self.handle_error(e, update)

                home_lst = list(filter(None, data["links"]["homepage"]))
                block_lst = list(filter(None,
                                        data["links"]["blockchain_site"]))
                annou_lst = list(
                    filter(None, data["links"]["announcement_url"]))
                chat_lst = list(filter(None, data["links"]["chat_url"]))
                forum_lst = list(
                    filter(None, data["links"]["official_forum_url"]))
                twitter = data["links"]["twitter_screen_name"]
                facebook = data["links"]["facebook_username"]
                btctalk = data["links"]["bitcointalk_thread_identifier"]
                telegram = data["links"]["telegram_channel_identifier"]
                reddit = data["links"]["subreddit_url"]

                fb_likes = data["community_data"]["facebook_likes"]
                tw_follow = data["community_data"]["twitter_followers"]
                rd_subsc = data["community_data"]["reddit_subscribers"]
                tg_usr_cnt = data["community_data"][
                    "telegram_channel_user_count"]

                msg = f"`Social data for {data['name']} ({coin})`\n\n"

                if home_lst:
                    url = utl.esc_md(utl.url(home_lst))
                    msg += f"`Homepage:`\n{url}\n"
                if block_lst:
                    url = utl.esc_md(utl.url(block_lst))
                    msg += f"`Block Explorer:`\n{url}\n"
                if annou_lst:
                    url = utl.esc_md(utl.url(annou_lst))
                    msg += f"`Announcements:`\n{url}\n"
                if chat_lst:
                    url = utl.esc_md(utl.url(chat_lst))
                    msg += f"`Chat:`\n{url}\n"
                if forum_lst:
                    url = utl.esc_md(utl.url(forum_lst))
                    msg += f"`Forum:`\n{url}\n"
                if twitter:
                    tw_follow = utl.format(tw_follow)
                    url = utl.esc_md(f"{self.TW_URL}{twitter}")
                    msg += f"`Twitter ({tw_follow} Followers):`\n{url}\n"
                if facebook:
                    fb_likes = utl.format(fb_likes)
                    url = utl.esc_md(f"{self.FB_URL}{facebook}")
                    msg += f"`Facebook ({fb_likes} Likes):`\n{url}\n"
                if btctalk:
                    url = utl.esc_md(f"{self.BT_URL}{btctalk}")
                    msg += f"`BitcoinTalk:`\n{url}\n"
                if telegram:
                    tg_usr_cnt = utl.format(tg_usr_cnt)
                    url = utl.esc_md(f"{self.TG_URL}{telegram}")
                    msg += f"`Telegram ({tg_usr_cnt} Users):`\n{url}\n"
                if reddit:
                    rd_subsc = utl.format(rd_subsc)
                    url = utl.esc_md(f"{utl.url(reddit)}")
                    msg += f"`Reddit ({rd_subsc} Subscribers):`\n{url}\n"

                break

        if not msg:
            update.message.reply_text(
                text=f"{emo.ERROR} No data found for *{coin}*",
                parse_mode=ParseMode.MARKDOWN)
            return

        update.message.reply_text(text=msg,
                                  disable_web_page_preview=True,
                                  parse_mode=ParseMode.MARKDOWN)
Example #22
0
 def get_cg_exchanges_list():
     if APICache.cg_exch_list:
         return APICache.cg_exch_list
     else:
         return CoinGecko().get_exchanges_list()