본문 바로가기
컴퓨터/Python

[Python] 파이썬, Matplotlib 실시간 주식 차트 업데이트 자동화 만들기

by sjblog 2022. 1. 6.
반응형

파이썬을 이용하여 실시간 오늘 주가 데이터를 받아오고 그래프로 확인하여 보겠습니다.

Matplotlib 실시간 데이터 업데이트 자동화

 

<완성본>

(실제 장이 열리는 시간에 각각 5분, 15분동안 녹화한 동영상이며, 주가변동이 크지 않아 64배속 하였습니다.)

 

 

1. 차트 구성

위의 <완성본>은 2일간의 OHLC(시가, 고가, 저가, 종가) 데이터를 나타내며

 

주식장이 열려있는 동안에도 종목별 오늘의 현재 가격을 실시간으로 반영합니다.

(다시 말해, 차트 그래프가 실시간으로 그려집니다.)

 

2. 준비물

VScode, Python

 

3. 전체 종목 데이터 가져오기

from pykrx import stock
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

from pykrx import stock

# pykrx를 통해 국내 주식 정보를 가져올 수 있습니다.

# pykrx를 사용해보니, 빠르긴 하지만 주가 데이터가 1분 정도 지연 표시됩니다.

# 증권사 api를 사용하시면 주가 데이터를 실시간으로 받을 수 있습니다.

https://github.com/sharebook-kr/pykrx

 

GitHub - sharebook-kr/pykrx: KRX 주식 정보 스크래핑

KRX 주식 정보 스크래핑. Contribute to sharebook-kr/pykrx development by creating an account on GitHub.

github.com

 

 

 

import matplotlib.pyplot as plt

# matplotlib를 사용하여 그래프를 그립니다.

https://matplotlib.org/

 

Matplotlib — Visualization with Python

seaborn seaborn is a high level interface for drawing statistical graphics with Matplotlib. It aims to make visualization a central part of exploring and understanding complex datasets. statistical data visualization Cartopy Cartopy is a Python package des

matplotlib.org

 

 

 

# 총 종목 설정
stock_list_stock = pd.DataFrame({'종목코드':stock.get_market_ticker_list(market="KOSPI")})
stock_list_stock1 = pd.DataFrame({'종목코드':stock.get_market_ticker_list(market="KOSDAQ")})
stock_list_stock = pd.concat([stock_list_stock, stock_list_stock1], axis=0, ignore_index=True)
stock_list_stock['종목명'] = stock_list_stock['종목코드'].map(lambda x: stock.get_market_ticker_name(x))
stock_list_etf = pd.DataFrame({'종목코드':stock.get_etf_ticker_list(datetime.today().strftime('%Y%m%d'))})
stock_list_etf['종목명'] = stock_list_etf['종목코드'].map(lambda x: stock.get_etf_ticker_name(x))

# 종목 ohlcv
def stock_stock(stock_code, stock_from, stock_to):
    # 종목
    stock_name = stock_list_stock.loc[stock_list_stock['종목코드'] == stock_code, '종목명']
    if str(stock_name.values) == '[]':
        stock_name = stock_list_etf.loc[stock_list_etf['종목코드']==stock_code, '종목명']
    df = stock.get_market_ohlcv_by_date(fromdate=stock_from, todate=stock_to, ticker=stock_code)

    # 칼럼명을 영문명으로 변경
    df = df.rename(columns={'시가':'Open', '고가':'High', '저가':'Low', '종가':'Close', '거래량':'Volume'})
    df['Close']=df['Close'].apply(pd.to_numeric,errors="coerce")
    df['ma20'] = df['Close'].rolling(window=20).mean() # 20일 이동평균
    df['stddev'] = df['Close'].rolling(window=20).std() # 20일 이동표준편차
    df['upper'] = df['ma20'] + 2*df['stddev'] # 상단밴드
    df['lower'] = df['ma20'] - 2*df['stddev'] # 하단밴드
    # 거래정지 시
    for i in range(len(df)):
        if df['Open'].iloc[i] == 0:
            df['Open'].iloc[i] = df['Close'].iloc[i]
            df['High'].iloc[i] = df['Close'].iloc[i]
            df['Low'].iloc[i] = df['Close'].iloc[i]
    return df, stock_name.values

 

 

stock_list_stock = pd.DataFrame({'종목코드':stock.get_market_ticker_list(market="KOSPI")})

# 코스피 모든 종목의 종목코드 가져오기

stock_list_stock1 = pd.DataFrame({'종목코드':stock.get_market_ticker_list(market="KOSDAQ")})

# 코스닥 모든 종목의 종목코드 가져오기

stock_list_stock = pd.concat([stock_list_stock, stock_list_stock1], axis=0, ignore_index=True)

# 코스피와 코스닥 종목코드 합치기

