Skip to content

Instantly share code, notes, and snippets.

@bestdan
Last active March 12, 2016 19:07
Show Gist options
  • Save bestdan/8a10aa43e3b881484841 to your computer and use it in GitHub Desktop.
Save bestdan/8a10aa43e3b881484841 to your computer and use it in GitHub Desktop.
rm(list=ls())
library(quantmod)
library(lubridate)
library(PerformanceAnalytics)
#' Required 'drawdown' size
#' Default: -6% return
drawdownHurdle<- -0.06
# Grab data -----------------------------------------------------------------------------------
sp500<- getSymbols("^GSPC", from="1950-01-01", auto.assign=FALSE)
sp500$returns<- dailyReturn(sp500)
# Find all potential ‘dips’? -----------------------------------------------------------------
allDrawdowns<- table.Drawdowns(R = sp500$returns,top = 1000)
allDrawdowns<- allDrawdowns[allDrawdowns$Depth<= -drawdownHurdle,]
head(allDrawdowns)
# Convert to DataFrame -----------------------------------------------------------------
sp500<- as.data.frame(sp500)
sp500$date<- as.Date(row.names(sp500))
sp500<- sp500[,c("date","returns")]
head(sp500)
sp500$dip<- 0
for(i in 1:nrow(allDrawdowns)) {
indexer<- which(sp500$date > allDrawdowns$From[i] & sp500$date < allDrawdowns$Trough[i])
sp500$dip[indexer]<- 1
}
table(sp500$dip)
# Deposits ------------------------------------------------------------------------------------
deposit<- 500
sp500$deposits<- ifelse(day(sp500$date) < c(NA,day(sp500$date[-length(sp500$date)])), deposit,0)
sp500$deposits[1]<- 0
sum(sp500$deposits)
calcFinalBalance<- function(returns,deposits) {
depositIndex<- as.numeric(which(deposits>0))
returns<- as.numeric(returns)
finalBalance<- 0
for(thisDeposit in depositIndex) {
thisReturns<- returns[thisDeposit:length(returns)]
cumulativeReturn<- tail(cumprod(thisReturns+1),1)
value<- cumulativeReturn * as.numeric(deposits[thisDeposit])
finalBalance<- finalBalance+value
rm(value)
}
return(finalBalance)
}
default_FinalBalance<- calcFinalBalance(sp500$returns,sp500$deposits)
default_growth<- default_FinalBalance/sum(sp500$deposits)
# Buy On Dips Only ----------------------------------------------------------------------------
#' A person holds cash until they both have cash, and are in a dip.
sp500$cash<- 0
sp500$invest<- 0
for(i in 2:nrow(sp500)) {
#' Simulate getting cash.
#' Note this is an accumulating function.
if(sp500$deposits[i] > 0) {
sp500$cash[i]<- sp500$cash[(i-1)] + sp500$deposits[i]
} else {
sp500$cash[i]<- sp500$cash[(i-1)]
}
#Simulate new investment decision
if(sp500$dip[i] ==1) {
sp500$invest[i]<- sp500$cash[i]
#' Reset Cash to zero
sp500$cash[i]<- 0
}
}
sum(sp500$invest)
sum(sp500$deposits)
buyOnDips_FinalBalance<- calcFinalBalance(sp500$returns,sp500$invest)
buyOnDips_growth<- buyOnDips_FinalBalance/sum(sp500$deposits)
# Results: -----------------------------------------------------------------------------------
options(scipen=10)
default_FinalBalance
buyOnDips_FinalBalance
formatC(default_FinalBalance - buyOnDips_FinalBalance,format = "f" ,digits=0,big.mark = ",",)
default_growth
buyOnDips_growth
default_growth-buyOnDips_growth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment