Objectives

The objectives of this analysis is as follows.
1. Ability to pull down Stock Data from Yahoo Finance using the Quantmod Package.
2. Ability to quickly calculate daily returns on chosen Stocks.
3. Ability to create a Buy Signal using a Technical Indicator (RSI)
4. Practice building graphs to see how well the Signal performed against other signals.

RSI

The relative strength index was created by J. Welles Wilder Jr. in the late 1970s; his “New Concepts in Trading Systems” (1978) is now an investment-lit classic. On a chart, RSI assigns stocks a value between 0 and 100. Once these numbers are charted, analysts compare them against other factors, such as the undersold or underbought values. To reach the best evaluation, experts generally chart the RSI on a daily time frame rather than hourly. However, sometimes shorter hourly periods are charted to indicate whether it is a good idea to make a short-term asset purchase.

Mathematically,

RSI = 100 − (100 / (1+RS))
RS = Average of x days’ down closes / Average of x days’ up closes

where:
RSI = relative strength index

Load Packages


We are going to use the following R packages for this analysis.
1. PerformanceAnalytics
PerformanceAnalytics is a library of functions designed for evaluating the performance and risk characteristics of nancial assets or funds.

2. quantmod - package to full stock data from Yahoo finance
3. tidyverse - for data manipulation and plotting

Base Model Building

Data Fetch and Wrangling

We are going to fetch Microsoft Corporation Stock data from Yahoo Finance. We will fetch it from 03 Jan 2007 to the day of analysis,i.e, 22 June 2020.
More information on the stock data can be accessed via https://in.finance.yahoo.com/quote/MSFT?p=MSFT&.tsrc=fin-srch

# fetch Microsoft stock data from yahoo finance
quantmod::getSymbols("MSFT")
[1] "MSFT"
# First 6 entries of the data
head(MSFT)
           MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume
2007-01-03     29.91     30.25    29.40      29.86    76935100
2007-01-04     29.70     29.97    29.44      29.81    45774500
2007-01-05     29.63     29.75    29.45      29.64    44607200
2007-01-08     29.65     30.10    29.53      29.93    50220200
2007-01-09     30.00     30.18    29.73      29.96    44636600
2007-01-10     29.80     29.89    29.43      29.66    55017400
           MSFT.Adjusted
2007-01-03      22.12369
2007-01-04      22.08664
2007-01-05      21.96068
2007-01-08      22.17555
2007-01-09      22.19778
2007-01-10      21.97551
# Structure of the data
str(MSFT)
An 'xts' object on 2007-01-03/2020-06-22 containing:
  Data: num [1:3391, 1:6] 29.9 29.7 29.6 29.6 30 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:6] "MSFT.Open" "MSFT.High" "MSFT.Low" "MSFT.Close" ...
  Indexed by objects of class: [Date] TZ: UTC
  xts Attributes:  
List of 2
 $ src    : chr "yahoo"
 $ updated: POSIXct[1:1], format: "2020-06-23 20:39:40"
summary(MSFT)
     Index              MSFT.Open        MSFT.High         MSFT.Low     
 Min.   :2007-01-03   Min.   : 15.20   Min.   : 15.62   Min.   : 14.87  
 1st Qu.:2010-05-15   1st Qu.: 27.97   1st Qu.: 28.25   1st Qu.: 27.76  
 Median :2013-09-26   Median : 35.51   Median : 35.73   Median : 34.91  
 Mean   :2013-09-26   Mean   : 53.75   Mean   : 54.26   Mean   : 53.22  
 3rd Qu.:2017-02-07   3rd Qu.: 64.10   3rd Qu.: 64.42   3rd Qu.: 63.69  
 Max.   :2020-06-22   Max.   :198.59   Max.   :200.76   Max.   :195.23  
   MSFT.Close      MSFT.Volume        MSFT.Adjusted   
 Min.   : 15.15   Min.   :  7425600   Min.   : 11.67  
 1st Qu.: 28.00   1st Qu.: 27074550   1st Qu.: 21.93  
 Median : 35.44   Median : 40528900   Median : 29.94  
 Mean   : 53.76   Mean   : 46721110   Mean   : 49.25  
 3rd Qu.: 64.03   3rd Qu.: 58292000   3rd Qu.: 60.61  
 Max.   :200.57   Max.   :319317900   Max.   :200.57  
# get Close price
price <- quantmod::Cl(MSFT)
head(price)
           MSFT.Close
2007-01-03      29.86
2007-01-04      29.81
2007-01-05      29.64
2007-01-08      29.93
2007-01-09      29.96
2007-01-10      29.66
# Calcluate Percentage price change - Returns
r <- price / quantmod::Lag(price) - 1
head(r)
             MSFT.Close
