본문 바로가기
  • plotly로 바로쓰는 동적시각화 in R & 파이썬
Plotly in R - 그래프에 마우스를 올려봅시다

동적 주가 그래프 in R

by 아참형인간 2022. 11. 23.
candlestick.knit

plotly를 사용한 주가 그래프 그리기

앞선 포스트에서는 ggplot2tidyquant, quadmod를 사용하여 주식 그래프를 그리는 방법을 살펴보았다. ggplot2를 사용하면 전반적인 흐름의 선 그래프를 그리는데 편하지만 주식 분석에 많이 사용되는 OLHC(Open, Low, High, Close)가 표시되는 형태의 그래프를 그리는데 한계가 있었다. 그래서 파이낸셜 전문 패키지인 tidiquant, quadmod의 패키지를 사용하여 OLHC가 표시된 주가 그래프를 그려보았다. 하지만 이들 그래프에 결정적인 단점이 있다면 정확한 날짜의 정확한 값을 알아보기가 어렵다는 것이다. 이럴때 사용할 수 있는 것이 동적 패키지의 대표적인 plotly를 사용하는 것이다. 앞선 포스트에서 가져온 주가(https://2stndard.tistory.com/104)를 사용하여 plotly 패키지를 사용한 주가 그래프를 그려본다.

우선 삼성전자의 최근 100일 주가를 가져오도록 하겠다.

library(tqk)
library(lubridate)
code <- code_get()

## 삼성전자 코드값을 가져온다. 
sse_code <- code |> filter(name == '삼성전자') |>
  select(code) |> 
  pull()

samsung <- tqk_get(sse_code, from=today() - 100, to=today())

plotly candlestick 차트 그리기

plotly에서는 주식차트에서 사용하는 캔들스틱 트레이스를 지원한다. 캔들스틱 트레이스를 사용하기 위해서는 add_trace()의 ‘type’ 속성을 ‘candlestick’으로 설정하고 ’open’, ‘close’, ‘high’, ‘low’ 값으로 그릴 값이 저장된 열을 매핑해주면 간단히 그려진다.

samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low) |> 
  layout(title = "삼성전자 Candlestick Chart")

위의 캔들스틱 그래프에서 보이듯이 기본적으로 시가, 종가, 고가, 저가가 표시되는 캔들스틱 그래프가 만들어졌는데 캔들스틱 그래프 아래에는 rangeslider가 자동적으로 그려져서 주가 기간을 쉽게 설정할 수 있도록 되어 있다. 만약 rangeslider가 없는 캔들스틱 그래프는 다음과 같이 그릴수 있다.

samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low) |> 
  layout(title = "삼성전자 Candlestick Chart", 
         xaxis = list(rangeslider = list(visible = F)))

캔들 스틱 색 변경

앞에서 그린 캔들스틱은 우리가 흔히 보는 주가 그래프와 조금 다른 점이 있다. 캔들스틱의 색인데 우리나라에서는 파란색과 붉은색으로 표시되는데 plotly에서는 초록색과 붉은색으로 표시된다. 이를 파란색과 붉은색으로 바꾸기 위해서는 ‘increasing’과 ’decreasing’ 속성을 사용한다.

samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low, 
    increasing = list(line = list(color = 'red')), 
    decreasing = list(line = list(color = 'blue'))
    ) |> 
  layout(title = "삼성전자 Candlestick Chart", 
         xaxis = list(rangeslider = list(visible = F)))

거래량 그래프 추가

이제 그래프 하단에 거래량 그래프를 추가해보도록 하겠다. 거래량 그래프를 추가하기 위해서는 subplot()을 사용하여 두 개의 트레이스를 붙여서 그려야 한다. 그래서 막대 트레이스로 거래량 그래프를 그리고 이 그래프를 캔들스틱 차트 아래에 붙이도록 하겠다. 일반적으로 거래량 그래프는 아래쪽에 위치하고 크기는 전체 높이의 20%정도로 설정하고 캔들스틱 차트를 70%, 여백으로 10%정도를 설정하겠다.

samsung <- samsung |> 
  mutate(direction = case_when(
    open > close ~ 'd', 
    open <= close ~ 'i'
  ))

fig1 <- samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low, 
    increasing = list(line = list(color = 'red')), 
    decreasing = list(line = list(color = 'blue'))
  ) |> 
  layout(title = "삼성전자 Candlestick Chart", 
         xaxis = list(rangeslider = list(visible = F)),
         yaxis = list(title = '주가'),
         showlegend = FALSE)

