Skip to content

quantstrat - model transactions on specific dates

7 messages · Mark Knecht, Brian G. Peterson, Joshua Ulrich

#
Hi,
   I suspect I'm making this far more difficult than it needs to be,
however I've spent time looking on Stack Overflow and couldn't find an
answer. Hopefully someone here can point me in the right direction.
Thanks in advance.

   I would like to do something in quantstrat like set up an initial
buy for all symbols in a portfolio on a certain date. To that end I
want a signal column that says the date is matching my buy date and
then I'l execute a specific rule. However signals need to match
columns which led me to wanting the index in a column as a value. To
that end the code below basically does this but returns  a numerical
value which (I think) is referenced to 1970-01-01.
xtsIndex
2014-10-01    16344
2014-10-02    16345
2014-10-03    16346
2014-10-06    16349
2014-10-07    16350
2014-10-08    16351
Anyway, how do I turn these numeric values back into dates that I
could test against 'testDate'?

Thanks,
Mark



require(quantstrat)

Sys.setenv(TZ="UTC")

symbol = "SPY"
getSymbols(symbol,src="yahoo",from="2014-01-01")

testDate = "2014-03-11"

xtsIndex = function(data){
  xtsIndex = reclass(index(data), match.to=data)
  colnames(xtsIndex)="xtsIndex"
  return(xtsIndex)
}

IndexAsXts = xtsIndex(get(symbol))

tail(IndexAsXts)

#Find origin

LastVal = last(IndexAsXts)
OriginDate = index(LastVal) - as.numeric(LastVal)
print(OriginDate)

tail(as.POSIXct(coredata(IndexAsXts), origin=OriginDate,
tz=Sys.getenv("TZ")), 5)
#
On Thu, Oct 9, 2014 at 1:05 PM, Mark Knecht <markknecht at gmail.com> wrote:
Humm...It gets considerably closer with

getSymbols(symbol,src="yahoo",from="2014-01-01",
           index.class=c("POSIXt","POSIXct"))
#
On 10/09/2014 03:05 PM, Mark Knecht wrote:
It seems to me that the simplest thing would be to just establish your 
initial portfolio.

Initialize the portfolio, then construct a data.frame for the txnData 
argument of addTxns.

Call addTxns before calling applyStrategy.

Alternately, you could modify sigFlatten to essentially do the opposite, 
and initiate on a certain time.

Regards,

Brian
#
On Thu, Oct 9, 2014 at 3:31 PM, Brian G. Peterson <brian at braverock.com> wrote:
You're thinking of sigTimestamp (which was based on sigFlatten, but
I'm not sure was ever made public).  Mark, I think sigTimestamp is
what you're looking for.
--
Joshua Ulrich  |  about.me/joshuaulrich
FOSS Trading  |  www.fosstrading.com
#
On Thu, Oct 9, 2014 at 1:35 PM, Joshua Ulrich <josh.m.ulrich at gmail.com> wrote:
Brian & Joshua,
   Thanks. I'll investigate them both.

   Longer term though I think my general question may still come up.
I've been looking at rebalancing at the portfolio level. Best I can
tell the applyStrategy.rebalance function rebalances individual stocks
based on the last entry date of that stock but not, for instance, on a
specific date like the a calendar quarter. (I wasn't going to post
this all right now until I was really sure so don't take this too
seriously.) Anyway I want to write something like what Faber &
Richardson wrote about in 'The Ivy Portfolio' where the whole
portfolio is rebalanced on a given date, like end-of-month,
independent of whether I'm using the 10 month SMA or not. For that
reason I figured I might need a way to match indexes to dates going
though time.

   Anyway, enough for now. Thanks for all your help guys!

Cheers,
Mark
#
On 10/09/2014 04:00 PM, Mark Knecht wrote:
see the faber_rebal demo.

The rebalance_on argument will call the rebalancing rule(s) on whatever 
periodicity you tell it to, you'll have to have something for them to do.

In the demo, I just changed max order size, but there's no reason you 
couldn't write a (strategy specific) rebalancing rule that wouldn't read 
all the positions, and do transactions on the rebalance date.

Regards,

Brian
#
On Thu, Oct 9, 2014 at 2:16 PM, Brian G. Peterson <brian at braverock.com> wrote:
Brian,
   Yes, that's what I'm thinking I'll need to do. Josh's suggestion
about using sigTimestamp looks like it could also be part of that.

   The code below (for casual readers or people coming later) is based
on the faber_rebal demo and generates generates faberTxns which shows
all the stocks trades together in one place. They are being rebalanced
but the trades occur at different times which is what I want to play
with. Also, this code includes the index as a testable column (not
used but generated as a test) and I moved the start date on the SPY,
for comparison purposes, to be the first entry date of whatever stock
executes first.

Thanks,
Mark


#This code is based on the faber_rebal demo file
#Thanks to those who wrote and debugged it
require(quantstrat)

Sys.setenv(TZ="UTC")

portfolio.st = "faber"
account.st   = "faber"
strategy.st  = "faber"

# Try to clean up in case the demo was run previously
suppressWarnings(rm("account.faber","portfolio.faber",pos=.blotter))
suppressWarnings(rm("ltaccount", "ltportfolio", "ClosePrice",
"CurrentDate", "equity",
                    "GSPC", "stratFaber", "initDate", "initEq",
"Posn", "UnitSize", "verbose"))
suppressWarnings(rm("order_book.faber",pos=.strategy))

initDate='1997-12-31'
initEq=100000
currency("USD")
symbols = c("XLF", "XLP", "XLE", "XLY", "XLV", "XLI", "XLB", "XLK", "XLU")

xtsIndex = function(data){
  xtsIndex = reclass(index(data), match.to=data)
  colnames(xtsIndex)="xtsIndex"
  return(xtsIndex)
}

