Financial Chart:
Quantmod and Highcharter Packages

Dr. Somsak Chanaim

International College of Digital innovation, CMU

October 30, 2024

Quantitative Financial Modelling Framework (quantmod)

quantmod logo

The quantmod is useful for quantitative financial modelling framework and have three goals:

  • download data

  • charting

  • technical indicator

Call the package

##  install.packages("quantmod")
library(quantmod)

getSymbols function

The function for load and manage data from multiple source

  • Symbols : vector of stock or asset name

  • src : “yahoo”, FRED” , etc (this course use yahoo)

  • periodicity : “daily”, “weekly”, or monthly”

  • from : Starting day: Year-month-day (2020-11-31)

  • to : Ending day: Year-month-day (2022-12-31)

The object from yahoo finance is XTS.

Example

getSymbols(Symbols = c("MSFT","META","AAPL"),
           src = "yahoo",         
           periodicity = "daily",##  "weekly", "month"
           from = "2020-01-01",  ##  Year-month-day
           to = "2024-01-31")    ##  Year-month-day
[1] "MSFT" "META" "AAPL"

Financial chart with the quantmod

The data from yahoo finance, the default graph is candlesticks, the barchart of value, and the background is dark theme.

chartSeries(AAPL) 

For the white color theme, we can set

chartSeries(AAPL, theme = chartTheme("white")) 

Financial Indicator

Modified chart by

Function Indicator
addADX() Add Directional Movement Index
addBBands() Add Bollinger Bands to Chart
addCCI() Add Commodity Channel Index
addExpiry() Add Contract Expiration Bars to Chart
addSMA()
addEMA()
addWMA() Add Moving Average to Chart ()
addEVWMA()
addZLEMA()
addMACD() Add Moving Average Convergence Divergence to Chart
addROC() Add Rate of Change to Chart
addRSI() Add Relative Strength Index to Chart
addSAR() Add Parabolic Stop and Reversal to Chart
addSMI() Add Stochastic Momentum Indicator to Chart

Example

chartSeries(AAPL, theme = chartTheme("white"), TA = NULL)
addSMA(7, col = "red") ##  short trend
addSMA(30, col = "blue") ##  median trend
addSMA(99, col = "green") ##  long trend

Exercise

Financial plot from MSFT stock price, and add the indicator SMA {10, 40, 100} with the hex color code “#ff8000”, “#00ff40”, and “#bf00ff” respectively. And add the indicator RSI.

Zoom the graph by the argument subset

plot.xts(AAPL$AAPL.Close, col ="red", 
         main = "AAPL daily closing price", 
         subset = "2023")

Useful function from quantmod

Let x be the xts object from the quantmod.

Op(x) ##  open price
Hi(x) ##  high price
Lo(x) ##  low price
Cl(x) ##  close price
Vo(x) ##  volume
Ad(x) ##  adjust close price
plot(Cl(AAPL))

Example

AAPL.close <- Cl(AAPL)
head(AAPL.close)
           AAPL.Close
2020-01-02    75.0875
2020-01-03    74.3575
2020-01-06    74.9500
2020-01-07    74.5975
2020-01-08    75.7975
2020-01-09    77.4075

Bar plot

Bar plot is good for weekly or monthly data

AAPL.month <- to.monthly(AAPL.close,)
plot(AAPL.month , col = "red", type = "h")

Add area under the line plot

# Main PLot
plot(AAPL.close, col = "#851835")
# create area
shade <- xts(x = cbind(0,AAPL.close), order.by = index(AAPL) )
# Add polygon
addPolygon(shade, on = 1, 
           col =  yarrr::transparent("#e5537a", trans.val = .5))

Add two area

# Main Plot
plot(AAPL.close, col = "#851835")
# Create polygon 1
shade <- xts(x = cbind(0, AAPL.close["2020-07-01/2021-07-01"]),
             order.by = index(AAPL["2020-07-01/2021-07-01"]) )
