본문 바로가기
Programming/Python

[Python] 주식 데이터 텔레그램 메시지 보내기

by 코딩하는 금융인 2024. 6. 19.

안녕하세요.

오늘은 파이썬 환경에서 국내주식 데이터텔레그램 메시지를 보내는 방법에 대해 알아보겠습니다

 

 국내주식 데이터 텔레그램 메시지 전송하기

 - 국내 주식시장은 주말과 휴일을 제외하고 매일 열리며, 거래대금은 종목 선택에 있어 중요한 변동성 지표임

 - 매일 일정 이상의 거래대금을 기록하는 종목들을 시장이 끝나고 따로 확인하는 작업을 자동화하기 위해 거래대금 1천억원 이상이 나오는 종목들을 텔레그램 메시지로 전송하는 파이썬 코드를 작성해보겠음

 

▣ 파이썬 pykrx 활용하기

 - pykrx 패키지를 활용하여 코스피, 코스닥 시장에서 거래대금 1천억원 이상을 기록한 종목들을 [종목명, 시장구분, 종가, 등락률, 거래대금, 거래대금 대비 시가총액] 형식의 데이터프레임으로 추출

 - 금액은 3자리 단위로 ,를 찍어주고 %는 소수점 2자리까지 반올림하여 전처리

from pykrx import stock
import pandas as pd
import aiohttp
import asyncio

# 날짜 설정
date = "20240619"

# KOSPI, KOSDAQ 데이터 가져오기
df_kospi = stock.get_market_ohlcv_by_ticker(date, market="KOSPI")
df_kospi['시장구분'] = 'KOSPI'
df_kosdaq = stock.get_market_ohlcv_by_ticker(date, market="KOSDAQ")
df_kosdaq['시장구분'] = 'KOSDAQ'

# 데이터프레임 결합
df = pd.concat([df_kospi, df_kosdaq])

# 시가총액 추가
kospi_info = stock.get_market_cap_by_ticker(date, market="KOSPI")
kosdaq_info = stock.get_market_cap_by_ticker(date, market="KOSDAQ")
df_info = pd.concat([kospi_info, kosdaq_info])
df = df.join(df_info[['시가총액']], how='inner')

# 종목명 추가
df['종목명'] = df.index.map(lambda x: stock.get_market_ticker_name(x))
df['등락률'] = ((df['종가'] - df['시가']) / df['시가']) * 100
df['거래대금/시가총액'] = (df['거래대금'] / df['시가총액']) * 100

# 거래대금 천억 이상 필터링
high_volume_stocks = df[df['거래대금'] >= 100000000000]

# 포맷팅
high_volume_stocks['거래대금'] = high_volume_stocks['거래대금'].apply(lambda x: f"{x:,.0f}")
high_volume_stocks['시가총액'] = high_volume_stocks['시가총액'].apply(lambda x: f"{x:,.0f}")
high_volume_stocks['등락률'] = high_volume_stocks['등락률'].apply(lambda x: f"{x:.2f}%")
high_volume_stocks['거래대금/시가총액'] = high_volume_stocks['거래대금/시가총액'].apply(lambda x: f"{x:.2f}%")

# 필요한 열만 선택
high_volume_stocks = high_volume_stocks[['종목명', '시장구분', '종가', '등락률', '거래대금', '시가총액', '거래대금/시가총액']]

# 거래대금 순으로 정렬
high_volume_stocks = high_volume_stocks.sort_values(by='거래대금', ascending=False)

 

 

 

 

▣ 해당 내용 텔레그램으로 메시지 보내기

- 메시지가 너무 길 경우, 텔레그램 전송에 에러가 있기에 메시지를 나누는 쿼리 추가

import pandas as pd
import aiohttp
import asyncio

# 텔레그램 봇 정보 설정
TELEGRAM_TOKEN = 'your_telegram_token'
CHAT_ID = 'your_chat_id'

# 메시지를 나누는 함수
def split_message(df, chunk_size=4096):
    messages = []
    message = ''
    for _, row in df.iterrows():
        row_message = '\n'.join([f"{col}: {val}" for col, val in row.items()]) + '\n\n'
        if len(message) + len(row_message) > chunk_size:
            messages.append(message)
            message = row_message
        else:
            message += row_message
    if message:
        messages.append(message)
    return messages

# 비동기 텔레그램 메시지 전송 함수
async def send_telegram_message(session, message):
    url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"
    payload = {
        'chat_id': CHAT_ID,
        'text': message,
        'parse_mode': 'HTML'
    }
    async with session.post(url, data=payload) as response:
        return await response.json()

# 비동기 메시지 전송 관리 함수
async def send_messages(messages):
    async with aiohttp.ClientSession() as session:
        tasks = []
        for message in messages:
            tasks.append(send_telegram_message(session, message))
        return await asyncio.gather(*tasks)

# 메시지를 나누어 전송
messages = split_message(high_volume_stocks)
asyncio.run(send_messages(messages))

print("Data sent to Telegram successfully.")

 

▣ 결과 확인하기

 - 텔레그램은 표 형식의 html을 지원하지 않으므로, [컬럼 : 컬럼 값] 형식으로 결과 전송 받은 것을 알 수 있음

텔레그램 메시지 전송결과

 

※ 추출된 데이터는 매수/매도를 권유하는 것이 아닌 예시이므로, 유의하시기 바랍니다.

 

 

반응형

댓글