본문 바로가기

정리/데이터 분석

[R] Bitcoin 데이터로 Envelope 와 Bollinger Band 그리기 (ggplot2)

728x90
Bitcoin Analysis with R(Envelope & Bollinger)

본 포스팅에는 다음의 정보를 담고 있습니다.

[1] Bitcoin openPrice에 대한 ggplot 그래프 그리기. (x축 lab 회전, character에서 시간으로 데이터 타입 변환)

[2] Envelope 그리기 (설명, 그림)

[3] Bollinger Band 그리기 (설명, 그림)

[4] Bitcoin Volumn Envelope 와 Bolliger Band 그리기.



이번엔 R을 이용하여 envelope indicator 와 Bollinger Band 를 다루는 것을 보여드리겠습니다.

원천 데이터는 WON/BTC 값이며 기본 그래프는 다음과 같습니다.



[1] Bitcoin openPrice에 대한 ggplot 그래프 그리기. (x축 lab 회전, character에서 시간으로 데이터 타입 변환)

################### WON/BTC 시계열 그래프 그리기
library(ggplot2, verbose=F,quietly=T, warn.conflicts=F)
library(scales, verbose=F,quietly=T, warn.conflicts=F)
library(lubridate, verbose=F,quietly=T, warn.conflicts=F) # for scale_x_datetime, as_datetime
# install.packages("latex2exp",quietly=T)
# library(latex2exp, verbose=F,quietly=T, warn.conflicts=F)

# mywd<-paste0("/",paste0(trimws(unlist(strsplit(getwd(),"/")))[2:5],collapse="/"),'/bitcoin/config/formarkdown_config.R')
source(paste0(getwd(),'/../../bitcoin/config/formarkdown_config.R'))
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
res<-callBTCWON(callConnection(), "2018-10-01",NA)
res[['candleDT']]<-1:nrow(res)  # index
res[['candleDateTime2']]<-as.POSIXct(res$candleDateTime, format = "%Y-%m-%dT%H:%M")  # character to date

gg<-ggplot(res)
gg+geom_line(aes(x=candleDateTime2, y=openingPrice), color="black")+
  scale_x_datetime(labels = date_format("%Y-%m-%d"), breaks=pretty_breaks(n = 20)(as_datetime(c("2018-10-01", "2018-10-20"))))+
  labs(x = "Date", y = "Open Price")+
  theme(axis.text.x = element_text(angle = 40, hjust = 1))

[설명] 위 그래프에서 아시다 시피 전체 그래프는 ggplot2로 그렸습니다.

그리고 theme 함수를 이용해 x 축은 40정도로 회전하여 가시성을 높였습니다.

charater 형인 candleDateTime 을 as.POSIXct 를 이용해 날짜 변환을 했습니다.

원래는 character를 ggplot에서 x 축으로 잘 인식하길래 candleDateTime 컬럼의 값을 10자리로 끊어서 (예, 2018-10-01) 보여만 주면 되겠구나 했는데 그게 안되더라고요.

고민한 끝에 그냥 많이쓰는 POSIXct 형태로 date format화 했습니다.

나중에 시간이 나면 R에서 Date 다루는 방법을 종합해서 올리겠습니다.



[2] Envelope 그리기 (설명, 그림)

이번엔 Envelope 그래프를 그려보겠습니다.

그 전에 envelope가 무엇인지 보시죠.

https://www.tradingview.com/wiki/Envelope_(ENV)

에 나와 있는데요.

Simple Moving Average(SMA) Base Line 에 대한 Upper 와 Lower Line 을 Envelope 라고 합니다.

결국 (1)SMA (2) Envelope 순으로 연산을 하면 되겠군요.



  1. Envelope 구현은 쉬우니 Pass.. 대신 (1)SMA 는 TTR의 SMA나 runMean 함수를 사용하면 됩니다.

다음은 Envelope Lower 와 Upper를 구하는 함수입니다.

library(TTR)
my.EnvelopeIndicator<-function(data, m=10, p=0.03){
  return(matrix(SMA(data, n=m) %>% {c( rep(.[m], m-1), .[which(is.na(.)==F)])})%*%c(1-p,1,1+p))
}
df_env<-as.data.frame(my.EnvelopeIndicator(res$openingPrice, m=5, p=0.03))
names(df_env)<-c("env_lower","env","env_upper")
res<-cbind(res, df_env)
head(res)
#(코드는 맨 아래 참고)


[설명]

설명을 하자면 TTR로 SMA 값을 구하고 NA 값이 나오면 가장 첫번째 SMA 값으로 통일하여 치환해줍니다. (사람에 따라서 다른 방식을 선택할 수도 있겠죠?)

