본문 바로가기
컴퓨터/Python

[Python] 파이썬, 캔들차트 matplotlib로 직접 그리기

by sjblog 2022. 9. 21.
반응형

파이썬 matplotlib을 이용하여 캔들차트를 직접 만들어 보겠습니다.

 

 

<완성본>

(아래 코드와 완성본이 다를 수 있습니다.)

 

1. 패키지 설치

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

 

2. OHLC 주가정보 가져오기

def stock_data(ticker, stock_from, stock_to):
	# ETF
    df = stock.get_etf_ohlcv_by_date(fromdate=stock_from, todate=stock_to, ticker=ticker)
    # 종목
    #df = stock.get_market_ohlcv_by_date(fromdate=stock_from, todate=stock_to, ticker=ticker)

    # 칼럼명을 영문명으로 변경
    df = df.rename(columns={'시가':'Open', '고가':'High', '저가':'Low', '종가':'Close', '거래량':'Volume'})
    df["Close"]=df["Close"].apply(pd.to_numeric,errors="coerce")
    # 거래정지 시
    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]
            
    # 볼린저밴드 구하기
    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'] # 하단밴드
    #df = df[19:] # 20일 이동평균을 구했기 때문에 20번째 행부터 값이 들어가 있음

    # MFI 구하기
    #ma20,stddev,upper,lower필요
    df['PB'] = (df['Close'] - df['lower']) / (df['upper'] - df['lower'])
    df['TP'] = (df['High'] + df['Low'] + df['Close']) / 3
    df['PMF'] = 0
    df['NMF'] = 0
    for i in range(len(df.Close)-1):
        if df.TP.values[i] <= df.TP.values[i+1]:
            df.PMF.values[i+1] = df.TP.values[i+1] * df.Volume.values[i+1]
            df.NMF.values[i+1] = 0
        else:
            df.NMF.values[i+1] = df.TP.values[i+1] * df.Volume.values[i+1]
            df.PMF.values[i+1] = 0
    df['MFR14'] = (df.PMF.rolling(window=14).sum() /
        df.NMF.rolling(window=14).sum())
    df['MFI14'] = 100 - 100 / (1 + df['MFR14'])
    #df = df[19:]

    #역추세를 위한 IIP계산
    df['II'] = (2*df['Close']-df['High']-df['Low'])/(df['High']-df['Low'])*df['Volume']
    df['IIP21'] = df['II'].rolling(window=21).sum()/df['Volume'].rolling(window=21).sum()*100

    df = df[25:]

    return df

OHLC 주가정보와

 

보조지표 볼린저밴드, MFI14, IIP21를 계산합니다.

 

3. Matplotlib 캔들차트 그리기

def matplotlib_data(df, stock_name):
    # 캔들차트
    for i in range(len(df)):
        if df['Open'][i] < df['Close'][i]:
            plt.vlines(df.index[i],df['Open'][i],df['Close'][i],color='red',linewidth=5)
            plt.vlines(df.index[i],df['Low'][i],df['High'][i],color='red')
        elif df['Open'][i] > df['Close'][i]:
            plt.vlines(df.index[i],df['Open'][i],df['Close'][i],color='blue',linewidth=5)
            plt.vlines(df.index[i],df['Low'][i],df['High'][i],color='blue')
        else:
            plt.vlines(df.index[i],df['Low'][i],df['High'][i],color='black')
            plt.plot(df.index[i],df['Close'][i],marker='_',color='black')

    plt.plot(df.index, df['upper'], linestyle='dashed', label='Upper band', color='red')
    plt.plot(df.index, df['ma20'], linestyle='dashed', label='Moving Average 20', color='black')
    plt.plot(df.index, df['lower'], linestyle='dashed', label='Lower band', color='dodgerblue')
    plt.fill_between(df.index, df['upper'], df['lower'], color='lightgray', alpha=0.5)
    plt.grid(True)
    plt.title(stock_name)
    plt.tight_layout()

    # 추세추종전략
    for i in range(len(df.Close)):
        if df.PB.values[i] > 0.8 and df.MFI14.values[i] > 80:
            plt.plot(df.index.values[i], df.Close.values[i], 'r^', markersize=15, alpha=0.5)  #빨강
        elif df.PB.values[i] < 0.2 and df.MFI14.values[i] < 20:
            plt.plot(df.index.values[i], df.Close.values[i], 'bv', markersize=15, alpha=0.5)  #파랑
    # 역추세전략
    for i in range(0, len(df.Close)):
        if df.PB.values[i] < 0.05 and df.IIP21.values[i] > 0:
            plt.plot(df.index.values[i], df.Close.values[i], 'm^', markersize=15, alpha=0.5)  #보라
        elif df.PB.values[i] > 0.95 and df.IIP21.values[i] < 0:
            plt.plot(df.index.values[i], df.Close.values[i], 'cv', markersize=15, alpha=0.5)  #하늘

 

4. 실행

stock_from = (datetime.today() + timedelta(days=-100)).strftime('%Y%m%d')
stock_to = datetime.today().strftime('%Y%m%d')

stock_K200_2X_in = '252670'     # KODEX 200선물인버스2X
stock_K200_2X_in = stock_data(stock_K200_2X_in, stock_from, stock_to)
matplotlib_data(stock_K200_2X_in, 'KODEX 200선물인버스2X')

#plt.savefig('KODEX_KODAQ.png')
plt.show()
반응형