Table Of Content
In this post we’ll take a look at how a trader could use R to calculate some basic Technical Analysis indicators. R is a free open-source statistical analysis environment and programming language. It is available for Windows, Mac OS, and Linux operating systems. Installation is easy and quick. For download and installation instructions go to: http://cran.r-project.org.
When developing a trading strategy it’s useful to be able to analyze and visualize data and to be able to test your trade-generation rules and their variations and models quickly and with minimum turn-around. While many trading platforms, such as Interactive Brokers, etc.. provide access to historical data via API or straight file download – analyzing that data and prototyping trading strategies often requires writing hundreds of lines of code in programming languages such as Java or C++, or writing cumbersome difficult-to-test formulas in Excel. This requires a significant time investment, regardless of how experience programmer you are. By contrast, a higher-level programming language such as R or Matlab, coupled with their interactive programming environments, allow their users to slice, dice, and analyze data within a fraction of time it takes with C++, C#, or Java. The amount of code required to develop a trading strategy in R is typically an order of magnitude less as well.
In this example we’ll use a simple comma-separate file containing open, high, low, and close price columns (a.k.a. OHLC), along with volume and timestamp values for SPY ETF. In this post we’ll demonstrate how to use a free R library to calculate Simple Moving Average (SMA), Exponential Moving Average (EMA), Bollinger Bands (BBands), RSI, and MACD technical analysis indicators. We will append calculated indicators as new columns to our input file so that it can be used for further analysis or trading strategy prototyping in Excel, R, or any other CSV-friendly software package of your choice.
Installing Technical Analysis library for R
1. To calculate Technical Analysis with R we will be using a free open-source library called “TTR” (Technical Trading Rules). This step includes instructions for installing TTR library, assuming you already have installed R on your computer. This steps only needs to be performed once per R installation on a computer.
To install the library on your computer:
1) Start R environment on your computer, then in the menu select: Packages & Data -> Package Installer
2) In Package Installer type “TTR” in the Package Search field, and click “Get List” button.
3) Select package “TTR” and click “Install Selected”.
Loading Historical Data (Input)
For demo purposes we will use daily historical prices for SPY ETF from September 2013 through May 2014. Click here to download the data file. This input file for this example was generated using IB Historical Data Downloader.
2. We are going to start off by opening R shell and loading “TTR” library, which is a free R extension that contains functions for calculating some of the most common indicators.
3. The next step is to import our data file with historical prices into R environment. We will load data from sample CSV file into R environment and store it a “data frame”, which an R variable type for storing data in table format in memory.
> data = read.csv(file="spy_historical_data.txt")
To display first few rows of the “data” table:
This by default shows first 6 rows of data along with column names (table header). To see how many rows you have in the “data” table:
This shows we have 187 data records in our SPY data file, for 187 trading days between Sep 3, 2013 – May 31, 2014.
We can also list table column names using “colnames” functions as follows:
4. Let’s now calculate 20-day Simple Moving Average (SMA) of the CLOSE price column using TTR library’s R function “SMA”:
> sma20 < - SMA(data[c language="('CLOSE')"][/c],n=20)
Now, let’s see first 50 values of the “sma20” array:
> head(sma20, n=50)
Here we used function SMA from TTR library we loaded above, telling it to calculate 20-day average (value of parameter “n”), of the “CLOSE” column from data frame “data”. The function returns an array of SMA values and stores it in a new variable called “sma20”.
You can bring up the help with a detailed description of the function and it’s parameters using ? followed by the function name, as below. It is always a good idea to read help pages for the functions you are using, since they will list all optional parameters that you can use to tweak the output. Also, many functions have variations or related functions, which could be helpful in various circumstances and will be listed on the help page.
5. Calculating Exponential Moving Average is similarly easy, just use a different function, this time EMA(). Notice that we calculate EMA for 14-period length
6. To calculate Bollinger Bands indicator we use the BBands function. There is a number of optional parameters that it takes, so we’ll provide several examples. In the example below we call BBands passing it data frame ‘data’ with a query that specifies that we want to use values from ‘CLOSE’ column, just as we’ve been doing above to SMA and EMA calculations above. Second parameter ‘sd’ takes the number of standard deviations for upper and lower bands. Since we don’t pass value for ‘n’ – BBands uses 20-period moving average by default. The output contains several columns: ‘dn’ for “lower” band, ‘mavg’ for the moving average, ‘up’ for the “upper” band, and pctB, which quantifies a security’s price relative to the upper and lower Bollinger Band, a detailed description of it can be found here.
- %B equals 1 when price is at the upper band
- %B equals 0 when price is at the lower band
- %B is above 1 when price is above the upper band
- %B is below 0 when price is below the lower band
- %B is above .50 when price is above the middle band (20-day SMA)
- %B is below .50 when price is below the middle band (20-day SMA)
> bb20 = BBands(data, sd=2.0)
6.1 Now we’d like to create a new data frame containing all input data from the ‘data’ frame, plus Bollinger Bands data we just calculated.
> dataPlusBB = data.frame(data,bb20)
The data.frame() function takes any number of data frames and joins them row-wise into a new data frame, so that elements from corresponding rows are “joined” together in the result.
6.2 Bollinger Bands plot:
> lines(dataPlusBB$CLOSE, col = ‘red’)
> lines(dataPlusBB$up, col = ‘purple’)
> lines(dataPlusBB$dn, col = ‘brown’)
> lines(dataPlusBB$mavg, col = ‘blue’)
6.3 Alternatively, we can specify explicitly what type of moving average should be used as the basis for Bollinger Bands using function parameter ‘maType’, which simply take a moving average function name. Refer to ?SMA help page to see different types of moving averages supported in TTR library. For example, if you’d like to calculate an EMA Bollinger Bands, you can pass EMA to maType. Notice that in this example we are overriding default length parameter for moving average, using 14-period average this time.
> bbEMA = BBands(data, sd=2.0, n=14, maType=EMA)
RSI – Relative Strength Indicator
7. RSI. To calculate RSI we use the RSI() function. You can use ?RSI command in R shell to get details for the function parameters. Basically, it’s very similar to the functions we used above to generate moving averages. It has two required parameters: time series (such as ‘CLOSE’ column from our ‘data’ data frame, and ‘n’ integer value for the “length” of the RSI indicator.
> rsi14 = RSI(data, n=14)
Here the first parameter to RSI function is: data, which is a statement that says “take column named ‘CLOSE’ from the ‘data’ table, and return it as a list of values, and the second parameter is n=14, where the parameter name is ‘n’, and the value 14 indicates that we want to calculate 14-day RSI values on the close prices.
8. The MACD function takes several arguments:
- input data series (such as ‘CLOSE’ price)
- number of periods for “fast” moving average
- number of periods for “slow” moving average
- number of periods for the “signal” line
You can also optionally specify moving average function you want to use for MACD moving averages. See a screenshot of the help page below (you can also use ?MACD command in R shell to open the help page yourself):
Let’s calculate a standard (12,26,9) MACD indicator using this function. We’ll be using standard simple moving averages, so, we’ll specify SMA function in ‘maType’ parameter:
> macd = MACD(data, nFast=12, nSlow=26, nSig=9, maType=SMA)
Join All Data Together
9. Now, we join all of the indicators calculated above with the original input data into a single data frame:
> allData = data.frame(data,sma20,ema14,bb20,rsi14,macd)
The data.frame() function takes any number of data frames and joins them row-wise, so that elements from corresponding rows are “glued” together in the resulting data.frame ‘allData’.
Write to text file
And, finally, we write contents of ‘allData’ data frame to a comma-separated values file. We use write.table() function, which contains a large number of optional parameters. A detailed help page is available using command “?write.table” in R shell.
> write.table(allData, file="spy_with_indicators.csv", na="", sep=",", row.names = FALSE)
When we call write.table() function we pass the following arguments:
- allData – this is simply a reference to the data frame containing data to be written to the output file.
- file = “…” – this is the path and name of the file we are creating.
- na = “” – makes sure that cells in the data frame that contain R value “NA” will contain empty values in the output file. Some cells have NA for rows where there were not enough data to generate a corresponding indicator value (for example first 19 rows for 20-day SMA).
- sep = “,” – sets column separator to comma (hence comma-separated values file). To create a tab-separated file (really a preferred format for serious software systems) – use: sep = “\t”.
- row.names = FALSE – it is important to set this value, otherwise first column in the output file will contain row numbers.
The resulting file is available here. Right-click and select “Save Linked File As…” Downloaded file can be opened in Excel or text editor.
10. There are more functions and features available in the “TTR” library. You can find out more by bringing up TTR’s help page:
R provides a convenient and versatile environment for data analysis and calculations. In addition to thousands of free open-source statistical, mathematical libraries and algorithms, R contains a great number of functions and libraries for reading and writing data to/from files, databases, URLs, Web Services, etc… That, combined with the conciseness of the language, is a powerful combination that can help traders save precious time. Traders can significantly cut down the time required to prototype and backtest trading strategies using R. There are also methods to integrate R with mainstream programming languages such as Java and C++. Don’t hesitate to post a comment or send as a message via Contact Us form if you have any questions regarding this material.
Finally, we’d like to mention a couple of books that have been very helpful in our development efforts. The first book – “Quantitative Trading with R” is a great mix of financial data analysis insights and application of R to backtesting, data exploration, and analysis. It has a number of great code examples and goes over a number of useful R packages. This is a good intro-to-intermediate level book for people who would like to build and backtest their own trading strategies.
The second book – “Mastering R for Quantitative Finance” – is a real gem. It contains more advanced information for traders with a good understanding of derivatives instruments and stronger mathematical background. We found that this book is a great follow up for the “Quantitative Trading with R”. In addition to great R code samples and packages it contains overviews of a number of advanced (and practical!) quantitative finance models and algorithms, and lets you get your feet wet with R code straight away.
Trading Geeks provides consulting services in trading strategy and software development for independent traders, partnerships, and hedge funds. Please inquire for more information or a free quote for your project via Contact Us form on the right.