Loading Packages

DATA

pacman::p_load(quantmod,plotly)

# Get data
stock <- getSymbols("MSFT", auto.assign = F)
dts <- index(stock)
df <- data.frame(stock, row.names = NULL)
df$dates <- dts
names(df) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted", "dates")
 
# Subset to after Jan 2016
df <- subset(df, dates > "2016-01-01")
 
# Color or volume bars
barcols <- c()
for (i in 1:length(df$dates)) {
  
  if (i == 1) {barcols[i] <- "#F95959"}
  
  if (i > 1) {
    x <- ifelse(df$Close[i] > df$Close[i - 1], "#455D7A", "#F95959")
    barcols[i] <- x
  }
}
 
# Moving Avg line
MA <- runMean(df$Close)
 
# Range selector
rangeselectorlist = list(
  x = 0, y = 0.9,
  bgcolor = "#0099cc",
  font = list(color = "white"),
  
  buttons = list(
    list(count = 1, label = "reset", step = "all"),
    list(count = 1, label = "1yr", step = "year", stepmode = "backward"),
    list(count = 3, label = "3 mo", step = "month", stepmode = "backward"),
    list(count = 1, label = "1 mo", step = "month", stepmode = "backward"),
    list(step = "all")
  )
)

BASE CANDLESTICK CHART WITH VOLUME PANEL