2007-01-03           NA
2007-01-04 -0.001674548
2007-01-05 -0.005702784
2007-01-08  0.009784110
2007-01-09  0.001002305
2007-01-10 -0.010013318
# Threshold value
delta <- 0.005

signal <- c(0) #first date has no signal

# Loop over all trading days except the first and assign buy signals(1) or no-buy signal(0)
for( i in 2:length(price)){
  if(r[i] > delta){
    signal[i] <- 1
  } else
    signal[i] <- 0
}

head(signal)
[1] 0 0 0 1 0 0
# remap the buy/no buy signals to corrosponding date
signal <- xts::reclass(signal, price)
head(signal)
           [,1]
2007-01-03    0
2007-01-04    0
2007-01-05    0
2007-01-08    1
2007-01-09    0
2007-01-10    0
tail(signal, n = 20)
           [,1]
2020-05-26    0
2020-05-27    0
2020-05-28    0
2020-05-29    1
2020-06-01    0
2020-06-02    1
2020-06-03    0
2020-06-04    0
2020-06-05    1
2020-06-08    1
2020-06-09    1
2020-06-10    1
2020-06-11    0
2020-06-12    1
2020-06-15    1
2020-06-16    1
2020-06-17    0
2020-06-18    1
2020-06-19    0
2020-06-22    1

Calculate Return when filter says Buy

# Lagging the Buy signal by one day
trade <- quantmod::Lag(signal,1)
head(trade)
           Lag.1
2007-01-03    NA
2007-01-04     0
2007-01-05     0
2007-01-08     0
2007-01-09     1
2007-01-10     0
# Get returns for days that only have a Buy signal
# calculate returns * buy signal
ret <- quantmod::dailyReturn(MSFT) * trade
head(ret)
           daily.returns
2007-01-03            NA
2007-01-04   0.000000000
2007-01-05   0.000000000
2007-01-08   0.000000000
2007-01-09   0.001002305
2007-01-10   0.000000000
# Change the column name
names(ret) <- "filter"

# Plot graphs
PerformanceAnalytics::charts.PerformanceSummary(ret, main = "Simple Filter")

RSI based Model

The Relative Strength Index (RSI) calculates a ratio of the recent upward price movements to the absolute price movemen.

How this RSI works.
RSI is considered overbought when above 70 and oversold when below 30. These traditional levels can also be adjusted if necessary to better fit the security. For example, if a security is repeatedly reaching the overbought level of 70 you may want to adjust this level to 80.
Note: During strong trends, the RSI may remain in overbought or oversold for extended periods.

RSI also often forms chart patterns that may not show on the underlying price chart, such as double tops and bottoms and trend lines. Also, look for support or resistance on the RSI.
In an uptrend or bull market, the RSI tends to remain in the 40 to 90 range with the 40-50 zone acting as support. During a downtrend or bear market the RSI tends to stay between the 10 to 60 range with the 50-60 zone acting as resistance. These ranges will vary depending on the RSI settings and the strength of the security’s or market’s underlying trend.
If underlying prices make a new high or low that isn’t confirmed by the RSI, this divergence can signal a price reversal. If the RSI makes a lower high and then follows with a downside move below a previous low, a Top Swing Failure has occurred. If the RSI makes a higher low and then follows with an upside move above a previous high, a Bottom Swing Failure has occurred.

Source: https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI#:~:text=The%20Relative%20Strength%20Index%20(RSI,and%20oversold%20when%20below%2030.

# 14 day rsi
day <- 14
# get close price of stock
price <- quantmod::Cl(MSFT)
head(price,10)
           MSFT.Close
2007-01-03      29.86
2007-01-04      29.81
2007-01-05      29.64
2007-01-08      29.93
2007-01-09      29.96
2007-01-10      29.66
2007-01-11      30.70
2007-01-12      31.21
2007-01-16      31.16
2007-01-17      31.10
str(price)
An 'xts' object on 2007-01-03/2020-06-22 containing:
  Data: num [1:3391, 1] 29.9 29.8 29.6 29.9 30 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr "MSFT.Close"
  Indexed by objects of class: [Date] TZ: UTC
  xts Attributes:  
List of 2
 $ src    : chr "yahoo"
 $ updated: POSIXct[1:1], format: "2020-06-23 20:39:40"
signal <- c(0)

# Calculate RSI
rsi <- RSI(price, day)
head(rsi, 50)
                rsi
