Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stock candlestick drawing issues with geom_boxplot (R)

I am using geom_boxplot to draw candlesticks using stock market data. The problem is that the individual boxplot's upper and lower edges as well as the upper whisker end point show up way higher on the y-axis than their corresponding values. The relative height (difference between upper and lower edges) and the end point of the lower whisker of each boxplot are fine though. Here's my code :

candlestickPlot <- function(x){

library("ggplot2")

# x is a data.frame with columns 'date','open','high','low','close'
x$candleLower <- pmin(x$open, x$close)
x$candleUpper <- pmax(x$open, x$close)
x$candleMiddle <- NA
x$fill <- "red"
x$fill[x$open < x$close] = "green"

# Draw the candlesticks
g <- ggplot(x, aes(x=date, lower=candleLower, middle=candleMiddle, upper=candleUpper, ymin=low, ymax=high)) 
g <- g + geom_boxplot(stat='identity', aes(group=date, fill=fill))
g 
}

Here's x :

    date     close volume  open  high   low
5 2013-12-30 25.82 3525026 27.30 27.76  25.7
4 2013-12-31 27.41 5487204 25.25 27.70 25.25
3 2014-01-02 30.70 7835374 29.25 31.24 29.21
2 2014-01-03 30.12 4577278 31.49 31.80 30.08
1 2014-01-06 30.65 4042724 30.89 31.88 30.37

Am I doing something wrong here?

like image 243
user3181905 Avatar asked Jan 10 '14 13:01

user3181905


People also ask

What do the thin lines on the candlestick charts mean?

Understanding Short Line Candles Candlestick charts are often used to assess positive or negative market sentiment at a glance. Short line candles generally signal that the market is consolidating with little price movement.

How do you read a candle wick for stocks?

Just above and below the real body are the "shadows" or "wicks." The shadows show the high and low prices of that day's trading. If the upper shadow on a down candle is short, it indicates that the open that day was near the high of the day. A short upper shadow on an up day dictates that the close was near the high.

What does a gray candle mean in stocks?

By default, green indicates an up trend where the current bar Close is greater than the previous Close, red indicates a down trend where the current bar Close is less than the previous Close, and grey indicates no change in Close from the previous to current bar.


2 Answers

There are more efficient ways to create OHLC candlesticks with ggplot2 than the way you have described using geom_boxplot. Your code seems very similar to the example in the link: http://www.perdomocore.com/2012/using-ggplot-to-make-candlestick-charts-alpha/

It seems many people are putting ggplot candlestick examples on the net that are based on the example in that link using geom_boxplot. But the problem with plotting with geom_boxplot is that the plotting itself gets slow at producing plots as the number of bars plotted increases.

Here is one computationally faster solution for plotting financial data using candlesticks/OHLC bars:

library(ggplot2)
library(quantmod)
FOSL <- getSymbols("FOSL", from="2015-01-01", auto.assign=FALSE)
names(FOSL) <- gsub("^.+\\.","",names(FOSL))  # remove "FOSL." from column names

rng <- "2015-08"
FOSL <- FOSL[rng]
FOSL <- data.frame(Date=as.POSIXct(index(FOSL)), FOSL[,1:4])

FOSL$chg <- ifelse(Cl(FOSL) > Op(FOSL), "up", "dn")
FOSL$width <- as.numeric(periodicity(FOSL)[1])
FOSL$flat_bar <- FOSL[, "High"] == FOSL[, "Low"]

# Candle chart:
pl <- ggplot(FOSL, aes(x=Date))+
  geom_linerange(aes(ymin=Low, ymax=High)) +
  theme_bw() +
  labs(title="FOSL") +
  geom_rect(aes(xmin = Date - width/2 * 0.9, xmax = Date + width/2 * 0.9, ymin = pmin(Open, Close), ymax = pmax(Open, Close), fill = chg)) + guides(fill = FALSE, colour = FALSE) + scale_fill_manual(values = c("dn" = "darkred", "up" = "darkgreen"))