plot_ly(df, type = "candlestick",
        x = ~dates,
        open = ~Open, high = ~High, low = ~Low, close = ~Close,
        yaxis = "y",
        increasing = list(line = list(color = "#455D7A")),
        decreasing = list(line = list(color = "#F95959")),
        name = "Price",
        height = 600, width = 1024) %>%
  
  add_bars(data = df, x = ~dates, y = ~Volume,
           marker = list(color = barcols),
           yaxis = "y2", inherit = F, name = "Vol") %>%
  
  add_lines(x = df$dates, y = MA,
            line = list(width = 3, dash = "5px", color = "#33bbff"),
            inherit = F, name = "Mov Avg") %>%
  
  layout(
    plot_bgcolor = "rgb(250,250,250)",
    xaxis = list(title = "", domain = c(0,0.95),
                 
                 rangeslider = list(visible = F),
                 
                 rangeselector = rangeselectorlist),
    yaxis = list(domain = c(0.22, 0.9)),
    yaxis2 = list(domain = c(0, 0.18), side = "right"),
    
    showlegend = F,
    
    annotations = list(
      list(x = 0, y = 1, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Microsoft</b>"),
           font = list(size = 30, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0.8, y = 0.95, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("[", paste(range(df$dates),collapse = " / "), "]"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0, y = 0.18, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Volume</b>"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE)
    )
  )

Fig. 30

BASE CANDLESTICK CHART WITH BOLLINGER BANDS

BB <- as.data.frame(BBands(df$Close))
plot_ly(df, type = "candlestick",
        x = ~dates,
        open = ~Open, high = ~High, low = ~Low, close = ~Close,
        yaxis = "y",
        increasing = list(line = list(color = "#455D7A")),
        decreasing = list(line = list(color = "#F95959")),
        name = "Price",
        height = 600, width = 1024) %>%
  
  add_bars(data = df, x = ~dates, y = ~Volume,
           marker = list(color = barcols),
           yaxis = "y2", inherit = F, name = "Vol") %>%
  
  # MA
  add_lines(x = df$dates, y = BB$mavg,
            line = list(width = 3, dash = "5px", color = "#33bbff"),
            inherit = F, name = "Mov Avg") %>%
  
  # Upper and Lower bounds
  add_lines(x = df$dates, y = BB$up,
            line = list(width = 1, dash = "5px", color = "#737373"),
            fill = "tonexty", fillcolor = "rgba(194, 240, 240, 0.2)",
            inherit = F, name = "Bollinger") %>%
  
  add_lines(x = df$dates, y = BB$dn,
            line = list(width = 1, dash = "5px", color = "#737373"),
            fill = "tonexty", fillcolor = "rgba(194, 240, 240, 0.2)",
            inherit = F, name = "Bollinger") %>%
  
  layout(
    plot_bgcolor = "rgb(250,250,250)",
    xaxis = list(title = "", domain = c(0,0.95),
                 
                 rangeslider = list(visible = F),
                 
                 rangeselector = rangeselectorlist),
    yaxis = list(domain = c(0.22, 0.9)),
    yaxis2 = list(domain = c(0, 0.18), side = "right"),
    showlegend = F,
    
    annotations = list(
      list(x = 0, y = 1, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Microsoft</b>"),
           font = list(size = 30, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0.8, y = 0.95, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("[", paste(range(df$dates),collapse = " / "), "]"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0, y = 0.18, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Volume</b>"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE)
    )
  )

Fig. 30

BASE CANDLESTICK CHART WITH CHAIKIN MONEY FLOW

CKD <- CMF(df[,c("High", "Low", "Close")], volume = df$Volume)
CKD.pos <- CKD
CKD.pos[CKD.pos < 0] <- 0
 
CKD.neg <- CKD
CKD.neg[CKD.neg > 0] <- 0
 
plot_ly(df, type = "candlestick",
        x = ~dates,
        open = ~Open, high = ~High, low = ~Low, close = ~Close,
        yaxis = "y",
        increasing = list(line = list(color = "#455D7A")),
        decreasing = list(line = list(color = "#F95959")),
        name = "Price",
        height = 600, width = 1024) %>%
  
  # MA
  add_lines(x = df$dates, y = BB$mavg,
            line = list(width = 3, dash = "5px", color = "#33bbff"),
            inherit = F, name = "Mov Avg") %>%
  
  # CKD
  add_lines(x = df$dates, y = CKD.pos,
            yaxis = "y2",
            line = list(width = 1, color = "black"),
            fill = "tozeroy", fillcolor = "#47d147",
            inherit = FALSE) %>%
  
  add_lines(x = df$dates, y = CKD.neg,
            yaxis = "y2",
            line = list(width = 1, color = "black"),
            fill = "tozeroy", fillcolor = "#ff6666",
            inherit = FALSE) %>%
  
  layout(
    plot_bgcolor = "rgb(250,250,250)",
    xaxis = list(title = "", domain = c(0,0.95),
                 
                 rangeslider = list(visible = F),
                 
                 rangeselector = rangeselectorlist),
    yaxis = list(domain = c(0.22, 0.9)),
    yaxis2 = list(domain = c(0, 0.18), side = "right"),
    showlegend = F,
    
    annotations = list(
      list(x = 0, y = 1, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Microsoft</b>"),
           font = list(size = 30, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0.8, y = 0.95, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("[", paste(range(df$dates),collapse = " / "), "]"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0, y = 0.18, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Chaikin Money Flow</b>"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE)
    )
  )

Fig. 30

BASE CANDLESTICK CHART WITH MACD

macd <- data.frame(TTR::MACD(df$Close, 12, 26, 9))
macd$diff <- macd$macd - macd$signal
 
plot_ly(df, type = "candlestick",
        x = ~dates,
        open = ~Open, high = ~High, low = ~Low, close = ~Close,
        yaxis = "y",
        increasing = list(line = list(color = "#455D7A")),
        decreasing = list(line = list(color = "#F95959")),
        name = "Price",
        height = 600, width = 1024) %>%
  
  # MA
  add_lines(x = df$dates, y = BB$mavg,
            line = list(width = 3, dash = "5px", color = "#33bbff"),
            inherit = F, name = "Mov Avg") %>%
  
  # MACD
  add_lines(x = df$dates, y = macd$macd,
            yaxis = "y2",
            line = list(width = 1, color = "#8c8c8c"),
            inherit = FALSE) %>%
  
  add_lines(x = df$dates, y = macd$signal,
            yaxis = "y2",
            line = list(width = 1, color = "#ff6666"),
            inherit = FALSE) %>%
  
  add_bars(x = df$dates, y = macd$diff,
           marker = list(color = "#bfbfbf"),
           yaxis = "y2",
           inherit = FALSE) %>%
  
  layout(
    plot_bgcolor = "rgb(250,250,250)",
    xaxis = list(title = "", domain = c(0,0.95),
                 rangeslider = list(visible = F),
                 rangeselector = rangeselectorlist),
    yaxis = list(domain = c(0.22, 0.9)),
    yaxis2 = list(domain = c(0, 0.18), side = "right"),
    showlegend = F,
    
    annotations = list(
      list(x = 0, y = 1, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>Microsoft</b>"),
           font = list(size = 30, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0.8, y = 0.95, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("[", paste(range(df$dates),collapse = " / "), "]"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE),
      
      list(x = 0, y = 0.18, xanchor = "left", yanchor = "top",
           xref = "paper", yref = "paper",
           text = paste0("<b>MACD (12, 26, 9)</b>"),
           font = list(size = 15, family = "serif"),
           showarrow = FALSE)
    )
  )

Fig. 30

Add Bollinger Bands and Buttons

library(plotly)
library(quantmod)

# get data
getSymbols("AAPL",src='yahoo')
## [1] "AAPL"
df <- data.frame(Date=index(AAPL),coredata(AAPL))

# create Bollinger Bands
bbands <- BBands(AAPL[,c("AAPL.High","AAPL.Low","AAPL.Close")])

# join and subset data
df <- subset(cbind(df, data.frame(bbands[,1:3])), Date >= "2015-02-14")

# colors column for increasing and decreasing
for (i in 1:length(df[,1])) {
  if (df$AAPL.Close[i] >= df$AAPL.Open[i]) {
      df$direction[i] = 'Increasing'
  } else {
      df$direction[i] = 'Decreasing'
  }
}

i <- list(line = list(color = '#17BECF'))
d <- list(line = list(color = '#7F7F7F'))

# plot candlestick chart
p <- df %>%
  plot_ly(x = ~Date, type="candlestick",
          open = ~AAPL.Open, close = ~AAPL.Close,
          high = ~AAPL.High, low = ~AAPL.Low, name = "AAPL",
          increasing = i, decreasing = d) %>%
  add_lines(x = ~Date, y = ~up , name = "B Bands",
            line = list(color = '#ccc', width = 0.5),
            legendgroup = "Bollinger Bands",
            hoverinfo = "none", inherit = F) %>%
  add_lines(x = ~Date, y = ~dn, name = "B Bands",
            line = list(color = '#ccc', width = 0.5),
            legendgroup = "Bollinger Bands", inherit = F,
            showlegend = FALSE, hoverinfo = "none") %>%
  add_lines(x = ~Date, y = ~mavg, name = "Mv Avg",
            line = list(color = '#E377C2', width = 0.5),
            hoverinfo = "none", inherit = F) %>%
  layout(yaxis = list(title = "Price"))

# plot volume bar chart
pp <- df %>%
  plot_ly(x=~Date, y=~AAPL.Volume, type='bar', name = "AAPL Volume",
          color = ~direction, colors = c('#17BECF','#7F7F7F')) %>%
  layout(yaxis = list(title = "Volume"))

# create rangeselector buttons
rs <- list(visible = TRUE, x = 0.5, y = -0.055,
           xanchor = 'center', yref = 'paper',
           font = list(size = 9),
           buttons = list(
             list(count=1,
                  label='RESET',
                  step='all'),
             list(count=1,
                  label='1 YR',
                  step='year',
                  stepmode='backward'),
             list(count=3,
                  label='3 MO',
                  step='month',
                  stepmode='backward'),
             list(count=1,
                  label='1 MO',
                  step='month',
                  stepmode='backward')
           ))

# subplot with shared x axis
p <- subplot(p, pp, heights = c(0.7,0.2), nrows=2,
             shareX = TRUE, titleY = TRUE) %>%
  layout(title = paste("Apple: 2015-02-14 -",Sys.Date()),
         xaxis = list(rangeselector = rs),
         legend = list(orientation = 'h', x = 0.5, y = 1,
                       xanchor = 'center', yref = 'paper',
                       font = list(size = 10),
                       bgcolor = 'transparent'))

# Create a shareable link to your chart
# Set up API credentials: https://plot.ly/r/getting-started
#chart_link = api_create(p, filename="finance/candlestick-bbands")
#chart_link

p

Fig. 30