try(rm("order_book.oneSideTrades", "order_book.twoSideTrades", pos=.strategy),silent=TRUE) try(rm("portfolio.oneSideTrades", "portfolio.twoSideTrades", "account.basket", pos=.blotter),silent=TRUE) library(PerformanceAnalytics) require(quantstrat) require(som) initDate = '2007-06-30' #the initDate as per the documentation is one day before the data in your sample starts endDate = '2010-07-02' startdate = '2007-07-02' initEq = 100000 oneSideSymbols <- c("IBM", "UTX", "CAT") twoSideSymbols <- c("MSFT") allSymbols <- c(oneSideSymbols, twoSideSymbols) getSymbols(oneSideSymbols, from=startdate, to=endDate) getSymbols(twoSideSymbols, from=startdate, to=endDate) currency("USD") stock(oneSideSymbols[1], currency="USD", multiplier=1) stock(oneSideSymbols[2], currency="USD", multiplier=1) stock(oneSideSymbols[3], currency="USD", multiplier=1) stock(twoSideSymbols[1], currency="USD", multiplier=1) # Create 2 portfolio objects - one to hold long trades and one to hold short trades portfolio1.st <- 'oneSideTrades' portfolio2.st <- 'twoSideTrades' allportfolios <- c(portfolio1.st, portfolio2.st) initPortf(name=portfolio1.st, oneSideSymbols, initDate=initDate) initPortf(name=portfolio2.st, twoSideSymbols, initDate=initDate) account.st <- 'basket' initAcct(account.st, portfolios=allportfolios, initDate=initDate, initEq=initEq) initOrders(portfolio=portfolio1.st,initDate=initDate) initOrders(portfolio=portfolio2.st,initDate=initDate) # Create position limits by symbol addPosLimit(portfolio=portfolio1.st, timestamp=initDate, symbol='IBM', maxpos=101, minpos=-101) addPosLimit(portfolio=portfolio1.st, timestamp=initDate, symbol='UTX', maxpos=168, minpos=-168) addPosLimit(portfolio=portfolio1.st, timestamp=initDate, symbol='CAT', maxpos=862, minpos=-862) addPosLimit(portfolio=portfolio2.st, timestamp=initDate, symbol='MSFT', maxpos=1000, minpos=-1000) # Create 2 strategy objects - one for strategies that will take long positions and another that will take short positions sideOne <- strategy('sideOne') sideTwo <- strategy('sideTwo') # Create an indicator - one for sideOne and one for sideTwo strategy objects sideOne <- add.indicator(strategy = sideOne, label="ma10", name = "SMA", arguments = list(x= quote(Cl(mktdata)), n=10)) sideOne <- add.indicator(strategy = sideOne, label="ma20", name = "SMA", arguments = list(x= quote(Cl(mktdata)), n=20)) sideTwo <- add.indicator(strategy = sideTwo, label="ma15", name = "SMA", arguments = list(x= quote(Cl(mktdata)), n=15)) sideTwo <- add.indicator(strategy = sideTwo, label="ma20", name = "SMA", arguments = list(x= quote(Cl(mktdata)), n=20)) # Create 2 sets of signals - 2 individual signals for sideOne and 2 individual signals for sideTwo sideOne <- add.signal(strategy = sideOne, name = "sigCrossover", arguments= list(column=c("ma10", "ma20"), relationship="gt"), label="ma10.gt.ma20") sideOne <- add.signal(strategy = sideOne, name = "sigCrossover", arguments= list(column=c("ma10", "ma20"), relationship="lt"), label="ma10.lt.ma20") sideTwo <- add.signal(strategy = sideTwo, name = "sigCrossover", arguments= list(column=c("ma15", "ma20"), relationship="gt"), label="ma15.gt.ma20") sideTwo <- add.signal(strategy = sideTwo, name = "sigCrossover", arguments= list(column=c("ma15", "ma20"), relationship="lt"), label="ma15.lt.ma20") # Create 2 sets of rules - 4 individual rules for sideOne and 4 individual rules for sideTwo (one = entry, one = exit) sideOne <- add.rule(strategy = sideOne, name='ruleSignal', type='enter', arguments = list(sigcol="ma10.gt.ma20", sigval=TRUE, orderqty=100000, ordertype='market', orderside='long', osFUN='osMaxPos')) sideOne <- add.rule(strategy = sideOne, name='ruleSignal', type='exit', arguments = list(sigcol="ma10.lt.ma20", sigval=TRUE, orderqty="all", ordertype='market', orderside='long')) sideOne <- add.rule(strategy = sideOne, name='ruleSignal', type='enter', arguments = list(sigcol="ma10.lt.ma20", sigval=TRUE, orderqty=-100000, ordertype='market', orderside='short', osFUN='osMaxPos')) sideOne <- add.rule(strategy = sideOne, name='ruleSignal', type='exit', arguments = list(sigcol="ma10.gt.ma20", sigval=TRUE, orderqty="all", ordertype='market', orderside='short')) sideTwo <- add.rule(strategy = sideTwo, name='ruleSignal', type='enter', arguments = list(sigcol="ma15.gt.ma20", sigval=TRUE, orderqty=100000, ordertype='market', orderside='long', osFUN='osMaxPos')) sideTwo <- add.rule(strategy = sideTwo, name='ruleSignal', type='exit', arguments = list(sigcol="ma15.lt.ma20", sigval=TRUE, orderqty="all", ordertype='market', orderside='long')) sideTwo <- add.rule(strategy = sideTwo, name='ruleSignal', type='enter', arguments = list(sigcol="ma15.lt.ma20", sigval=TRUE, orderqty=-100000, ordertype='market', orderside='short', osFUN='osMaxPos')) sideTwo <- add.rule(strategy = sideTwo, name='ruleSignal', type='exit', arguments = list(sigcol="ma15.gt.ma20", sigval=TRUE, orderqty="all", ordertype='market', orderside='short')) out<-try(applyStrategy(strategy=sideOne, portfolios=portfolio1.st)) out<-try(applyStrategy(strategy=sideTwo, portfolios=portfolio2.st)) #account.st <- 'basket' #initAcct(account.st, portfolios=allportfolios, initDate=initDate, initEq=initEq) # Not sure why I cant just use Portfolio=allportfolios since that vector contains 'portfolio1.st' and 'portfolio2.st' ## Because updatePortf isn't set up to handle that, and more importantly neither is the function from blotter, .getBySymbol, that ## updatePortf calls. updatePortf(Portfolio=portfolio1.st,Dates=paste('::',as.Date(Sys.time()),sep='')) updatePortf(Portfolio=portfolio2.st,Dates=paste('::',as.Date(Sys.time()),sep='')) #updateAcct(name=account.st, Dates=paste('::',as.Date(Sys.time()),sep='')) updateAcct(name=account.st, Dates='2007-07-02::2010-07-03') updateEndEq <- function (Account, Dates = NULL) { aname <- Account Account <- try(get(paste("account", aname, sep = "."), envir = .blotter)) if (inherits(Account, "try-error")) stop(paste("Account", aname, " not found, use initAcct() to create a new account")) if (is.null(Dates)) Dates = time(Account$summary)[-1] else Dates = time(Account$summary[Dates]) PrevDate = time(Account$summary[first(Account$summary[Dates, which.i = TRUE]) - 1, ]) PrevEndEq = getEndEq(aname, PrevDate) Additions = Account$summary[Dates]$Additions Withdrawals = Account$summary[Dates]$Withdrawals NetPerformance = rowSums(Account$summary[Dates, c("Int.Income", "Net.Trading.PL", "Advisory.Fees")]) Account$summary$Net.Performance[Dates] <- NetPerformance EndCapital = PrevEndEq + cumsum(Additions + Withdrawals + NetPerformance) Account$summary$End.Eq[Dates] <- EndCapital assign(paste("account", aname, sep = "."), Account, envir = .blotter) return(aname) } updateEndEq(account.st) #, Dates='2007-07-01::2010-07-03') a <- getAccount(account.st) head(a$summary) tail(a$summary) cat('Basket Strategy Return: ',((getEndEq(Account=account.st, Date='2010-07-03')-initEq)/initEq)*100,'\n') charts.PerformanceSummary(ROC(getAccount(account.st)$summary$End.Eq)[-1], main="Basket Strategy Return")