Skip to content

Python

Kimchi Premium Telegram bot by a python beginner

As a non-programmer who has work experiences as a project manager and is interested in IT development, I have learnt basic python from a Udemy course since pandemic is all over the world. and as many people aware, the kimchi premium was more than 10–15% in 2021 April-May, and I decided to create my own telegram bot to have a notification of kimchi premium rate as well as to practice my python with a real use case.

t.me/kimp_tracker_bot What is kimchi premium by the way?

Kimchi premium is basically a price gap between South Korea crypto exchanges and other countries. The price difference may be caused by many different reasons such as a strong capital control by Korea government or/and by a lack of high-return investment options for investors in South Korea. Personally as a Korean expat out of South Korea, i more believe that the reason is a strong capital and financial control by governments. it is difficult to take out my Korean won to out of Korea… too many regulation, too high transfer fees. What does this kimchi premium bot do?

this kimchi premium telegram bot is returning the real time price differences between Upbit (Korean exchange) and Bitkub(Thailand exchange) — KRW vs THB. you can set up an alert to receive a notification when the kimchi premium rate is higher/lower than a specific % per crypto currency. in the future I am planning to add bithumb exchange for EUR.

I have uploaded my code in my github repository. as an open source and I would like to receive feedback/advice on my code by posting this blog :) Let’s look into the code!

everything is based on ‘functions’ in python. (limited to my knowledge lol)

‘start’ function to greet with a message by simply replying with update.message.reply_text( ). this start function will be called when execution at the end of the code.

def start(update, context):
    start_message = '🇬🇧 Hola, welcome to the bot! \n this bot provides <b>kimchi premium rate</b> between Upbit(in Korea) and Bitkub(in Thailand).\n /kimpnow - check realtime rate \n /alert - create an notification \n /status - check current notification setting \n /cancel - cancel your notifications \n /source - check the info \n\n'
    start_message += '🇰🇷 안녕하세요, 봇에 온걸 환영합니다! \n 이 봇은 업비트(한국)과 비트컵(태국)사이의 김치프리미엄 퍼센트를 제공합니다. \n /kimpnow - 현재 김프 확인 \n /alert - 김프알림 설정 \n /status - 설정된 알람 확인 \n /cancel - 알람 취소하기 \n /source - 소스정보 확인'
    update.message.reply_text(start_message)

‘kimpnow’ function to calculate the diff % from Bitkub and Upbit price per crypto currency. here is the big chunk of the code. now here we need to call Bitkub API and Upbit API to extract the real time price of each cryto currency and calculate the %, and display all per crypto currency.

in order to do so, first, I have created separate functions (exchange_upbit, exchange_bitkub) to be embedded in ‘kimpnow’ function. with each exchange function, I can get real time price of crypto currency i wanted.

def exchange_upbit(crypto):
    #contents_upbit = requests.get("https://api.upbit.com/v1/ticker?markets=KRW-"+crypto).json()
    #price_upbit = contents_upbit[0]['trade_price']
    price_upbit = pyupbit.get_current_price("KRW-"+crypto)
    return price_upbit

def exchange_bitkub(crypto):
    contents_bitkub = requests.get("https://api.bitkub.com/api/market/ticker?sym=THB_"+crypto).json()
    price_bitkub = contents_bitkub['THB_'+crypto]["last"]
    return price_bitkub

as each price is in different fiat currency (THB, KRW), I need foreign exchange rate to compare. based on my research, people usually use USDT for USD forex(it is hard to find the free forex API). but my bot is for THB and KRW, which we don’t have a solid stablecoin for yet. so I needed to have a real forex API, luckily I got one from dunamu. here is the get_forex function to be embedded in kimpnow function.

def get_forex(fiat_code):
    contents_forex = requests.get("https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes=FRX.KRW"+fiat_code).json()
    forex = contents_forex[0]['basePrice']
    return forex

now I have functions to get real price data from each exchange (exchange_upbit, exchange_bitkub), function to extract the foreign exchange rate (get_forex). with these, let’s build the kimpnow function to get kimchi premium rate!

crypto_list = ["ETH","BTC","XRP","LTC"]

