3

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.

matcava
  • 53
  • 8

2 Answers2

3

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.

Alex Bădoi
  • 830
  • 2
  • 9
  • 24
  • Hi Alex! thank you for your answer and suggestions! The papers seem very interesting and I will try to develop the strategy without quantstrat. About the randomness... I totally agree with you, but I found some interesting patterns that highligt the possibility to profit using VIX's MACD on SPY. I want to start with a very superficial analysis and then go deeper and deeper as the results get better! About quantstrat: do you know if I can do what I explained (building up the strategy on the VIX and then apply it to the SPY)? Thank you very much – matcava Apr 05 '16 at 14:10
  • I'm sure it's possible but i haven't used the package sufficiently myself to able able to answer your question. additionally your code is very long and complex and as i mentioned before this place is great for asking very specific questions on 2-3 lines of code but not for "fixing" an entire algo that doesn't work. If you just want to try this as an experiment you should do something simple like i explained above. – Alex Bădoi Apr 06 '16 at 10:47
  • Fine! thank you once again Alex, you've been super kind! good luck with your thesis – matcava Apr 06 '16 at 10:51
  • here are more papers on VIX http://papers.ssrn.com/sol3/cf_dev/AbsByAuth.cfm?per_id=1009018 if my answer was sufficient to put you in the right direction and no-one else has something to contribute i'd appreciate if you mark my reply as a correct answer. – Alex Bădoi Apr 06 '16 at 10:51
  • and also can I ask you this: VIX is negatively correlated with the SPY, and the SPY perfectly explains VIX (not the other way around). You want to use a MACD indicator on VIX to trade SPY. But since they are inversely correlated why not just use MACD on the SPY directly. You think VIX could give an earlier signal? also be aware that VIX contains option risk premia which may interfere with your signal and findings. Either way if you find anything interesting follow me up with a mail. – Alex Bădoi Apr 06 '16 at 10:58
  • Unfortunately I still haven't the "rights" to mark replies. For the VIX/SPY topic, I'll contact you via email as soon as I can! – matcava Apr 06 '16 at 11:19
  • I can't even use the chat unfortunately.. if you send me yuor email address I'll get back to you as I can! – matcava Apr 06 '16 at 11:28
  • on the left hand side of my original post (not the comments) you have the option of marking it as a correct answer. alex.badoi1@gmail.com good luck! – Alex Bădoi Apr 06 '16 at 13:17
1

This is easy! Just create a function contaning the dataset of the MACD on the VIX and load it in as an indicator. Heres the code:

library(quantstrat)
# dates and variables
stocks <- c('SPY') #OFG FGBI
initdate <- "1999-01-01"
from <- "2015-01-01"
to <- Sys.Date()
### MACD on Vix
vixMACD <- function(nFast = 12, nSlow = 26, nSig = 9, maType = 'SMA'){
  getSymbols('^VIX', to = to, from = from, adjust = TRUE)
  vixMACD <- MACD(x = Cl(VIX), nFast = nFast, nSlow = nSlow, nSig = nSig, maType = maType)
  colnames(vixMACD$macd) <- 'vixMACD'
  colnames(vixMACD$signal) <- 'vixMACDsignal'
  return(vixMACD)
}
##################
getSymbols(stocks, from = from, to = to, src = "yahoo", adjust = TRUE)
Sys.setenv(TZ = "UTC")
currency("USD")
for(stock in stocks) {
  stock(stock, currency = "USD", multiplier = 1)
}
initeq <- 10000
tradesize <- initeq/length(stocks)
# initialize portfolio objects
strategy.st <- portfolio.st <- account.st <- "backtest"
rm.strat(strategy.st)
initPortf(portfolio.st, symbols = stocks, initDate = initdate, currency = "USD")
initAcct(account.st, portfolios = portfolio.st, symbols = stocks, initDate = initdate, currency = "USD", initEq = initeq)
initOrders(portfolio.st, initDate = initdate)
strategy(strategy.st, store = TRUE)
# add indicators to strategy
add.indicator(strategy.st, name = "vixMACD", arguments = list(x = quote(Cl(mktdata))), label = "vixMACD")
test <- applyIndicators(strategy= strategy.st, mktdata = OHLC(MS))
tail(test)
Noah Tover
  • 11
  • 3