You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We find some stocks seem reverting around a trend line, although stock price movement is complex. We notice the price of a stock in the short term can deviate from its long-term trend line. The long-term trend can be characterized by a moving average line or a regression. We often find the short-term prices deviate and then reverts back to the regression line. Of various combinations of stock trading strategies, a common type of trading stategies is the mean reversion. It identifies anomalous opportunities as the entry or exit points. This strategy has been quite popular among traders.
# The easiest way to get dplyr is to install the whole tidyverse:
library(tidyverse) # https://www.tidyverse.org/
library(dplyr) # or just dplyr
library(quantmod)
library(TTR)
library(PerformanceAnalytics)
library("IRdisplay")
getSymbols(c("AMZN","DAL"))
‘getSymbols’ currently uses auto.assign=TRUE by default, but will
use auto.assign=FALSE in 0.5-0. You will still be able to use
‘loadSymbols’ to automatically load data. getOption("getSymbols.env")
and getOption("getSymbols.auto.assign") will still be checked for
alternate defaults.
This message is shown once per session and may be disabled by setting
options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
Learning objective 2: Common stock data transformation
These common stock data transformation can be handled easily by the functions in the quantmod library
df2<-df# Returns from Open to Close, Hi to Close, or Close to Close df2$OpCl<- OpCl(df2)
df2$OpOp<- OpOp(df2)
df2$HiCl<- HiCl(df2)
df2$ClCl<- ClCl(df2)
df2$pcntOpCl1<- Delt(Op(df2),Cl(df2),k=1)
df2$pcntOpCl2<- Delt(Op(df2),Cl(df2),k=2)
df2$pcntOpCl3<- Delt(Op(df2),Cl(df2),k=3)
#One period lag of the close df2$lagCl<- Lag(Cl(df2))
df2$lag2Cl<- Lag(Cl(df2),2)
df2$lag3Cl<- Lag(Cl(df2),3)
# Move up the OpCl by one perioddf2$nextOpCl<- Next(OpCl(df2))
#head(df2)
rtn.daily<- dailyReturn(df) # returns by day rtn.weekly<- weeklyReturn(df) # returns by week rtn.monthly<- monthlyReturn(df) # returns by month, indexed by yearmon # daily,weekly,monthly,quarterly, and yearly rtn.allperiods<- allReturns(df) # note the plural
head(rtn.daily)
Learning objective 3: The basic characteristics of stock returns
A standard normal distribution has 0 mean, 1 standard deviation, and 0 excess kurtosis
The ditribution of a typical stock returns has small standard deviation and positive excess kurtosis
# Generate a standard normal distributionrn<- rnorm(100000)
print(paste0("standard deviation: ", sd(rn)))
print(paste0("Kurtosis: ", round(kurtosis(rn),2)))
options(repr.plot.width=4, repr.plot.height=4)
#hist(rn,breaks=100,prob=TRUE)#curve(dnorm(x, mean=0, sd=1), col="darkblue", lwd=2, add=TRUE ) # Overlay a standard normal distribution
print(paste0("standard deviation: ", sd(rtn.daily)))
print(paste0("Kurtosis: ", round(kurtosis(rtn.daily),2)))
options(repr.plot.width=4, repr.plot.height=4)
m<-mean(rtn.daily)
std<-sqrt(var(rtn.daily))
m# Overlay a standard normal distribution#curve(dnorm(x, mean=m, sd=std), col="darkblue", lwd=2, add=TRUE )#hist(rtn.daily, breaks=100, prob=TRUE) # Make it a probability distribution
MACD=12-Period EMA − 26-Period EMA, or "fast EMA - slow FMA"
The MACD was developed by Gerald Appel and is probably the most popular price oscillator.
It can be used as a generic oscillator for any univariate series, not only price.
The MACD has a positive value whenever the 12-period EMA is above the 26-period EMA and a negative value when the 12-period EMA is below the 26-period EMA. The more distant the MACD is above or below its baseline indicates that the distance between the two EMAs is growing.
RSI
Introduced by Welles Wilder Jr. in his seminal 1978 book "New Concepts in Technical Trading Systems", the relative strength index (RSI) is a popular momentum indicator.
It measures the magnitude of recent price changes to evaluate overbought or oversold conditions.
The RSI is displayed as an oscillator and can have a reading from 0 to 100.
RSI >= 70: a security is overbought or overvalued and may be primed for a trend reversal or corrective pullback in price.
RSI <= 30: an oversold or undervalued condition.
It can be used in the price of a stock or other asset.
Bollinger Bands
Bollinger Bands are a type of price envelope developed by John Bollinger
Bollinger Bands are envelopes plotted at a standard deviation level above and below a simple moving average of the price. Because the distance of the bands is based on standard deviation, they adjust to volatility swings in the underlying price.
Bollinger Bands use 2 parameters, Period and Standard Deviations, StdDev. The default values are 20 for period, and 2 for standard deviations, although you may customize the combinations.
Bollinger bands help determine whether prices are high or low on a relative basis. They are used in pairs, both upper and lower bands and in conjunction with a moving average. Further, the pair of bands is not intended to be used on its own. Use the pair to confirm signals given with other indicators.
"Distance from a moving average" or "standard deviation" apply the same concept
macd<- MACD(AMZN$AMZN.Adjusted, nFast=12, nSlow=26, nSig=9, maType="SMA", percent=FALSE)
rsi<- RSI(AMZN$AMZN.Adjusted, n=14, maType="SMA")
# Strategy 1: if macd>signal, enter and stay in the market. If macd<signal, exit the market.strategy1<- ifelse ((macd$signal<macd$macd) , 1, 0)
strategy1[is.na(strategy1)] <-0# Strategy 2: if overbought, enter and stay in the market.strategy2<- ifelse ((macd$signal<macd$macd) & (rsi$rsi>70), 1, 0)
strategy2[is.na(strategy2)] <-0# Strategy 3: if oversold, enter and stay in the market.strategy3<- ifelse ((macd$signal>macd$macd) & (rsi$rsi<30), 1, 0)
strategy3[is.na(strategy3)] <-0# Buy-and-hold: keep it all time. So "1", not "0"bh_strategy<- rep(1,dim(macd)[1])
Learning objective 7: Backtesting
Annualized return
An annualized total return is the average amount earned by an investment each year over a given time period.
Usually, any Sharpe ratio greater than 1.0 is considered acceptable to good by investors. A ratio higher than 2.0 is rated as very good. A ratio of 3.0 or higher is considered excellent. A ratio under 1.0 is considered sub-optimal.
"Lag": Since we are working with Closing prices, we can BUY or SELL on our signal the next day only