def kimpnow(update, context):
    chat_id = update.message.chat_id
    context.bot.sendChatAction(chat_id=chat_id, action="typing")
    forex = get_forex("THB")
    kimp_message = f"Exchange rate 환율 : <b>{forex} KRW/THB</b>\n\n"
    for crypto in crypto_list:
        kimp = get_kimp(crypto)
        price_upbit = exchange_upbit(crypto)
        price_bitkub = exchange_bitkub(crypto)
        equal_bitkub = price_bitkub*forex
        f_price_upbit = "{:,.0f}".format(price_upbit)
        f_price_bitkub = "{:,.0f}".format(price_bitkub)
        f_equal_bitkub ="{:,.0f}".format(equal_bitkub)
        kimp_message += f"☑️<b>{crypto}</b>\n"
        kimp_message += f"Kimchi premium rate 김프: <b>{kimp}%</b>\n"
        kimp_message += f"Upbit 업비트  : {f_price_upbit} KRW \nBitkub 비트컵 : {f_equal_bitkub} KRW ({f_price_bitkub} THB)\n"
    context.bot.send_message(chat_id=chat_id, text=kimp_message) 

as you can see, I have a list(crypto_list) in global to indicate 4 crypto currencies that I want to check kimchi premium rate for.

with the list, kimpnow function get forex from get_forex, and with the forex, I used for and in method to go through crypto_list to calculate kimp (kimchi premium) and display messages. with these functions above, you will be able to receive premium rate with a command ‘/kimpnow’ as below screenshot! *the command to display message is something that we will indicate at the end of the code.

now, I would like to add ‘alert’ function to set up a notification to get alert when the premium reach a specific %. ( a key functionality of the bot!)

first of all, I will get input from a command /alert.“/alert ETH > 1” meaning, I would like to get alert when ETH of kimchi premium is more than 1%. I followed one blog that I found for creating an arbitrage telegram bot (Thank you so much!)


def alert(update, context):
    chat_id = update.message.chat_id
    context.bot.sendChatAction(chat_id=chat_id, action="typing")
    if len(context.args) >= 3:
        crypto = context.args[0].upper()
        sign = context.args[1]
        rate = context.args[2]
        #if crypto is in crypto_list :
        i=1
        alert_num = i
        alert_id = str(chat_id)+"_"+str(alert_num)
        while i < 4 :
            alert_num = i
            alert_id = str(chat_id)+"_"+str(alert_num)
            if alertdict.get(alert_id) is None:
                alertdict.update({alert_id : [crypto, sign, rate]})
                context.job_queue.run_repeating(AlertCallback, interval=60, first=15, context=[crypto, sign ,rate, chat_id, alert_id])
                print(alertdict)
                response = f"⏳ I will let you know when kimchi premium of <b>{crypto}</b> reaches <b>{rate}%</b>. \n"
                response += f"⏳ <b>{crypto}</b> 김프가 <b>{rate}%</b>될 때 알려드릴게요."
                break
            else :
                i+=1
                continue 
        else : 
            response = "⚠️you reach the maximum number of notifications that you can setup"
            response += "⚠️최대 설정할 수 있는 알람 횟수를 초과하였습니다"

as you can see, I get the input with context.arg[] for type of crypto currency, higher/lower and rate. and I have created ‘alert_id’ per user (chat_id) to set up multiple alerts (maximum 3), and once the alert is set, using AlertCallback function(to come) to keep checking the price per 60 seconds.

so here, AlertCallBack function should do : check the kimp, if kimp reach the specific rate that we input earlier, return the message with rate Or keep checking as following.


def AlertCallback(context):
    crypto = context.job.context[0]
    sign = context.job.context[1]
    rate = context.job.context[2]
    chat_id = context.job.context[3]
    alert_id = context.job.context[4]

    send = False
    spot_rate = get_kimp(crypto)

    if sign == '>':
        if float(rate) <= float(spot_rate):
            send = True
    else :
        if float(rate) >= float(spot_rate):
            send = True

    if send:
        response = f"👋 kimchi premium of {crypto} is now <b>{spot_rate}%!</b> \n"
        response += f"👋 지금 {crypto} 김프가 <b>{spot_rate}%</b>입니다! \n"

        context.job.schedule_removal()
        alertdict.pop(alert_id)
        print(alertdict)

        context.bot.send_message(chat_id=chat_id, text=response)

