[Blotter-commits] r1577 - pkg/blotter/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Dec 6 20:23:06 CET 2013
Author: bodanker
Date: 2013-12-06 20:23:05 +0100 (Fri, 06 Dec 2013)
New Revision: 1577
Modified:
pkg/blotter/R/addTxn.R
Log:
- addTxns now splits transactions that would cross through zero
- addTxn and addTxns now re-calculate fees pro-rata by quantity
Modified: pkg/blotter/R/addTxn.R
===================================================================
--- pkg/blotter/R/addTxn.R 2013-12-06 15:55:29 UTC (rev 1576)
+++ pkg/blotter/R/addTxn.R 2013-12-06 19:23:05 UTC (rev 1577)
@@ -66,11 +66,13 @@
# split transactions that would cross through zero
if(PrevPosQty!=0 && sign(PrevPosQty+TxnQty)!=sign(PrevPosQty) && PrevPosQty!=-TxnQty){
+ txnFeeQty=TxnFees/abs(TxnQty) # calculate fees pro-rata by quantity
addTxn(Portfolio=pname, Symbol=Symbol, TxnDate=TxnDate, TxnQty=-PrevPosQty, TxnPrice=TxnPrice, ...,
- TxnFees = TxnFees, ConMult = ConMult, verbose = verbose, eps=eps)
+ TxnFees = txnFeeQty*abs(PrevPosQty), ConMult = ConMult, verbose = verbose, eps=eps)
TxnDate=TxnDate+2*eps #transactions need unique timestamps, so increment a bit
TxnQty=TxnQty+PrevPosQty
PrevPosQty=0
+ TxnFees=txnFeeQty*abs(TxnQty+PrevPosQty)
}
Portfolio<-get(paste("portfolio",pname,sep='.'),envir=.blotter)
@@ -153,7 +155,7 @@
#' @rdname addTxn
#' @export
-addTxns<- function(Portfolio, Symbol, TxnData , verbose=FALSE, ..., ConMult=NULL)
+addTxns<- function(Portfolio, Symbol, TxnData , verbose=FALSE, ..., ConMult=NULL, eps=1e-06)
{
pname<-Portfolio
Portfolio<-get(paste("portfolio",pname,sep='.'),envir=.blotter)
@@ -179,12 +181,37 @@
} else {
NewTxns$Txn.Fees <- 0
}
+ # split transactions that would cross through zero
+ Pos <- drop(cumsum(NewTxns$Txn.Qty))
+ Pos <- merge(Qty=Pos, PrevQty=lag(Pos))
+ PosCrossZero <- Pos$PrevQty!= 0 & sign(Pos$PrevQty+NewTxns$Txn.Qty) != sign(Pos$PrevQty) & Pos$PrevQty!= -NewTxns$Txn.Qty
+ PosCrossZero[1] <- FALSE
+ if(any(PosCrossZero)) {
+ # subset position object
+ Pos <- Pos[PosCrossZero,]
+ # subset transactions we need to split, and initialize objects we can alter
+ flatTxns <- initTxns <- NewTxns[PosCrossZero,]
+ # set quantity for flat and initiating transactions
+ flatTxns$Txn.Qty <- -Pos$PrevQty
+ initTxns$Txn.Qty <- initTxns$Txn.Qty + Pos$PrevQty
+ # calculate fees pro-rata by quantity
+ txnFeeQty <- NewTxns$Txn.Fees/abs(NewTxns$Txn.Qty)
+ flatTxns$Txn.Fees <- txnFeeQty * abs(flatTxns$Txn.Qty)
+ initTxns$Txn.Fees <- txnFeeQty * abs(initTxns$Txn.Qty)
+ # transactions need unique timestamps, so increment initiating transaction index
+ .index(initTxns) <- .index(initTxns) + 2*eps
+ # remove split transactions from NewTxns, add flat and initiating transactions
+ NewTxns <- rbind(NewTxns[!PosCrossZero,], flatTxns, initTxns)
+ rm(flatTxns, initTxns, txnFeeQty) # clean up
+ }
+ rm(Pos, PosCrossZero) # clean up
+ # calculate transaction values
NewTxns$Txn.Value <- .calcTxnValue(NewTxns$Txn.Qty, NewTxns$Txn.Price, NewTxns$Txn.Fees, ConMult)
NewTxns$Txn.Avg.Cost <- .calcTxnAvgCost(NewTxns$Txn.Value, NewTxns$Txn.Qty, ConMult)
# intermediate objects to aid in vectorization; only first element is non-zero
- initPosQty <- initPosAvgCost <- numeric(nrow(TxnData))
- initPosQty[1] <- getPosQty(pname, Symbol, start(TxnData))
- initPosAvgCost[1] <- .getPosAvgCost(pname, Symbol, start(TxnData))
+ initPosQty <- initPosAvgCost <- numeric(nrow(NewTxns))
+ initPosQty[1] <- getPosQty(pname, Symbol, start(NewTxns))
+ initPosAvgCost[1] <- .getPosAvgCost(pname, Symbol, start(NewTxns))
# cumulative sum of transaction qty + initial position qty
NewTxns$Pos.Qty <- cumsum(initPosQty + NewTxns$Txn.Qty)
# only pass non-zero initial position qty and average cost
More information about the Blotter-commits
mailing list