# Add polygon 1
addPolygon(shade, on = 1, 
           col =  yarrr::transparent("#e5537a", trans.val = .5))
# Create polygon 2
shade <- xts(x = cbind(0,AAPL.close["2022-02-01/"]),
             order.by = index(AAPL["2022-02-01/"]) )
# Add polygon 2
addPolygon(shade, on = 1, 
           col =  yarrr::transparent("#53e5be", trans.val = .5))

Modified return plot

if return is positve show blue color else show red color.

# compute dialy return
MSFT.return <- dailyReturn(Cl(MSFT))
# assign color to return
MSFT.col <- ifelse(MSFT.return$daily.returns >= 0, 
                   yes = "blue", no = "red")
head(MSFT.col)
           daily.returns
2020-01-02          blue
2020-01-03           red
2020-01-06          blue
2020-01-07           red
2020-01-08          blue
2020-01-09          blue

Result

plot(Cl(AAPL),  col = "red", main = "AAPL")

addSeries(MSFT.return, 
           col = MSFT.col, 
            on = NA,
          main ="AAPL return", 
          type = "h")

Add text with mtext() function

plot(Cl(AAPL), col = "red", main = "AAPL")
addSeries(MSFT.return, col = MSFT.col, on = NA,
          main = "AAPL return", type = "h")
# add text
mtext("TEXT",  # your message
      line = -5,
      side = 2, #1,2,3 or 4
       adj = .9, # real number from 0 to 1
       col = "blue")

Add two time series= legend

# main plot
plot(Cl(AAPL), col = "red")
# add another plot
addSeries(Cl(MSFT), col = "blue", on = 1)
# add legend
addLegend("topleft", 
          legend.names = c("AAPL", "MSFT"), 
          col = c("red", "blue"), lty = 1)

Add polygon for focus some important event

Step 1: Find the number of day.

length(Cl(AAPL)["2020-04-01/2022-06-01"])
[1] 547

Step 2: Create Polygon

shade <- xts(cbind(10, rep(x = 430, times = 547)),
             order.by = index(Cl(AAPL)["2020-04-01/2022-06-01"]))

Step 3: Create Polygon

plot(Cl(AAPL), col = "red")
addSeries(Cl(MSFT), col = "blue", on = 1,)
addLegend("bottomright",legend.names = c("AAPL","MSFT"), col =c("red","blue"), lty = 1)
addPolygon(shade, col = yarrr::transparent("red",
                trans.val = 0.5), on = 1)
mtext("COVID-19 period", side = 3, line= -10, adj = 0.3)

Result

# Compute weekly return
AAPL.R <-weeklyReturn(Cl(AAPL))
# assign green color for positive return else red color
Col <- ifelse(AAPL.R$weekly.returns >0, yes = "green", no = "red")
# main plot weekly price
plot(Cl(to.weekly(AAPL)), col = "red", main ="AAPL")
# create polygon min height is 60, max height is 200
shade <- xts(x = cbind(rep(60,
          time = length(index(AAPL["2022-12/2023-03"]))), 200), 
      order.by = index(AAPL["2022-12/2023-03"]))
# Add polygon
addPolygon(shade, col = yarrr::transparent("red",trans.val = 0.5), 
           on =1)
# Add subplot (return)
addSeries(AAPL.R, col = as.vector(Col), 
          on = NA,
          main = "AAPL return", type = "h")

Multiple line in one plot

4 lines in one plot (Open, High, Low, and Close price)

plot(AAPL[, 1:4])

Separate into two plots, and each plot must have two line plots.

plot(AAPL[, 1:4], multi.panel = 2, col = c("blue", "green", "red", "pink"))

4 plots in one graph

layout(matrix(1:4, 2, 2))
plot(AAPL[, 1:4], multi.panel = 1, yaxis.same = FALSE)

Join XTS object

