python/주식

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

맑은안개 2021. 1. 27. 07:05

들어가며...

앞선 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 캔들 + 이동평균선 차트

 

반응형