stock_list_stock['종목명'] = stock_list_stock['종목코드'].map(lambda x: stock.get_market_ticker_name(x))

# 종목코드에 맞는 종목명을 추가합니다.

stock_list_etf = pd.DataFrame({'종목코드':stock.get_etf_ticker_list(datetime.today().strftime('%Y%m%d'))})

# ETF 모든 종목의 종목코드 가져오기

stock_list_etf['종목명'] = stock_list_etf['종목코드'].map(lambda x: stock.get_etf_ticker_name(x))

# ETF 종목코드에 맞는 ETF 종목명을 추가합니다.

 

def stock_stock(stock_code, stock_from, stock_to):

# 종목코드에 해당하는 종목의 OHLC 데이터를 받아옵니다.

# 20일 이동평균선, 볼린저밴드를 계산합니다.

 

 

4. Matplotlib 차트 데이터

def matgraph(i,code):
    stock_from = (datetime.today() - timedelta(days=50)).strftime('%Y%m%d')
    stock_to = datetime.today().strftime('%Y%m%d')

    df, stock_name = stock_stock(code,stock_from,stock_to)
    
    plt.subplot(1,len(codes),i)
    plt.hlines(df['upper'][-1],0,2,color='red', zorder = 0)
    plt.hlines(df['ma20'][-1],0,2,color='black', zorder = 0)
    plt.hlines(df['lower'][-1],0,2,color='blue', zorder = 0)
    # 금일 데이터
    if df['Open'][-1] < df['Close'][-1]:
        plt.vlines(1,df['Open'][-1],df['Close'][-1],color='red',linewidth=5, zorder = 2)
    else:
        plt.vlines(1,df['Open'][-1],df['Close'][-1],color='blue',linewidth=5, zorder = 2)

    if df['Open'][-1] < df['Close'][-1]:
        plt.vlines(1,df['Low'][-1],df['High'][-1],color='red', zorder = 0)
    else:
        if df['Open'][-1] > df['Close'][-1]:
            plt.vlines(1,df['Low'][-1],df['High'][-1],color='blue', zorder = 0)
        else:
            plt.vlines(1,df['Low'][-1],df['High'][-1],color='black', zorder = 0)
            plt.plot(1,df['Close'][-1],marker='_',color='black', zorder = 2)
    # 전일 데이터
    if df['Open'][-2] < df['Close'][-2]:
        plt.vlines(0.5,df['Open'][-2],df['Close'][-2],color='red',linewidth=5, zorder = 2)
    else:
        plt.vlines(0.5,df['Open'][-2],df['Close'][-2],color='blue',linewidth=5, zorder = 2)

    if df['Open'][-2] < df['Close'][-2]:
        plt.vlines(0.5,df['Low'][-2],df['High'][-2],color='red', zorder = 0)
    else:
        if df['Open'][-2] > df['Close'][-2]:
            plt.vlines(0.5,df['Low'][-2],df['High'][-2],color='blue', zorder = 0)
        else:
            plt.vlines(0.5,df['Low'][-2],df['High'][-2],color='black', zorder = 0)
            plt.plot(0.5,df['Close'][-2],marker='_',color='black', zorder = 2)

    plt.title(stock_name)
    plt.grid(axis='y')
    plt.tight_layout()

plt.subplot(1,len(codes),i)

# 조회할 종목의 수만큼 subplot을 할당합니다.

plt.hlines(df['upper'][-1],0,2,color='red'zorder = 0)

# 오늘 볼린저 상단 밴드를 빨강으로 직선을 그립니다.

plt.hlines(df['ma20'][-1],0,2,color='black'zorder = 0)

# 오늘 20일 이동평균선을 검정으로 직선을 그립니다.

plt.hlines(df['lower'][-1],0,2,color='blue'zorder = 0)

# 오늘 볼린저 하단 밴드를 파랑으로 직선을 그립니다.

plt.title(stock_name)

# 종목명을 제목으로 추가합니다.

plt.grid(axis='y')

# y축 그리드를 추가합니다.

plt.tight_layout()

# 그래프 여백을 줄입니다.

 

 

5.  Matplotlib 차트 그리기

# 메인
fig = plt.figure()
while True:
    i=0
    fig.clear()
    codes = ['005930','000660','005935','035420','207940']
    for code in codes:
        i+=1
        matgraph(i,code)
    plt.draw() 
    plt.pause(5)

codes = ['005930','000660','005935','035420','207940']

# 조회할 종목의 종목코드를 추가해주세요.

# 개별종목과 ETF 종목 조회 가능합니다. (코넥스와 기타 종목은 코드 수정으로 가능합니다.)

plt.pause(5)

# 5초간 대기합니다.

# 5초마다 그래프가 갱신됩니다. (원하시는 시간으로 수정해주세요.)

 

 

 

 

반응형