Last Observation on XTS Plot - r

Is there a way to add the value of the right most observation on an XTS plot? Another word, I want to display the most recent observation on the chart somehow.
Preferably a number on the axis? or Maybe a horizontal level line.

You could show the latest value in the title of the plot (top left corner), and then mark a line on the xts chart for it:
# If you don't already have it, use latest version of xts for nicer plot.xts, which this code uses:
# devtools::install_github("joshuaulrich/xts")
# Sample data:
library(quantmod)
getSymbols("AAPL")
data <- AAPL["2016"]
# Solve the question:
lastval <- last(Cl(data))
plot(Cl(data), main = paste("latest value = ", round(lastval, 2)))
lines(xts(rep(lastval, NROW(data)), index(data)), on = 1, col = "red", lty = 2, main = "hi")
# Check we are we plotting the xts last value? (right most value)
> last(Cl(data))
AAPL.Close
2016-10-07 114.06
Quick and dirty approach: Are you aware that you could plot with package quantmod, and by default they show the latest values "out of the box", which might be quicker/easier for you? Use functions chartSeries and you could use addTA. They show the latest values in the top left corners of the charts. For example:
chartSeries(Cl(AAPL["2016"]))
addTA(RSI(Cl(AAPL["2016"])))

Related

Plot multiple columns saved in data frame with no x

My problem is multifaceted.
I would like to plot multiple columns saved in a data frame. Those columns do not have an x variable but would essentially be 1 to 101 consistent for all. I have seen that I can transfer them into long format but most ggplot options require an X. I tried zoo which does what I want it to, but the x-label is all jumbled and I am not aware of how to fix it. (Example of data below, and plot)
df <- zoo(HIP_131_Y0_LC_walk1[1:9])
plot(df)
I have multiple data frames saved in a list so ultimately would like to run a function and apply to all. The zoo function solves step one but I am not able to apply to all the data frames in the list.
graph<-lapply(myfiles,function(x) zoo(x) )
print(graph)
Ideally I would like to also mark minimum and maximum, which I am aware can be done with ggplot but not zoo.
Thank you so much for your help in advance
Assuming that the problem is overlapped panel names there are numerous solutions to this:
abbreviate the names using abbreviate. We show this for plot.zoo and autoplot.zoo .
put the panel name in the upper left. We show this for plot.zoo using a custom panel.
Use a header on each panel. We show this using xyplot.zoo and using ggplot.
The examples below use the test input in the Note at the end. (Next time please provide a complete example including all input in reproducible form.)
The first two examples below abbreviates the panel names and using plot.zoo and autoplot.zoo (which uses ggplot2). The third example uses xyplot.zoo (which uses lattice). This automatically uses headers and is probably the easiest solution.
library(zoo)
plot(z, ylab = abbreviate(names(z), 8))
library(ggplot2)
zz <- setNames(z, abbreviate(names(z), 8))
autoplot(zz)
library (lattice)
xyplot(z)
(click on plots to see expanded; continued after plots)
This fourth example puts the panel names in the upper left of the panel themselves using plot.zoo with a custom panel.
pnl <- function(x, y, ..., pf = parent.frame()) {
legend("topleft", names(z)[pf$panel.number], bty = "n", inset = -0.1)
lines(x, y)
}
plot(z, panel = pnl, ylab = "")
(click on plot to see it expanded)
We can also get headers with autoplot.zoo similar to in lattice above.
library(ggplot2)
autoplot(z, facets = ~ Series, col = I("black")) +
theme(legend.position = "none")
(click to expand; continued after graphics)
List
If you have a list of vectors L (see Note at end for a reproducible example of such a list) then this will produce a zoo object:
do.call("merge", lapply(L, zoo))
Note
Test input used above.
library(zoo)
set.seed(123)
nms <- paste0(head(state.name, 9), "XYZ") # long names
m <- matrix(rnorm(101*9), 101, dimnames = list(NULL, nms))
z <- zoo(m)
L <- split(m, col(m)) # test list using m in Note

Highlight a Specific Section of a Treemap using Treemap package in R

