基于R语言自定义分箱绘制股票ROC累积概率密度函数求助
R语言股票ROC分析与自定义分箱CPDF可视化问题
需求:
- 导入任意股票的每日行情数据,选取历史时段将收盘价转换为每日ROC(变化率)百分比
- 基于ROC序列创建支持自定义分箱数量/区间(比如22个分箱、区间幅度0.3%)的累积概率密度函数(CPDF),并用直方图或散点图绘制
- 对同一股票的两个不同时段数据执行上述操作,实现并排可视化
问题:针对SPY编写的代码无法正常运行,原代码如下:
library(quantmod) library(tidyquant) library(tidyverse) # using tidyverse to import a ticker spy <- tq_get("spy") spy010422 <- tq_get("spy", get ="stock.prices", from ='2022-01-04', to = '2022-01-24') str(spy010422) # getting ROC between prices in the series spy010422.rtn = ROC(spy010422$close, n = 1, type = c("discrete"), na.pad = TRUE) str(spy010422.rtn) # trying to use ggplot and tibble to create an ECDF function spy010422.rtn %>% tibble() %>% ggplot() + stat_ecdf(aes(.)) # another attempt at running ECDF on the ROC series spy010422.rtn %>% ggplot(spy010422.rtn) + stat_ecdf(aes(close)) # trying to set the number of bins and bin size for the ECDF spy010422.rtn %>% mutate(rounded = round(close/.3, 0) *.3, bin = min_rank(rounded)) %>% ggplot(aes(close, bin)) + geom_line() # next time segment of the ticker spy to compare this to spy020222 <- tq_get("spy", get ="stock.prices", from ='2022-02-02', to = '2022-02-24')
问题分析与修正方案
原代码的核心问题:
ROC返回的是时间序列对象,转成tibble后列名不明确,ggplot无法正确识别映射变量- 绘制ECDF时变量映射错误,误用了原收盘价列而非ROC值
- 自定义分箱逻辑错误,没有基于ROC值计算,且分箱逻辑不符合CPDF的要求
- 缺少两个时段数据的并排可视化逻辑
修正后的完整可运行代码
library(quantmod) library(tidyquant) library(tidyverse) library(gridExtra) # 导入两个时段的SPY行情数据 spy_period1 <- tq_get("SPY", get = "stock.prices", from = '2022-01-04', to = '2022-01-24') spy_period2 <- tq_get("SPY", get = "stock.prices", from = '2022-02-02', to = '2022-02-24') # 封装ROC计算函数:生成百分比格式的每日ROC,移除NA值 calculate_roc <- function(data) { data %>% mutate(roc_pct = ROC(close, n = 1, type = "discrete", na.pad = TRUE) * 100) %>% drop_na(roc_pct) } spy_roc1 <- calculate_roc(spy_period1) spy_roc2 <- calculate_roc(spy_period2) # 封装自定义分箱的CPDF绘图函数 create_cpdf_plot <- function(data, bin_width = 0.3, plot_title = "") { # 根据指定区间幅度自动生成分箱边界 roc_min_max <- range(data$roc_pct) bin_breaks <- seq(floor(roc_min_max[1]/bin_width)*bin_width, ceiling(roc_min_max[2]/bin_width)*bin_width, by = bin_width) # 分箱并计算累积概率 binned_data <- data %>% mutate(bin = cut(roc_pct, breaks = bin_breaks, include.lowest = TRUE)) %>% count(bin) %>% mutate(cum_prob = cumsum(n)/sum(n), # 提取分箱中点作为x轴显示值 bin_mid = (as.numeric(str_extract(bin, "^\\((.*?),") %>% str_remove_all("\\(|,")) + as.numeric(str_extract(bin, ",(.*?)\\]$") %>% str_remove_all(",|\\]")))/2) # 绘制CPDF折线+散点图 ggplot(binned_data, aes(x = bin_mid, y = cum_prob)) + geom_line(color = "#2c3e50", linewidth = 1) + geom_point(color = "#e74c3c", size = 2) + scale_y_continuous(labels = scales::percent_format(accuracy = 1)) + labs(title = plot_title, x = "ROC 日变化率 (%)", y = "累积概率") + theme_minimal() } # 生成两个时段的CPDF图 plot_period1 <- create_cpdf_plot(spy_roc1, bin_width = 0.3, plot_title = "SPY 2022.01.04-2022.01.24") plot_period2 <- create_cpdf_plot(spy_roc2, bin_width = 0.3, plot_title = "SPY 2022.02.02-2022.02.24") # 并排展示两个图形 grid.arrange(plot_period1, plot_period2, ncol = 2)
关键修正说明
- ROC标准化处理:把ROC转换为百分比,封装成函数复用,同时移除无意义的NA值(第一个交易日没有前收盘价,无法计算ROC)
- 自定义分箱逻辑:根据输入的
bin_width自动生成适配数据范围的分箱区间,计算每个分箱的累积概率,并提取分箱中点作为x轴,保证可视化的准确性 - CPDF可视化优化:用折线+散点的组合展示累积概率变化,y轴转为百分比格式更直观
- 并排可视化:借助
gridExtra包实现两个时段图形的并排展示,方便对比
内容的提问来源于stack exchange,提问作者lvbx9
相关产品推荐
相关产品推荐