fig2 <- samsung %>% plot_ly() |>
  add_trace(type = 'bar', x=~date, y=~volume, type='bar',
                 color = ~direction, colors = c('blue','red'), showlegend = FALSE) |>
  layout(yaxis = list(title = '거래량'))

subplot(fig1, fig2, heights = c(0.7,0.2), nrows=2,
        shareX = TRUE)

주말과 공휴일 효과의 제거

앞서 그려본 주가 그래프에서 보면 캔들스틱 차트와 거래량 막대 그래프에서 중간중간 데이터가 빠진곳이 나타난다. 이 곳은 주말과 공유일로 인해 데이터가 누락된 부분인데 이 부분을 제거하기 위해서는 ‘rangebreak’ 속성을 사용하고 이 중 ‘bound’와 ’value’ 속성을 설정함으로써 주말과 공휴일을 제거할 수 있다. 여기서 하나 유의할 것은 ‘rangebreak’ 속성을 쓸 때 속성값이 단순 list가 아닌 named list의 list를 속성값으로 사용해야 한다는 것이다.

fig1 <- samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low, 
    increasing = list(line = list(color = 'red')), 
    decreasing = list(line = list(color = 'blue'))
  ) |> 
  layout(title = "삼성전자 Candlestick Chart", 
         xaxis = list(rangeslider = list(visible = F), 
                      rangebreaks=list(
                        list(bounds=list("sat", "mon")), 
                        list(values = list("2022-09-09", "2022-09-12", "2022-10-03", "2022-10-10"))
                      )
         ),
         yaxis = list(title = '주가'),
         showlegend = FALSE)

fig2 <- samsung %>% plot_ly() |>
  add_trace(type = 'bar', x=~date, y=~volume, type='bar',
            color = ~direction, colors = c('blue','red'), showlegend = FALSE) |>
  layout(xaxis = list(rangebreaks=list(
    list(bounds=list("sat", "mon")), 
    list(values = list("2022-09-09", "2022-09-12", "2022-10-03", "2022-10-10"))
  )
  ),
  yaxis = list(title = '거래량'))

subplot(fig1, fig2, heights = c(0.7,0.2), nrows=2,
        shareX = TRUE)

호버의 편집

이번에는 호버의 형태를 설정해보도록 한다. 디폴트로 나오는 호버는 날짜, open, high, low, close의 순서로 표시되는데 천단위는 ‘k’로 표기된다. 캔들스틱 트레이스에서는 ’hovertemplate’속성을 지원하지 않기 때문에 ’text’ 속성을 사용해서 호버의 템플릿을 설정하여야 한다. 그래서 호버의 정보를 한글로 바꾸기 위해 ’text’로 화면에 표시되는 문자열을 paste0()를 사용해 만들어주고 hoverinfo 속성을 ’text’로 설정해서 호버에 ’text’속성이 표시되도록 설정하였다. 그리고 화면에 표시되는 숫자를 콤마가 표시된 원 단위로 표시해주기 위해 scales 패키지의 comma()함수를 사용하였다.

fig1 <- samsung |> plot_ly() |>
  add_trace(
    type="candlestick", x = ~date,
    open = ~open, close = ~close,
    high = ~high, low = ~low, 
    increasing = list(line = list(color = 'red')), 
    decreasing = list(line = list(color = 'blue')), 
    text = paste0(samsung$date,"<br>시가:",scales::comma(samsung$open), '원', 
                  "<br>고가:", scales::comma(samsung$high), '원', 
                  "<br>저가:",scales::comma(samsung$low), '원', 
                  "<br>종가:", scales::comma(samsung$close), '원'),
    hoverinfo='text'
  ) |> 
  layout(title = "삼성전자 Candlestick Chart", 
         xaxis = list(rangeslider = list(visible = F), 
                      rangebreaks=list(
                        list(bounds=list("sat", "mon")), 
                        list(values = list("2022-09-09", "2022-09-12", "2022-10-03", "2022-10-10"))
                      )
         ),
         yaxis = list(title = '주가'),
         showlegend = FALSE)


fig2 <- samsung %>% plot_ly() |>
  add_trace(type = 'bar', x=~date, y=~volume, type='bar',
            color = ~direction, colors = c('blue','red'), showlegend = FALSE, 
            text = paste0(samsung$date, '<br>거래량:', scales::comma(samsung$volume)), 
            hoverinfo = 'text') |>
  layout(xaxis = list(rangebreaks=list(
    list(bounds=list("sat", "mon")), 
    list(values = list("2022-09-09", "2022-09-12", "2022-10-03", "2022-10-10"))
  )
  ),
  yaxis = list(title = '거래량'))

subplot(fig1, fig2, heights = c(0.7,0.2), nrows=2,
        shareX = TRUE)

댓글