x <- xts(4:10, Sys.Date()+4:10)
y <- xts(1:6, Sys.Date()+1:6)
x
           [,1]
2024-11-03    4
2024-11-04    5
2024-11-05    6
2024-11-06    7
2024-11-07    8
2024-11-08    9
2024-11-09   10
y
           [,1]
2024-10-31    1
2024-11-01    2
2024-11-02    3
2024-11-03    4
2024-11-04    5
2024-11-05    6
merge(x,y)
            x  y
2024-10-31 NA  1
2024-11-01 NA  2
2024-11-02 NA  3
2024-11-03  4  4
2024-11-04  5  5
2024-11-05  6  6
2024-11-06  7 NA
2024-11-07  8 NA
2024-11-08  9 NA
2024-11-09 10 NA
merge(x,y, join = 'inner')
           x y
2024-11-03 4 4
2024-11-04 5 5
2024-11-05 6 6
merge(x,y, join = 'left')
            x  y
2024-11-03  4  4
2024-11-04  5  5
2024-11-05  6  6
2024-11-06  7 NA
2024-11-07  8 NA
2024-11-08  9 NA
2024-11-09 10 NA
merge(x,y, join = 'right')
            x y
2024-10-31 NA 1
2024-11-01 NA 2
2024-11-02 NA 3
2024-11-03  4 4
2024-11-04  5 5
2024-11-05  6 6

merge xts object

Data <- merge(Cl(AAPL), Cl(META), Cl(MSFT))
head(Data)
           AAPL.Close META.Close MSFT.Close
2020-01-02    75.0875     209.78     160.62
2020-01-03    74.3575     208.67     158.62
2020-01-06    74.9500     212.60     159.03
2020-01-07    74.5975     213.06     157.58
2020-01-08    75.7975     215.22     160.09
2020-01-09    77.4075     218.30     162.09

plot multiple financial data

plot(Data, col =c("red", "blue", "green"))

layout(matrix(1:3, nrow = 3))
plot(Data, multi.panel = 1, yaxis.same = FALSE
     ,col = c("red", "blue", "green"), main = "")

Reference

https://joshuaulrich.github.io/xts/plotting_panels.html

Highcharter Package

The logo of highcharter pacakge

Highcharter is a R wrapper for Highcharts javascript library and its modules. Highcharts is very flexible and customizable javascript charting library and it has a great and powerful API.

The main features of highcharter are:

  • Chart various R objects with one function: with hchart(x) you can chart data.frames, numeric or character vectors, ts, xts, forecast, survfit objects.

  • Support Highstock You can create a candlestick charts in 2 lines of code. Support xts class from the {quantmod} package.

  • Support Highmaps Create choropleth charts or add information in geojson format.

  • Themes: you configure your chart in multiples ways. There are implemented themes like economist, financial times, google, 538 among others.

  • A lot of features and plugins: motion, draggable points, font-awesome, tooltips, annotations.

Call library

library(highcharter)

Basics Highstock work well with the quantmod package. It’s easy chart symbols using hchart(). Then you can add more series using hc_add_series().

Candlestick chart

hchart(AAPL)

Line chart

hchart(AAPL$AAPL.Close)

Add title

hchart(AAPL) |> 
  hc_title(text = "candlestick chart of AOT",
           align = "center")  # "left", "center", "right"

change theme

hchart(AAPL) |> 
hc_add_theme(hc_theme_economist()) |> 
   hc_title(text = "candlestick chart of AOT", align = "center")

List of theme

  • hc_theme_538()

  • hc_theme_sparkline_vb()

  • hc_theme_tufte2()

  • hc_theme_alone()

  • hc_theme_bloom()

  • hc_theme_chalk()

  • hc_theme_darkunica()

  • hc_theme_db()

  • hc_theme_economist()

  • hc_theme_elementary()

  • hc_theme_ffx()

  • hc_theme_flat()

  • hc_theme_flatdark()

  • hc_theme_ft()

  • hc_theme_ggplot2()

  • hc_theme_google()

  • hc_theme_gridlight()

  • hc_theme_handdrawn()

  • hc_theme_hcrt()

  • hc_theme_monokai()

  • hc_theme_null()

  • hc_theme_sandsignika()

  • hc_theme_smpl()

  • hc_theme_sparkline()

  • hc_theme_superheroes()

  • hc_theme_tufte()

