반응형

부제: 관심 주식종목의 새 공시 알림 받기

 

 

앞서 "파이썬 텔레그램 봇(telegram bot) 만들기 1: 토큰(token) 받기" 와 "파이썬 텔레그램 봇(telegram bot) 만들기 2: 간단 채팅봇 만들기"를 했었던 이유는 기업이 공시를 발표했을 때, 메신저로 바로 알림을 받기 위한 봇(bot)을 만들기 위해 시작했었습니다. 위의 두 편에서는 간단하게 메시지를 주면 반응하는 봇이었으나, 실시간으로 전자공시 DART를 확인하고 제게 메시지를 주는 것은 다루지 않았습니다.

 

이번에는 전자공시 API를 이용하여 주기적으로 새로운 전자공시를 확인하고 텔레그램 메신저로 알림을 주는 것을 간략하게 보여드리겠습니다.

 

Open DART로부터 전자공시를 받아오는 함수는 기존에 "전자공시(Open DART) 재무제표 크롤링 : Python"과 "전자공시(Open DART) 재무제표 크롤링 2 : Python"에서 다뤘던 함수들을 이용합니다. (필요한 함수 소스는 이번 글에서도 확인 가능합니다.)

 

텔레그램에서 메시지를 주고 받는 것 이외에 주기적으로 다른 작업을 수행하려면 Updater.job_queue를 이용하면 됩니다. job_queue에는 run_repeating나 run_daily 등의 함수가 있어, 주기적으로 특정 함수를 실행할 수 있어서, 이를 이용하면 주기적으로 전자공시를 확인하고 제게 메시지를 보내는 것이 가능합니다.

 

다음에 보여드리는 소스 코드는 전자공시를 5분마다 확인하여 관심 종목에 해당되는 공시가 있으면 메시지를 보내는 프로그램입니다. 주의하셔야 할 것은 간략한 예시를 보이려고 소스의 여러 부분을 생략하다보니, 이를 그대로 이용하면 이미 알림을 보내줬던 공시도 반복해서 알림을 보내는 소스가 되어버렸습니다.

from telegram.ext import Updater, MessageHandler, Filters, CommandHandler, CallbackContext
import pandas as pd
import json

def convertFnltt(self, url, items, item_names, params):
  res = requests.get(url, params)
  json_dict = json.loads(res.text)
  data = []
  if json_dict['status'] == "000":
    for line in json_dict['list']:
      data.append([])
      for itm in items:
        if itm in line.keys():
          data[-1].append(line[itm])
        else: data[-1].append("")
  else:
    return False
  df = pd.DataFrame(data,columns=item_names)
  return df

def get_list(crtfc_key,**kwargs):
  keys = ['corp_code','bgn_de','end_de','last_reprt_at','pblntf_ty',
          'pblntf_detail_ty','corp_cls''sort','sort_mth','page_no','page_count']
  for key in kwargs.keys():
    if not key in keys:
      print("get_list() has no parameter \'"+key+"\'")
      return False
  params = {**{'crtfc_key':crtfc_key},**kwargs}
  items = ['corp_cls','corp_name','corp_code','stock_code','report_nm',
          'rcept_no','flr_nm','rcept_dt','rm']
  item_names = ['법인구분','종목명','고유번호','종목코드','보고서명','접수번호',
               '공시제출인명','접수일자','비고']
  url = "https://opendart.fss.or.kr/api/list.json"
  return convertFnltt(url,items,item_names,params)

def get_new_notices():
  interest_list = ['삼성전자','LG화학','씨젠']
  new_noti_list = []
  page = 1
  df = None
  while True:
    cur_df = get_list(dart_crtf_key,page_no=str(page),page_count="100")
    if len(cur_df) > 0:
      df = cur_df if (page == 1) else pd.concat([df,cur_df], ignore_index=True)
    if len(cur_df) < 100:
      break
    page += 1
  for oneCorp in interest_list:
    idx_list = df.index[df['종목명']==oneCorp].tolist()
    if len(idx_list) > 0:
      for idx in idx_list:
        text = "▶ "+df.loc[idx,'종목명']+"\n"
        text += "▶ "+df.loc[idx,'보고서명']+"\n"
        text += "▶ http://m.dart.fss.or.kr/html_mdart/MD1007.html?rcpNo="+\
                df.loc[idx,'접수번호']+"\n"
        new_noti_list.append(text)
  return new_noti_list

def check_dart(context: CallbackContext):
  new_noti_list = get_new_notices()
  if len(new_noti_list) > 0:
    for text in new_noti_list:
      context.bot.send_message(chat_id=chat_id, text=text)

dart_crtf_key = "OPEN DART 인증키"
token = '텔레그램 토큰'
chat_id = '텔레그램 내 챗아이디'

updater = Updater(token=token, use_context=True)
dispatcher = updater.dispatcher
job = updater.job_queue

job_repeating = job.run_repeating(check_dart, interval=300, first=0)

updater.start_polling(timeout=3, clean=True)
updater.idle()

 

간략히 설명을 붙이면,

  • convertFnltt()와 get_list() 함수는 기존 전자공시 크롤링 포스트의 소스를 그대로 활용했습니다.
  • 아래서 3번째, job_repeating은 5분(interval=300)마다 check_dart()함수를 실행합니다.
  • check_dart()함수를 get_new_notices()함수를 호출하여 새로운 공지가 있으면 string list로 반환받아 메시지를 보냅니다.
  • get_new_notices()는 당일 게시된 공시를 한 페이지에 100개씩 마지막 페이지까지 받아 하나의 데이터프레임을 만들고, 관심 종목명(interest_list)가 데이터프레임에 있다면 종목명, 보고서명, 공시 모바일링크를 전송합니다.

 

실제로 위의 코드를 변형하여 이용하시려면, 공시를 확인할때마다 마지막 공시를 어딘가 저장해둬야 이미 메시지를 보낸 공시인지 아닌지를 구분할 겁니다. 앞서 말씀드린대로 위의 코드 그대로 실행하면 메시지를 보냈던 공시가 반복적으로 옵니다. 적절히 수정바랍니다.

 

다음 스크린샷은 저의 텔레그램 챗봇이 제게 전자공시를 전송해준 것을 예시로 보여드립니다.

 

기존에 전자공시 크롤링과 텔레그램 채팅봇 포스트의 내용들을 조합하면 다양한 기능을 추가할 수 있습니다. 저의 경우, 메신저에서 바로 관심 종목을 추가, 삭제, 조회를 하게끔 하는 기능과, 기업명을 전송하면 기업정보를 받는 등의 기능을 추가해서 쓰고 있습니다.

또한 함수를 잘 조합하면, 평일 일과시간에는 5분마다, 새벽, 저녁, 주말 등에는 다른 시간 간격으로 전자공시를 확인할 수 있습니다.

 

잘 응용하시면 자신만의 전자공시 챗봇을 만드실 수 있을 겁니다.

 

반응형

+ Recent posts