February 6, 2018 | by swapna |

With the increase in the market value of cryptocurrencies like bitcoin, many traders have started trading these digital coins. The most important task for a trader is to forecast a decision on whether to buy or not.

In this post, we will see how to build a simple trading strategy for trading cryptocurrency using historical OHLC(Open High Low Close) data and also backtest to evaluate the results.

Import the following libraries:

library(formatR) library(yaml) library(knitr) 1 2 3 4 library ( formatR ) library ( yaml ) library ( knitr )

Importing the data for Bitcoin Trading

Import the historical data of ethereum and subset 1-year data starting from Jan 1 2017 to Dec 31 2017.

Crypto library in R retrieves the historical market data provided by ‘Cryptocurrency Market Capitalizations’ https://coinmarketcap.com.

library(crypto) 1 2 library ( crypto )

<code>getcoins</code> function is used to get historical data of the coins.

c_data <- crypto::getCoins(coin="ethereum") data <- c_data[c_data$date>="2017-01-01"&c_data$date<="2017-12-31",] rownames(data) = c(1:nrow(data)) kable(head(data)) 1 2 3 4 5 c_data < - crypto :: getCoins ( coin = "ethereum" ) data < - c_data [ c_data $ date >= "2017-01-01" & c_data $ date <= "2017-12-31" , ] rownames ( data ) = c ( 1 : nrow ( data ) ) kable ( head ( data ) )

Candlestick charts are used to visualize the open, high, low, close prices on a day. They are one of the technical analysis tools by traders.

In r, these charts can be plot by using <code>amCandlestick</code> function of the rAmCharts library.

library(rAmCharts) library(dplyr) 1 2 3 library ( rAmCharts ) library ( dplyr )

CandlestickChart has the following components: body and shadows(also known as tails or wicks)

The top of the upper tail represents the high, bottom of the lower tail represents the low. If the body is green color filled(in the following plot) it indicates that closing price is higher than opening price, top of the body indicates closing price and the bottom of the body indicates opening price. If the body is red color filled(in the following plot) it indicates that opening price is higher than closing price, top of the body indicates opening price and the bottom of the body indicates closing price.

amCandlestick takes the data as arguments and the data must Contain minimum five columns: category, open , close , low , high

category is column with dates. So, let us add another column named category which contains dates.

data$category = data$date amCandlestick(data = data, positiveColor = "green", negativeColor = "red",dataDateFormat = "YYYY-MM-DD", minPeriod = "DD") 1 2 3 data $ category = data $ date amCandlestick ( data = data , positiveColor = "green" , negativeColor = "red" , dataDateFormat = "YYYY-MM-DD" , minPeriod = "DD" )

Build a Bitcoin Trading Strategy

The following strategy predicts whether to buy(go long) or not based on the past 3 days data. Suppose if you want to predict for 4th day collect data of first 3 days.

The following are the set of trading rules to buy:

Irrespective of the color, the body of the 3rd candlestick bar must be greater than the body of the prevoius 2 candlestick bars.

The body of second day candlestick bar must be white in color i.e., it should have open>close.

close of the 3rd day must be greater than the close of 2nd day.

If all the above 3 rules are satisfied, on the 4th day take a buy decision.

In the following code, body is a vector of close-open and abs_body is the absolute value of length of the body.

b_rule_i represents rule ith to buy.

For loop starts from 3 as we need past 3 days data to predict for 4th day and if we start from 2/1 they don’t have previous days data.

buy_Signal vector takes “1” if buy rules are satisfied otherwise “0”.

body = data$close-data$open abs_body = abs(body) close <- data$close buy_signal<-vector() for(i in 3:nrow(data)){ b_rule_1 <- ifelse(((abs_body[i]>abs_body[i-1])&(abs_body[i]>abs_body[i-2])),1,0) b_rule_2 <- ifelse((body[i-1]<0),1,0) b_rule_3 <- ifelse((close[i]>close[i-1]),1,0) buy_signal[i] <- ifelse((b_rule_1&b_rule_2&b_rule_3),1,0) } buy_signal[is.na(buy_signal)]=0 1 2 3 4 5 6 7 8 9 10 11 12 body = data $ close - data $ open abs_body = abs ( body ) close < - data $ close buy_signal < - vector ( ) for ( i in 3 : nrow ( data ) ) { b_rule_1 < - ifelse ( ( ( abs_body [ i ] > abs_body [ i - 1 ] ) & ( abs_body [ i ] > abs_body [ i - 2 ] ) ) , 1 , 0 ) b_rule_2 < - ifelse ( ( body [ i - 1 ] < 0 ) , 1 , 0 ) b_rule_3 < - ifelse ( ( close [ i ] > close [ i - 1 ] ) , 1 , 0 ) buy_signal [ i ] < - ifelse ( ( b_rule_1 & b_rule_2 & b_rule_3 ) , 1 , 0 ) } buy_signal [ is . na ( buy_signal ) ] = 0

Evaluation of the performance of our Bitcoin Trading algorithm

Backtesting the results helps in evaluating the performance of the strategy.

Determine the daily returns using quantmod’s delt function. Delt function is used to determine the percent difference.

close <- as.data.frame(data[,"close"]) rownames(close) <- data[,"date"] class(close) library(quantmod) return <- Delt(close) kable(head(return)) 1 2 3 4 5 6 7 close < - as . data . frame ( data [ , "close" ] ) rownames ( close ) < - data [ , "date" ] class ( close ) library ( quantmod ) return < - Delt ( close ) kable ( head ( return ) )

If the strategy says buy then we have to buy on the following day, so there is a lag.

trade_return <- return*Lag(buy_signal) 1 2 trade_return < - return * Lag ( buy_signal )

R has PerformanceAnalytics library which provides various functions to analyze returns data.

library(PerformanceAnalytics) 1 2 library ( PerformanceAnalytics )

Return.cumulative and Return.annualized functions are used to calculate cumulative returns and annual returns.

charts.PerformanceSummary function plts the performance of trade.

trade signal throughout the period, very selective-good hit ratio or very frequent

cumm_return <- Return.cumulative(trade_return) annual_return <- Return.annualized(trade_return) charts.PerformanceSummary(trade_return) 1 2 3 4 cumm_return < - Return . cumulative ( trade_return ) annual_return < - Return . annualized ( trade_return ) charts . PerformanceSummary ( trade_return )

Please feel free to ask for additional details on the comment section.

Note: All the strategies posted on Analytics Profile are for learning purpose. Analytics Profile does not necessarily own these strategies. In some cases, we pick useful strategies from public forums and post it here with the better explanation of use cases. Analytics Profile doesn’t intend to take credit for others work. If you find any misleading or non-reproducible content then please inform us at admin@analyticsprofile.com

Thanks,

Swapna