Search code examples
rquantmodquantstrat

Changing time frame in quantstrat from daily to weekly


So I am just doing EMA50 cross strategy in quantstrat, it works fine, but I was hoping to change the time frame from daily to weekly. I tried storing stock() function as to.weekly(SPY) but they wouldn't let me do that. I want to try this for the multiple numbers of stocks later, so it has to be applied within the portfolio.

library(quantstrat)
rm(list=ls(.blotter), envir=.blotter)

strategy.st<-"firststrat"
portfolio.st<-"firststrat"
account.st<-"firststrat"
rm.strat(strategy.st)


#assignsymbol
getSymbols("SPY",auto.assign=TRUE,adjust=TRUE)

initdate<-"2009-01-01"
from<-"2010-01-01"
to<-"2016-11-01"
Sys.setenv(TZ="UTC")
currency("USD")
stock("SPY",currency="USD",multiplier=1)
tradesize<-10000
inieq<-100000

rm.strat(portfolio.st)
initPortf(portfolio.st,symbols="SPY",initDate=initdate,currency='USD')
initAcct(account.st,portfolios = portfolio.st,initDate = initdate,initEq = inieq,currency="USD")
initOrders(portfolio = portfolio.st,initDate = initdate)
strategy(strategy.st,store=TRUE)



add.indicator(strategy = strategy.st,name="EMA",arguments=list(x=quote(Cl(mktdata)),n=50),label="EMA50")
#if closing price goes over moving average 50 and TSi fference is less then 0.15, then long
#short when closing price touches below original closing price by x(depends on atr? previous lows?) 


add.signal(strategy.st,name="sigCrossover",
           arguments = list(columns=c("Close","EMA50"),
                            relationship="gt"),
           label="crossentry"    
)
add.signal(strategy.st,name="sigCrossover",
           arguments = list(columns=c("Close","EMA50"),
                            relationship="lt"),
           label="crossexit"    
)


add.rule(strategy.st,name="ruleSignal",
         arguments=list(sigcol = "crossentry",
                        sigval=TRUE,
                        orderqty=100,
                        ordertype="market",
                        orderside="long",
                        replace=FALSE,
                        prefer="Open",
                        path.dep=TRUE
         ),
         type="enter"
)           

add.rule(strategy.st,name="ruleSignal",
         arguments=list(sigcol = "crossexit",
                        sigval=TRUE,
                        orderqty="all",
                        ordertype="market",
                        orderside="long",
                        replace=FALSE,
                        prefer="Open",
                        path.dep=TRUE
         ),
         type="exit"
)           


out <- applyStrategy(strategy = strategy.st, portfolios = portfolio.st)

....

[1] "2016-01-04 00:00:00 SPY -100 @ 197.432029165538"
[1] "2016-02-23 00:00:00 SPY 100 @ 191.041013032617"
[1] "2016-02-24 00:00:00 SPY -100 @ 187.72241891553"
[1] "2016-02-26 00:00:00 SPY 100 @ 193.571820974787"
[1] "2016-03-01 00:00:00 SPY -100 @ 192.035603073637"

.... Any way I can change it to weekly?


Solution

  • You're on the right track. If you do SPY <- to.weekly(SPY) before running applyStrategy, then you'll run the strategy on weekly bars. Remember that quantstrat uses the names of the symbols to find the data, regardless of what frequency that underlying data is stored at (whether it be daily or weekly in the object named SPY in your case).

    Here is a more general automated approach for you, since you want to do this for a portfolio of securities. To improve readability, I'm just showing the sections of the code in your question that you need to modify to run with >= 2 securities:

    symbols <- c("SPY", "XLE")
    
    getSymbols(symbols,auto.assign=TRUE,adjust=TRUE)
    # Change to weekly frequency, using the same names for the symbols in the global environment (which is where you have assigned them in your getSymbols call)
    lapply(symbols, function(x) assign(x = x, value = to.weekly(get(x, envir = globalenv()), name = x), envir = globalenv()))
    
    initdate<-"2009-01-01"
    from<-"2010-01-01"
    to<-"2016-11-01"
    Sys.setenv(TZ="UTC")
    currency("USD")
    
    
    # Use your symbols to construct the correct instrument types for your strategy.  You are running on stocks only, so simply pass in the vector named `symbols` to stock:
    stock(symbols,currency="USD",multiplier=1)
    tradesize<-10000
    inieq<-100000
    
    rm.strat(portfolio.st)
    # When initializing your portfolios, pass in the symbols you want the strategy to run on (the vector named `symbols` here):
    initPortf(portfolio.st,symbols=symbols,initDate=initdate,currency='USD')
    
    # ... run the rest of your original code
    

    After applyStrategy has successfully run, you can check mktdata is of the format you wanted (weekly) for the most recent symbol run (the XLE ETF in the symbols vector in this example). You should see something like this:

    mktdata["2016-04/2016-05"]
    # XLE.Open XLE.High  XLE.Low XLE.Close XLE.Volume XLE.Adjusted EMA.EMA50 crossentry crossexit
    # 2016-04-01 61.08612 61.83661 59.70363  60.29613   70527800     60.29613  64.16397         NA        NA
    # 2016-04-08 60.18750 61.92548 59.19014  61.58974   81670700     61.58973  64.06302         NA        NA
    # 2016-04-15 62.08348 63.73259 61.33299  62.74510   94225700     62.74510  64.01134         NA        NA
    # 2016-04-22 61.45149 66.44819 61.30337  66.20132   94215100     66.20131  64.09722          1        NA
    # 2016-04-29 65.97419 67.95905 64.96695  66.65556   92445000     66.65556  64.19754         NA        NA
    # 2016-05-06 66.53706 66.81356 63.69309  64.45345   76727000     64.45345  64.20758         NA        NA
    # 2016-05-13 64.08809 65.90507 62.70560  64.17696   65436100     64.17696  64.20638         NA         1
    # 2016-05-20 65.01632 66.07294 63.68321  65.33233   79205200     65.33233  64.25053          1        NA
    # 2016-05-27 64.94720 67.07030 64.72008  66.29019   55806400     66.29018  64.33052         NA        NA