19 Introcuction to Dygraph for Financial Analysis

Nathaniel Ho

19.1 Project Motivation

The motivation of this project is to give an introduction to dygraph, while specifically highlighting tools within the package that would prove useful for time-series financial data. Currently, the most popular package for financial analysis is Quantmod. While Quantmod is useful for retrieving time-series financial data and has a set of rudimentary graphs it can generate, it does not have an interactive component. Therefore, this project utilizes the data generated by the use of Quantmod to show different types of graphs the user can create for an individual/multiple stocks, as well as customization options for visualizing the data, including user interaction.

19.2 Gathering Data

We utilize the Quantmod package to get stock market data for AMZN and GME. We will not cover specifics of the code here as there is writeup from another group that covers the package very well. We simply get individual stock prices, as well as the combination of closing prices of the stocks we choose into one dataframe.

library(quantmod)
library(dygraphs)
tickers <- c("AMZN", "GME")
getSymbols(tickers)
## [1] "AMZN" "GME"
closePrices <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))

amzn <- getSymbols("AMZN")
gme <- getSymbols("GME")

19.3 Types of Graphs

19.3.1 Individual Dynamic Chart

The first is an individual dynamic chart. These are useful if you want to display summary data for a singular financial instrument (such as the opening, closing, day high/low of a stock). Here, we use AMZN’s closing price as an example.

dygraph(AMZN[,4], main="AMZN Closing Price")

19.3.2 Multiline Dynamic Chart

If two series share the same x-axis (such as date), then we can compare the two series by putting them in the same dynamic chart to directly compare them. Common usages include prices or percent changes between two stocks, as well as more technical aspects of a stock such as rolling alpha/beta, Sharpe’s Ratiom etc. Below, we plot both Gamestock’s and Amazon’s stock prices on a multiline dynamic chart.

stocks <- cbind(AMZN[,4], GME[,4])
dygraph(stocks, main = "Closing Prices of Amazon and Gamestop") %>% 
  dySeries(c("AMZN.Close"), label = "AMZN") %>%
  dySeries(c("GME.Close"), label = "GME")

This proves to be useful in multiple ways. For example, we can also combine different types of graphs. Here, we show AMZN’s stock price, as well as a step chart below that shows total trading volume for financial analysis. This creates a chart that closely mirrors Quantmod’s generated graph, but this graph is interactive.

stocks <- cbind(AMZN[1000:2000,4], AMZN[1000:2000,5]/100000000)
dygraph(stocks, main = "Closing Price of Amazon with Daily Trading Volume") %>% 
  dySeries("AMZN.Close", label = "AMZN") %>%
  dySeries("AMZN.Volume", stepPlot = TRUE, fillGraph = TRUE, color = "grey", label="Volume (In Tens of Millions)")

19.3.3 Moving Average/Rolling

If we wanted to create moving averages for a stock (some common ones are 50 MA, 200 MA), we can utilize another built-in tool in the dygraphs package called “rollPeriod.” The tool gives the option to choose the number of data points to average, creating a smoothed version of the graph (i.e. a graph more focused on trends than day-to-day volatility). The following example is the 50-day MA of AMZN stock:

dygraph(AMZN[,4], main = "50-day Moving Average of AMZN") %>% 
  dyRoller(rollPeriod = 50) %>%
  dySeries("AMZN.Close", label = "Moving Average Price")

19.3.4 Candlestick

Finally, there is the candlestick graph. The candlestick graph is useful for showing daily moves for a stock, as well as multiple data points such as opening price, closing price, daily low, daily high, and range all in one graph, making analysis of day-to-day stock movement a lot easier to digest.

dygraph(AMZN[3000:3050,1:4], main = "AMZN Stock Price") %>%
  dyCandlestick() %>%
dySeries("AMZN.Open", label = "Open") %>%
dySeries("AMZN.High", label = "High") %>%
dySeries("AMZN.Low", label = "Low") %>%
dySeries("AMZN.Close", label = "Close")

19.4 In-Graph Modifications

