본문 바로가기

python

python 주식 가격 알림 메일 보내기

반응형

안녕하세요.

오늘은 python으로 특정 주식 가격이 얼마 이상 또는 얼마 이하가 되면 내게 메일을 보내는 툴을 만들어 볼까 합니다.

얼마전에 가지고 있던 애플주식 몇주를 팔았는데, 애플 주가가 얼마 이하고 떨어지면 다시 사고 싶은 생각이 들었어요.

물론 매일 밤 미국 주식 시장이 시작되는 23:30부터 모니터링 할 수도 있지만,

python으로 이것저것 사부작 사부작 해 보고 있는데, 이정도는 해 볼만 하지 않을까 하여 시작해 보았습니다.

 

1. 주가 정보 수집

먼저 주가 정보를 수집할 수 있어야 합니다. 구글에 검색해 보면 엄청 다양한 방법들이 나옵니다. 어지럽네요 ㅡㅡ; 난 애플주가만 좀 알았으면 하는데, 어떤 방법을 써야하나...

그 중 가장 쉬워보이는 yfinance 라이브러리를 사용해 보도록 하겠습니다.

import yfinance as yf

data = yf.download(tickers='AAPL', period='1d', interval='1m')
# 마지막 가격 가져오기
last_price = data.iloc[-1]['Close']
print("APPLE 의 주가 : {last_price}")

이렇게 하면 애플의 주가를 가져와서 출력하는거네요.

아래와 같이 잘 출력되는 것 확인이 되었습니다.

주가 출력

2. 이메일 보내기

다음으로 이메일을 보내는 방법이 필요합니다. 이부분은 아래와 같은 코드로 가능합니다.

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def send_email(subject, message):
    try:
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()
        # 여기에 본인의 구글 아이디와 비밀번호를 입력하세요.
        server.login("XXXX@gmail.com", "XXXX")

        msg = MIMEMultipart()
        msg['From'] = "XXXX@gmail.com"
        msg['To'] = "XXXX@naver.com"
        msg['Subject'] = subject

        body = message
        msg.attach(MIMEText(body, 'plain'))

        text = msg.as_string()

        server.sendmail("XXXX@gmail.com", "XXXX@naver.com", text)

    except Exception as e:
        print(f"Error: {e}")

    finally:
        server.quit()

send_email("Apple Stock Alert!", f"Apple stock price is now 190")

위의 구글 아이디와 비밀번호에서 비밀번호는 앱비밀번호입니다. 구글 검색창에 '구글 앱 비밀번호' 라고 검색하시면 아래와 같이 나오는데 그대로 따라하시면 됩니다.

앱비밀번호 설정

결과는 다음과 같이 제 naver메일로 잘 왔네요.

메일 전송 결과

3. 가격비교해서 메일 보내기

위의 두가지 준비가 되었으니 거의 끝난거 같네요. 제가 원하는 건 애플주식 가격이 제가 이전에 샀던 가격이 되었는지를 알고 싶은거에요.

 

'원하는 가격 입력하고, 시작버튼 누르면 1분에 한번씩 체크해서 입력한 가격 이하가 되면 내게 알림메일을 보내도록 한다.'

 

이게 제가 최종적으로 원하는 요구사항이 되겠네요. 그래서 아래와 같이 코드를 마련해 보았습니다.

import os
import tkinter as tk
from datetime import datetime
import yfinance as yf
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


def send_email(subject, message):
    try:
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()
        # 여기에 본인의 구글 아이디와 비밀번호를 입력하세요.
        server.login("XXXX@gmail.com", "xxxx xxxx xxxx xxxx")

        msg = MIMEMultipart()
        msg['From'] = "xxxx@gmail.com"
        msg['To'] = "xxxx@naver.com"
        msg['Subject'] = subject

        body = message
        msg.attach(MIMEText(body, 'plain'))

        text = msg.as_string()

        server.sendmail("xxxx@gmail.com", "xxxx@naver.com", text)

    except Exception as e:
        print(f"Error: {e}")

    finally:
        server.quit()


