16 Quantmod & Tidyquant Tutorials and Comparison
Mildred Ouyang and Peishan Lyu
#install.packages(“quantmod”)
#install.packages("tidyverse")
#install.packages("tidyquant")
library("quantmod")
library("tidyverse")
library("tidyquant")
16.1 Motivation:
All the Quantmod tutorials and documentations we have found did not provide a quick starter guide to beginners of R or people new to using Quantmod. The goal of our tutorial for Quantmod is to teach starters how to use the most essential exploratory data analysis tools and the most commonly used functions in Quantmod. We also hope that our tutorial can serve as a bridge for users to explore more advanced features of Quantmod in the future.
We feel that our tutorial does a nice job in telling the users the tasks can be completed by some cores functions in Quantmod and Tidyquant. To make improvements, we might create an additional cheatsheet to illustrate the required arguments of each function so that users can conveniently make flexible and more advanced adjustments based on their needs.
16.2 Quantmod
16.2.1 Getting Data:
The function used to load the data is : getSymbols(). This will return an object which stores the data.
If not specifying the source (src=“source_name”) in getSymbols(), Quantmod will use the default source which is Yahoo Finance. Some common data sources to download data from are:Yahoo, the Federal Reserve Economic Data (FRED), local database source using MySQL, csv files, and so on.(Note: Google Finance is no longer a data source. It stopped providing data in March, 2018.)
If getting data from local database using MySQL, username and password to access the database can be stored using the wrapper function: setDefaults(getSymbols.MySQL, user=‘____’, password=‘____’, dbname=‘_____’). After setting up, the user can get data using getSymbols() and change src=‘MySQL’.
Data range can be specified by passing in range start and end dates, but end date is optional. If no end date, the latest available data will be shown.
Example:
getSymbols("META", src="yahoo", from="2022-01-01", to="2022-6-30")
## [1] "META"
getSymbols("TSLA;AAPL;UBER", src="yahoo", from="2022-01-01", to="2022-6-30")
## [1] "TSLA" "AAPL" "UBER"
16.2.2 Data Visualization:
There are three primary chart types in Quantmod: bar chart, candle chart, and line chart.
Primary function to create charts: chartSeries() - by default, the open-high-low-close chart and the volume data will be shown.
Wrapper functions: barChart(), candleChart(), lineChart()
Modify the original chart: reChart() - can dynamically change the chart by only specifying the changing argument(s). This can be used to can the log-scale the y-axis, subset the data to show a specific time period, and set the ticks, range of y-axis, chart title, colors, and so on.
Examples:
chartSeries(META)
The above shows the open-high-low-close chart and the volume data. The orange color signifies that the closing price was lower than the opening price of the same day. The green color signifies the opposite.
Users can also add stock indicators to the chart for analysis. There are 26 indicators available in Quantmod. Some commonly used stock indicators are: Bollinger Bands - addBBands(), Moving Average Convergence Divergence - addMACD(), Commodity Channel Index - addCCI(), Volume - addVo(), Williams %R - addWPR(), Simple Moving Average - addSMA(), Rate of Change - addROC(), Momentum - addMomentum(), Parabolic Stop and Reverse - addSAR(), and so on.
Example:
The below example adds the Moving Average Convergence Divergence (MACD) indicator to the original graph. The below method will output two graphs, one original and one with the MACD. Later, we will introduce a way to only output one graph. The MACD has the following arguments: fast, slow, signal, type, histogram, and col. The fast and slow address the length of fast and slow periods. The signal addresses the length of the signal period. The type indicates which type of moving average to use. The histogram takes in boolean values to either or not output a histogram. Lastly, the col is optional. It changes the color for the lines. The second graph below is drawn with the default values of MACD (fast = 12, slow = 26, signal = 9, type = “EMA”, histogram = TRUE).
chartSeries(META)
addMACD()
The indicator can also be passed directly as an argument into the chartSeries function. In this way, only one graph will be drawn.
Example:
The below chart shows the Bollinger Bands drawn with default argument values. The default sets the moving average period (n) to 20, the standard deviation (sd) to 2, moving average type (maType) to simple moving average (can also be changed to weighted moving avarage and so on), and also the indicator to draw (draw) to ‘bands’ (can also be changed to percent or width).
chartSeries(META, TA = "addBBands(n=20, sd=2, maType = 'SMA', draw = 'bands')")
The below chart shows the moving average over a period of 20 days.
chartSeries(META, TA = "addSMA(n=20)")
The below chart shows the moving average over a period of 40 days.
chartSeries(META, TA = "addSMA(n=40)")
Multiple indicators can be passed in together and reflect on the same graph.
The below graph shows both the Bollinger Bands and the Moving Average Convergence Divergence indicator (with default argument values).
chartSeries(META, TA = "addBBands();addMACD()")
The below line chart plots the opening data for the stock.
lineChart(META)
The below bar chart plots the highest, lowest, opening(the right horizontal line), and closing (the left horizontal line) prices of the stock.
barChart(META)
If only want to show the highest, lowest, and closing price of one day, the user can do the following:
barChart(META, bar.type='hlc')
The candle chart below graphs the OHLC data.
candleChart(META)
Customization of the chart’s color can be done by passing the arguments multi.col and theme.
multi.col - changes the color of the bars
theme - changes the color of the background
Examples:
chartSeries(META, multi.col = TRUE)
chartSeries(META, theme = "white")
Moreover, Quantmod also allows only graphing a portion of the data. The subset argument can be used to select a specific range of data to graph.
Example: The below graph only plots the first two months of data.
chartSeries(META, multi.col = TRUE, theme = "white", subset = "2022-1::2022-2")
Subset can also take in value like “first 3 months” and “last 6 weeks”.
chartSeries(META, subset = "last 6 weeks")
Furthermore, Qauntmod allows modifications of the original graph without restating all the original arguments again.
Example:
chartSeries(META, multi.col = TRUE)
reChart(major.ticks = "months") # change the tick mark to months
16.3 Tidyquant
Tidyquant integrates quantmod, xts, zoo, TTR, and PerformanceAnalytics packages, and we can use it to generate tidier graphs than using Quantmod only. In general, we can use Tidyquant to compare stock prices, evaluate stock performance, and evaluate portfolio performance. We can easily perform financial analysis using some core tidyquant functions to get stock indexes/exchange, get quantitative data from various web-sources, transmute and mutate quantitative data, and analyze the performance of assets and portfolios.
The major functions introduced below are originally adapted from the documentation:
https://cran.r-project.org/web/packages/tidyquant/
which contains Vignettes introducing core functions and charting with Tidyquant.
We feel that the original documentation with core functions is very tidy and useful, but the authors derive different datasets using different tools, which makes it a little hard to compare similarities and differences among tools for deriving data. We attempted to use different tools to achieve data of the same four companies and included some details and new tips. This tutorial provides some basic ideas in how to get data, clean data, and chart with Tidyquant.
16.3.1 Before Getting Data
Before getting quantitative data, we want to check the list of stock index we could possibly retrieve. There are eighteen available (only 5 are shown here). They measure the performance of assets from different perspectives.
## [1] "DOW" "DOWGLOBAL" "SP400" "SP500" "SP600"
There are three stock exchanges (where exhange of securities happen) available.
## [1] "AMEX" "NASDAQ" "NYSE"
After browsing the specific data sources accessible from tq_get, we can get daily stock data from Yahoo Finance, economic data from FRED and Quandl, as well as financial data from Quandl, Tiingo, Alpha Vantage, and Bloomberg’s Financial API (though paid account is required for Bloomberg).
“stock.prices” - Yahoo Finance
“economic.data” - FRED
“quandl” and “quandl.datatable” - Nasdaq API
“tiingo”, “tiingo.iex”, “tiingo.crypto” - Tiingo API
“alphavantager”, “alphavantage” - Alpha Vantage API
“rblpapi” - Bloomberg
## [1] "stock.prices" "stock.prices.japan" "dividends"
## [4] "splits" "economic.data" "quandl"
## [7] "quandl.datatable" "tiingo" "tiingo.iex"
## [10] "tiingo.crypto" "alphavantager" "alphavantage"
## [13] "rblpapi"
16.3.2 Getting Data
Example for calling tq_index(“INDEXNAME”) function
SP500 provides a dataset with 8 columns with a capitalization-weighted index such that companies with a higher market cap receives a higher weighting in the index.
tq_index("SP500")
## # A tibble: 503 × 8
## symbol company ident…¹ sedol weight sector share…² local…³
## <chr> <chr> <chr> <chr> <dbl> <chr> <dbl> <chr>
## 1 AAPL Apple Inc. 037833… 2046… 0.0651 Infor… 1.72e8 USD
## 2 MSFT Microsoft Corporation 594918… 2588… 0.0567 Infor… 8.47e7 USD
## 3 AMZN Amazon.com Inc. 023135… 2000… 0.0243 Consu… 1.01e8 USD
## 4 GOOGL Alphabet Inc. Class A 02079K… BYVY… 0.0170 Commu… 6.81e7 USD
## 5 BRK-B Berkshire Hathaway Inc. C… 084670… 2073… 0.0167 Finan… 2.05e7 USD
## 6 GOOG Alphabet Inc. Class C 02079K… BYY8… 0.0152 Commu… 6.09e7 USD
## 7 UNH UnitedHealth Group Incorp… 91324P… 2917… 0.0149 Healt… 1.06e7 USD
## 8 JNJ Johnson & Johnson 478160… 2475… 0.0140 Healt… 2.99e7 USD
## 9 NVDA NVIDIA Corporation 67066G… 2379… 0.0134 Infor… 2.85e7 USD
## 10 XOM Exxon Mobil Corporation 30231G… 2326… 0.0132 Energy 4.74e7 USD
## # … with 493 more rows, and abbreviated variable names ¹identifier,
## # ²shares_held, ³local_currency
Examples for calling tq_get() function
(1). Getting data from Yahoo!Finance - set tq_get(…get = “stock.prices”…)
If we want to get stock prices of companies, Yahoo!Finance is a great choice.
Assume we want stock prices of Apple, Meta, Tesla, and Uber:
aapl_price_yahoo <- tq_get("AAPL", get = "stock.prices", from = "2022-01-01", to = "2022-06-30")
aapl_price_yahoo
## # A tibble: 123 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 AAPL 2022-01-03 178. 183. 178. 182. 104487900 181.
## 2 AAPL 2022-01-04 183. 183. 179. 180. 99310400 179.
## 3 AAPL 2022-01-05 180. 180. 175. 175. 94537600 174.
## 4 AAPL 2022-01-06 173. 175. 172. 172 96904000 171.
## 5 AAPL 2022-01-07 173. 174. 171. 172. 86709100 171.
## 6 AAPL 2022-01-10 169. 172. 168. 172. 106765600 171.
## 7 AAPL 2022-01-11 172. 175. 171. 175. 76138300 174.
## 8 AAPL 2022-01-12 176. 177. 175. 176. 74805200 175.
## 9 AAPL 2022-01-13 176. 177. 172. 172. 84505800 171.
## 10 AAPL 2022-01-14 171. 174. 171. 173. 80440800 172.
## # … with 113 more rows
meta_price_yahoo <- tq_get("META", get = "stock.prices", from = "2022-01-01", to = "2022-06-30")
meta_price_yahoo
## # A tibble: 123 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 META 2022-01-03 338. 341. 337. 339. 14537900 339.
## 2 META 2022-01-04 340. 343. 332. 337. 15998000 337.
## 3 META 2022-01-05 333. 336. 324. 324. 20564500 324.
## 4 META 2022-01-06 323. 339. 323. 332. 27962800 332.
## 5 META 2022-01-07 333. 337 329. 332. 14722000 332.
## 6 META 2022-01-10 325. 328. 315. 328. 24942400 328.
## 7 META 2022-01-11 327. 335. 325. 334. 16226800 334.
## 8 META 2022-01-12 335. 336. 330. 333. 14104900 333.
## 9 META 2022-01-13 335. 336. 326. 326. 14797100 326.
## 10 META 2022-01-14 322. 333. 321. 332. 16868500 332.
## # … with 113 more rows
tsla_price_yahoo <- tq_get("TSLA", get = "stock.prices", from = "2022-01-01", to = "2022-06-30")
tsla_price_yahoo
## # A tibble: 123 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 TSLA 2022-01-03 383. 400. 379. 400. 103931400 400.
## 2 TSLA 2022-01-04 397. 403. 374. 383. 100248300 383.
## 3 TSLA 2022-01-05 382. 390. 360. 363. 80119800 363.
## 4 TSLA 2022-01-06 359 363. 340. 355. 90336600 355.
## 5 TSLA 2022-01-07 360. 360. 337. 342. 84164700 342.
## 6 TSLA 2022-01-10 333. 353. 327. 353. 91815000 353.
## 7 TSLA 2022-01-11 351. 359. 346. 355. 66063300 355.
## 8 TSLA 2022-01-12 360. 372. 358. 369. 83739000 369.
## 9 TSLA 2022-01-13 370. 372. 342. 344. 97209900 344.
## 10 TSLA 2022-01-14 340. 351. 338. 350. 72924300 350.
## # … with 113 more rows
uber_price_yahoo <- tq_get("UBER", get = "stock.prices", from = "2022-01-01", to = "2022-06-30")
uber_price_yahoo
## # A tibble: 123 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 UBER 2022-01-03 42.5 44.4 41.9 44.0 26089000 44.0
## 2 UBER 2022-01-04 44.2 44.8 42.6 44.4 30845300 44.4
## 3 UBER 2022-01-05 44.3 45.9 42.9 43.2 28498700 43.2
## 4 UBER 2022-01-06 43.1 44.1 41.0 42.0 32434300 42.0
## 5 UBER 2022-01-07 42 42.7 41.2 41.5 24875800 41.5
## 6 UBER 2022-01-10 41.5 42.8 40.2 42.6 29783800 42.6
## 7 UBER 2022-01-11 42.4 44.2 42.2 43.6 22161000 43.6
## 8 UBER 2022-01-12 44.0 44.1 42.5 43.0 18993900 43.0
## 9 UBER 2022-01-13 43.3 43.9 42.7 42.9 17190100 42.9
## 10 UBER 2022-01-14 42.4 42.7 40.4 41.5 25817800 41.5
## # … with 113 more rows
(2). Getting data from FRED Economic data - tq_get() function - set tq_get(…get = “economic.data”…)
When considering if we want to retrieve data from FRED, we consider it covers major areas of macroeconoc analysis, including some major indicators:
Growth: GDP, real GDP, real potential GDP
Prices and inflation: CPI for all urban consumers for all items/all items less food & energy, GDP: implicit price deflater
Money Supply: St.Louise adjusted monetary, M1 money stock, M2 money stock, velocity of M1 money stock, velocity of M2 money stock
Interest rates: effective federal funds rate, 3-month treasury bill, 5/10/30 year treasury constant maturity rate, 5/10 year breakeven inflation rate, 5 year forward inflation expectation rate, TED Spread, bank prime loan rate
Employment: Civilian Unemployment Rate, Natural Long-Term/Short-Term Rate of Unemployment, Civilian Labor Force Participation Rate, Civilian Employment-Population Ratio, Unemployed, All Employees: Total nonfarm, All Employees: Manufacturing, Initial Claims, 4-Week Moving Average of Initial Claims
Income and expenditure: Real Median Household Income in the United States, Real Disposable Personal Income, Personal Consumption Expenditures, Personal Consumption Expenditures: Durable Goods, Personal Saving Rate, Real Retail and Food Services Sales, Disposable personal income.
Other economic indicators: Industrial Production Index, Capacity Utilization: Total Industry, Housing Starts: Total: New Privately Owned Housing Units Started, Gross Private Domestic Investment, Corporate Profits After Tax (without IVA and CCAdj), St. Louis Fed Financial Stress Index, Crude Oil Prices: West Texas Intermediate (WTI) - Cushing, Oklahoma, Leading Index for the United States, Trade Weighted U.S. Dollar Index: Major Currencies, Trade Weighted U.S. Dollar Index: Broad.
Debt: Federal Debt: Total Public Debt, Federal Debt: Total Public Debt as Percent of Gross Domestic Product, Excess Reserves of Depository Institutions, Commercial and Industrial Loans, All Commercial Banks
(The code for these indicators can be accessed from the website: https://data.nasdaq.com/data/FRED-federal-reserve-economic-data/documentation)
Assume we want to inspect the GDP within a given tiem window, we found only period data is available.
gdp_fred <- tq_get("GDP", get = "economic.data", from = "2010-01-01", to = "2022-01-01")
gdp_fred
## # A tibble: 49 × 3
## symbol date price
## <chr> <date> <dbl>
## 1 GDP 2010-01-01 14765.
## 2 GDP 2010-04-01 14980.
## 3 GDP 2010-07-01 15142.
## 4 GDP 2010-10-01 15309.
## 5 GDP 2011-01-01 15351.
## 6 GDP 2011-04-01 15558.
## 7 GDP 2011-07-01 15648.
## 8 GDP 2011-10-01 15842.
## 9 GDP 2012-01-01 16069.
## 10 GDP 2012-04-01 16207.
## # … with 39 more rows
(3). Getting data from Nasdaq Data Link (Quandl) API - set tq_get(…get = “quandl”…)
- quandl_search(… query = “KEY IN THE DATASET”…)
This is useful for deciding which dataset we want to use. We can get info about the newest and oldest available date as well as the frequency of data. If we want to look for all datasets with “GDP” as part of the name, we set query = “GDP”.
We can also set database_code = “CODENAME” if already we know the code of the dataset. We can also set the number of returns per page.
Datasets are available here: https://data.nasdaq.com/search
quandl_search(query = "GDP", page = 1)
## Gross Domestic Product
## Code: FRED/GDP
## Desc: Units: Billions of Dollars
## Seasonal Adjustment: Seasonally Adjusted Annual Rate
## Notes: A Guide to the National Income and Product Accounts of the United States (NIPA) - (http://www.bea.gov/national/pdf/nipaguid.pdf)
## Freq: quarterly
## Cols: Date | Value
##
## (GDPS) Adjusted Stock Prices
## Code: OTCB/GDPS
## Desc: <b>Ticker</b>: GDPS <br> <br> <b>Exchange</b>: OTCB <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in USD currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## Goldplat Plc (GDP) Adjusted Stock Prices
## Code: XLON/GDP
## Desc: <b>Ticker</b>: GDP <br> <br> <b>Exchange</b>: XLON <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in GBX currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## GDP Volatility & Option Implied Surface
## Code: OPT/GDP
## Desc: <p><p>Implied volatility surface for GDP.</p><p>For more information please view <a href='https://www.quandl.com/data/OPT/documentation'>OPT Documentation</a>.</p>
## Freq: daily
## Cols: date | stockpx | iv30 | iv60 | iv90 | m1atmiv | m1dtex | m2atmiv | m2dtex | m3atmiv | m3dtex | m4atmiv | m4dtex | slope | deriv | slope_inf | deriv_inf | 10dclsHV | 20dclsHV | 60dclsHV | 120dclsHV | 252dclsHV | 10dORHV | 20dORHV | 60dORHV | 120dORHV | 252dORHV
##
## Goodrich Petroleum Corp. (GDP) Adjusted Stock Prices
## Code: XNAS/GDP
## Desc: <b>Ticker</b>: GDP <br> <br> <b>Exchange</b>: XNAS <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in USD currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## Goodrich Petroleum Corp. (GDP) Adjusted Stock Prices
## Code: XNYS/GDP
## Desc: <b>Ticker</b>: GDP <br> <br> <b>Exchange</b>: XNYS <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in USD currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## Goodrich Petroleum Corp. (GDP) Adjusted Stock Prices
## Code: XASE/GDP
## Desc: <b>Ticker</b>: GDP <br> <br> <b>Exchange</b>: XASE <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in USD currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## Goodrich Petroleum Corporation (GDP) Market Betas, Correlations, and Risks
## Code: QRM/GDP
## Desc: Market Betas, Correlations, and Systematic and Unsystematic Risks for Goodrich Petroleum Corporation (GDP). All time periods are measured in calendar days. See documentation for methodology.
## Freq: daily
## Cols: Date | Beta30 | Cor30 | Srisk30 | Urisk30 | Beta60 | Cor60 | Srisk60 | Urisk60 | Beta90 | Cor90 | Srisk90 | Urisk90 | Beta360 | Cor360 | Srisk360 | Urisk360
##
## Golden Pursuit Resources Ltd. (GDP) Adjusted Stock Prices
## Code: XTSX/GDP
## Desc: <b>Ticker</b>: GDP <br> <br> <b>Exchange</b>: XTSX <br> <br> Columns: <br> <br> Open,High,Low,Close,Volume are adjusted and shown in CAD currency. <br> <br> Adjustment Factor shows the factor by which prices are adjusted on days which adjustments take place <br> <br> Adjustment Type is a number representing the type of adjustment. Refer to documentation for more information on these codes.
## Freq: daily
## Cols: Date | Open | High | Low | Close | Volume | Adjustment Factor | Adjustment Type
##
## Daily Active Analyst Ratings for GDP — Goodrich Petroleum Corp.
## Code: CBARH/GDP
## Desc: <p>Daily active analyst ratings for GDP — Goodrich Petroleum Corp.</p>
## Freq: daily
## Cols: Date | Total | Average Rating | Rating Count Strong Sell | Rating Count Moderate Sell | Rating Count Hold | Rating Count Moderate Buy | Rating Count Strong Buy | Action Count Initiated | Action Count Upgraded | Action Count Downgraded | Action Count Reiterated | Action Ratio Upgraded | Action Ratio Downgraded
## # A tibble: 10 × 13
## id datas…¹ datab…² name descr…³ refre…⁴ newes…⁵ oldes…⁶ colum…⁷ frequ…⁸
## <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <list> <chr>
## 1 1.20e5 GDP FRED Gros… "Units… 2022-0… 2021-1… 1947-0… <chr> quarte…
## 2 3.79e7 GDPS OTCB (GDP… " <b>T… 2017-0… 2006-1… 2006-1… <chr> daily
## 3 3.78e7 GDP XLON Gold… " <b>T… 2022-1… 2022-1… 2007-0… <chr> daily
## 4 2.35e7 GDP OPT GDP … "<p><p… 2021-1… 2021-1… 2010-0… <chr> daily
## 5 3.79e7 GDP XNAS Good… " <b>T… 2022-0… 2021-1… 2017-0… <chr> daily
## 6 4.35e7 GDP XNYS Good… " <b>T… 2022-0… 2021-1… 2018-0… <chr> daily
## 7 3.76e7 GDP XASE Good… " <b>T… 2022-0… 2021-1… 2017-0… <chr> daily
## 8 3.39e7 GDP QRM Good… "Marke… 2022-0… 2021-1… 2006-0… <chr> daily
## 9 3.78e7 GDP XTSX Gold… " <b>T… 2022-1… 2022-1… 2006-0… <chr> daily
## 10 2.60e7 GDP CBARH Dail… "<p>Da… 2021-0… 2021-0… 2012-0… <chr> daily
## # … with 3 more variables: type <chr>, premium <lgl>, database_id <int>, and
## # abbreviated variable names ¹dataset_code, ²database_code, ³description,
## # ⁴refreshed_at, ⁵newest_available_date, ⁶oldest_available_date,
## # ⁷column_names, ⁸frequency
- tq_get(…get = “quandl”…) - get Quandl time series free data using the API key.
The code can run successfully if users uncomment the code and insert their api key into the “my_api_key” argument.
#my_quandl_api <- quandl_api_key("my_api_key")
Types of free datasets in Quandl:
Wiki Continuous Futures, which is curated by the Quandl community and built on top of raw data from ICE, CME, LIFFE, etc.
Zillow Real Estate Data, which provides real estate and rental marketplace information.
FRED Economic Data, including indicators for macroeconomic analysis mentioned above in section.
It provides additional info about dividends and split ratio as well as some adjusted measures than Yahoo!Finance, but data is not available for Meta and Uber, and for apple and tesla, and we can get 4 years from each call. No new data is available after 2018-03-27.
#tq_get("WIKI/META", get = "quandl")
#tq_get("WIKI/AAPL", get = "quandl", from = "2017-01-01", to = "2020-12-31")
#tq_get("WIKI/TSLA", get = "quandl", from = "2017-01-01", to = "2020-12-31")
#tq_get("WIKI/UBER", get = "quandl")
- tq_get(…get = “quandl.datatable”, datatable_code = “CODENAME”…) to get some larger datasets not in time series, and note that the argument “datatable_code” is required to filled in before getting data.
(4). Getting data from Tiingo API - tq_get() - set tq_get(…get = “tiingo”/“tiingo.iex”…)
The first step is to get tiingo api key.
#my_tiingo_api <- tiingo_api_key("my_api_key")
It kind of combined the benefits of Yahoo!Finance and Quandl API in the way that we have info about some adjusted measures while data is available for all four companies from the desired time window from a single call.
#tq_get(c("AAPL", "META","TSLA","UBER"), get = "tiingo", from = "2022-01-01", to = "2022-06-30")
We can continue to look at data each hour within a specific day/multiple days.
#tq_get(c("AAPL", "META","TSLA","UBER"), get = "tiingo.iex", from = "2022-11-01", to = "2022-11-01", resample_frequency = "60min")
(5). Getting data from Alpha Vantage - set tq_get(…get = “alphavantage”…)
Also, The first step is to get tiingo api key.
#my_vantage_key <- av_api_key("my_api_key")
Like we did in former tools, we can get daily stock prices and adjusted info. The downside is it allows setting intervals only instead of the “from and to” date.
#c("AAPL","META","TSLA", "UBER") %>%
#tq_get(get = "alphavantage", av_fun = "TIME_SERIES_DAILY_ADJUSTED", interval = "daily")
Like we did using Tiingo api, we can also easily inspect data for each hour by setting the interval, but also setting the start and end time is a concern.
#c("AAPL","META","TSLA", "UBER") %>%
#tq_get(get = "alphavantage", av_fun = "TIME_SERIES_INTRADAY", interval = "60min")
(6). Bloomberg
Bloomberg charges, so it might not be the best choice for the beginners. If we still want to use it, there are some steps to take:
create a Bloomberg Terminal account.
run blpConnect()
set tq_get(…get = “Rblpapi”…)
More details could be found in the original Tidyquant documentation.
16.3.3 Data Handling
Transmute
We typically transmute when we want to change periodicity of data, and tq_transmute() will return a new data frame with new periodicity.
Before transmuting, we might explore compatible functions such that we could set tq_transmute(…mutate_fun = “CODEFROMPACKAGES”…). CODEFROMPACKAGES are returned from the call below.
## $zoo
## [1] "rollapply" "rollapplyr" "rollmax"
## [4] "rollmax.default" "rollmaxr" "rollmean"
## [7] "rollmean.default" "rollmeanr" "rollmedian"
## [10] "rollmedian.default" "rollmedianr" "rollsum"
## [13] "rollsum.default" "rollsumr"
##
## $xts
## [1] "apply.daily" "apply.monthly" "apply.quarterly" "apply.weekly"
## [5] "apply.yearly" "diff.xts" "lag.xts" "period.apply"
## [9] "period.max" "period.min" "period.prod" "period.sum"
## [13] "periodicity" "to_period" "to.daily" "to.hourly"
## [17] "to.minutes" "to.minutes10" "to.minutes15" "to.minutes3"
## [21] "to.minutes30" "to.minutes5" "to.monthly" "to.period"
## [25] "to.quarterly" "to.weekly" "to.yearly"
##
## $quantmod
## [1] "allReturns" "annualReturn" "ClCl" "dailyReturn"
## [5] "Delt" "HiCl" "Lag" "LoCl"
## [9] "LoHi" "monthlyReturn" "Next" "OpCl"
## [13] "OpHi" "OpLo" "OpOp" "periodReturn"
## [17] "quarterlyReturn" "seriesAccel" "seriesDecel" "seriesDecr"
## [21] "seriesHi" "seriesIncr" "seriesLo" "weeklyReturn"
## [25] "yearlyReturn"
##
## $TTR
## [1] "adjRatios" "ADX" "ALMA"
## [4] "aroon" "ATR" "BBands"
## [7] "CCI" "chaikinAD" "chaikinVolatility"
## [10] "CLV" "CMF" "CMO"
## [13] "CTI" "DEMA" "DonchianChannel"
## [16] "DPO" "DVI" "EMA"
## [19] "EMV" "EVWMA" "GMMA"
## [22] "growth" "HMA" "keltnerChannels"
## [25] "KST" "lags" "MACD"
## [28] "MFI" "momentum" "OBV"
## [31] "PBands" "ROC" "rollSFM"
## [34] "RSI" "runCor" "runCov"
## [37] "runMAD" "runMax" "runMean"
## [40] "runMedian" "runMin" "runPercentRank"
## [43] "runSD" "runSum" "runVar"
## [46] "SAR" "SMA" "SMI"
## [49] "SNR" "stoch" "TDI"
## [52] "TRIX" "ultimateOscillator" "VHF"
## [55] "VMA" "volatility" "VWAP"
## [58] "VWMA" "wilderSum" "williamsAD"
## [61] "WMA" "WPR" "ZigZag"
## [64] "ZLEMA"
##
## $PerformanceAnalytics
## [1] "Return.annualized" "Return.annualized.excess"
## [3] "Return.clean" "Return.cumulative"
## [5] "Return.excess" "Return.Geltner"
## [7] "zerofill"
For convenience, we only work with data retrieved for Meta from Yahoo!Finance as an example.
We transmute daily stock prices for Meta to weekly data.
meta_price_yahoo_weekly <- meta_price_yahoo %>%
# No need to group at this point, but it allows the "META" name to show. can be deleted.
group_by(symbol) %>%
# set indexAt allow the date to be the last day of each week.
tq_transmute(select = adjusted, mutate_fun = to.weekly, indexAt = "lastof")
meta_price_yahoo_weekly
## # A tibble: 26 × 3
## # Groups: symbol [1]
## symbol date adjusted
## <chr> <date> <dbl>
## 1 META 2022-01-07 332.
## 2 META 2022-01-14 332.
## 3 META 2022-01-21 303.
## 4 META 2022-01-28 302.
## 5 META 2022-02-04 237.
## 6 META 2022-02-11 220.
## 7 META 2022-02-18 206.
## 8 META 2022-02-25 210.
## 9 META 2022-03-04 200.
## 10 META 2022-03-11 188.
## # … with 16 more rows
Tesla data is converted for regression in the next steps.
tsla_price_yahoo_weekly <- tsla_price_yahoo %>%
# No need to group at this point, but it allows the "TSLA" name to show. can be deleted.
group_by(symbol) %>%
# set indexAt allow the date to be the last day of each week.
tq_transmute(select = adjusted, mutate_fun = to.weekly, indexAt = "lastof")
tsla_price_yahoo_weekly
## # A tibble: 26 × 3
## # Groups: symbol [1]
## symbol date adjusted
## <chr> <date> <dbl>
## 1 TSLA 2022-01-07 342.
## 2 TSLA 2022-01-14 350.
## 3 TSLA 2022-01-21 315.
## 4 TSLA 2022-01-28 282.
## 5 TSLA 2022-02-04 308.
## 6 TSLA 2022-02-11 287.
## 7 TSLA 2022-02-18 286.
## 8 TSLA 2022-02-25 270.
## 9 TSLA 2022-03-04 279.
## 10 TSLA 2022-03-11 265.
## # … with 16 more rows
Mutate
We mutate weekly return data with the original dataset to show how tq_mutate() works. tq_mutate(mutate_fun = periodReturn, period = “weekly”) gives a weekly return.
meta_price_yahoo_weekly_returns <- meta_price_yahoo_weekly %>%
group_by(symbol) %>%
tq_mutate(mutate_fun = periodReturn, period = "weekly", type = "log")
meta_price_yahoo_weekly_returns
## # A tibble: 26 × 4
## # Groups: symbol [1]
## symbol date adjusted weekly.returns
## <chr> <date> <dbl> <dbl>
## 1 META 2022-01-07 332. 0
## 2 META 2022-01-14 332. 0.000331
## 3 META 2022-01-21 303. -0.0905
## 4 META 2022-01-28 302. -0.00483
## 5 META 2022-02-04 237. -0.241
## 6 META 2022-02-11 220. -0.0769
## 7 META 2022-02-18 206. -0.0629
## 8 META 2022-02-25 210. 0.0207
## 9 META 2022-03-04 200. -0.0508
## 10 META 2022-03-11 188. -0.0643
## # … with 16 more rows
We might also want to show how to mutate info from computations across the columns in the original dataset. The original documentation takes rollapply from the zoo package as an example. Rollapply enables applying custom function across a rolling window. We may follow the documentation and use it to compute a rolling regression. We adapt the code from the original documentation and run the rolling regression on our Meta and Tesla dataset.
To prepare for showing how to mutate rolling regressions on the returns of Meta and Tesla, we mutate the weekly returns of Tesla with the original Tesla dataset from Yahoo!Finance as well.
tsla_price_yahoo_weekly_returns <- tsla_price_yahoo_weekly %>%
group_by(symbol) %>%
tq_mutate( mutate_fun = periodReturn, period = "weekly", type = "log")
tsla_price_yahoo_weekly_returns
## # A tibble: 26 × 4
## # Groups: symbol [1]
## symbol date adjusted weekly.returns
## <chr> <date> <dbl> <dbl>
## 1 TSLA 2022-01-07 342. 0
## 2 TSLA 2022-01-14 350. 0.0218
## 3 TSLA 2022-01-21 315. -0.106
## 4 TSLA 2022-01-28 282. -0.109
## 5 TSLA 2022-02-04 308. 0.0870
## 6 TSLA 2022-02-11 287. -0.0710
## 7 TSLA 2022-02-18 286. -0.00352
## 8 TSLA 2022-02-25 270. -0.0565
## 9 TSLA 2022-03-04 279. 0.0345
## 10 TSLA 2022-03-11 265. -0.0526
## # … with 16 more rows
Again, to prepare for running rolling regressions, we select the weekly returns columns from each dataset and join them by date as shown below.
meta_price_yahoo_weekly_returns_only <- meta_price_yahoo_weekly_returns %>%
select(weekly.returns, date)
tsla_price_yahoo_weekly_returns_only <- tsla_price_yahoo_weekly_returns %>%
select(weekly.returns, date)
joined_returns <- left_join(meta_price_yahoo_weekly_returns_only, tsla_price_yahoo_weekly_returns_only,
by ="date")
joined_returns
## # A tibble: 26 × 5
## symbol.x weekly.returns.x date symbol.y weekly.returns.y
## <chr> <dbl> <date> <chr> <dbl>
## 1 META 0 2022-01-07 TSLA 0
## 2 META 0.000331 2022-01-14 TSLA 0.0218
## 3 META -0.0905 2022-01-21 TSLA -0.106
## 4 META -0.00483 2022-01-28 TSLA -0.109
## 5 META -0.241 2022-02-04 TSLA 0.0870
## 6 META -0.0769 2022-02-11 TSLA -0.0710
## 7 META -0.0629 2022-02-18 TSLA -0.00352
## 8 META 0.0207 2022-02-25 TSLA -0.0565
## 9 META -0.0508 2022-03-04 TSLA 0.0345
## 10 META -0.0643 2022-03-11 TSLA -0.0526
## # … with 16 more rows
Here our joined_returns dataset will be passed into regr_fun as an xts object. The timetk::tk_tbl function converts our data into the dataframe.
regr_fun <- function(data) {
coef(lm(weekly.returns.x ~ weekly.returns.y, data = timetk::tk_tbl(data, silent = TRUE)))
}
Notice that we make computations within the tq_mutate() function. The new dataframe is created with the coefficients with regressions attached.
joined_returns %>%
tq_mutate(mutate_fun = rollapply,
# 2-week window.
width = 2,
FUN = regr_fun,
# We need to specify by.column since we don't want the regression to run on each column in the dataset.
by.column = FALSE)
## # A tibble: 26 × 7
## symbol.x weekly.returns.x date symbol.y weekly.ret…¹ X.Inter…² weekly…³
## <chr> <dbl> <date> <chr> <dbl> <dbl> <dbl>
## 1 META 0 2022-01-07 TSLA 0 NA NA
## 2 META 0.000331 2022-01-14 TSLA 0.0218 -1.36e-20 0.0152
## 3 META -0.0905 2022-01-21 TSLA -0.106 -1.52e- 2 0.710
## 4 META -0.00483 2022-01-28 TSLA -0.109 -3.19e+ 0 -29.2
## 5 META -0.241 2022-02-04 TSLA 0.0870 -1.36e- 1 -1.20
## 6 META -0.0769 2022-02-11 TSLA -0.0710 -1.51e- 1 -1.04
## 7 META -0.0629 2022-02-18 TSLA -0.00352 -6.22e- 2 0.206
## 8 META 0.0207 2022-02-25 TSLA -0.0565 -6.85e- 2 -1.58
## 9 META -0.0508 2022-03-04 TSLA 0.0345 -2.37e- 2 -0.786
## 10 META -0.0643 2022-03-11 TSLA -0.0526 -5.61e- 2 0.155
## # … with 16 more rows, and abbreviated variable names ¹weekly.returns.y,
## # ²X.Intercept., ³weekly.returns.y..1
Also, mutate_fun may require two different inputs. In this case, we want to use tq_mutate_xy() instead of tq_mutate() only. For example, If we want to mutate some indicator with the original dataset calculated from two columns of data from the original dataset, we want to set mutate_fun = CODENAME of the new indicator, and input the name of the two columns of x and y. Example is shown in the original documentation.
16.3.4 Charting with Tidyquant
Line Chart
Plotting opening price vs.time.
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_line() +
labs(title = "META Line Chart", y = "Opening Price", x = "") +
theme_tq()
meta_price_yahoo %>%
ggplot(aes(x = date, y = volume)) +
geom_line() +
labs(title = "META Line Chart", y = "Volume", x = "") +
theme_tq()
Changing color of the theme, using the first plot as an example.
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_line() +
labs(title = "META Line Chart", y = "Opening Price", x = "") +
theme_tq_green()
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_line() +
labs(title = "META Line Chart", y = "Opening Price", x = "") +
theme_tq_dark()
Additionally, scale_color_tq(theme = “green”/“dark”) and scale_fill_tq(theme = “green”/“dark”) may be used when color and fill are specified as aes().
The change of themes applies for all other types of plots as well.
Bar Chart
meta_price_yahoo %>%
# We can also set y = close, which is equivalent to setting y = close.
ggplot(aes(x = date, y = open)) +
geom_barchart(aes(open = open, high = high, low = low, close = close)) +
labs(title = "META Bar Chart", y = "Price", x = "") +
theme_tq()
Candlestick Chart
meta_price_yahoo %>%
# We can also set y = close, which is equivalent to setting y = close.
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
labs(title = "META Candlestick Chart", y = "Price", x = "") +
theme_tq()
We can further modify the candlestick chart by
color, “color_up” and “color_down” modifies the color of lines, while fill_up and fill_down modifies the color of rectangle fills.
range of graph, we may use coord_x_date(xlim = …) to zoom into specific sections of data. We may also set ylim = … if zooming in causes a great change in the range of y values.
Preparing for only charting a portion of data. We set the range of x.
Reseting the range of y if we adjust plotting the range of x.
reset_y_range <- meta_price_yahoo %>%
# the last 60 lines of data.
tail(60) %>%
summarise(
# max value within the selected range
max_high = max(high),
# min value within the selected range
min_low = min(low)
)
reset_y_range
## # A tibble: 1 × 2
## max_high min_low
## <dbl> <dbl>
## 1 237. 154.
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close), colour_up = "darkgreen", colour_down = "darkred",
fill_up = "darkgreen", fill_down = "darkred") +
labs(title = "META Candlestick Chart", subtitle = "Zoomed in Version", y = "Price", x = "") +
coord_x_date(xlim = c(start, end), ylim = c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
Graphing different data from different companies
concat1 <- rbind(meta_price_yahoo, aapl_price_yahoo)
concat2 <- rbind(tsla_price_yahoo, concat1)
concat3 <- rbind(uber_price_yahoo, concat2)
concat3
## # A tibble: 492 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 UBER 2022-01-03 42.5 44.4 41.9 44.0 26089000 44.0
## 2 UBER 2022-01-04 44.2 44.8 42.6 44.4 30845300 44.4
## 3 UBER 2022-01-05 44.3 45.9 42.9 43.2 28498700 43.2
## 4 UBER 2022-01-06 43.1 44.1 41.0 42.0 32434300 42.0
## 5 UBER 2022-01-07 42 42.7 41.2 41.5 24875800 41.5
## 6 UBER 2022-01-10 41.5 42.8 40.2 42.6 29783800 42.6
## 7 UBER 2022-01-11 42.4 44.2 42.2 43.6 22161000 43.6
## 8 UBER 2022-01-12 44.0 44.1 42.5 43.0 18993900 43.0
## 9 UBER 2022-01-13 43.3 43.9 42.7 42.9 17190100 42.9
## 10 UBER 2022-01-14 42.4 42.7 40.4 41.5 25817800 41.5
## # … with 482 more rows
concat3 %>%
ggplot(aes(x = date, y = close, group = symbol)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
labs(title = "Multiple Candlestick Charts",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end)) +
facet_wrap(~ symbol, ncol = 2, scale = "free_y") +
theme_tq()
Instead of zooming into specific sections using coord_x_date, we could run scale_x_date instead, which removes out-of-bounds data from charting. There is a trade off between distorting the scale of the y-axis (removing too little) and not getting a moving average (removing too much). We may call the filter() function to remove an appropriate number of days to find a balance. Examples are included in the original documentation.
Visualizing Moving Averages
Moving averages help to evaluate time-series trends, and they are applied as an added layer to a chart with geom_ma function. Different types of moving averages are available: Simple moving averages(SMA), exponential moving averages (EMA), weighted moving averages(WMA), double exponential moving averages (DEMA), zero-lag exponential moving averages (ZLEMA), volume-weighted moving averages (VWMA), and elastic volume-weighted moving averages (EVWMA).
We adapted sample code from the original documentation. We can set ma_fun argument equal to the types of moving average we want to graph and adjust the appearance by adjusting linetype, size, color, etc.
- charting moving average (SMA) - identify the trend direction of a stock.
Graph SMA over 20/40 days:
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = SMA, n = 20, linetype = 5, size = 1.25) +
geom_ma(ma_fun = SMA, n = 40, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day SMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- charting exponential moving average (EMA) - determine entry and exit points of a trade. formula: closing price * multiplier + EMA of the previous day * (1-multiplier) multiplier formula: [2/(number of days of observation+1)]
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = EMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = EMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day EMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- charting weighted moving averages (WMA) - determine trend directions and help see when to buy or sell stocks
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = WMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = WMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day WMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- charting double exponential moving averages (DEMA) - improved EMA, which removes the lag associated with moving averages by placing more weights on recent values
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = DEMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = DEMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day DEMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- charting zero-lag exponential moving averages (ZLEMA) - improved EMA, reduce lags with removed inherent lag by removing data from lag days ago
meta_price_yahoo %>%
ggplot(aes(x = date, y = open)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = ZLEMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = ZLEMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day ZLEMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- charting volume-weighted moving averages (VWMA) - weighting prices based on the amount of trading activity within the time window
meta_price_yahoo %>%
ggplot(aes(x = date, y = open, volume = volume)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = VWMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = VWMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day VWMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
- elastic volume-weighted moving averages (EVWMA) - approximate the average price paid per share. Large gaps between price and EVWMA is a signal of overbought/sold
meta_price_yahoo %>%
ggplot(aes(x = date, y = close, volume = volume)) +
geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
geom_ma(ma_fun = EVWMA, n = 20, wilder = TRUE, linetype = 5, size = 1.25) +
geom_ma(ma_fun = EVWMA, n = 40, wilder = TRUE, color = "red", size = 1.25) +
labs(title = "META Candlestick Chart",
subtitle = "20 and 40-Day EVWMA",
y = "Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
Adding Bollinger Bands
Bollinger bands are used to visualize volatility by plotting a range around a moving average two standard deviations up and down. Geom_bbands works almost identically to geom_ma. We can use color_ma, color_bands, alpha, and fill arguments to change the appearance of bollinger bands.
meta_price_yahoo %>%
# high, low, and close information are required.
ggplot(aes(x = date, y = close, open = open, high = high, low = low, close = close)) +
geom_candlestick() +
# sd = 2 by default.
geom_bbands(ma_fun = SMA, sd = 2, n = 20) +
labs(title = "META Candlestick Chart",
subtitle = "BBands with SMA",
y = "Closing Price", x = "") +
coord_x_date(xlim = c(start, end),
c(reset_y_range$min_low, reset_y_range$max_high)) +
theme_tq()
16.4 Quantmod vs. Tidyquant
16.4.1 Quantmod:
Pros-
1. Beginner friendly, no need to have knowledge of other R libraries/packages to create graphs
2. Easy syntax
3. Contains all the essential tools and indicators for traders
Cons-
1. Not flexible (for example, cannot freely edit elements on the chart, like the caption and volume number)
2. Limited functions (for example, cannot conduct data cleaning directly and cannot create multi-facet plot)
3. Limited data source connections, currently only has 3 direct online data source connections (Yahoo Finance, FRED, oanda)
16.4.2 Tidyquant:
Pros-
1. Can use tidyverse and ggplot packages, which contains functions to clean data, make tidy graphs, and implement modeling and scaling analysis
2. Contain all the quantitative analytical functions in Quantmod, xts, TTR, and PerformanceAnalytics
3. Multiple data source connections available, currently has 6 connections (Yahoo Finance, FRED, Quandl, Tiingo, Alpha Vantage, Bloomberg)
4. Flexible (since can use tidyverse and ggplot)
Cons-
1. Not beginner friendly comparing with Quantmod
2. Syntax can be complex
16.5 Sources:
-
https://cran.r-project.org/web/packages/quantmod/quantmod.pdf
-
https://www.rdocumentation.org/packages/quantmod/versions/0.4.20
-
https://www.quantmod.com/documentation/
- https://rdrr.io/cran/quantmod/
- https://cran.r-project.org/web/packages/tidyquant/vignettes/
- https://data.nasdaq.com/data/FRED-federal-reserve-economic-data/documentation
- https://www.analyticsvidhya.com/blog/2017/09/comparative-stock-analysis/
- https://www.business-science.io/code-tools/2017/03/19/tidyquant-quandl-integration.html