Проблемы с отрисовкой биржевых свечей с помощью geom_boxplot (R)

Я использую geom_boxplot для рисования свечей, используя данные фондового рынка. Проблема заключается в том, что верхние и нижние края отдельных коробчатых диаграмм, а также верхняя конечная точка усов отображаются на оси Y намного выше, чем их соответствующие значения. Однако относительная высота (разница между верхним и нижним краями) и конечная точка нижнего уса каждого ящика в порядке. Вот мой код:

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 
}

Вот х:

    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

Я делаю что-то не так здесь?


person user3181905    schedule 10.01.2014    source источник
comment
Я воспроизвел ваш код, но, похоже, он работает нормально. Свечи соответствуют своим значениям по оси Y. Возможно, вы могли бы перепроверить, являются ли наборы данных, которые вы визуализируете и читаете вручную, одним и тем же?   -  person Alexander Vos de Wael    schedule 10.01.2014


Ответы (4)


Есть более эффективные способы создания свечей OHLC с помощью ggplot2, чем описанный вами способ с использованием geom_boxplot. Ваш код очень похож на пример в ссылке: http://www.perdomocore.com/2012/using-ggplot-to-make-candlestick-charts-alpha/

Кажется, многие люди размещают в сети примеры свечей ggplot, основанные на примере по этой ссылке, используя geom_boxplot. Но проблема с построением графика с помощью geom_boxplot заключается в том, что само построение графика становится медленным при построении графиков по мере увеличения количества отображаемых баров.

Вот одно вычислительно более быстрое решение для построения финансовых данных с использованием свечей/баров OHLC:

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)

введите описание изображения здесь

person FXQuantTrader    schedule 21.09.2015

Спасибо FXQuantTrader за то, что представили красивую и быструю альтернативу свечным барам в R! Красиво, лаконично, легко читается! Вот немного улучшенная версия решения FXQuantTrader, которая включает в себя:
- оборачивает его в функцию
- поддерживает более низкое разрешение (до 1-секундных баров)
- меняет цвет усов свечи с черного на правильный< br> - добавляет небольшую горизонтальную линию для баров с Close == Open
- добавляет 3-й цвет (синий) для баров с Close == Open
- добавляет аргумент 'альфа', который позволяет сделать весь график свечей более прозрачны, поэтому, когда вы рисуете поверх полос Боллинджера и/или скользящих средних, столбцы будут менее отвлекающими (больше похожи на фон)
- немного больше комментариев для новичков, чтобы понять, что происходит :)

Вот она:

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
}
person Dmitry Shevkoplyas    schedule 01.12.2016
comment
+1 Красиво. Если вы хотите отобразить «дни» или другие частоты без пробелов на диаграмме, вы можете расширить свою функцию, как это сделано здесь (это похоже на то, что chart_Series делает в quantmod) stackoverflow.com/questions/28201587 / - person FXQuantTrader; 01.12.2016
comment
@FXQuantTrader, вы упомянули интересные доклады о ТАК! Благодарю вас! Я бы скрыл отсутствующие даты по оси X, но у них есть проблема упорядочения, решаемая порядковым коэффициентом, что, в свою очередь, может привести к проблемам с некоторыми форматами дат. Как насчет: просто используйте номера строк как X, но пометьте их как даты, хранящиеся в $Date. Но тогда сложно решить, как часто должны проходить тики по оси X, и они должны выглядеть сексуально (например, 1-й день и 15-й, а не как 3-й и 28-й;). Между прочим, эти гэпы не влияют на простые индикаторы! Я согласен, что подавление пробелов было бы неплохо иметь вариант. Есть ли у вас другие идеи о том, как реализовать? - person Dmitry Shevkoplyas; 01.12.2016

Не удалось полностью понять вашу проблему, но, похоже, это работает хорошо:

http://www.perdomocore.com/2012/using-ggplot-to-make-candlestick-charts-alpha/

person CMichael    schedule 10.01.2014
comment
есть ли способ создать эти графики свечей с помощью ggplot2 для python? - person yoshiserry; 19.02.2016

Я создал пакет, генерирующий свечной график с возможностью дальнейшего расширения.

https://github.com/dominikduda/candlePlotter

Из справки:

График OHLC

(...)

Аргументы:

time_series: кадр данных со столбцами c('Time', 'Open', 'High', 'Low', 'Close'), где столбец Time должен иметь тип POSIXct.

chart_title: необязательная строка с заголовком основного графика.

under_candles_layers: вектор слоев ggplot для печати под свечами.

Рабочий пример использования:

 # Plotting a chart and saving it from a string:

 raw_data <- "
 Time Open High Low Close
 2018-08-30 7050.267 7068.232 6740.648 6985.976
 2018-08-31 6982.225 7075.417 6915.935 7046.783
 2018-09-01 7040.911 7257.571 7030.790 7193.122
 2018-09-02 7203.630 7314.289 7136.561 7277.199
 2018-09-03 7286.205 7334.481 7201.419 7255.241
 2018-09-04 7269.067 7394.179 7251.269 7364.443
 2018-09-05 7365.232 7391.967 6704.715 6704.715
 2018-09-06 6715.508 6715.508 6365.000 6503.564
 2018-09-07 6514.690 6544.672 6378.351 6446.210
 2018-09-08 6426.220 6485.850 6147.691 6203.588
 2018-09-09 6202.271 6417.675 6178.907 6260.216
 2018-09-10 6270.848 6351.214 6263.048 6317.647
 2018-09-11 6320.536 6391.365 6241.453 6289.961
 2018-09-12 6296.140 6349.481 6238.578 6339.010
 2018-09-13 6345.973 6525.523 6337.746 6498.652
 2018-09-14 6488.631 6583.669 6428.993 6492.367
 2018-09-15 6488.870 6561.979 6480.306 6524.671"
 data_for_chart <- read.table(text = raw_data, header = TRUE)
 data_for_chart <- transform(data_for_chart, Time = as.POSIXct(Time))
 plot <- prettyCandlePlot(data_for_chart, 'BTCUSD')

 ggsave(
   'btc_usd_daily.png',
   plot = plot,
   width = 30,
   height = 18,
   units = 'cm'
 )
person dominikduda    schedule 27.08.2019