Now so far you have alert notification set! (command to display message, input the message are at the end of code)

have you followed well so far? with all above codes, finally it’s time to build the main function to keep running the bot.

def main():
    updater = Updater(TOKEN,use_context=True,defaults=Defaults(parse_mode=ParseMode.HTML))
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("kimpnow",kimpnow))
    dp.add_handler(CommandHandler("alert", alert, pass_args=True))
    dp.add_error_handler(error)
    updater.start_webhook(listen="0.0.0.0",
                          port=PORT,
                          url_path=TOKEN,
                          webhook_url=WEBHOOK_URL + TOKEN)
    updater.idle()

CommandHandler is for the command in telegram ‘/’ and especially as /alert command has an input after, you need to pass through with pass_args.

I have hosted my bot in Heroku with webhook, so that’s where updater.start_webhook sits. there are many blogs to guide you how to host your telegram bot in Heroku, so please feel free to research!

what do you think? it is quite simple and do-able for even non-programmer! for me it took literally one week to establish the bot with above functions after testing and testing. I am sure for professional programmer, it may take only 1–2 hours to complete (haha). bur for me it was a great learning and I am proud of myself to accomplish my first real use case bot for me to use. I am happy to share the code and I am going to enhance the bots continuously (as there are some known issues) by posting in kimptracker twitter. please stay tuned and feel free to add comments/feedback/advice please! last word that I would like to share :

Everyone can do the coding!

파이썬으로 김프 알람 텔레그램 봇 만들기

파이썬을 작년에 Udemy course 하나로 처음 배웠는데, (통계학 전공했고, 컴퓨터 프로그래밍은 제대로 배우려는 건 이번이 처음이었습니다. Udemy course 추천!) 뭐 배울 때는 그냥 그렇구나.. 하고 배웠지만 실제로 응용을 해본 적은 없었다. 그러다가 자가격리하는김에 생각나 후딱 만들어본 김치프리미엄 알려주는 텔레그램 봇!

t.me/kimp_tracker_bot

그저 태국에 산다는 이유로 항상 비트컵(https://www.bitkub.com/)과의 김프 퍼센트를 매뉴얼로 체크 했는데 (= 비트컵 가격, 업비트 가격, 환율 체크 후 계산) 알람 하나만 있으면 참 좋겠다 싶어서, 또 파이썬 연습도 해볼겸, 만들어보았다.

김프 알림봇이라 하면 정말 잘만들어논 텔레그램봇이 이미 있다. 여러가지 features들도 잘 갖춰져있고, 7일무료사용후 월 정액을 크립토로 받으시고. 존경! 그치만 나는 그냥 코딩 맛 좀 볼겸, 그리고 내가 원하는 김프는 태국과 한국간 이기때문에 내가 만들 수 밖에없었다.

혼자 스스로 3일만에 MVP (Minimum viable product)을 만들어서 deploy 까지 할 수있었던 내자신에 놀랐다… 파이썬 쪼끔만 알면 누구나 할수 있다는 것을 알리기위해서, 대충 내가 한것 들을 정리해봤다.

욕심 빼고 MVP (Minimum viable product) 구상하기
Botfather 로 내 로봇 설정 시작하기
파이썬 파일 생성해서 코딩 시작하기.
쥬피터를 이용해서 계속해서 에러 테스팅 하면서 완성하기
Heroku를 이용해서 호스팅하기
홍보하기! 사용하기! (트위터 계정만들어서 새로운 기능을 넣을때마다 알려주고있다)

내가 참고한 여러 블로그들

  • https://itnext.io/creating-a-crypto-price-alert-bot-on-telegram-with-python-ce3779879357
  • https://towardsdatascience.com/bring-your-telegram-chatbot-to-the-next-level-c771ec7d31e4

조만간 코드를 github에올려서 오픈할예정이고, 그에관한 영어포스팅을 진행할까한다!