Search code examples
rplotshinypackagequantmod

Quantmod Heikin-Ashi plotting unavailable


Recently I have been working with the quantmod package of R. The idea is to use shiny package to design the user interface of the web app while using quantmod functions to plot graphs of stock data for users.

Nonetheless, from the documentation of source code, there seems to be no pre-written functions (such as chartSeries) for plotting Heikin-Ashi graphs.

Is there alternative solution to plot Heikin-Ashi graphs without building the plotting function from scratch.

Any help is appreciated.

enter image description here


Solution

  • In some legacy / not working code of quantmod there is some Heikin-Ashi functionality hidden. But the formula used is incorrect and can produce errors. But a Heikin-Ashi chart is just a candlestick chart but with different open high low and close numbers. But these are just based on the standard ohlc data. Knowing the formula you can calculate the numbers yourself and pass these on to a candlestick chart.

    I created this function in my own package on github. But if you use this function you are set to go. I tested it on chartSeries and chart_Series from quantmod, rtsplot from rtsplot, and geom_candlestick from tidyquant to see if all of them work correctly with the data. Comparing with broker data and platforms that show Heikin-Ashi charts the results are the same.

    Basically:

    library(quantmod)
    ADM <- getSymbols("ADM", from = "2018-10-01", auto.assign = FALSE)
    ha_ADM <- heikin_ashi(AMD)
    chartSeries(ha_ADM) # or chart_Series or rtsplot or geom_candlestick
    

    heikin_ashi function:

    heikin_ashi <- function(data) {
    
      if(!quantmod::is.OHLC(data)) stop("data must contain OHLC columns")
    
      heikin_close <- xts::xts(Matrix::rowMeans(quantmod::OHLC(data)), order.by = index(data))
      heikin_open  <- quantmod::Op(data)
    
      # need a loop: heiki ashi open is dependent on the previous value
      for(i in 2:nrow(data)) {
        heikin_open[i] <- (heikin_open[i-1] + heikin_close[i-1]) / 2
      }
    
      heikin_high <- xts::xts(apply(cbind(quantmod::Hi(data), heikin_open, heikin_close), 1, max), order.by = index(data))
      heikin_low <- xts::xts(apply(cbind(quantmod::Lo(data), heikin_open, heikin_close), 1, min), order.by = index(data))
    
      out <- merge(heikin_open, heikin_high, heikin_low, heikin_close)
      out <- setNames(out, c("Open", "High", "Low", "Close"))
    }