본문 바로가기
파이썬 (투자분석용)/Plotly 및 Dash

[python, plotly] 캔들(candlestick) 차트 그리기

by amAToRoi 2022. 2. 5.
반응형

각 단계는 10분 이상을 소요하지 않도록 설계했다. (아마도 이해하는데는 1~2분?)

1. 캔들차트(봉차트)란?

봉차트는 생김새가 양초처럼 생겨 캔들차트라고도 불린다. 캔들차트는 기술적 분석을 위한 가장 기초적인 차트로 활용되는데, 일정기간(보통, 하루) 동안의

  • 시가, 시작(Open)
  • 고가, 최고지점(High)
  • 저가, 최저지점(Low)
  • 끝, 마지막(Close)

을 한눈에 표시하는 표기법이다. 자세한 설명은 생략한다. 하루 이상 차트를 보았다면, 모를리 없는 바로 그 차트.

그래도 모르는 사람들을 위해 내가 좋아하는 슈카의 영상을 남긴다. 30분 10초(자동시작 설정해둠)부터 한 4분 정도 보고도 심심하면 처음부터 다시 보시길...

 

2. 차트 데이터 수집하기

내 블로그의 2개 다른 글을 통해 종목코드를 받는 방법주가정보를 가져오는 방법을 기록한 바 있다. 데이터를 가져오는데 기본이 되는 로직은 지난 포스트 살펴 보기를 눌러 확인할 수 있다.

 

종목코드만 알고 있다면, 아래의 사용자함수(GetPriceList)로 pandas DataFrame 형태의 가격정보를  가져올 수 있다.  반환되는 형태는 주석으로 달아둔 것과 같다. 

# -*- coding:UTF-8 -*-

import pandas as pd
import requests
import io
import ast

def GetPriceList(ticker, tf='day', rqtyp = 0, cnt = 100000, stime='19900101', etime='20220101'):
    '''
    [usage]
        참고 URL: https://api.finance.naver.com/siseJson.naver?
                  symbol=005930&requestType=1&count=1&startTime=20191011&
                  endTime=20210602&timeframe=day
        파라미터 종류: symbol, requestType, count, startTime, endTime, timeframe
            requestType = 0, 1, 2 가 가능하며,
                0: 최근 count 개수
                1: startTime 부터 endTime 까지
                2: startTime 까지의 최근 count 개수 (0의 변형)
            timeframe = minute, day, week, month가 가능
            단, minute일 경우, 각 파라미터의 의미가 다름으로 1가지 만 사용하길 바람
            url = 'https://api.finance.naver.com/siseJson.naver?' \
                  f'symbol={ticker}&requestType=0&count=1&timeframe=minute'

    [return]
                             Open   High    Low  Close    Volume  외국인소진율
                 Date
                 1990-01-03  44000  45000  43200  44800     26240     NaN
                 1990-01-04  45000  45800  44800  45300     41900     NaN
                 1990-01-05  45000  45300  44300  44300     27400     NaN
                 1990-01-06  44800  45000  44500  44500     26380     NaN
                 1990-01-08  44500  44900  44000  44000     14790     NaN
                 ...           ...    ...    ...    ...       ...     ...
                 2022-01-26  73900  74400  73100  73300  12976730   52.16
                 2022-01-27  73800  74000  71300  71300  22274777   52.14
                 2022-01-28  71300  73700  71200  73300  21367447   52.12
                 2022-02-03  74900  74900  73300  73300  17744721   52.09
                 2022-02-04  74300  74600  73400  74000  12375640   52.09

                 [8342 rows x 6 columns]

    '''
    # timeframe 확인부, minute 일 때만 url 형식이 다름
    if tf == 'minute':
        url = 'https://api.finance.naver.com/siseJson.naver?' \
              f'symbol={ticker}&requestType=0&count=1&timeframe=minute'
    elif tf in ['day','week','month']:
        url = 'https://api.finance.naver.com/siseJson.naver?' \
              f'symbol={ticker}&requestType={str(rqtyp)}&count={str(cnt)}&startTime={stime}&endTime={etime}&
timeframe={tf}'
    else:
        raise ValueError('"timeframe" 은 day, week, month, minute 중 하나여야함')

    # naver에서 주가데이터 가져오고, List 타입으로 변환
    res = requests.get(url)
    data = res.text.replace("'", '"').strip()
    data = ast.literal_eval(data)

    # 분석을 위해 pandas DataFrame 형태로 변환하고, 문자열데이터를 숫자 또는 날짜로 변환
    name = ticker
    priceData = pd.DataFrame(data[1:], columns=["Date","Open","High","Low","Close","Volume","외국인소진율"])
    priceData['Open'] = pd.to_numeric(priceData['Open'])
    priceData['High'] = pd.to_numeric(priceData['High'])
    priceData['Low'] = pd.to_numeric(priceData['Low'])
    priceData['Close'] = pd.to_numeric(priceData['Close'])
    priceData['Volume'] = pd.to_numeric(priceData['Volume'])
    priceData['Date'] = pd.to_datetime(priceData['Date'], format='%Y%m%d', errors='coerce')
    priceData.set_index('Date', inplace=True)
    priceData.sort_index(inplace = True)
    priceData.index.name = name
    
    return priceData.copy()

 

3. 차트용 데이터 만들기 

캔들차트는 데이터의 양이 너무 많아서 눈에 들어오지 않으면 의미를 상실한다. 따라서, 최근 100개 데이터만 간추리기로 하였다.

'''
 "2. 차트 데이터 수집하기"의 사용자함수 부분 생략
'''

# 삼성전자 일별 주가정보 가져오기
pdata = GetPricesList('005930')
# 캔들차트에 필요한 데이터만 정리
pdata = pdata.tail(100).loc[:,['Open','High','Low','Close','Volume']]

 

4. Plotly로 캔들차트 그리기

Plotly는 라이브러리 자체로 캔들차트를 제공하고 있다. 내가 아는 범위 내에서는 맷플롯립(MatPlotLib)에서는 캔들차트를 그리기 위해서는 tricky한 방식을 사용하거나(box plot을 열심히 그리는 거지) MPLfinance 모듈을 사용해야 한다. 관리의 편의 측면에서도 plotly가 더 편한 것 같다.

티스토리에 plotly 그래프 삽입 방법을 포스팅할 때 이미 언급했지만, 핵심적으로 기억해야 할 것은 두가지 이다.  Data와 Layout !!

'''
	3. 차트용 데이터 만들기 부분 생략
'''

# plotly의 graph_objects 모듈 import
import plotly.graph_objects as go

# fig로 go.Figure을 정의하는데, 우선 data와 layout을 정의하고
# 		data에 캔들차트정보 x축, OHLC 값을 넣으면 끝~
fig = go.Figure(
				data=[
                	go.Candlestick(
                    	x =pdata.index,
                     	open = pdata['Open'],
                     	high = pdata['High'],
                     	low  = pdata['Low'],
                     	close= pdata['Close'],
                     	increasing_line_color = 'red',  # 상승색, default는 녹색
                     	decreasing_line_color = 'blue', # 하락색, default는 적색
                     	showlegend = False)				# True는 boxplot형태가 legend로 표시됨
                     ],
                layout=go.Layout(
                    title=go.layout.Title(text='Samsung Elec, 캔들차트'))
                )

# 웹브라우저가 열리며, 그래프 확인가능
fig.show()

 

5. 결과물

반응형

댓글