2007-01-03       NA
2007-01-04       NA
2007-01-05       NA
2007-01-08       NA
2007-01-09       NA
2007-01-10       NA
2007-01-11       NA
2007-01-12       NA
2007-01-16       NA
2007-01-17       NA
2007-01-18       NA
2007-01-19       NA
2007-01-22       NA
2007-01-23       NA
2007-01-24 67.72331
2007-01-25 56.50083
2007-01-26 58.24718
2007-01-29 57.09522
2007-01-30 56.23961
2007-01-31 61.02044
2007-02-01 55.83426
2007-02-02 50.17079
2007-02-05 42.83575
2007-02-06 41.70365
2007-02-07 40.10560
2007-02-08 38.84604
2007-02-09 35.76682
2007-02-12 35.33591
2007-02-13 36.77155
2007-02-14 44.20416
2007-02-15 45.27007
2007-02-16 36.30663
2007-02-20 37.96022
2007-02-21 46.58835
2007-02-22 47.19668
2007-02-23 41.03144
2007-02-26 43.77555
2007-02-27 32.33649
2007-02-28 36.78393
2007-03-01 36.10246
2007-03-02 33.35717
2007-03-05 31.70495
2007-03-06 36.23970
2007-03-07 34.31193
2007-03-08 31.90279
2007-03-09 31.65518
2007-03-12 34.39688
2007-03-13 28.48915
2007-03-14 39.12352
2007-03-15 38.04822
signal[1:day + 1] <- 0

# Traditionally the RSI is considered overbought when above 70 and oversold when below 30.
# Loop over all trading days to create signal
for(i in (day + 1):length(price)){
  if(rsi[i] < 50){
    signal[i] <- 1
  } else
    signal[i] <- 0
}


# remap the buy/no buy signals to corrosponding date
signal <- xts::reclass(signal, price)

# Lagging the Buy signal by one day
trade2 <- quantmod::Lag(signal,1)
head(trade2)
           Lag.1
2007-01-03    NA
2007-01-04     0
2007-01-05     0
2007-01-08     0
2007-01-09     0
2007-01-10     0
# Get returns for days that only have a Buy signal
# calculate returns * buy signal
ret2 <- quantmod::dailyReturn(MSFT) * trade2
head(ret2)
           daily.returns
2007-01-03            NA
2007-01-04             0
2007-01-05             0
2007-01-08             0
2007-01-09             0
2007-01-10             0
# Change the column name
names(ret) <- "Simple"
names(ret2) <- "RSI"

# Combining both simple and RSI returns
retcomb <- cbind(ret, ret2)
head(retcomb, 200)
                  Simple           RSI
