Introduction

We have looked at Portfolio Analytics, another major finance package that we will use is quantomod. You can find out more about quantmod here

Install and use

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

Download data

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

Exercise 1.0

  • Take a look at the xts cheat sheet.
  • Download to your FN675 folder

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')

Technical trading tools

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

Exercise 2.0

  • Look at some of the technical tools that you can use
  • Search for any technical tool that you already know

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')

Calculating returns

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.

Exercise 3.0

  • Compare simple (discrete) and log (continuous) returns

Performance

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

Turn the data back into a dataframe

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")

Download from Fred

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.

Exercise 4.0

  • Work out what index(UNRATE) does.
  • Graph the US inflation rate