Plot volume

hchart(MSFT$MSFT.Volume, type = "column", color = "#1BBD36")

Add series

hchart(AAPL) |> 
  hc_add_series(MSFT, upColor = "green", color = "red")
hchart(AAPL) |> 
  hc_add_series(MSFT, upColor = "green", color = "red") |> 
  hc_add_series(META, upColor = "green", color = "red")  

Add indicators

# simple moving average for 7 day
sma7  <- SMA(Cl(AAPL), n = 7)
# simple moving average for 30 day
sma30 <- SMA(Cl(AAPL), n = 30)
# simple moving average for 100 day
sma100 <- SMA(Cl(AAPL), n = 100)
# Relative Strength Index
RSI.14 <- RSI(Cl(AAPL))
# Relative Strength Index (Over buy)
RSI.SellLevel <- xts(rep(70, NROW(AAPL)), index(AAPL))
# Relative Strength Index (Over sell)
RSI.BuyLevel <- xts(rep(30, NROW(AAPL)), index(AAPL))

# empty plot
highchart(type = "stock") |> 
# Create structure plot 3 part
hc_yAxis_multiples(create_axis(naxis = 2,   # number of plot 
                               height = c(3, 1), # size of each plot
                               turnopposite = TRUE)) |>    
# add price series
hc_add_series(AAPL, yAxis = 0) |> 
# add sma series
hc_add_series(  sma7, color = "red"  , yAxis = 0, name = "short trend") |> 
hc_add_series( sma30, color = "blue" , yAxis = 0, name = "median trend") |> 
hc_add_series(sma100, color = "green", yAxis = 0, name = "long trend") |> 

# add RSI  
hc_add_series(RSI.14, color = "black",yAxis = 1, name = "Osciallator") |> 

hc_add_series(RSI.SellLevel, color = "blue", yAxis = 1, 
              dashStyle = "shortdash", name = "Sell Level") |> 

hc_add_series(RSI.BuyLevel, color = "red", yAxis = 1, 
              dashStyle = "ShortDashDot", name = "Buy Level") 
# empty plot
highchart(type ="stock") |> 
# Create structure plot 3 part
hc_yAxis_multiples(create_axis(naxis = 3,   # number of plot 
                               height = c(1,1, 1), # size of each plot
                               turnopposite = TRUE)) |>    
# add price series
hc_add_series(AAPL$AAPL.Close, yAxis = 0, name = "AAPL") |> 
hc_add_series(MSFT$MSFT.Close, yAxis = 1, name = "MSFT") |> 
hc_add_series(META$META.Close, yAxis = 2, name ="META") 

dashStyle:

  • SolidLine: The default behavior. No dashes, solid line.

  • ShortDash: A dash pattern with short dashes separated by small gaps.

  • ShortDot: A dash pattern with short dashes separated by dots.

  • ShortDashDot: A dash pattern with short dashes separated by dots and followed by a longer gap.

  • ShortDashDotDot: A dash pattern with short dashes separated by dots, followed by a dot, and then a longer gap.

  • Dot: A dash pattern with dots only, no dashes.

  • Dash: A dash pattern with longer dashes separated by shorter gaps.

  • LongDash: A dash pattern with even longer dashes separated by shorter gaps.

  • DashDot: A dash pattern with a dash followed by a dot, then repeated.

  • LongDashDot: A dash pattern with a long dash followed by a dot, then repeated.

  • LongDashDotDot: A dash pattern with a long dash followed by two dots, then repeated

Manual

manual