【问题标题】:Stock candlestick drawing issues with geom_boxplot (R)geom_boxplot (R) 的股票烛台绘图问题
【发布时间】:2014-01-29 12:25:24
【问题描述】:

我正在使用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 
}

这是 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

我在这里做错了吗?

【问题讨论】:

  • 我复制了你的代码,但它似乎工作得很好。蜡烛与它们的 y 轴值相匹配。也许您可以仔细检查您渲染的数据集和您手动读取的数据集是否相同?

标签: r ggplot2 financial candlestick-chart


【解决方案1】:

我创建了一个生成烛台图的包,可以进一步扩展。

https://github.com/dominikduda/candlePlotter

来自帮助:

绘制 OHLC 图

(...)

参数:

time_series: 带有 c('Time', 'Open', 'High', 'Low', 'Close') 列,其中时间列必须是 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'
 )

【讨论】:

    【解决方案2】:

    感谢 FXQuantTrader 为 R 中的烛台条引入了一种美观且快速的替代方法!很棒,简洁,易读! 这是 FXQuantTrader 解决方案的一些改进版本,其中包括:
    - 将其包装成一个函数
    - 支持较低的分辨率(低至 1 秒条)
    - 将蜡烛的胡须颜色从黑色更改为正确的颜色
    - 为关闭 == 打开的条形添加小水平线
    - 将第三种颜色(蓝色)添加到关闭 == 打开的条形
    - 添加 'alpha' 参数,让您可以使整个烛台图表更加透明,因此当您在一些布林带和/或移动平均线顶部绘制时,条形图将不会分散注意力(更像是背景)
    - 更多的 cmets 让新手弄清楚发生了什么 :)

    她来了:

    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
    }
    

    【讨论】:

    • +1 不错。如果您也想在图表中绘制“天”或其他没有空白间隙的频率,您可能希望像这里所做的那样扩展您的功能(这就像 chart_Seriesquantmod 中所做的那样)stackoverflow.com/questions/28201587/…跨度>
    • @FXQuantTrader,你提到的有趣的 SO 谈话!谢谢!我会从 X 轴隐藏缺失的日期,但它有由有序因子解决的排序问题,这反过来又会给我们带来一些日期格式的麻烦。怎么样:只需将行号用作 X,但将其标记为存储在 $Date 中的日期。但是,要决定 X 轴上的刻度应该多久移动一次并且它们应该看起来很性感(例如:第 1 天和第 15 天,而不像第 3 天和第 28 天;)是很棘手的。顺便说一句,这些差距不会影响简单的指标!我同意压制差距会很高兴有选择。您对如何实施还有其他想法吗?
    【解决方案3】:

    使用ggplot2 创建 OHLC 烛台的方法比使用 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)
    

    【讨论】:

      【解决方案4】:

      无法完全理解您的问题,但这似乎很好用:

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

      【讨论】:

      • 有没有办法用 ggplot2 for python 创建这些烛台图表?
      猜你喜欢
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 2014-04-27
      相关资源
      最近更新 更多