2007-01-03            NA            NA
2007-01-04  0.0000000000  0.0000000000
2007-01-05  0.0000000000  0.0000000000
2007-01-08  0.0000000000  0.0000000000
2007-01-09  0.0010023054  0.0000000000
2007-01-10  0.0000000000  0.0000000000
2007-01-11  0.0000000000  0.0000000000
2007-01-12  0.0166123122  0.0000000000
2007-01-16 -0.0016020186  0.0000000000
2007-01-17  0.0000000000  0.0000000000
2007-01-18  0.0000000000  0.0000000000
2007-01-19  0.0000000000  0.0000000000
2007-01-22  0.0000000000  0.0000000000
2007-01-23  0.0000000000  0.0000000000
2007-01-24  0.0000000000  0.0000000000
2007-01-25 -0.0205853651  0.0000000000
2007-01-26  0.0000000000  0.0000000000
2007-01-29  0.0000000000  0.0000000000
2007-01-30  0.0000000000  0.0000000000
2007-01-31  0.0000000000  0.0000000000
2007-02-01 -0.0097213866  0.0000000000
2007-02-02  0.0000000000  0.0000000000
2007-02-05  0.0000000000  0.0000000000
2007-02-06  0.0000000000 -0.0033772711
2007-02-07  0.0000000000 -0.0047441206
2007-02-08  0.0000000000 -0.0037453523
2007-02-09  0.0000000000 -0.0095693780
2007-02-12  0.0000000000 -0.0013802277
2007-02-13  0.0000000000  0.0024187629
2007-02-14  0.0000000000  0.0134436401
2007-02-15  0.0020407823  0.0020407823
2007-02-16  0.0000000000 -0.0244398854
2007-02-20  0.0000000000  0.0031315240
2007-02-21  0.0000000000  0.0180367673
2007-02-22  0.0013628279  0.0013628279
2007-02-23  0.0000000000 -0.0166723041
2007-02-26  0.0000000000  0.0058823529
2007-02-27 -0.0412796354 -0.0412796354
2007-02-28  0.0000000000  0.0107642264
2007-03-01 -0.0028399006 -0.0028399006
2007-03-02  0.0000000000 -0.0117479530
2007-03-05  0.0000000000 -0.0075648775
2007-03-06  0.0000000000  0.0101633760
2007-03-07 -0.0079051024 -0.0079051024
2007-03-08  0.0000000000 -0.0105034766
2007-03-09  0.0000000000 -0.0010980600
2007-03-12  0.0000000000  0.0054965187
2007-03-13 -0.0262391390 -0.0262391390
2007-03-14  0.0000000000  0.0254491402
2007-03-15 -0.0043795255 -0.0043795255
2007-03-16  0.0000000000  0.0018328079
2007-03-19  0.0000000000  0.0182949140
2007-03-20  0.0003593245  0.0003593245
2007-03-21  0.0000000000  0.0244252874
2007-03-22 -0.0087657784  0.0000000000
2007-03-23  0.0000000000  0.0000000000
2007-03-26  0.0000000000  0.0071377231
2007-03-27 -0.0177179312  0.0000000000
2007-03-28  0.0000000000 -0.0028860030
2007-03-29  0.0000000000  0.0039797758
2007-03-30  0.0000000000  0.0043243604
2007-04-02  0.0000000000 -0.0046645495
2007-04-03  0.0000000000  0.0046864095
2007-04-04  0.0000000000  0.0226049149
2007-04-05  0.0017543509  0.0000000000
2007-04-09  0.0000000000  0.0000000000
2007-04-10  0.0000000000  0.0000000000
2007-04-11  0.0000000000  0.0000000000
2007-04-12  0.0000000000  0.0152970468
2007-04-13  0.0024526979  0.0000000000
2007-04-16  0.0000000000  0.0000000000
2007-04-17  0.0000000000  0.0000000000
2007-04-18  0.0000000000  0.0000000000
2007-04-19  0.0000000000  0.0000000000
2007-04-20  0.0000000000  0.0000000000
2007-04-23 -0.0082701241  0.0000000000
2007-04-24  0.0000000000  0.0000000000
2007-04-25  0.0000000000  0.0000000000
2007-04-26  0.0037944119  0.0000000000
2007-04-27  0.0000000000  0.0000000000
2007-04-30 -0.0059760954  0.0000000000
2007-05-01  0.0000000000  0.0000000000
2007-05-02  0.0069079276  0.0000000000
2007-05-03  0.0117607967  0.0000000000
2007-05-04 -0.0132386184  0.0000000000
2007-05-07  0.0000000000  0.0000000000
2007-05-08  0.0000000000  0.0000000000
2007-05-09  0.0000000000  0.0000000000
2007-05-10  0.0000000000  0.0000000000
2007-05-11  0.0000000000  0.0000000000
2007-05-14  0.0025898350  0.0000000000
2007-05-15  0.0000000000  0.0000000000
2007-05-16  0.0000000000  0.0000000000
2007-05-17 -0.0028966849  0.0000000000
2007-05-18  0.0000000000  0.0000000000
2007-05-21  0.0000000000  0.0000000000
2007-05-22 -0.0115941389  0.0000000000
2007-05-23  0.0000000000  0.0000000000
2007-05-24  0.0000000000  0.0000000000
2007-05-25  0.0000000000  0.0102751077
2007-05-29  0.0101706365  0.0000000000
2007-05-30  0.0103929844  0.0000000000
2007-05-31 -0.0135004817  0.0000000000
2007-06-01  0.0000000000  0.0000000000
2007-06-04  0.0000000000  0.0000000000
2007-06-05  0.0000000000  0.0000000000
2007-06-06  0.0000000000  0.0000000000
2007-06-07  0.0000000000 -0.0221195107
2007-06-08  0.0000000000  0.0145171501
2007-06-11 -0.0009983029 -0.0009983029
2007-06-12  0.0000000000 -0.0056628914
2007-06-13  0.0000000000  0.0180904188
2007-06-14  0.0042777560  0.0000000000
2007-06-15  0.0000000000  0.0000000000
2007-06-18  0.0000000000  0.0000000000
2007-06-19  0.0000000000  0.0000000000
2007-06-20  0.0000000000  0.0000000000
2007-06-21  0.0000000000  0.0069976341
2007-06-22 -0.0241561557 -0.0241561557
2007-06-25  0.0000000000  0.0000000000
2007-06-26  0.0000000000  0.0010172940
2007-06-27  0.0000000000  0.0118564024
2007-06-28 -0.0013391697 -0.0013391697
2007-06-29  0.0000000000 -0.0120684211
2007-07-02  0.0000000000  0.0091618938
2007-07-03  0.0094149294  0.0094149294
2007-07-05 -0.0009993338 -0.0009993338
2007-07-06  0.0000000000 -0.0006669223
2007-07-09  0.0000000000 -0.0033366034
2007-07-10  0.0000000000 -0.0180783723
2007-07-11  0.0000000000  0.0054551654
2007-07-12  0.0196676840  0.0196676840
2007-07-13 -0.0083139342  0.0000000000
2007-07-16  0.0000000000  0.0070422871
2007-07-17  0.0249750241  0.0000000000
2007-07-18  0.0045483754  0.0000000000
2007-07-19  0.0000000000  0.0000000000
2007-07-20 -0.0111075849  0.0000000000
2007-07-23  0.0000000000  0.0000000000
2007-07-24  0.0000000000  0.0000000000
2007-07-25  0.0000000000  0.0000000000
2007-07-26  0.0000000000  0.0000000000
2007-07-27  0.0000000000 -0.0196798199
2007-07-30  0.0000000000  0.0003402858
2007-07-31  0.0000000000 -0.0139455782
2007-08-01  0.0000000000  0.0106933080
2007-08-02  0.0075085668  0.0075085668
2007-08-03 -0.0189702236 -0.0189702236
2007-08-06  0.0000000000  0.0200276941
2007-08-07  0.0003384563  0.0003384563
2007-08-08  0.0000000000  0.0152284608
2007-08-09 -0.0233333667  0.0000000000
2007-08-10  0.0000000000 -0.0201365195
2007-08-13  0.0000000000 -0.0027864856
2007-08-14  0.0000000000 -0.0125741884
2007-08-15  0.0000000000 -0.0060134418
2007-08-16  0.0000000000 -0.0103203203
2007-08-17  0.0000000000  0.0158216834
2007-08-20  0.0003539823  0.0003539823
2007-08-21  0.0000000000 -0.0067232838
2007-08-22  0.0000000000  0.0053437478
2007-08-23  0.0028348690  0.0028348690
2007-08-24  0.0000000000  0.0180212021
2007-08-27 -0.0111072201 -0.0111072201
2007-08-28  0.0000000000 -0.0196560197
2007-08-29  0.0000000000  0.0236305048
2007-08-30 -0.0048967821 -0.0048967821
2007-08-31  0.0000000000  0.0098417923
2007-09-04  0.0027845110  0.0027845110
2007-09-05  0.0000000000 -0.0114543218
2007-09-06  0.0000000000  0.0150983146
2007-09-07 -0.0162573158  0.0000000000
2007-09-10  0.0000000000  0.0014064345
2007-09-11  0.0000000000  0.0158005618
2007-09-12  0.0000000000  0.0000000000
2007-09-13  0.0000000000  0.0000000000
2007-09-14 -0.0041151920  0.0000000000
2007-09-17  0.0000000000  0.0000000000
2007-09-18  0.0000000000  0.0069613644
2007-09-19 -0.0089872105  0.0000000000
2007-09-20  0.0000000000 -0.0087199163
2007-09-21  0.0000000000  0.0080928923
2007-09-24  0.0150087260  0.0150087260
2007-09-25  0.0165061554  0.0000000000
2007-09-26 -0.0020297362  0.0000000000
2007-09-27  0.0000000000  0.0000000000
2007-09-28  0.0000000000  0.0000000000
2007-10-01  0.0000000000  0.0000000000
2007-10-02 -0.0023513268  0.0000000000
2007-10-03  0.0000000000  0.0000000000
2007-10-04  0.0000000000  0.0000000000
2007-10-05  0.0043756649  0.0000000000
2007-10-08  0.0000000000  0.0000000000
2007-10-09  0.0000000000  0.0000000000
2007-10-10  0.0043189369  0.0000000000
2007-10-11  0.0000000000  0.0000000000
2007-10-12  0.0000000000  0.0000000000
2007-10-15 -0.0043088830  0.0000000000
2007-10-16  0.0000000000  0.0000000000
2007-10-17  0.0250659631  0.0000000000
# Plot graphs
PerformanceAnalytics::charts.PerformanceSummary(retcomb, main = "Simple Filter Vs RSI Filter")

A drawdown is a peak-to-trough decline during a specific period for an investment, trading account, or fund. A drawdown is usually quoted as the percentage between the peak and the subsequent trough.

In Simple Words, The drawdown is the measure of the decline from a historical peak in some variable (typically the cumulative profit or total open equity of a financial trading strategy)

Drawdowns are important for measuring the historical risk of different investments, comparing fund performance, or monitoring personal trading performance.

Conclusion

We can observe that our RSI model was a better indicator for trading than our Simple trading model built initially.