본문 바로가기
Python, API

텔레그램의 I/O Bound 해결

by 오늘밤날다 2021. 9. 13.

텔레그램의 API를 활용하면

시스템트레이딩 중에 매수나 매도 시그널이 발생할 경우

지정된 사용자의 텔레그램 계정으로 메시지를 보낼 수 있다.

그런데 우연히 프로그램의 로그파일을 보다가 소요시간이 생각보다(?) 오래 걸리는 걸 발견했는데,

텔레그램으로 메시지를 보낼 때 서버와 교신하면서 발생하는 네트워크의 지연시간 때문이라는 걸 알게 되었다.

 

결론적으로는

멀티스레드 기능을 활용하는 모듈 등을 이용해서 텔레그램의 API로 메시지를 보내면 되겠다 싶어서

한동안 AIOGRAM, ASYNCIO 같은 모듈을 공부했었는데 수준이 만만치 않았다.

 

그런데 생각해보니 내 입장에선

원격으로 텔레그램에 메시지나 정해놓은 명령문을 보내고 정보를 다시 리턴 받는 건 필요가 없고

정해놓은 상황에 시스템이 보내주는 메시지만 확인하면 된다.

애초에 시스템의 운영에 개입할 수 있는 방법이 생길 수 있는 것도 원치 않는다.

그런데 이놈의 I/O BOUND때문에 거래 타이밍이 지연되거나 하는 것은 문제가 있었다.

 

 

일단 아래와 같이 일반적인 경우 

텔레그램 메시지를 보내는 경우 소요시간을 측정해보면 아래와 같은데,

이 시간은 처음 메시지를 보낼때 대략 1초 정도 소요되고 이후 상황은 0.4초가 걸린다.

0.4초면 별거 아닐수도 있지만 그 사이에 몇 틱이 움직일 수도 있기 때문에 중요하다

from telegram import Bot
from datetime import *

user_id = #########
token = '##################################'
bot = Bot(token=token)


def send_msg(text):
    result = bot.send_message(user_id, text)
    print(result, text)


for i in range(3):
    start_time = datetime.now()
    text = 'test message'
    send_msg(text)
    end_time = datetime.now()
    used_time = end_time - start_time
    print(used_time)
# 실행결과

test message
0:00:01.004926
test message
0:00:00.474432
test message
0:00:00.463422

 

 

해결방법은 위 코드에다가 Threading 모듈을 추가로 Import하고

send_msg를 thread로 실행하기 위한 send_msg_thread함수를 하나를 추가하고 그 함수를 호출하면 해결된다.

 

from telegram import Bot
from datetime import *
import threading

user_id = $$$$$$$$$
token = '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'
bot = Bot(token=token)


def send_msg(text):
    bot.send_message(user_id, text)
    print(text)


def send_msg_thread(text):
    work = threading.Thread(target=send_msg, args=(text,))
    work.start()


for i in range(3):
    start_time = datetime.now()
    text = 'test message'
    send_msg_thread(text)
    end_time = datetime.now()
    used_time = end_time - start_time
    print(used_time)
# 실행결과

0:00:00.002002
0:00:00
0:00:00
test message
test message
test message