These different graphs can be further modified to give a clearer visualization of why a stock moves a certain direction. This tutorial will cover shading, events, and upper/lower bars.

19.4.1 Shading

Shading is useful if you want to denote a particular range where a macroeconomic event is happening. For example, many analysts use technical analysis to predict how a stock a move (common examples are bull/bear flags, channels, and the infamous “dead cat bounce”). In this example, we highlight where the initial wave of COVID lockdowns occured on AMZN’s stock price chart to better visualize its movement during that period.

dygraph(AMZN[,4], main="AMZN Closing Price w/COVID Lockdown Highlighted") %>%
  dyShading(from = "2020-2-14", to = "2020-8-12", color = "#FFE6E6")

19.4.2 Events and Limits

If there is a factor that shocks the market within one day, we can add an event to pinpoint the immediate effects of that positive/negative shock on that financial instrument. For example, we can highlight the stock market crash of 2009 on AMZN’s stock to better visualize how this economic shock led to a steep decline in the stock price.

dygraph(AMZN[0:1000,4], main="AMZN Closing Price w/ Great Recession Crash") %>%
   dyEvent("2008-9-29", "Great Recession Crash", labelLoc = "bottom")

Alternatively, we can add limits onto the graph to better visualize the absolute max and min of a stock. AMZN’s stock price peaked on July 8, 2021. We can create a limit that shows the limit of the absolute max.

dygraph(AMZN[,4], main="AMZN Closing Price w/ All-Time High Limit") %>%
   dyLimit(as.numeric(AMZN['2021-07-08', 4]), as.numeric(AMZN['2021-07-08', 4]), color = "black")

19.4.3 Upper/Lower Bars

Another way we can directly modify the graph is by adding upper/lower bounds to the graph. These are particularly useful if you are using prediction ML models for time-series data and want to provide an upper/lower bound. For the sake of clarity, we utilize daily low/high for our ranges for AMZN stock to visualize upper/lower bounds rather than an ML prediction model.

dygraph(AMZN[2000:2050,2:4], main="AMZN Stock w/ Daily Low/High") %>%
    dySeries(c("AMZN.Low", "AMZN.Close", "AMZN.High"), label = "AMZN")

19.5 User Interactivity

In addition to modifications that directly apply to the graph, there are also modules for user interactivity that you could add to your visualization: namely, selection highlighting and range selection.

19.5.1 Selection Highlighting

Selection Highlighting is a useful interaction for users who want a clear indicator of what time-series they are following if there are multiple ones on the plot. For example, in the graph below, if the user hovers over the stock they are tracking, the line is emboldened, which makes it easier to trace the trend of that particular stock. Additionally, we add a circle to where the user is hovering to make it easier to distinguish the data point of interest.

stocks <- cbind(AMZN[,4], GME[,4])
dygraph(stocks, main = "Closing Prices of Amazon and Gamestop w/ Selection Highlighting") %>% 
  dySeries(c("AMZN.Close"), label = "AMZN") %>%
  dySeries(c("GME.Close"), label = "GME") %>%
  dyHighlight(highlightCircleSize = 3, 
              highlightSeriesBackgroundAlpha = 0.4,
              hideOnMouseOut = FALSE)

19.5.2 Range Selection

Additionally, you can give users control over the time range for the data that they want to view. This is useful if you want to import the entirety of a dataset, but want to give the user to analyze only a subset of the data. An example of this is seen below with the default range being from 2020 to 2022:

dygraph(AMZN[,4], main="AMZN Stock w/ Range Selection") %>%
  dyRangeSelector(dateWindow = c("2020-01-01", "2022-01-01"))

19.6 Project Summary and Evaluation

This project’s aim was to give a brief introduction to dygraph and its applications to create interactive graphs for time-series data of financial instruments. This tutorial covers the basics needed to create a compelling visual story for a financial instrument, but there are far more extensions and customization options that can be utilized that the reader can explore to better tell a data-driven story. If there were more time, I would expand on dygraph’s use cases beyond financial instruments, such as in time-series trends in fields such as health and technology.