I am using the Treemap package in R to highlight the number of COVID outbreaks in different settings. I am making a number of different reports using R Markdown. Each one describes a different type of settings and I would like to highlight that setting in the treemap for each report, showing what proportion of total outbreaks occur in the setting in question. For example you I am currently working on the K-12 school report and would like to highlight the box representing that category in the figure.
I was previously using an exploded donut pie chart however there were two many subcategories and the graph became hard to read.
I am picturing a way to change the label or border on one specific box, ie. put a yellow border around the box or make the label yellow. I found a way to do both these things for all the boxes but not just one specific box. I made this image using the snipping tool to further illustrate what the desired outcome might look like. The code to generate the treemap can be found in the link below. It looks like this:
# library
library(treemap)
# Build Dataset
group <- c(rep("group-1",4),rep("group-2",2),rep("group-3",3))
subgroup <- paste("subgroup" , c(1,2,3,4,1,2,1,2,3), sep="-")
value <- c(13,5,22,12,11,7,3,1,23)
data <- data.frame(group,subgroup,value)
# treemap
treemap(data,
index=c("group","subgroup"),
vSize="value",
type="index"
)
This is the most straightforward information I can find about the package, this is where I took the sample image and code from: https://www.r-graph-gallery.com/236-custom-your-treemap.html
It looks like the treemap package doesn't have a built-in way to do this. But we can hack it by using the data frame returned by treemap() and adding a rectangle to the appropriate viewport.
# Plot the treemap and save the data used for plotting.
t = treemap(data,
index = c("group", "subgroup"),
vSize = "value",
type = "index"
)
# Add a rectangle around subgroup-2.
library(grid)
library(dplyr)
with(
# t$tm is a data frame with one row per rectangle. Filter to the group we
# want to highlight.
t$tm %>%
filter(group == "group-1",
subgroup == "subgroup-2"),
{
# Use grid.rect to add a rectangle on top of the treemap.
grid.rect(x = x0 + (w / 2),
y = y0 + (h / 2),
width = w,
height = h,
gp = gpar(col = "yellow", fill = NA, lwd = 4),
vp = "data")
}
)

Controlling addLines

I have an xts object (NCGSpot) I use for charting and would like to add a vertical line on a given date to the plot. Here is what I do:
chartSeries(NCGSpot, TA="addBBands();addLines()", subset="2015-04-02::2016-08-01",theme="white")
How can I control where the Lines is drawn. I have seen stuff like
addLines(v=anynumber)
But I cannot make much sense out of it and could not find any information on it.
Its there any way I pass on a date to addLines and get the line on that date?
Thx in advance
If you use chart_Series, (better charting capabilities than chartSeries) you can create vertical lines from scratch using an xts object containing a matrix type of logical, where TRUE applies to the dates where vertical lines are desired. The argument on should be set to 1 or -1 if you want the vertical lines on your main chart. Setting -1 will put the lines behind the candles. Other useful parameters included col and border (should be self explanatory). Here is an example to get you started:
library(quantmod)
getSymbols("AAPL")
xt <- xts(rep(FALSE, NROW(AAPL)), index(AAPL))
dates_for_vertical_marks <- c("2016-02-01", "2016-04-29")
xt[dates_for_vertical_marks, ] <- TRUE
xt2 <- xts(rep(FALSE, NROW(AAPL)), index(AAPL))
dates_for_vertical_marks <- c("2016-07-01")
xt2[dates_for_vertical_marks, ] <- TRUE
chart_Series(AAPL, subset="2016")
add_TA(xt, on =-1, col= "orange", border='blue')
add_TA(xt2, on = 1, col= "darkgreen", border='darkgreen')

How to overlay multiple TA in new plot using quantmod?

