#' Back test on historical stock data
#'
#' This function is backtesting simple stochastic oscillator strategy on chosen stock data.
#' Function on its own is providing data to back tests from google finance.
#'
#' @param symbol Symbol of a stock exchange data.
#' @param initial_portfolio Initial amount of money involved in investment.
#' @param investment_size Percentage size of portfolio which will be involved in every single
#' teoretic transaction during investment period.
#' @param start_date Start date for back tests.
#' @param end_date End date for back tests.
#' @return A plot and statement for portfolio, during given period of tests.
#' @examples
#' stoch_oscilator_strategy_back_test("GOOG", 10000, 0.01, "2010-01-01", "2017-05-01")
#' stoch_oscilator_strategy_back_test("YHOO", 10000, 0.007, "2006-01-01", "2016-12-30")
#' @export
stoch_oscilator_strategy_back_test <-function(symbol, initial_portfolio, investment_size, start_date, end_date){
# tests
assertthat::assert_that(is.character(symbol))
assertthat::assert_that( !(class(try(as.Date( start_date, format = "%Y-%m-%d" ))) == "try-error" || is.na(start_date)),
msg = "start_date is incorrect, enter in the format \"%Y-%m-%d\" "
)
assertthat::assert_that( !(class(try(as.Date( end_date, format = "%Y-%m-%d" ))) == "try-error" || is.na(end_date)),
msg = "end_date is incorrect, enter in the format \"%Y-%m-%d\" "
)
assertthat::assert_that(is.numeric(initial_portfolio))
assertthat::assert_that(is.numeric(investment_size))
assertthat::assert_that(investment_size < 0.05,
msg = "investment_size has to be less then 5% of initial_portfolio because the strategy could lead to almost instant bankruptcy ")
assertthat::assert_that(investment_size > 0,
msg = "investment_size has to be positive number")
assertthat::assert_that(initial_portfolio > 5000,
msg = "initial_portfolio has to to be greater then 5000 USD because
with less capital we should not invest on the US stock market")
# get data
options(warn = -1)
data <- quantmod::getSymbols(symbol, src = "google", from = start_date, to = end_date, env = NULL)
options(warn = 1)
data <- na.omit(merge(data, TTR::stoch(quantmod::Cl(data))))
# test that the columns are in set order
assertthat::assert_that(grepl("Close",colnames(data)[4]))
# create signals according to strategy. 1 - buy, -1 - sell, 0 - outside the market
data$sig <- NA
fast_over_slow <- data$fastD > data$slowD
data$sig <- rep(0, nrow(data))
data$sig[which(diff(fast_over_slow) == 1 & data$slowD < 0.2)] <- 1
data$sig[which(diff(fast_over_slow) == -1 & data$slowD > 0.8)] <- -1
for(i in 2 : length(data$sig)){
if(data$sig[i] == 0){data$sig[i] <- data$sig[i - 1]}
}
fi.stoch <- as.numeric(data$sig)
#test that strategy vector is builded only from values: 0,1,-1
assertthat::assert_that(all(grepl("^1$", fi.stoch) | grepl("^-1$", fi.stoch) | grepl("^0$", fi.stoch)))
# count returns
returns <- as.numeric(diff(data[ , 4]))
returns <- returns[2 : length(returns)]
returns <- c(returns, 0)
# count changes in portfolio
portfolio_returns <- returns * fi.stoch * investment_size * initial_portfolio
portfolio<-initial_portfolio +cumsum(portfolio_returns)
# plot porfolio over during period
plot(portfolio, type="l", xlab="Investment day", main = "Account balance")
# print statements
print(paste("At the end of investment period, portfolio value is equal to: ", round(portfolio[length(portfolio)])))
print(paste("During the investment period, the portfolio achieves the lowest value at the level of: ", round(min(portfolio))))
print(paste("During the investment period, the portfolio achieves the highest value at the level of: ", round(max(portfolio))))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.