We have looked at Portfolio Analytics, another major finance package that we will use is quantomod. You can find out more about quantmod here
As usual, it is necessary to install the package if
you have not done that before by using install.packages()
and then make it available for use by using either
library() or require.
require(quantmod)
## Loading required package: quantmod
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
One of the most useful aspects of quantmod is the ability to download data automatically from Yahoo finance, the St. Louis Fed database and some other sources.
getSymbols('BAC')
## [1] "BAC"
getSymbols('SPY')
## [1] "SPY"
You should see the data, installed as an xts object in the Global Environment (top right corner of Rstudio). xts stands for extended time series. There are a huge number of useful properties for this package. You can find a cheat sheet for xts here
One we have automatically downloaded the data, we would like to take a look at the data and use some of the other features of quantmod.
head(BAC)
## BAC.Open BAC.High BAC.Low BAC.Close BAC.Volume BAC.Adjusted
## 2007-01-03 53.40 54.18 52.99 53.33 16028200 38.01837
## 2007-01-04 53.33 53.89 53.05 53.67 13175000 38.26075
## 2007-01-05 53.59 53.59 53.03 53.24 10205000 37.95422
## 2007-01-08 53.46 53.64 52.80 53.45 9685900 38.10392
## 2007-01-09 53.60 53.71 52.97 53.50 12546500 38.13955
## 2007-01-10 53.26 53.70 53.16 53.58 10083900 38.19661
head(Ad(BAC))
## BAC.Adjusted
## 2007-01-03 38.01837
## 2007-01-04 38.26075
## 2007-01-05 37.95422
## 2007-01-08 38.10392
## 2007-01-09 38.13955
## 2007-01-10 38.19661
quantmod has functions Ad(), Hi(),
Lo() and Cl() to extract the Adjusted
close, High, Low and Close. Quantmod
also has its own version of the plot() which has defaults
that may be useful for you.
plot(Ad(BAC), col = 'black')
We will speak about technical analysis in coming weeks. However, you may remember that one of the other packages that is loaded when you require or library quantmod is TTR. This is a package of technical trading tools. You can find out more about Technical Trading Rules here
For example, to create a moving average we could use the function
SMA().
BACma12 <- SMA(Cl(BAC), 12)
BACma30 <- SMA(Cl(BAC), 30)
head(BACma12, n = 15)
## SMA
## 2007-01-03 NA
## 2007-01-04 NA
## 2007-01-05 NA
## 2007-01-08 NA
## 2007-01-09 NA
## 2007-01-10 NA
## 2007-01-11 NA
## 2007-01-12 NA
## 2007-01-16 NA
## 2007-01-17 NA
## 2007-01-18 NA
## 2007-01-19 53.42083
## 2007-01-22 53.44750
## 2007-01-23 53.41833
## 2007-01-24 53.41500
tail(BACma30)
## SMA
## 2024-02-21 33.21067
## 2024-02-22 33.21000
## 2024-02-23 33.22067
## 2024-02-26 33.23600
## 2024-02-27 33.28533
## 2024-02-28 33.35833
?SMA
plot(Cl(BAC)['2022'])
lines(BACma30['2022'], col = 'red')
lines(BACma12['2022'], col = 'blue')
quantmod has a built in function to calculate returns. These can be simple (percentage) or continuously compounded (log). The options in the function are discrete and continuous. If we calculate the discrete returns from the closing Cl price of Bank of America and the S&P 500, we can bind the results together with the the cbind function.
mydata <- cbind(ROC(Cl(BAC), type = 'discrete'),
ROC(Cl(SPY), type = 'discrete'))
names(mydata) <- c("BACR", "SPYR")
head(mydata)
## BACR SPYR
## 2007-01-03 NA NA
## 2007-01-04 0.0063753296 0.002122113
## 2007-01-05 -0.0080118596 -0.007976317
## 2007-01-08 0.0039443854 0.004625083
## 2007-01-09 0.0009354394 -0.000849884
## 2007-01-10 0.0014953613 0.003331580
tail(mydata)
## BACR SPYR
## 2024-02-21 -0.0076560167 0.0009058332
## 2024-02-22 -0.0026706276 0.0206954983
## 2024-02-23 0.0092233726 0.0006896672
## 2024-02-26 -0.0091390795 -0.0036625300
## 2024-02-27 0.0199344884 0.0018577491
## 2024-02-28 0.0008752216 -0.0013216478
str(mydata)
## An xts object on 2007-01-03 / 2024-02-28 containing:
## Data: double [4318, 2]
## Columns: BACR, SPYR
## Index: Date [4318] (TZ: "UTC")
## xts Attributes:
## $ src : chr "yahoo"
## $ updated: POSIXct[1:1], format: "2024-02-29 14:27:42"
You can see that this has created an xts object.
We can make use of the Performance Analytics package to get a picture of the relative performance of Bank of America and the market now that we have calculated these returns.
require(PerformanceAnalytics)
table.Stats(mydata)
## BACR SPYR
## Observations 4317.0000 4317.0000
## NAs 1.0000 1.0000
## Minimum -0.2897 -0.1094
## Quartile 1 -0.0110 -0.0043
## Median 0.0000 0.0006
## Arithmetic Mean 0.0004 0.0004
## Geometric Mean -0.0001 0.0003
## Quartile 3 0.0111 0.0060
## Maximum 0.3527 0.1452
## SE Mean 0.0005 0.0002
## LCL Mean (0.95) -0.0005 0.0000
## UCL Mean (0.95) 0.0013 0.0008
## Variance 0.0010 0.0002
## Stdev 0.0313 0.0127
## Skewness 0.8701 -0.0680
## Kurtosis 23.7078 13.7607
Some of the functions that we have been using work with dataframes
but not xts objects. We might want to change the xts back into a
dataframe. We can do that using the function
as.datea.frame()
We can then run a regression with the lm() function and
draw a scatterplot.
mydatadf <- as.data.frame(mydata)
# This extracts the data from xts file so that we can
# use a standard scatterplot
eq1 <- lm(mydatadf$SPYR ~ mydatadf$BACR)
head(index(mydata))
## [1] "2007-01-03" "2007-01-04" "2007-01-05" "2007-01-08" "2007-01-09"
## [6] "2007-01-10"
plot(mydatadf$SPYR, mydatadf$BACR)
abline(eq1, col = 'red')
plot(index(mydata)[-1], eq1$residuals, xlab = "Date",
ylab = "Residuals", main = "Regression residuals")
It is also possible to download data from the St. Louis Fed database. This database is commonly called Fred. You can access Fred here. You will need the code to identify the data in order to be able to download data automatically. In this case, ``UNRATE```is the US unemployment rate.
getSymbols('UNRATE', src = 'FRED')
## [1] "UNRATE"
base::plot(index(UNRATE), as.vector(UNRATE), type = 'l', main =
"US Unemployment Rate", xlab = "Year",
ylab = "Unemployment rate", cex.main = 0.8)
In this case you can see that I have turned the unemployment data
back into a vector with the as.vector() function and I have
use the base R plotting function.
index(UNRATE) does.