<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/tidyquant-bringing-quantitative-financial-analysis-to-the-tidyverse/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html"> mattdancho.com - Articles</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>My new package, <code>tidyquant</code>, is now available on CRAN. <code>tidyquant</code> integrates the best quantitative resources for collecting and analyzing quantitative data, <code>xts</code>, <code>quantmod</code> and <code>TTR</code>, with the tidy data infrastructure of the <code>tidyverse</code> allowing for seamless interaction between each. While this post aims to introduce <code>tidyquant</code> to the <em>R community</em>, it just scratches the surface of the features and benefits. We’ll go through a simple stock visualization using <code>ggplot2</code>, which which shows off the integration. The package is open source, and you can view the code on the <a target="_blank" rel="nofollow" href="https://github.com/mdancho84/tidyquant">tidyquant github page</a>.</p>
<h1>Table of Contents</h1>
<ul>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#why">Why tidyquant?</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#benefits">Benefits</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#example">Example: Visualizing Moving Averages</a>
<ul>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#step1">Step 1: Prerequisites</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#step2">Step 2: Use tq_get to get stock prices</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#step3">Step 3: Use tq_mutate to add moving averages</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#step4">Step 4: Visualize the Simple Moving Averages</a></li>
</ul>
</li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#conclusion">Conclusion</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#recap">Recap</a></li>
<li><a target="_blank" rel="nofollow" href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html#further-reading">Further Reading</a></li>
</ul>
<h1>Why tidyquant? <a></a></h1>
<p>One of the reasons why I began my journey into <em>R programming</em> is because it’s the best open-source option for stock analysis. With quantitative financial analysis (QFA) packages like <code>quantmod</code>, <code>xts</code> and <code>TTR</code>, stock data can quickly be retrieved, sliced and diced, transformed and mutated, and visualized so I can make investment decisions. It’s really a beautiful thing.</p>
<p>Over time, the <em>R programming</em> landscape has evolved. A major step forward was the <code>tidyverse</code>, a collection of <em>R packages</em> that work in harmony, are built for scale-ability, and are well documented in <a target="_blank" rel="nofollow" href="http://r4ds.had.co.nz/">R for Data Science</a>. However, a problem has surfaced: the QFA packages are not easy to use with the <code>tidyverse</code>. The <code>tidyverse</code> works with data frames while the QFA packages work with extensible time-series (<code>xts</code>) objects. Both are great, but they don’t easily work together.</p>
<p>As you can imagine, my workflow was longer than I’d like. I’d work in <code>xts</code> to use various functions to calculate moving averages, moving average convergence divergence (MACD), Bollinger Bands, etc, and then convert to tibbles (tidy dataframes) for mapping functions with <code>purrr</code> to scale to many stocks, for mutating dataframes with <code>dplyr</code> to add new columns, and for visualizing my analysis using <code>ggplot2</code>. This got very long and repetitive…</p>
<p>Enter <code>tidyquant</code>. The package started off as a collection of scripts aimed at increasing my efficiency and performance of my stock analyses:</p>
<ul>
<li>I would start by getting data with <code>tq_get()</code>, which returns data, such as stock prices or financial statements, as a <code>tibble</code> object.</li>
<li>I’d use <code>tq_transform()</code> to use the various <code>quantmod</code> and <code>xts</code> functions that can change periodicities, such as period returns and conversion from daily to monthly periodicity.</li>
<li>I’d use <code>tq_mutate()</code> to seamlessly apply the various <code>TTR</code> functions, such as moving averages, MACD’s, Bollinger Bands, etc.</li>
<li>And, I’d do all of this without ever leaving the <code>tidyverse</code>, which allowed me to mutate, pipe (<code>%>%</code>), and scale my analyses at ease.</li>
</ul>
<p>In this evolution and in the spirit of open source, I have released the <code>tidyquant</code> package to the <em>R community</em> with the hope that others can benefit from the integration between the QFA packages (<code>quantmod</code>, <code>xts</code>, and <code>TTR</code>) and the <code>tidyverse</code>. I believe this is the right way to go, and I’m looking forward to hearing your feedback.</p>
<h1>Benefits <a></a></h1>
<p><strong>The <code>tidyquant</code> philosophy:</strong></p>
<ul>
<li><strong>A few core functions with a lot of power, that</strong></li>
<li><strong>leverage the quantitative analysis power of <code>xts</code>, <code>quantmod</code> and <code>TTR</code>, and are</strong></li>
<li><strong>designed to be used and scaled with the <code>tidyverse</code>.</strong></li>
</ul>
<h1>Example: Visualizing Moving Averages <a></a></h1>
<p>I’ll go through an example of visualizing the 15-day and 50-day moving averages of the stock symbol, <em>AAPL</em>, which is for Apple Inc. Moving averages are a popular trading tool that stock analysts use to determine buying and selling signals. According to <a target="_blank" rel="nofollow" href="http://www.investopedia.com/terms/m/movingaverage.asp">Investopedia</a>, the moving average is…</p>
<blockquote>
<p>A widely used indicator in technical analysis that helps smooth out price action by filtering out the “noise” from random price fluctuations. A moving average (MA) is a trend-following or lagging indicator because it is based on past prices. The two basic and commonly used MAs are the simple moving average (SMA), which is the simple average of a security over a defined number of time periods, and the exponential moving average (EMA), which gives bigger weight to more recent prices. The most common applications of MAs are to identify the trend direction and to determine support and resistance levels. While MAs are useful enough on their own, they also form the basis for other indicators such as the Moving Average Convergence Divergence (MACD).</p>
</blockquote>
<p>Of particular interest is the crossover, the point at which a trend begins to emerge, which can be used as a buy or sell signal.</p>
<p><img alt="Moving Averages" src="https://i2.wp.com/i.investopedia.com/inv/dictionary/terms/MovingAverage2.gif?w=456" data-recalc-dims="1"></p>
<p>Source: <a target="_blank" rel="nofollow" href="http://www.investopedia.com/terms/m/movingaverage.asp">Investopedia: Moving Averages</a></p>
<p>Let’s go through an example to visualize the 15-day and 50-day moving averages for <em>AAPL</em>.</p>
<h2>Step 1: Prerequisites <a></a></h2>
<p>The <code>tidyquant</code> package can be downloaded from CRAN:</p>
<figure>
<pre><code data-lang="r"><span>install.packages</span><span>(</span><span>&quot;tidyquant&quot;</span><span>)</span></code></pre>
</figure>
<p>For those following along in <em>R</em>, you’ll need to load the following package:</p>
<figure>
<pre><code data-lang="r"><span># Loads tidyquant, tidyverse, lubridate, quantmod, TTR, and xts
</span><span>library</span><span>(</span><span>tidyquant</span><span>)</span></code></pre>
</figure>
<p>I also recommend the open-source <a target="_blank" rel="nofollow" href="https://www.rstudio.com/">RStudio</a> IDE, which makes <em>R Programming</em> easy and efficient.</p>
<h2>Step 2: Use tq_get to get stock prices <a></a></h2>
<p>We’ll start by getting the last year of stock prices. We use the tidyquant <code>tq_get()</code> function for all data retrieval. Set the parameter <code>get = &quot;stock.prices&quot;</code> to tell tidyquant we want the historical stock prices. We can use the <code>from</code> argument to pass a date as the start of the collection, which accepts character string in the form of “YYYY-MM-DD”. We can use <code>lubridate</code> functions <code>today()</code> and <code>years()</code> to get the date from one year ago.</p>
<figure>
<pre><code data-lang="r"><span>from</span><span> </span><span>&lt;-</span><span> </span><span>today</span><span>()</span><span> </span><span>-</span><span> </span><span>years</span><span>(</span><span>1</span><span>)</span><span>
</span><span>AAPL</span><span> </span><span>&lt;-</span><span> </span><span>tq_get</span><span>(</span><span>&quot;AAPL&quot;</span><span>,</span><span> </span><span>get</span><span> </span><span>=</span><span> </span><span>&quot;stock.prices&quot;</span><span>,</span><span> </span><span>from</span><span> </span><span>=</span><span> </span><span>from</span><span>)</span><span>
</span><span>AAPL</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## # A tibble: 252 × 7
##          date   open   high    low  close   volume  adjusted
##        &lt;date>  &lt;dbl>  &lt;dbl>  &lt;dbl>  &lt;dbl>    &lt;dbl>     &lt;dbl>
## 1  2016-01-04 102.61 105.37 102.00 105.35 67649400 103.05706
## 2  2016-01-05 105.75 105.85 102.41 102.71 55791000 100.47452
## 3  2016-01-06 100.56 102.37  99.87 100.70 68457400  98.50827
## 4  2016-01-07  98.68 100.13  96.43  96.45 81094400  94.35077
## 5  2016-01-08  98.55  99.11  96.76  96.96 70798000  94.84967
## 6  2016-01-11  98.97  99.06  97.34  98.53 49739400  96.38550
## 7  2016-01-12 100.55 100.69  98.84  99.96 49154200  97.78438
## 8  2016-01-13 100.32 101.19  97.30  97.39 62439600  95.27031
## 9  2016-01-14  97.96 100.48  95.74  99.52 63170100  97.35395
## 10 2016-01-15  96.20  97.71  95.36  97.13 79010000  95.01597
## # ... with 242 more rows</code></pre>
</figure>
<p>We now have 252 days of stock prices as a <code>tibble</code> object. This is exactly the format we want for working in the <code>tidyverse</code>.</p>
<h2>Step 3: Use tq_mutate to add moving averages <a></a></h2>
<p>We need to get the 15-day and 50-day moving averages. We want to use the <code>SMA()</code> function from the <code>TTR</code> package. To use any of these functions in the <code>tidyverse</code>, we have a few options with pros and cons:</p>
<ul>
<li>
<p><code>dplyr::mutate()</code>: Used to add a single column to a data set. Only able to add a single column to a tibble. For <code>SMA()</code>, this works because a single column is generated. For other functions such as <code>BBands()</code> and <code>MACD</code>, multiple columns are generated that fail on <code>mutate()</code>.</p>
</li>
<li>
<p><code>tidyquant::tq_mutate()</code>: Used to add single or multiple columns to a data set. Uses <code>quantmod</code> OHLC notation (more on this in a minute). The output generated must be the number of rows as the input dataframe (otherwise the data can’t be joined). Because multiple columns can be returned, works with <code>BBands()</code> and <code>MACD()</code>.</p>
</li>
<li>
<p><code>tidyquant::tq_transform()</code>: Used to return a new data set with output only (does not return the input dataframe). Uses OHLC notation. Most flexible option.</p>
</li>
<li>
<p><code>tidyquant::tq_mutate_xy()</code>: Same as <code>tq_mutate()</code> but works using up to two column inputs instead of OHLC notation.</p>
</li>
<li>
<p><code>tidyquant::tq_transform_xy()</code>: Same as <code>tq_transform()</code> but works using up to two column inputs instead of OHLC notation.</p>
</li>
</ul>
<p>For this tutorial, we will use <code>tq_mutate()</code> to expose you to OHLC notation along with the <code>tidyquant</code> function workflow. We’ll also show <code>tq_mutate_xy()</code> so you can see the difference in arguments.</p>
<h3>tq_mutate() function</h3>
<p><code>tq_mutate()</code> has two primary arguments: <code>x_fun</code> and <code>mutate_fun</code>:</p>
<ul>
<li>
<p><code>x_fun</code>: Takes <code>quantmod::OHLC</code> functions, which are <code>Op</code>, <code>Cl</code>, <code>Hi</code>, <code>Lo</code>, <code>Vo</code>, <code>Ad</code>, <code>HLC</code>, <code>OHLC</code>, and <code>OHLCV</code>. The OHLC notation is the basis of all <code>quantmod</code>, <code>xts</code>, and <code>TTR</code> functions. These functions collect a subset of the dataframe columns matching open, high, low, close, volume, and/or adjusted. Think of the OHLC notation akin to the <code>dplyr::select()</code> function, which selects columns. <code>Op</code> selects the column named “open”, and <code>HLC</code> selects “high”, “low” and “close” columns.</p>
</li>
<li>
<p><code>mutate_fun</code>: Takes any <code>quantmod</code>, <code>xts</code>, or <code>TTR</code> function listed in <code>tq_mutate_fun_options()</code> (see below for compatible functions). The <code>mutation_fun</code> performs the work. Any additional parameters of the passed via <code>...</code> in the <code>tq_mutate()</code> function go to the <code>mutation_fun</code>.</p>
</li>
</ul>
<figure>
<pre><code data-lang="r"><span># Get list of tq_mutate() options
</span><span>tq_mutate_fun_options</span><span>()</span><span> </span><span>%>%</span><span> </span><span>str</span><span>()</span><span> </span><span>#</span><span> </span><span>str</span><span>()</span><span> </span><span>to</span><span> </span><span>minimize</span><span> </span><span>output.</span><span> </span><span>Remove</span><span> </span><span>str</span><span>()</span><span> </span><span>to</span><span> </span><span>see</span><span> </span><span>full</span><span> </span><span>output.</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## List of 3
##  $ xts     : chr [1:27] &quot;apply.daily&quot; &quot;apply.monthly&quot; &quot;apply.quarterly&quot; &quot;apply.weekly&quot; ...
##  $ quantmod: chr [1:25] &quot;allReturns&quot; &quot;annualReturn&quot; &quot;ClCl&quot; &quot;dailyReturn&quot; ...
##  $ TTR     : chr [1:61] &quot;adjRatios&quot; &quot;ADX&quot; &quot;ALMA&quot; &quot;aroon&quot; ...</code></pre>
</figure>
<p>An example with <code>SMA()</code> from the <code>TTR</code> package helps solidify how it works. Reviewing the documentation for <code>SMA</code>, we see that the function, <code>SMA(x, n = 10, ...)</code>, accepts <code>x</code> a price or volume and <code>n</code> a number of periods to average over. For the 15-day simple moving average, we would pass a set of prices, either “close” or “adjusted”, and <code>n = 15</code> for 15 days. In OHLC notation <code>x_fun = Cl</code> for “close” or <code>x_fun = Ad</code> for adjusted. The <code>mutate_fun = SMA</code>, and we pass <code>n = 15</code> as an additional argument. Shown below, we pipe (<code>%>%</code>) our tibble of AAPL stock prices to <code>tq_mutate(x_fun = Cl, mutate_fun = SMA, n = 15)</code>, which creates an additional column with the simple moving average of the close prices.</p>
<figure>
<pre><code data-lang="r"><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate</span><span>(</span><span>x_fun</span><span> </span><span>=</span><span> </span><span>Cl</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>15</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## # A tibble: 252 × 8
##          date   open   high    low  close   volume  adjusted   SMA
##        &lt;date>  &lt;dbl>  &lt;dbl>  &lt;dbl>  &lt;dbl>    &lt;dbl>     &lt;dbl> &lt;dbl>
## 1  2016-01-04 102.61 105.37 102.00 105.35 67649400 103.05706    NA
## 2  2016-01-05 105.75 105.85 102.41 102.71 55791000 100.47452    NA
## 3  2016-01-06 100.56 102.37  99.87 100.70 68457400  98.50827    NA
## 4  2016-01-07  98.68 100.13  96.43  96.45 81094400  94.35077    NA
## 5  2016-01-08  98.55  99.11  96.76  96.96 70798000  94.84967    NA
## 6  2016-01-11  98.97  99.06  97.34  98.53 49739400  96.38550    NA
## 7  2016-01-12 100.55 100.69  98.84  99.96 49154200  97.78438    NA
## 8  2016-01-13 100.32 101.19  97.30  97.39 62439600  95.27031    NA
## 9  2016-01-14  97.96 100.48  95.74  99.52 63170100  97.35395    NA
## 10 2016-01-15  96.20  97.71  95.36  97.13 79010000  95.01597    NA
## # ... with 242 more rows</code></pre>
</figure>
<p>We need both the 15-day and the 50-day moving average, which is two steps with the pipe. I <code>rename</code> in between steps so the column names are more descriptive.</p>
<figure>
<pre><code data-lang="r"><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate</span><span>(</span><span>x_fun</span><span> </span><span>=</span><span> </span><span>Cl</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>15</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.15</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate</span><span>(</span><span>x_fun</span><span> </span><span>=</span><span> </span><span>Cl</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.50</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## # A tibble: 252 × 9
##          date   open   high    low  close   volume  adjusted SMA.15
##        &lt;date>  &lt;dbl>  &lt;dbl>  &lt;dbl>  &lt;dbl>    &lt;dbl>     &lt;dbl>  &lt;dbl>
## 1  2016-01-04 102.61 105.37 102.00 105.35 67649400 103.05706     NA
## 2  2016-01-05 105.75 105.85 102.41 102.71 55791000 100.47452     NA
## 3  2016-01-06 100.56 102.37  99.87 100.70 68457400  98.50827     NA
## 4  2016-01-07  98.68 100.13  96.43  96.45 81094400  94.35077     NA
## 5  2016-01-08  98.55  99.11  96.76  96.96 70798000  94.84967     NA
## 6  2016-01-11  98.97  99.06  97.34  98.53 49739400  96.38550     NA
## 7  2016-01-12 100.55 100.69  98.84  99.96 49154200  97.78438     NA
## 8  2016-01-13 100.32 101.19  97.30  97.39 62439600  95.27031     NA
## 9  2016-01-14  97.96 100.48  95.74  99.52 63170100  97.35395     NA
## 10 2016-01-15  96.20  97.71  95.36  97.13 79010000  95.01597     NA
## # ... with 242 more rows, and 1 more variables: SMA.50 &lt;dbl></code></pre>
</figure>
<h3>tq_mutate_xy() function</h3>
<p>Not all <code>quantmod</code>, <code>xts</code>, and <code>TTR</code> functions work with OHLC notation. A few of these functions take two primary inputs. An example of this is the <code>Delt</code> function from the <code>quantmod</code> package. The function form is <code>Delt(x1, x2 = NULL, k = 0, type = c(&quot;arithmetic&quot;, &quot;log&quot;))</code>, which has <code>x1</code> and <code>x2</code> arguments. In these situations you will need to use the XY variant, <code>tq_mutate_xy()</code>, which accepts <code>.x</code> (required) and <code>.y</code> (optional). For the <code>Delt</code> function, <code>.x = x1</code> and <code>.y = x2</code>.</p>
<p>For the <code>SMA()</code> function, we don’t need the <code>.y</code> argument, but we can use the XY variant to accomplish the same task as the OHLC variant. The operation is the same except instead of <code>x_fun = Cl</code> we replace with <code>.x = close</code> (the name of the column being passed to the mutation function).</p>
<figure>
<pre><code data-lang="r"><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate_xy</span><span>(</span><span>.x</span><span> </span><span>=</span><span> </span><span>close</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>15</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.15</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate_xy</span><span>(</span><span>.x</span><span> </span><span>=</span><span> </span><span>close</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.50</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## # A tibble: 252 × 9
##          date   open   high    low  close   volume  adjusted SMA.15
##        &lt;date>  &lt;dbl>  &lt;dbl>  &lt;dbl>  &lt;dbl>    &lt;dbl>     &lt;dbl>  &lt;dbl>
## 1  2016-01-04 102.61 105.37 102.00 105.35 67649400 103.05706     NA
## 2  2016-01-05 105.75 105.85 102.41 102.71 55791000 100.47452     NA
## 3  2016-01-06 100.56 102.37  99.87 100.70 68457400  98.50827     NA
## 4  2016-01-07  98.68 100.13  96.43  96.45 81094400  94.35077     NA
## 5  2016-01-08  98.55  99.11  96.76  96.96 70798000  94.84967     NA
## 6  2016-01-11  98.97  99.06  97.34  98.53 49739400  96.38550     NA
## 7  2016-01-12 100.55 100.69  98.84  99.96 49154200  97.78438     NA
## 8  2016-01-13 100.32 101.19  97.30  97.39 62439600  95.27031     NA
## 9  2016-01-14  97.96 100.48  95.74  99.52 63170100  97.35395     NA
## 10 2016-01-15  96.20  97.71  95.36  97.13 79010000  95.01597     NA
## # ... with 242 more rows, and 1 more variables: SMA.50 &lt;dbl></code></pre>
</figure>
<h3>Back to the example</h3>
<p>Returning back to our need, we get the simple moving averages using one of the the code options mentioned previously.</p>
<figure>
<pre><code data-lang="r"><span>AAPL</span><span> </span><span>&lt;-</span><span> </span><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate</span><span>(</span><span>x_fun</span><span> </span><span>=</span><span> </span><span>Cl</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>15</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.15</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>tq_mutate</span><span>(</span><span>x_fun</span><span> </span><span>=</span><span> </span><span>Cl</span><span>,</span><span> </span><span>mutate_fun</span><span> </span><span>=</span><span> </span><span>SMA</span><span>,</span><span> </span><span>n</span><span> </span><span>=</span><span> </span><span>50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>rename</span><span>(</span><span>SMA.50</span><span> </span><span>=</span><span> </span><span>SMA</span><span>)</span></code></pre>
</figure>
<h2>Step 4: Visualize the Simple Moving Averages <a></a></h2>
<p>We have our 15-day and 50-day simple moving averages. Now all we need to do is visualize using <code>ggplot2</code>. The format of the data will need to be tidy, which requires us to use <code>gather()</code> from the <code>tidyr</code> package to shift the close, SMA.15, and SMA.50 columns into a long form with type and price. The code and final data form is shown below.</p>
<figure>
<pre><code data-lang="r"><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>select</span><span>(</span><span>date</span><span>,</span><span> </span><span>close</span><span>,</span><span> </span><span>SMA.15</span><span>,</span><span> </span><span>SMA.50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>gather</span><span>(</span><span>key</span><span> </span><span>=</span><span> </span><span>type</span><span>,</span><span> </span><span>value</span><span> </span><span>=</span><span> </span><span>price</span><span>,</span><span> </span><span>close</span><span>:</span><span>SMA.50</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## # A tibble: 756 × 3
##          date  type  price
##        &lt;date> &lt;chr>  &lt;dbl>
## 1  2016-01-04 close 105.35
## 2  2016-01-05 close 102.71
## 3  2016-01-06 close 100.70
## 4  2016-01-07 close  96.45
## 5  2016-01-08 close  96.96
## 6  2016-01-11 close  98.53
## 7  2016-01-12 close  99.96
## 8  2016-01-13 close  97.39
## 9  2016-01-14 close  99.52
## 10 2016-01-15 close  97.13
## # ... with 746 more rows</code></pre>
</figure>
<p>Now, we can use <code>ggplot2</code> to plot the tidy data. We use the same select and gather statements above and pipe to <code>ggplot</code>. I add a custom palette to match the black, blue and red colors from the Investopedia graphic. The final code chunk for the visualization is as follows:</p>
<figure>
<pre><code data-lang="r"><span>my_palette</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;black&quot;</span><span>,</span><span> </span><span>&quot;blue&quot;</span><span>,</span><span> </span><span>&quot;red&quot;</span><span>)</span><span>
</span><span>AAPL</span><span> </span><span>%>%</span><span>
</span><span>select</span><span>(</span><span>date</span><span>,</span><span> </span><span>close</span><span>,</span><span> </span><span>SMA.15</span><span>,</span><span> </span><span>SMA.50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>gather</span><span>(</span><span>key</span><span> </span><span>=</span><span> </span><span>type</span><span>,</span><span> </span><span>value</span><span> </span><span>=</span><span> </span><span>price</span><span>,</span><span> </span><span>close</span><span>:</span><span>SMA.50</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>price</span><span>,</span><span> </span><span>col</span><span> </span><span>=</span><span> </span><span>type</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>()</span><span> </span><span>+</span><span>
</span><span>scale_colour_manual</span><span>(</span><span>values</span><span> </span><span>=</span><span> </span><span>my_palette</span><span>)</span><span> </span><span>+</span><span> </span><span>theme</span><span>(</span><span>legend.position</span><span>=</span><span>&quot;bottom&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>ggtitle</span><span>(</span><span>&quot;Simple Moving Averages are a Breeze with tidyquant&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>xlab</span><span>(</span><span>&quot;&quot;</span><span>)</span><span> </span><span>+</span><span> </span><span>ylab</span><span>(</span><span>&quot;Stock Price&quot;</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-10" src="https://i2.wp.com/www.mattdancho.com/figure/source/2017-1-1-tidyquant-introduction/unnamed-chunk-10-1.png?w=456" data-recalc-dims="1"></p>
<h1>Conclusion <a></a></h1>
<p>The <code>tidyquant</code> package integrates the three primary QFA packages, <code>quantmod</code>, <code>xts</code>, and <code>TTR</code>, with the <code>tidyverse</code>.</p>
<h1>Recap <a></a></h1>
<p>The purpose of this post was twofold:</p>
<ol>
<li>Introduce you to the <code>tidyquant</code> package</li>
<li>Show an example of the integration between the QFA packages and the <code>tidyverse</code>.</li>
</ol>
<p>We discussed why there is a need for <code>tidyquant</code>, which is to help minimize the back and forth between <code>xts</code> and <code>tibble</code> (tidy dataframes). We also went through an example of getting simple moving averages, which previously required jumping back and forth between <code>xts</code> and <code>tibble</code> objects. The <code>tidyquant</code> package made this much easier.</p>
<p>This example just scratches the surface of the power of <code>tidyquant</code>. See the vignette for a detailed discussion on each of the <code>tidyquant</code> features.</p>
<h1>Further Reading <a></a></h1>
<ol>
<li>
<p><strong><a target="_blank" rel="nofollow" href="https://github.com/mdancho84/tidyquant/blob/master/vignettes/tidyquant.md">tidyquant Vignette</a></strong>: This tutorial just scratches the surface of <code>tidyquant</code>. The vignette explains much, much more!</p>
</li>
<li>
<p><strong><a target="_blank" rel="nofollow" href="http://r4ds.had.co.nz/">R for Data Science</a></strong>: A free book that thoroughly covers the <code>tidyverse</code> packages.</p>
</li>
<li>
<p><strong><a target="_blank" rel="nofollow" href="http://www.quantmod.com/">Quantmod Website</a></strong>: Covers many of the <code>quantmod</code> functions. Also, see the <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=quantmod">quantmod vignette</a>.</p>
</li>
<li>
<p><strong><a target="_blank" rel="nofollow" href="http://joshuaulrich.github.io/xts/index.html">Extensible Time-Series Website</a></strong>: Covers many of the <code>xts</code> functions. Also, see the <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=xts">xts vignette</a>.</p>
</li>
<li>
<p><strong><a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=TTR">TTR Vignette</a></strong>: Covers each of the <code>TTR</code> functions.</p>
</li>
</ol>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.mattdancho.com/code-tools/2017/01/01/tidyquant-introduction.html"> mattdancho.com - Articles</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/-keUpD_P_fw"></a></div>