Business Analytics Mini-bootcamp - Summer 2025 (day 2) - Stock Market Data Analysis using quantmod and R

Author

Simranjeet Kaur, taught by Zhenning ‘Jimmy’ Xu, Ph.D.

Introduction

##This Quarto notebook explores stock market data using R packages like quantmod, PerformanceAnalytics, and tidyverse. We analyze and visualize data for multiple tickers including QQQ, TSLA, JPM, and GS.

Context: Tools like quantmod are widely used in algorithmic trading platforms and fintech firms. For example:

  • Lemon Markets, a European brokerage API platform, uses similar R-based or Python-based workflows to empower retail and institutional clients.
  • QuantInsti, a leading training provider in algorithmic trading, uses packages like quantmod and PerformanceAnalytics in strategy design, backtesting, and risk analysis.

Load Stock Data

JPM <- getSymbols("JPM", src = "yahoo", from = "2015-01-01", to = "2025-06-01", auto.assign = FALSE)

Reflection Question:

What are some advantages of using programmatic data collection (via getSymbols) over manually downloading CSV files from Yahoo Finance?

View Sample Data

head(JPM)
           JPM.Open JPM.High JPM.Low JPM.Close JPM.Volume JPM.Adjusted
2015-01-02    62.18    62.96   62.07     62.49   12600000     47.17426
2015-01-05    62.06    62.28   60.23     60.55   20100600     45.70973
2015-01-06    60.64    60.75   58.35     58.98   29074100     44.52452
2015-01-07    59.89    59.89   58.67     59.07   23843200     44.59247
2015-01-08    59.97    60.90   59.97     60.39   16971100     45.58896
2015-01-09    60.72    60.79   59.29     59.34   15396200     44.79630
barChart(JPM, name = "JPM Volume Bar Chart")

chartSeries(JPM, type = "bar", theme = chartTheme("white"))

chartSeries(JPM, type = "line", theme = chartTheme("white"))

chartSeries(JPM, type = "candlesticks", theme = chartTheme("white"))

Reflection Question:

Explore each chart type. How do line, bar, and candlestick charts differ in the kind of information they emphasize?

Daily and Yearly Returns

plot(dailyReturn(JPM), main = "JPM Daily Returns")

plot(yearlyReturn(JPM), main = "JPM Yearly Returns")

Discussion Idea:

QuantInsti trains traders to analyze returns across multiple timeframes. Why might a yearly return plot give a different impression than a daily return plot?

write.table(JPM, file = "JPM_stock.csv", row.names = FALSE, col.names = TRUE, sep = ",")

Convert to Data Frame and Visualize

JPM_df <- data.frame(JPM)
JPM_df$time <- index(JPM)

head(JPM_df)
           JPM.Open JPM.High JPM.Low JPM.Close JPM.Volume JPM.Adjusted
2015-01-02    62.18    62.96   62.07     62.49   12600000     47.17426
2015-01-05    62.06    62.28   60.23     60.55   20100600     45.70973
2015-01-06    60.64    60.75   58.35     58.98   29074100     44.52452
2015-01-07    59.89    59.89   58.67     59.07   23843200     44.59247
2015-01-08    59.97    60.90   59.97     60.39   16971100     45.58896
2015-01-09    60.72    60.79   59.29     59.34   15396200     44.79630
                 time
2015-01-02 2015-01-02
2015-01-05 2015-01-05
2015-01-06 2015-01-06
2015-01-07 2015-01-07
2015-01-08 2015-01-08
2015-01-09 2015-01-09
## Do you still remember the ggplot functions we used yesterday?
ggplot(JPM_df, aes(x = time, y = JPM.Adjusted)) +
  geom_point() +
  labs(title = "JPM Adjusted Closing Price",
       x = "Date", y = "Adjusted Price")

Critical Thinking:

Why might financial analysts prefer adjusted closing prices over raw closing prices when visualizing or modeling stock performance?

Technical Indicators: Bollinger Bands

What Are Bollinger Bands?

Bollinger Bands are a technical analysis tool used to measure a stock’s price volatility and identify potential buying or selling opportunities.

They consist of three lines:

Middle Band: This is usually a simple moving average (SMA) — often a 20-day average.

Upper Band: This is the middle band plus 2 standard deviations.

Lower Band: This is the middle band minus 2 standard deviations.

These bands move with the stock price and expand or contract based on how volatile the stock is.

🧠 Why Use Bollinger Bands? They help answer questions like:

Is the stock price relatively high or low compared to recent history?

Is the stock entering a period of increased volatility?

📌 How to Read Bollinger Bands When the price touches or moves above the upper band: → The stock might be overbought (price could be too high). → Some traders see this as a sell signal.

When the price touches or falls below the lower band: → The stock might be oversold (price could be too low). → This could be a buy signal.

GS <- getSymbols("GS", src = "yahoo", auto.assign = FALSE)

chartSeries(GS, subset = 'last 3 months', theme = chartTheme("white"))

addBBands(n = 20, sd = 2, maType = "SMA", draw = "bands", on = -1)

Reflection:

Bollinger Bands are popular in technical analysis. What kind of market behavior do the upper and lower bands signal? How might a quant fund use this indicator?

What is one key insight or skill you learned today? Briefly explain it in your own words.

The one thing I learned today how to analysis the stocks in R and I learned about the package quantmod.

What is one concept or tool from today’s session that you would like to apply in the future? Describe how you might use it.

I would definitely apply the analysis of taco sales data in my agriculural work and also in future if I get a role in the Finance sector, then I will also apply the package quantmod and stock analysis lesson. ## References

quantmod website: https://www.quantmod.com/

10 great R packages for stock market data:https://dev.to/lemon-markets/10-great-r-packages-for-stock-market-data-1ocp

QuantInsti: Guide to quantmod: https://blog.quantinsti.com/a-guide-on-r-quantmod-package-how-to-get-started/

chartSeries documentation: https://www.rdocumentation.org/packages/quantmod/versions/0.4.27/topics/chartSeries

Shorting strategy in R: https://blog.quantinsti.com/shorting-high-algo-trading-strategy-r/