[Blotter-commits] r1543 - pkg/blotter/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Oct 19 19:26:25 CEST 2013
Author: bodanker
Date: 2013-10-19 19:26:25 +0200 (Sat, 19 Oct 2013)
New Revision: 1543
Modified:
pkg/blotter/R/perTradeStats.R
Log:
- Use integer indexing instead of ISO8601-style subsetting, which was causing
issues with floating-point rounding errors when digits.secs was set, and
also caused issue #5015.
Modified: pkg/blotter/R/perTradeStats.R
===================================================================
--- pkg/blotter/R/perTradeStats.R 2013-10-18 17:25:18 UTC (rev 1542)
+++ pkg/blotter/R/perTradeStats.R 2013-10-19 17:26:25 UTC (rev 1543)
@@ -60,24 +60,27 @@
switch(tradeDef,
flat.to.flat = {
# identify start and end for each trade, where end means flat position
- trades$Start <- index(posPL[which(posPL$Pos.Qty!=0 & lag(posPL$Pos.Qty)==0),])
- trades$End <- index(posPL[which(posPL$Pos.Qty==0 & lag(posPL$Pos.Qty)!=0),])
+ trades$Start <- which(posPL$Pos.Qty!=0 & lag(posPL$Pos.Qty)==0)
+ trades$End <- which(posPL$Pos.Qty==0 & lag(posPL$Pos.Qty)!=0)
},
flat.to.reduced = {
# find all transactions that bring position closer to zero ('trade ends')
decrPos <- diff(abs(posPL$Pos.Qty)) < 0
# find all transactions that open a position ('trade starts')
initPos <- posPL$Pos.Qty!=0 & lag(posPL$Pos.Qty)==0
- # all 'trades' start when we open a position, so determine which starts correspond to each end
- StartEnd <- cumsum(!(decrPos[initPos | decrPos]))
- starts <- sapply(split.default(StartEnd, StartEnd), function(i) rep(start(i), nrow(i)-1))
- starts <- unlist(starts, recursive=FALSE, use.names=FALSE)
- attributes(starts) <- attributes(index(StartEnd))
+ # 'trades' start when we open a position, so determine which starts correspond to each end
+ # add small amount to Start index, so starts will always occur before ends in StartEnd
+ Start <- xts(initPos[initPos,which.i=TRUE],index(initPos[initPos])+1e-5)
+ End <- xts(decrPos[decrPos,which.i=TRUE],index(decrPos[decrPos]))
+ StartEnd <- merge(Start,End)
+ StartEnd$Start <- na.locf(StartEnd$Start)
+ StartEnd <- StartEnd[!is.na(StartEnd$End),]
+ # populate trades list
+ trades$Start <- drop(coredata(StartEnd$Start))
+ trades$End <- drop(coredata(StartEnd$End))
# add extra 'trade start' if there's an open trade, so 'includeOpenTrade' logic will work
if(last(posPL)[,"Pos.Qty"] != 0)
- starts <- c(starts, last(starts))
- trades$Start <- starts
- trades$End <- index(decrPos[decrPos])
+ trades$Start <- c(trades$Start, last(trades$Start))
}
)
@@ -85,7 +88,7 @@
if(length(trades$Start)>length(trades$End))
{
if(includeOpenTrade)
- trades$End <- c(trades$End,last(index(posPL)))
+ trades$End <- c(trades$End,nrow(posPL))
else
trades$Start <- head(trades$Start, -1)
}
@@ -93,16 +96,9 @@
# calculate information about each trade
for(i in 1:length(trades$End))
{
- #timespan <- paste(format(trades$Start[[i]], "%Y-%m-%d %H:%M:%OS6"),
- #format(trades$End[[i]], "%Y-%m-%d %H:%M:%OS6"), sep="::")
- timespan <- paste(trades$Start[[i]], trades$End[[i]], sep="/")
-
- trade <- posPL[timespan]
+ timespan <- seq.int(trades$Start[i], trades$End[i])
+ trade <- posPL[timespan]
- # close and open may occur in at same index timestamp, must be corrected
- if(first(trade)$Pos.Qty==0) trade <- tail(trade, -1)
- if(last(trade)$Pos.Qty!=0) trade <- head(trade, -1)
-
# add cost basis column
trade$Pos.Cost.Basis <- cumsum(trade$Txn.Value)
#add running posPL column
@@ -140,6 +136,8 @@
trades$tick.MAE[i] <- min(0,trade$tick.PL)
trades$tick.MFE[i] <- max(0,trade$tick.PL)
}
+ trades$Start <- index(posPL)[trades$Start]
+ trades$End <- index(posPL)[trades$End]
return(as.data.frame(trades))
} # end fn perTradeStats
More information about the Blotter-commits
mailing list