rtradingquantstrat

QUANTSTRAT - How to build a strategy on a certain asset and use it on another one?


I am writing my MSc final dissertation and I am stuck trying to develop a trading strategy with the quantstrat package. What I would like to do is to trade the SPY looking at the signals generated by a MACD built on the VIX.

I am struggle with developing the strategy on the VIX and then use it on the SPY. I want to take the VIX and compute a MACD. When the VIX's MACD crosses downward the signal line, I want the algo to buy the SPY. When the VIX's MACD crosses upward the signal line, I want the algo to close the previous position.

This is the code I wrot untill now:

# MACD strategy on VIX and SPY (SPDR S&P500 FUND)
#
# I will use MACD as trend indicator.
#
# This is the main idea. 
#
# I want to make prediction on SPY's returns. Due to the EMH, returns are not predictable. 
# Otherwise, the volatility clustering effect allows us to forecast volatility.
# The VIX is the S&P500's implied volatility index. I can make previsions about it and use them
# to forecast the SPY returns. This is because S&P500 and VIX have a strong negative correlation.
# 
# This strategy consists of buying/selling the SPY when the VIX's MACD generates sell/buy signal
#
# Author: Matteo Cavaggioni, 2016
######################################################################################################################
require(quantstrat)

ttz <- Sys.getenv('TZ')
Sys.setenv(TZ = 'UTC')

#startDate <- '2000-01-01'
initDate <- '2004-01-02'
endDate <- '2015-12-31'
initEq <- 1e6

fastMA <- 12
slowMA <- 26
signalMA <- 9
maType <- "EMA"

symb1 <- '^VIX'
symb2 <- 'SPY'

portfolio1.st <- "vmacd"
portfolio2.st <- "smacd"
account.st <- "vsmacd"

getSymbols(c(symb1, symb2), from = initDate, to = endDate, adjust = TRUE, index.class = c("POSIXt", "POSIXct"))
symb1 <- 'VIX'

currency("USD")
stock(symb1, currency = "USD", multiplier = 1)
stock(symb2, currency = "USD", multiplier = 1)

volStrat <- 'volStrat'

rm.strat(volStrat)

initPortf(name = portfolio1.st, symbols = symb1, initDate = initDate) # portafoglio contenente il VIX
initPortf(name = portfolio2.st, symbols = symb2, initDate = initDate) # portafoglio contenente lo SPY
initAcct(name = account.st, portfolios = c(portfolio1.st, portfolio2.st), initEq = initEq, initDate = initDate)
initOrders(portfolio = portfolio2.st, initDate = initDate)

volStrat <- strategy('volStrat', store = TRUE, assets = symb1)

volStrat <- add.indicator(strategy = volStrat, name = "MACD",
                          arguments = list(x = quote(Ad(mktdata)),
                                           nFast = fastMA,
                                           nSlow = slowMA,
                                           nSig = signalMA,
                                           maType = maType), 
                          label = 'macd.out')
#####
volStrat <- add.signal(strategy = volStrat, name = "sigCrossover",
                       arguments = list(columns = c("macd.macd.out", "signal.macd.out"),
                                        relationship = "gt"),
                       label = "macd.gt.signal")
volStrat <- add.signal(strategy = volStrat, name = "sigCrossover",
                       arguments = list(columns = c("macd.macd.out", "signal.macd.out"),
                                        relationship = "lt"),
                       label = "macd.lt.signal")

# go long when macd < signal
volStrat <- add.rule(strategy = volStrat, name = "ruleSignal",
                     arguments = list(sigcol = "macd.lt.signal", sigval = TRUE,
                                      orderqty = 1000,
                                      ordertype = "market",
                                      orderside = "long"),
                     type = "enter")

# exit long when macd > signal
volStrat <- add.rule(strategy = volStrat, name = "ruleSignal",
                     arguments = list(sigcol = "macd.gt.signal", sigval = TRUE,
                                      orderqty = "all",
                                      ordertype = "market",
                                      orderside = "long"),
                     type = "exit")

#####

start_t <- Sys.time()
out <- applyStrategy(strategy = volStrat, portfolios = portfolio2.st,
                     parameters = list(nFast = fastMA, nSlow = slowMA, nSig = signalMA, maType = maType), verbose = T)
end_t <- Sys.time()
print(end_t - start_t)

start_t<-Sys.time()
updatePortf(Portfolio='smacd',Dates=paste('::',as.Date(Sys.time()),sep=''))
updateAcct(account.st)
updateEndEq(account.st)
end_t<-Sys.time()
print(end_t-start_t)

book    = getOrderBook('smacd')
stats   = tradeStats('smacd')
ptstats = perTradeStats('smacd')
rets    = PortfReturns(account.st)
txns    = getTxns('smacd', symb2)

chart.Posn(Portfolio = 'smacd',Symbol = symb2)
plot(add_MACD(fast = fastMA, slow = slowMA, signal = signalMA, maType = "EMA"))

# COMPARING STRATEGY WITH SPY
instRets <- PortfReturns(account.st)

portfRets <- xts(rowMeans(instRets) * ncol(instRets), order.by = index(instRets))
portfRets <- portfRets[!is.na(portfRets)]
cumPortfRets <- cumprod(1 + portfRets)
firstNonZeroDay <- as.character(index(portfRets)[min(which(portfRets != 0))])

getSymbols("SPY", from = firstNonZeroDay, to = endDate)
SPYrets <- diff(log(Cl(SPY)))[-1]
cumSPYrets <- cumprod(1 + SPYrets)
comparison <- cbind(cumPortfRets, cumSPYrets)
colnames(comparison) <- c("strategy", "SPY")
chart.TimeSeries(comparison, legend.loc = "topleft", colors = c("green", "red"))
#

Sys.setenv(TZ=ttz)

Can anyone help me in figuring out what is wrong with it?

Thank you so much.


Solution

  • This is funny, i randomly clicked on your question out of curiosity. I am currently doing heavy research into the VIX indexes.

    exploiting the negative correlation using MACD... it could work but technical analysis is useless on random series. if you perform randomness tests on the VIX it will not reject the hypothesis.

    additionally VIX has random intraday spikes which are not reflected in closing prices ( as yielded by getSybmols - not a reliable source for research). in a real life scenario you would get stopped out or reach your price target before your data set actually represents it. You can avoid that by using higher frequencies which is highly recommended here.

    Here are 2 papers which you should read:

    The VIX Futures Basis: Evidence and Trading Strategies - David P.Simon (2013)

    The above strategy is the same as the yield strategy in this next paper: Easy Volatility Investing - Tony Cooper (2013)

    the last paper comes with 4 other strategies besides the yield one.

    related to the code, since u have almost no posts it's worth mentioning that its highly unlikely someone will check your entire code. unless you probably pay them and still would you trust a stranger with your calculations?

    Zorro is an easy enough way of implementing strategies like this and integrates with R. check it out.

      You're using a very complex package for something very simple. I haven't looked at yoru code but if I were you i would try something like this: 
            1. calculate MACD for VIX
            2. Create a trade signal - Make new column by SPY with 1s for periods where VIX MACD >0 and zeros for VIX MACD <0 
            3. Simply add up SPY returns for rows that contain either 0s or 1s in the $MACD column / multiply by -1 if you want to go short..
    
    
    P.S. use the xts package - helps u keep track of dates and not missmatch data  
    

    Good luck i'm also doing my thesis atm, not in this tho.