for(symbol in symbols){
  stock(symbol, currency="USD",multiplier=1)
}

getSymbols(symbols, src='yahoo', index.class=c("POSIXt","POSIXct"),
from='1999-01-01')
for(symbol in symbols) {
  if (symbol == symbols[1]){
    tmpData = Cl(get(symbol))
  }else{
    tmpData = cbind(tmpData, Cl(get(symbol)))
  }
}
#Find first common data date
tmpData = tmpData[complete.cases(tmpData)]
startDate = first(index(tmpData))
print(startDate)
#rm(tmpData)

for(symbol in symbols) {
  x<-get(symbol)
  x<-to.monthly(x,indexAt='lastof',drop.time=TRUE)
  indexFormat(x)<-'%Y-%m-%d'
  colnames(x)<-gsub("x",symbol,colnames(x))
#  x = x[paste0(startDate,"/")]
  assign(symbol,x)
}


initPortf(portfolio.st, symbols=symbols, initDate=initDate)
initAcct(account.st, portfolios=portfolio.st, initDate=initDate, initEq=100000)
initOrders(portfolio=portfolio.st, initDate=initDate)

# set intial position limits
posval<-initEq/length(symbols)
for(symbol in symbols){
  pos<-round((posval/first(getPrice(get(symbol)))[,1]),-2)
  addPosLimit(portfolio.st,symbol,initDate, maxpos=pos,minpos=-pos)
}
print("setup completed")

# Initialize a strategy object
strategy(strategy.st, store=TRUE)


add.indicator(strategy.st, name = "SMA", arguments = list(x =
quote(Cl(mktdata)), n=10), label="SMA10")
add.indicator(strategy.st, name = "xtsIndex", arguments = list(data =
quote(mktdata)), label="Index")

add.signal(strategy.st,name="sigCrossover",arguments =
list(columns=c("Close","SMA10"),relationship="gte"),label="Cl.gt.SMA")
add.signal(strategy.st,name="sigCrossover",arguments =
list(columns=c("Close","SMA10"),relationship="lt"),label="Cl.lt.SMA")

add.rule(strategy.st, name='ruleSignal', arguments =
list(sigcol="Cl.gt.SMA", sigval=TRUE, orderqty=100000,
osFUN='osMaxPos', ordertype='market', orderside='long',
pricemethod='market',TxnFees=-5), type='enter', path.dep=TRUE)
#add.rule(strategy.st, name='ruleSignal', arguments =
list(sigcol="Cl.lt.SMA", sigval=TRUE, orderqty='all',
ordertype='market', orderside='long',
pricemethod='market',TxnFees=-5), type='exit', path.dep=TRUE)

# # add rebalancing rule
add.rule(strategy.st, 'rulePctEquity',
         arguments=list(rebalance_on='quarters',
                        trade.percent=1/length(symbols),

refprice=quote(last(getPrice(mktdata)[paste('::',as.character(curIndex),sep='')][,1])),
                        digits=0
         ),
         type='rebalance',
         label='rebalance'
)

# Process the strategy and generate trades
start_t<-Sys.time()
out<-applyStrategy.rebalancing(strategy=strategy.st , portfolios=portfolio.st)
#out<-applyStrategy(strategy=strategy.st , portfolios=portfolio.st)
end_t<-Sys.time()
print("Strategy Loop:")
print(end_t-start_t)


start_t<-Sys.time()
updatePortf(Portfolio=portfolio.st,Dates=paste('::',as.Date(Sys.time()),sep=''))
updateAcct(account.st)
end_t<-Sys.time()
print("trade blotter portfolio update:")
print(end_t-start_t)

# hack for new quantmod graphics, remove later
themelist<-chart_theme()
themelist$col$up.col<-'lightgreen'
themelist$col$dn.col<-'pink'

#dev.new() #Removed for RStudio
layout(mat=matrix(1:(length(symbols)+1),ncol=2))
for(symbol in symbols){
  chart.Posn(Portfolio=portfolio.st,Symbol=symbol,theme=themelist,TA="add_SMA(n=10,col='darkgreen')")
}

ret1 <- PortfReturns(portfolio.st)
ret1$total <- rowSums(ret1)

faber.stats<-tradeStats(portfolio.st)[,c('Net.Trading.PL','Max.Drawdown','Num.Trades','Profit.Factor','Std.Dev.Trade.PL','Largest.Winner','Largest.Loser','Max.Equity','Min.Equity')]
faber.stats = t(round(faber.stats,2))
View(faber.stats)

#Plot all the individual equities
par(mfrow=c(1,1))
plot.zoo(cumprod(1+ret1[,1:(ncol(ret1)-1)]), screens=1,
col=rainbow(n=ncol(ret1)-1))

#Get # of shares and txn prices

for (i in 1:length(symbols)){
  tmp1 = getTxns(portfolio.st,symbols[i])[,1:2]
  colnames(tmp1) = c(paste0(symbols[i],".sh"), paste0(symbols[i],".pr"))
#  print(tmp1)
  if (i == 1){
    faberTxns = tmp1
  }else{
    faberTxns = cbind(faberTxns, tmp1)
  }
}

View(faberTxns)

ComparisonDate = index(faberTxns)[2]

if("package:PerformanceAnalytics" %in% search() ||
require("PerformanceAnalytics",quietly=TRUE)){
  getSymbols("SPY", src='yahoo', index.class=c("POSIXt","POSIXct"),
from=ComparisonDate)
  SPY<-to.monthly(SPY, indexAt='lastof')
  SPY.ret <- Return.calculate(SPY$SPY.Close)
  #  dev.new() #Removed for RStudio
  charts.PerformanceSummary(cbind(ret1$total,SPY.ret),
geometric=FALSE, wealth.index=TRUE)
}