We can plot candle stick chart using chart series function chartSeries(Cl(PSEC)) I have created some custom values (I1,I2 and I3) which I want to plot together(overlay) outside the candle stick pattern. I have used addTA() for this purpose
chartSeries(Cl(PSEC)), TA="addTA(I1,col=2);addTA(I2,col=3);addTA(I3,col=4)")
The problem is that it plots four plots for Cl(PSEC),I1,I2 and I3 separately instead of two plots which I want Cl(PSEC) and (I1,I2,I3)
EDITED
For clarity I am giving a sample code with I1, I2 and I3 variable created for this purpose
library(quantmod)
PSEC=getSymbols("PSEC",auto.assign=F)
price=Cl(PSEC)
I1=SMA(price,3)
I2=SMA(price,10)
I3=SMA(price,15)
chartSeries(price, TA="addTA(I1,col=2);addTA(I2,col=3);addTA(I3,col=4)")
Here is an option which preserves largely your original code.
You can obtain the desired result using the option on=2 for each TA after the first:
library(quantmod)
getSymbols("PSEC")
price <- Cl(PSEC)
I1 <- SMA(price,3)
I2 <- SMA(price,10)
I3 <- SMA(price,15)
chartSeries(price, TA=list("addTA(I1, col=2)", "addTA(I2, col=4, on=2)",
"addTA(I3, col=5, on=2)"), subset = "last 6 months")
If you want to overlay the price and the SMAs in one chart, you can use the option on=1 for each TA.
Thanks to #hvollmeier who made me realize with his answer that I had misunderstood your question in the previous version of my answer.
PS: Note that several options are described in ?addSMA(), including with.col which can be used to select a specific column of the time series (Cl is the default column).
If I understand you correctly you want the 3 SMAs in a SUBPLOT and NOT in your main chart window.You can do the following using newTA.
Using your data:
PSEC=getSymbols("PSEC",auto.assign=F)
price=Cl(PSEC)
Now plotting a 10,30,50 day SMA in a window below the main window:
chartSeries(price['2016'])
newSMA <- newTA(SMA, Cl, on=NA)
newSMA(10)
newSMA(30,on=2)
newSMA(50,on=2)
The key is the argument on. Use on = NA in defining your new TA function, because the default value foron is 1, which is the main window. on = NA plots in a new window. Then plot the remaining SMAs to the same window as the first SMA. Style the colours etc.to your liking :-).
You may want to consider solving this task using plotting with the newer quantmod charts in the quantmod package (chart_Series as opposed to chartSeries).
Pros:
-The plots look cleaner and better (?)
-have more flexibility via editing the pars and themes options to chart_Series (see other examples here on SO for the basics of things you can do with pars and themes)
Cons:
-Not well documented.
PSEC=getSymbols("PSEC",auto.assign=F)
price=Cl(PSEC)
chart_Series(price, subset = '2016')
add_TA(SMA(price, 10))
add_TA(SMA(price, 30), on = 2, col = "green")
add_TA(SMA(price, 50), on = 2, col = "red")
# Make plot all at once (this approach is useful in shiny applications):
print(chart_Series(price, subset = '2016', TA = 'add_TA(SMA(price, 10), yaxis = list(0, 10));
add_TA(SMA(price, 30), on = 2, col = "purple"); add_TA(SMA(price, 50), on = 2, col = "red")'))

Quantmod Oscillators

Utilizing the chartSeries function in the quantmod package, I want to modify the RSI oscillator. Given an xts object containing OHLC price data, here is the call that I am using:
chartSeries(plot_report[, 1:4],
name = substr(ticker, 1, nchar(ticker) - 4),
theme = chartTheme('white.mono', grid.col = NA),
TA = c(addRSI(n = 14, maType = "SMA")),
type = "line",
bar.type = 'ohlc',
major.ticks = 'months',
show.grid = FALSE,
log.scale = TRUE)
Generating this chart:
I have four questions:
How can I change the default color of blue to something else? I have tried: c(addRSI(n = 14, maType = "SMA", col = "black")). However, I get the "unused argument" error.
Can I draw horizontal lines in the oscillator panel? Traditional RSI's have a horizontal red line at a y-axis value of 70 and a horizontal green line at a y-axis value of 30 to indicate overbought/oversold levels.
Is it possible to plot another calculation as an oscillator line below the chart? I have some proprietary oscillators that I want to visualize instead of the RSI or any of the indicators in the TTR package.
How can I get involved in improving the quantmod charting functionality; is this project being actively maintained?
You can't. You would need to add ... to the arguments for addRSI and modify the body of the function to use ... appropriately. A work-around is to calculate RSI manually, then call addTA as done in the answer to Change line colors of technical indicators made by R quantmod TTR?.
Use addLines:
getSymbols("SPY"); chartSeries(SPY, TA="addRSI();addLines(h=c(30,70), on=2)")
Use addTA with the object containing your proprietary data.
See quantmod's GitHub page. Yes, it's actively maintained. The last update was pushed to CRAN a couple months ago.

Resources