# Handle special case of drawing a flat bar where OHLC = Open:
if (any(FOSL$flat_bar)) pl <- pl + geom_segment(data = FOSL[FOSL$flat_bar,], aes(x = Date - width / 2 * 0.9, y = Close, yend = Close, xend = Date + width / 2 * 0.9))

print(pl)

enter image description here

like image 182
FXQuantTrader Avatar answered Oct 19 '22 19:10

FXQuantTrader


Thank you FXQuantTrader for introducing a beautiful and fast alternative approach to the candlestick bars in R! Awesome, concise, easy to read! Here comes a bit improved version of FXQuantTrader's solution, which include:
  - wraps it into a function
  - supports lower resolution (down to 1 sec bars)
  - changes candle's whiskers colour from black to proper one
  - adds small horizontal line for bars with Close == Open
  - adds 3rd colour (blue) to bars with Close == Open
  - adds 'alpha' argument which allows you to make the whole candlesticks chart more transparent, so when you draw on top some Bollinger Bands and/or Moving Averages the bars will be less distracting (more like a background)
- a bit more comments for newbies to figure out what is going on :)

Here she comes:

library(ggplot2)
library(quantmod)
draw_candles <- function(df, title_param, alpha_param = 1){
  df$change <- ifelse(df$Close > df$Open, "up", ifelse(df$Close < df$Open, "down", "flat"))

  # originally the width of the bars was calculated by FXQuantTrader with use of 'periodicity()', which 
  # seems to work ok only with: ‘minute’,‘hourly’, ‘daily’,‘weekly’, ‘monthly’,
  # ‘quarterly’, and ‘yearly’, but can not do 1 sec bars while we want arbitrary bar size support!-)
  # df$width <- as.numeric(periodicity(df)[1])
  # So let us instead find delta (seconds) between 1st and 2nd row and just 
  # use it for all other rows. We check 1st 3 rows to avoid larger "weekend gaps"
  width_candidates <- c(as.numeric(difftime(df$Date[2], df$Date[1]), units = "secs"), 
                        as.numeric(difftime(df$Date[3], df$Date[2]), units = "secs"), 
                        as.numeric(difftime(df$Date[4], df$Date[3]), units = "secs"))

  df$width_s = min(width_candidates)  # one (same) candle width (in seconds) for all the bars

  # define the vector of candle colours either by name or by rgb()
  #candle_colors = c("down" = "red", "up" = "green", "flat" = "blue")
  candle_colors = c("down" = rgb(192,0,0,alpha=255,maxColorValue=255), "up" = rgb(0,192,0,alpha=255,maxColorValue=255), "flat" = rgb(0,0,192,alpha=255,maxColorValue=255))

  # Candle chart:
  g <- ggplot(df, aes(x=Date))+
    geom_linerange(aes(ymin=Low, ymax=High, colour = change), alpha = alpha_param) +  # candle whiskerss (vertical thin lines:)
    theme_bw() +
    labs(title=title_param) +
    geom_rect(aes(xmin = Date - width_s/2 * 0.9, xmax = Date + width_s/2 * 0.9, ymin = pmin(Open, Close), ymax = pmax(Open, Close), fill = change), alpha = alpha_param) +                            # cabdke body
    guides(fill = FALSE, colour = FALSE) +
    scale_color_manual(values = candle_colors) +  # color for line
    scale_fill_manual(values = candle_colors)     # color for candle fill  

    # Handle special cases: flat bar and Open == close:
    if (any(df$change == "flat")) g <- g + geom_segment(data = df[df$change == "flat",], aes(x = Date - width_s / 2 * 0.9, y = Close, yend = Close, xend = Date + width_s / 2 * 0.9, colour = change), alpha = alpha_param)

  #print(g)
  g
}
like image 28
Dmitry Shevkoplyas Avatar answered Oct 19 '22 18:10

Dmitry Shevkoplyas