Hi list,
I am running R on windows, via R studio with all the packages I require
currently up to date.
In an effort to create a softly adaptive trading system I am trying to code a
custom indicator that returns some statistics about how the strategy would have
performed if run over the previous preceding x number of days. i.e. the
indicator performs a rolling window backtest across all the dates in the
provided xts (minus the first x days where the window is not big enough) and
returns some information on the performance of the strategy (currently set to
be the Sharpe Ratio).
I am new to R, and I have taken the idea as far as I can, and how need to turn
to some of you R wizards out there for help. The below code returns just
NaNâs for my Sharpe Ratios when I know that the range of SPY data I provide
should give some non-NaN backtest result across the 90 day window I have
specified.
Any help would be very much appreciated.
Thank you in advance,
Tim
CODE BELOW:
####################################################################################################################################
# Code to create a custom indicator which, for each date (i) in a time series,
will return the Sharpe Ratio of a defined trading #
# strategy that has been run over a smaller subset of the data up to date (i).
The idea is to eventually be able to use this #
# indicator itself as part of a quantstrat backtest i.e. the previous
performance of a strategy becomes an input to the strategy #
####################################################################################################################################
#install required packages
require(quantstrat)
require(PerformanceAnalytics)
# Set initial date for the market data from which we will build our indicator
time series
initDate <- "2008-01-30"
endDate <- "2010-12-31"
# Pull Yahoo Finance data
symbols <- c("SPY")
getSymbols(symbols, from=initDate, to=endDate,
index.class=c("POSIXt","POSIXct"))
# simple custom function identify when a series of close prices has performed a
certain number (n)
# of up closes or down closes
# returns 1 (TRUE) if the runSum number, n (+ve & -ve), is achieved in the run
window (abs(n)) days
runCounter <- function(myXts,n) {
# myXts in an xts object with a Close column included
# calc 1-day rate of change and translate into 1 for +ve, -1 for -ve
temp <- ifelse(ROC(Cl(myXts),1,type="discrete") > 0,1,-1)
# if the run sum equals the desired level return 1, else 0
temp <- ifelse(runSum(temp,abs(n)) == n,1,0)
temp
}
# function to run the strategy backtest on a sub-set of the data and return the
Sharpe Ratio of the strategy up to that date
# Sharpe Ratio to be used as indicator
# days is the subset window within the overall backtest, within which to run
the strategy backtest
# inn and outt are variables to be passed to runCounter
# prices is the xts
runBTstrat <- function(prices,days,inn,outt) {
.runBT <- function(i) {
#do not run the backtest if we are not far enough into the overall xts
data for the correct size backtest window to exist
if(i < days) {
my <- NaN
}
else {
# select the beginning of the sub-backtest window
firstIndex <- (i - (days-1))
# extract the subset from the xts upon which we are going to run the
strategy
myXts <- prices[firstIndex:i]
# beginning & end dates of the subset
beginDate <- as.character.Date(index(first(myXts)))
finalDate <- as.character.Date(index(last(myXts)))
# initial equity of sub-backtest
startEquity = 100000
# define symbols of instrument we are using
symbols <- c("SPY")
# Set up instruments with FinancialInstruments package
currency("USD")
for(symbol in symbols) {
stock(symbol, currency="USD", multiplier=1)
}
# As the sub-backtest will be run for everday in the overall xts
(minus the sub-backtest window) we need to
# delete the temp portfolio, account, and order book from the
previous days backtest
suppressWarnings(rm("account.temp","portfolio.temp",pos=.blotter))
suppressWarnings(rm("order_book.temp",pos=.strategy))
# now we move to execute the backtest on the sub-window of datat
# Initialize portfolio and account
initPortf("temp", symbols=symbols, initDate=beginDate)
initAcct("temp", portfolios="temp", initDate=beginDate,
initEq=startEquity)
initOrders(portfolio="temp", initDate=beginDate)
# Initialize a strategy object
strattemp <- strategy("temp")
####INDICATORS####
# indicators or simple runs of closes up or down
# Add the price run into indicator
strattemp <- add.indicator(strategy=strattemp, name="runCounter",
arguments = list(myXts=myXts, n=inn), label="runInto")
# Add the price run out indicator
strattemp <- add.indicator(strategy=strattemp, name="runCounter",
arguments = list(myXts=myXts, n=outt), label="runOutOf")
####SIGNALS####
# First when price run with number of obs inn has occured
strattemp <- add.signal(strattemp,
name="sigThreshold",arguments=list(threshold=1, column="runInto",
relationship="eq", cross=TRUE), label="intoT")
# Second when price run with number of obs outt has occured
strattemp <- add.signal(strattemp,
name="sigThreshold",arguments=list(threshold=1, column="runOutOf",
relationship="eq", cross=TRUE), label="outOfT")
####RULES####
# The first is to enter a sell trade when inn signal is observed
strattemp <- add.rule(strattemp, name="ruleSignal",
arguments=list(sigcol="intoT", sigval=TRUE, orderqty=-1000, ordertype="market",
pricemethod="market", TxnFees=-5, osFUN=osMaxPos), type="enter", path.dep=TRUE)
# The second is to exit when an outt signal is observed
strattemp <- add.rule(strattemp, name="ruleSignal",
arguments=list(sigcol="outOfT", sigval=TRUE, orderqty=1000, ordertype="market",
pricemethod="market", TxnFees=-5, osFUN=osMaxPos), type="exit", path.dep=TRUE)
# Set position limits
addPosLimit("temp", "SPY", timestamp=beginDate, maxpos=1000,
minpos=-1000)
# Process the indicators and generate trades
out <- try(applyStrategy(strategy=strattemp, portfolios="temp"))
updatePortf("temp")
# Evaluate results
portTemp <- PortfReturns("temp")
ret <- SharpeRatio.annualized(portTemp)
my <- ret[,1]
}
return(my)
}
return( xts ( sapply(1:nrow(prices), .runBT), order.by=index(prices)))
}
# apply the new custom indicator to the previously loaded data, using a
backtest window of 90 days and 1 run up, 1 run down signals
test <- runBTstrat(SPY,90,1,-1)
[[alternative HTML version deleted]]
_______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.