본문 바로가기
python/주식

3. Python - Plotly 캔들차트 + 이동평균선 ( feat. rolling API 사용법 )

by 맑은안개 2021. 1. 27.

들어가며...

앞선 1, 2편에 이어 Plotly 데이터 시각화 라이브러리를 사용하여 이동평균선을 그려본다. Pandas dataframe은 window 계산 함수 rolling을 제공한다. 이를 사용하여 5, 20, 60일간 이동평균값을 쉽게 구할 수 있다.

 

1. Python - 캔들차트(candlestick) 만들기 ( mplfinance, Plotly )

2. Python - Plotly 캔들 + 거래량 차트 만들기

이동평균선

주식시장이나 파생상품 시장에서 기술적 분석을 할 때 쓰이는 기본 도구 중 하나. 풀네임보다는 줄여서 이평선이라고 많이 부른다. 거래액, 매매대금, 주가 등 다양한 분야에서 접목할 수 있다. 과거의 평균적 수치에서 현상을 파악(주로 추세)하여 현재의 매매와 미래의 예측에 접목할 수 돕는 것이 목적이다. - 나무위키

 

Plotly 설치 ( 이미 설치 되어있다면 Skip )

pip install plotly

주식 데이터 조회 ( 엔씨소프트 )

import plotly.graph_objects as go
import plotly.subplots as ms
import pandas_datareader as web

df = web.naver.NaverDailyReader('036570', start='20200601' , end='20201231').read()

df = df.astype(int) # Object 데이터를 int로 변환

이동평균선 구하기

주가이동평균선을 구하기 위해 먼저 Pandas에서 제공하는 window 계산함수 rolling을 먼저 살펴보자.

 

pandas.Series.rolling

Series.rolling(windowmin_periods=Nonecenter=Falsewin_type=Noneon=Noneaxis=0closed=None)

 

rolling 함수를 사용하여 윈도우크기 만큼 합(sum)하거나 평균(mean)한다.  

간단한 예를 살펴보자.

>>> test = pd.DataFrame({'A':range(5)})
>>> test
   A
0  0
1  1
2  2
3  3
4  4

sum

>>> test.rolling(window=2).sum()
     A
0  NaN
1  1.0
2  3.0
3  5.0
4  7.0

mean

>>> test.rolling(window=2).mean()
     A
0  NaN
1  0.5
2  1.5
3  2.5
4  3.5

 

rolling 객체는 다음과 같이 집계함수를 사용할 수 있다. 

>>> r = test.rolling(2)
>>> r
Rolling [window=2,center=False,axis=0]
>>> r.agg('sum')
     A
0  NaN
1  1.0
2  3.0
3  5.0
4  7.0
>>> r.agg('mean')
     A
0  NaN
1  0.5
2  1.5
3  2.5
4  3.5
>>> r.agg('max')
     A
0  NaN
1  1.0
2  2.0
3  3.0
4  4.0
>>> r.agg('min')
     A
0  NaN
1  0.0
2  1.0
3  2.0
4  3.0

이제 이동평균선을 구하여 DataFrame에 구성해보자.

>>> df['MA5'] = df['Close'].rolling(5).mean()
>>> df['MA20'] = df['Close'].rolling(20).mean()
>>> df['MA60'] = df['Close'].rolling(60).mean()
>>> df.tail(10)
              Open    High     Low  ...       MA5      MA20           MA60
Date                                ...                                   
2020-12-16  872000  884000  866000  ...  878800.0  851250.0  812650.000000
2020-12-17  870000  875000  864000  ...  876800.0  853250.0  813433.333333
2020-12-18  871000  881000  863000  ...  871800.0  855000.0  814416.666667
2020-12-21  863000  867000  851000  ...  867600.0  857100.0  815700.000000
2020-12-22  865000  876000  859000  ...  865600.0  859350.0  816700.000000
2020-12-23  873000  899000  870000  ...  869600.0  863500.0  818383.333333
2020-12-24  894000  903000  888000  ...  875400.0  867550.0  820266.666667
2020-12-28  898000  903000  888000  ...  882400.0  871350.0  821916.666667
2020-12-29  899000  919000  899000  ...  892200.0  876500.0  823700.000000
2020-12-30  913000  934000  911000  ...  905400.0  880450.0  826066.666667

캔들차트 생성

>>> candle = go.Candlestick(
	x=df.index,
	open=df['Open'],
	high=df['High'],
	low=df['Low'],
	close=df['Close'],
    increasing_line_color = 'red', # 상승봉 스타일링
    decreasing_line_color = 'blue' # 하락봉 스타일링
)

이동평균선 생성

>>> ma5 = go.Scatter(x=df.index, y=df['MA5'], line=dict(color='black', width=0.8), name='ma5')
>>> ma20 = go.Scatter(x=df.index, y=df['MA20'], line=dict(color='red', width=0.9), name='ma20')
>>> ma60 = go.Scatter(x=df.index, y=df['MA60'], line=dict(color='green', width=1), name='ma60')

라인형태의 차트를 그리기 위해 Scatter를 사용했다. ( line API는 현재 사용되지 않는다. ), width 를 사용하여 라인굵기에 차이를 주었다. name 속성은 범례에 표시된다. 

그래프 객체 바인딩

fig = go.Figure(data=[candle, ma5, ma20, ma60])

레이아웃 설정 - 타이틀

>>> fig.update_layout(title=dict(text="엔씨소프트 2020년 하반기 일 차트", x=0.5))

# 위 코드는 아래 처럼 표현할 수 있다.
fig.update_layout(title_text="엔씨소프트 2020년 하반기 일 차트", title_x=0.5)

그래프 출력

>>> fig.show()

Plotly 캔들 + 이동평균선 차트

 

반응형