I would like to use indicators of timeframes different to the data I am using. I have seen this asked a few time but no solutions as of yet (at least for me anyway).
The below example uses daily stock data however the actual project uses intraday currency data. I have an easy work around for importing the intraday csv data now so the example and real-world should be interchangeable enough.
library(quantstrat)
initDate="2000-01-01"
from="2003-01-01"
to="2016-12-31"
#set account currency and system timezone
currency('USD')
Sys.setenv(TZ="UTC")
#get data
symbols <- "SPY"
getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE)
stock(symbols, "USD")
#trade sizing and initial equity settings
tradeSize <- 100000
initEq <- tradeSize*length(symbols)
#set up the portfolio, account and strategy
strategy.st <- portfolio.st <- account.st <- "mtf.strat"
rm.strat(strategy.st)
initPortf(portfolio.st, symbols=symbols, initDate=initDate, currency='USD')
initAcct(account.st, portfolios=portfolio.st, initDate=initDate, currency='USD',initEq=initEq)
initOrders(portfolio.st, initDate=initDate)
strategy(strategy.st, store=TRUE)
#SMA length
nSMA <- 14
Adding the SMA as, in this case a daily indicator works a treat
add.indicator(strategy.st, name="SMA",
arguments=list(x=quote(Cl(mktdata)), n=nSMA, maType = "SMA"),
label="SMA")
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))
Yet trying to add, in this case a weekly SMA
add.indicator(strategy.st, name="SMA",
arguments=list(x=quote(to.period(Cl(mktdata), period = "weeks", k = 1, indexAt = "startof")), n=nSMA, maType = "SMA"),
label="SMAw1")
## Or this
add.indicator(strategy.st, name="SMA",
arguments=list(x=quote(to.weekly(Cl(mktdata))), n=nSMA, maType = "SMA"),
label="SMAw1")
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))
# Error in runSum(x, n) : ncol(x) > 1. runSum only supports univariate 'x'
Calling the Close column directly without Cl(x)
results in the same error. I did this as TTR:::runSum
will throw the above error if given more than one column of data.
I'm not entirely sure what the problem is so some assistance would be great.
The problem is that to.period
(and therefore to.weekly
) return OHLC objects, not a univariate series like TTR::SMA
expects. So you need to wrap the output of to.period
in Cl
.
add.indicator(strategy.st, name="SMA",
arguments=list(x=quote(Cl(to.weekly(Cl(mktdata)))), n=nSMA, maType = "SMA"),
label="SMAw1")
test <- applyIndicators(strategy.st, mktdata=OHLC(SPY))
Now that code runs, but it may still be a problem for your strategy. There will be a lot of NA
when that indicator is merged with the daily mktdata
.
R> tail(merge(SPY, test$SMA))
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1
2016-11-25 221.10 221.56 221.01 221.52 37861800 221.52 215.0720
2016-11-28 221.16 221.48 220.36 220.48 70284100 220.48 NA
2016-11-29 220.52 221.44 220.17 220.91 67079400 220.91 NA
2016-11-30 221.63 221.82 220.31 220.38 99783700 220.38 NA
2016-12-01 220.73 220.73 219.15 219.57 77230500 219.57 NA
2016-12-02 219.67 220.25 219.26 219.68 70863400 219.68 215.3207
So it's a good idea to create your own SMA wrapper function to handle all these steps. Then call add.indicator
using your wrapper function.
mySMA <- function(x, on = "days", k = 1, n = 10) {
agg <- x[endpoints(x, on, k)]
sma <- SMA(agg, n)
# merge with zero-width xts object w/original index, filling NA
result <- merge(sma, xts(,index(x)), fill = na.locf)
return(result)
}
add.indicator(strategy.st, name = "mySMA",
arguments = list(x = quote(Cl(mktdata)),
on = "weeks",
n = nSMA),
label = "SMAw1")
test <- applyIndicators(strategy.st, mktdata = OHLC(SPY))
Now the indicator will have a value for every observation in mktdata
when it's merged.
> tail(merge(SPY, test$SMA))
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted SMA.SMAw1
2016-11-25 221.10 221.56 221.01 221.52 37861800 221.52 215.0720
2016-11-28 221.16 221.48 220.36 220.48 70284100 220.48 215.0720
2016-11-29 220.52 221.44 220.17 220.91 67079400 220.91 215.0720
2016-11-30 221.63 221.82 220.31 220.38 99783700 220.38 215.0720
2016-12-01 220.73 220.73 219.15 219.57 77230500 219.57 215.0720
2016-12-02 219.67 220.25 219.26 219.68 70863400 219.68 215.3207