그 다음 matrix로 변환하여 vector 와 matrix 곱합니다. 이 부분이 (2) Envelope 구현 부분이 될 수 있겠네요.

자세한 %>% 연산 스킬 설명은 여기서 보시면 됩니다.

여기여기

다음은 Envelope 그래프 입니다.


kk<-ggplot(res)
kk+
  geom_line(aes(x=candleDateTime2, y=openingPrice), color="blue")+
  geom_line(aes(x=candleDateTime2,y=env_lower), color="red")+
  # geom_line(aes(x=candleDateTime2,y=env), color="black")+
  geom_line(aes(x=candleDateTime2,y=env_upper), color="red")+
    scale_x_datetime(labels = date_format("%Y-%m-%d"), breaks=pretty_breaks(n = 20)(as_datetime(c("2018-10-01", "2018-10-20"))))+
  labs(x = "Date", y = "Envelope Price")+
  theme(axis.text.x = element_text(angle = 40, hjust = 1))


[설명]

blue 는 openPrice 이며 red 는 각각 envelope 의 upper, lower 입니다.




[3] Bollinger Band 그리기 (설명, 그림)



볼린저 밴드는 MA(Moving Average) 개념과 변동성 개념을 섞은 지표입니다.

https://en.wikipedia.org/wiki/Bollinger_Bands

이곳에서 확인이 가능합니다. 마찬가지로 TTR 패키지에서 불러들일 수 있습니다.

함수명은 BBands 입니다.

여기서 주의할 부분은 data에 들어가는 값은 Matrix 값이고 High, Low, Close 값이 들어가야 한다는 사실입니다.

다음은 BBands 를 수정한 함수입니다.

my.BBands<-function(data, m=20, std=1, hlc_c=c("highPrice","lowPrice","tradePrice")){
  return(BBands(data[, c(hlc_c[1],hlc_c[2],hlc_c[3])], n=m, sd=std)[,c(1,2,3)] %>% {rbind(matrix(rep(.[m,], m-1), ncol=3, byrow=T),.[m:nrow(.),])})
}
df_bbands<-as.data.frame(my.BBands(data=res, m=40, std=3))
res<-cbind(res,df_bbands)
# res<-res[,c(1:16)]
# str(res)

#(코드는 맨 아래 참고)

다음은 Bollinger Band 그래프 입니다.

bb<-ggplot(res[1:1000,])
bb+
  geom_line(aes(x=candleDateTime2, y=openingPrice), color="black")+
  geom_line(aes(x=candleDateTime2,y=dn), color="red")+
  geom_line(aes(x=candleDateTime2,y=mavg), color="blue")+
  geom_line(aes(x=candleDateTime2,y=up), color="red")+
    scale_x_datetime(labels = date_format("%Y-%m-%d"), breaks=pretty_breaks(n = 20)(as_datetime(c("2018-10-01", "2018-10-20"))))+
  labs(x = "Date", y = "BBands Price")+
  theme(axis.text.x = element_text(angle = 40, hjust = 1))

[설명]

잘 나오는 것 같습니다. 조기 변동성을 감지할 수도 있겠군요.

Volumn을 Envelope 와 볼밴으로 그렸을 때 어떻게 보일까요?




[4] Bitcoin Volumn를 Envelope로 그리기.

df_env<-as.data.frame(my.EnvelopeIndicator(res$candleAccTradeVolume, m=30, p=0.03))
names(df_env)<-c("env_vlower","envv","env_vupper")
res<-cbind(res, df_env)
cc<-ggplot(res)
cc+
  geom_line(aes(x=candleDateTime2, y=envv), color="blue")+
  geom_line(aes(x=candleDateTime2,y=env_vlower), color="red")+
  # geom_line(aes(x=candleDateTime2,y=env), color="black")+
  geom_line(aes(x=candleDateTime2,y=env_vupper), color="red")+
    scale_x_datetime(labels = date_format("%Y-%m-%d"), breaks=pretty_breaks(n = 20)(as_datetime(c("2018-10-01", "2018-10-20"))))+
  labs(x = "Date", y = "Envelope Volumn")+
  theme(axis.text.x = element_text(angle = 40, hjust = 1))


[설명]

역시나 해당 기간의 체결량의 격차가 많음에 따라 뚜렷한 Envelope line이 보이지 않는군요.

국소적으로 봐야겠습니다.

이정도로 포스팅은 마무리 하겠습니다.

다음은 이들을 가지고 어떤 전략을 세울만 한지 실험적으로 파악해보겠습니다.



코드