def check_price():
    global job_id  # Make sure we're using the global job_id variable

    now_hour = datetime.now().hour

    if (now_hour >= 23) or (now_hour < 6):
        data = yf.download(tickers='AAPL', period='1d', interval='1m')

        # 마지막 가격 가져오기
        last_price = data.iloc[-1]['Close']

        # Get the threshold price from the entry widget and convert it to a float.
        threshold_price = float(entry.get())

        if last_price <= threshold_price:
            send_email("Apple Stock Alert!", f"Apple stock price is now {last_price}")
    else:
        print("Now is not on time !!!")  # _Alarm 메시지 출력

    # Schedule the function to run again after 60 seconds and store the job ID.
    job_id = window.after(60000, check_price)



def stop_check():
    global job_id  # Make sure we're using the global job_id variable

    if job_id is not None:
        window.after_cancel(job_id)
        job_id = None

    print("check price canceled !!!")  # _Alarm 메시지 출력

window = tk.Tk()
window.title("Check Stock")
window.geometry("300x100")

# 레이블 생성 및 배치
label = tk.Label(window, text="가격입력")
label.grid(row=0, column=0)
# 텍스트 입력 상자 생성 및 배치
entry = tk.Entry(window)
entry.insert(0, '150')  # Insert '150' at position 0 (the start) of the entry widget.
entry.grid(row=0, column=1)

# 버튼 생성 및 배치
button_start = tk.Button(window, text="check_price", command=check_price)
button_start.grid(row=1, column=0)

# Stop button that cancels the scheduled function
button_stop = tk.Button(window, text="Stop", command=stop_check)
button_stop.grid(row=1, column=1)

# Initialize job_id to None
job_id = None
window.mainloop()
  • Start 버튼을 누르면 1분에 한번씩 애플 가격을 얻어와서 비교하게 됩니다.

미국주식시장 시간동안만 체크

  • 위의 부분은 미국 주식 시장이 열린 23시부터 다음날 06시 이전에만 체크하도록 하려고 넣은 코드입니다.
  • 조건에 맞으면 1분에 한번씩 메일이 오게 되겠네요. 밤에 자다가 사고 싶으면 핸드폰에서 알림 설정을 다시 켜놔야겠네요. 

 

4. 정리하며...

위의 내용들을 진행하면서 yfinance 라이브러리는 어떤 정보들을 제공해주고 있는지 궁금해서 검색해 보니 다음과 같이 많으 정보들을 제공하고 있네요.

  1. 가격 정보: download 함수를 사용하여 특정 기간 동안의 개별 주식 또는 여러 주식의 가격 정보(오픈 가격, 종가, 최고가, 최저가 등)를 가져올 수 있습니다.
  2. 회사 기본 정보: Ticker 객체에서 info 속성을 사용하여 회사에 대한 기본적인 정보(시장 자본금, 배당률, 섹터 등)를 얻을 수 있습니다.
  3. 재무제표: Ticker 객체에서 financials, balance_sheet, 그리고 cashflow 메소드를 사용하여 각각 손익계산서, 재무상태표 및 현금흐름표 데이터를 가져올 수 있습니다.
  4. 배당 및 분할:  Ticker 객체에서 dividends, 그리고  splits 메소드로 배당 및 분할 내역을 확인할 수 있습니다.
  5. 일일 변동률: 'history' 메소드에서 반환되는 DataFrame에 포함된 'Close' 열을 이용해 일일 변동률을 계산할 수 있습니다.
  6. 거래량: 'volume' 항목으로 해당 종목의 거래량을 확인할 수 있습니다.

위와 같이 매우 광범위한 금융 데이터를 제공하고 있습니다. 가져다가 해볼만한 게 많을 거 같습니다.

다음번에는 다른 거 시도해보고 기록해 보도록 하겠습니다.

 

그럼 모두 좋은 하루 되세요~~

반응형