[Blotter-commits] r403 - in pkg/blotter: . R demo

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Oct 2 20:12:25 CEST 2010


Author: braverock
Date: 2010-10-02 20:12:24 +0200 (Sat, 02 Oct 2010)
New Revision: 403

Modified:
   pkg/blotter/DESCRIPTION
   pkg/blotter/R/calcPortfAttr.R
   pkg/blotter/R/calcPortfSummary.R
   pkg/blotter/R/chart.Posn.R
   pkg/blotter/R/initPosPL.R
   pkg/blotter/R/updatePortf.R
   pkg/blotter/R/updatePosPL.R
   pkg/blotter/demo/turtles.R
Log:
- fix edge cases for PL calc when transactions happen on first measurement period
- simplify some of the other calculations
- fix turtles demo so it can be run multiple times in the same session

Modified: pkg/blotter/DESCRIPTION
===================================================================
--- pkg/blotter/DESCRIPTION	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/DESCRIPTION	2010-10-02 18:12:24 UTC (rev 403)
@@ -5,11 +5,15 @@
 Date: $Date$
 Author: Peter Carl, Brian G. Peterson, Joshua Ulrich
 Maintainer: Brian G. Peterson <brian at braverock.com>
-Description: Transaction infrastructure for defining instruments, transactions, portfolios and accounts for trading systems and simulation.  Intends to provide portfolio support for multi-asset class and multi-currency portfolios.  Still in heavy development.
+Description: Transaction infrastructure for defining instruments,
+    transactions, portfolios and accounts for trading systems and
+    simulation.  Intends to provide portfolio support for multi-asset
+    class and multi-currency portfolios.  Still in heavy development.
 License: GPL
 LazyLoad: yes
-Depends: R (>= 2.9.0), xts (>= 0.7-5), quantmod (>= 0.3-14), FinancialInstrument
+Depends: R (>= 2.9.0), xts (>= 0.7-5), quantmod (>= 0.3-14),
+    FinancialInstrument
 Suggests: PerformanceAnalytics, PortfolioAnalytics, Hmisc, RUnit
-Contributors: Wolfgang Wu, Ben McCann 
+Contributors: Wolfgang Wu, Ben McCann
 URL: https://r-forge.r-project.org/projects/blotter/
-Copyright: (c) 2008-2010
+Copyright: (c) 2008-2010
\ No newline at end of file

Modified: pkg/blotter/R/calcPortfAttr.R
===================================================================
--- pkg/blotter/R/calcPortfAttr.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/calcPortfAttr.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -24,15 +24,15 @@
             result = xts(rowSums(table, na.rm=TRUE), order.by=index(table))
             colnames(result) = 'Net.Trading.PL'
         },
-        Realized.PL = {
-            table = .getBySymbol(Portfolio = Portfolio, Attribute = 'Realized.PL', Dates = Dates, Symbols = Symbols)
+        Period.Realized.PL = {
+            table = .getBySymbol(Portfolio = Portfolio, Attribute = 'Period.Realized.PL', Dates = Dates, Symbols = Symbols)
             result = xts(rowSums(table, na.rm=TRUE), order.by=index(table))
-            colnames(result) = 'Realized.PL'
+            colnames(result) = 'Period.Realized.PL'
         },
-        Unrealized.PL = {
-            table = .getBySymbol(Portfolio = Portfolio, Attribute = 'Unrealized.PL', Dates = Dates, Symbols = Symbols)
+        Period.Unrealized.PL = {
+            table = .getBySymbol(Portfolio = Portfolio, Attribute = 'Period.Unrealized.PL', Dates = Dates, Symbols = Symbols)
             result = xts(rowSums(table, na.rm=TRUE), order.by=index(table))
-            colnames(result) = 'Unrealized.PL'
+            colnames(result) = 'Period.Unrealized.PL'
         },
         Net.Value = {
             table = .getBySymbol(Portfolio = Portfolio, Attribute = 'Pos.Value', Dates = Dates, Symbols = Symbols)

Modified: pkg/blotter/R/calcPortfSummary.R
===================================================================
--- pkg/blotter/R/calcPortfSummary.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/calcPortfSummary.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -11,8 +11,8 @@
     
     GrossTradingPL = calcPortfAttr(Portfolio, 'Gross.Trading.PL', Dates)
     NetTradingPL = calcPortfAttr(Portfolio, 'Net.Trading.PL', Dates)
-    RealizedPL = calcPortfAttr(Portfolio, 'Realized.PL', Dates)
-    UnrealizedPL = calcPortfAttr(Portfolio, 'Unrealized.PL', Dates)
+    RealizedPL = calcPortfAttr(Portfolio, 'Period.Realized.PL', Dates)
+    UnrealizedPL = calcPortfAttr(Portfolio, 'Period.Unrealized.PL', Dates)
     # UnrealizedPL = TradingPL - RealizedPL
     TxnFees = calcPortfAttr(Portfolio, 'Txn.Fees', Dates)
     NetValue = calcPortfAttr(Portfolio, 'Net.Value', Dates)

Modified: pkg/blotter/R/chart.Posn.R
===================================================================
--- pkg/blotter/R/chart.Posn.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/chart.Posn.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -1,5 +1,10 @@
+#' chart trades against market data, position through time, and equity curve
+#' @param Portfolio string identifying the portfolio to chart
+#' @param Symbol string identifying the symbol to chart
+#' @param Dates date range, currently not used
+#' @param ... any other passthru parameters (typically parameters to \code{chart_Series})
 #' @export
-chart.Posn <- function(Portfolio, Symbol = NULL, Dates = NULL, ...)
+chart.Posn <- function(Portfolio, Symbol, Dates = NULL, ...)
 { # @author Peter Carl
     pname<-Portfolio
     Portfolio<-getPortfolio(pname)

Modified: pkg/blotter/R/initPosPL.R
===================================================================
--- pkg/blotter/R/initPosPL.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/initPosPL.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -18,7 +18,7 @@
 
     # FUNCTION
     posPL <- xts( as.matrix(t(c(initPosQty,initConMult,initCcyMult,0,0,0,0,0,0,0,0))), order.by=as.POSIXct(initDate) )
-    colnames(posPL) <- c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Pos.Avg.Cost', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
+    colnames(posPL) <- c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Pos.Avg.Cost', 'Txn.Value',  'Period.Realized.PL', 'Period.Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
     class(posPL)<- c("posPL",class(posPL))
     return(posPL)
 }

Modified: pkg/blotter/R/updatePortf.R
===================================================================
--- pkg/blotter/R/updatePortf.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/updatePortf.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -15,7 +15,7 @@
 #' @param Prices
 #' @export
 updatePortf <- function(Portfolio, Symbols=NULL, Dates=NULL, Prices=NULL)
-{ #' @author Peter Carl
+{ #' @author Peter Carl, Brian Peterson
     pname<-Portfolio
     Portfolio<-getPortfolio(pname) # TODO add Date handling
 
@@ -32,7 +32,7 @@
     Portfolio<-getPortfolio(pname) # refresh with an updated object
 	if(is.null(Dates)) Dates <- time(Portfolio$symbols[[1]]$posPL)  #not quite right, only using first symbol...
     #Symbols = names(Portfolio$symbols)
-    Attributes = c('Long.Value', 'Short.Value', 'Net.Value', 'Gross.Value', 'Realized.PL', 'Unrealized.PL', 'Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
+    Attributes = c('Long.Value', 'Short.Value', 'Net.Value', 'Gross.Value', 'Period.Realized.PL', 'Period.Unrealized.PL', 'Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
     summary = NULL
 	tmp.attr=NULL
     for(attribute in Attributes) {
@@ -58,8 +58,8 @@
 						Net.Value   = {	result = xts(rowSums(table, na.rm=TRUE), order.by=index(table))	}
 				)
             },
-			Realized.PL =,
-			Unrealized.PL =,
+			Period.Realized.PL =,
+			Period.Unrealized.PL =,
 			Gross.Trading.PL =,
 			Txn.Fees =,
 			Net.Trading.PL = { 

Modified: pkg/blotter/R/updatePosPL.R
===================================================================
--- pkg/blotter/R/updatePosPL.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/R/updatePosPL.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -48,52 +48,65 @@
 	# trim posPL slot to not double count, related to bug 831 on R-Forge 
 	Portfolio$symbols[[Symbol]]$posPL<-Portfolio$symbols[[Symbol]]$posPL[paste('::',startDate,sep='')]
 	Portfolio$symbols[[Symbol]][[paste('posPL',p.ccy.str,sep='.')]]<-Portfolio$symbols[[Symbol]][[paste('posPL',p.ccy.str,sep='.')]][paste('::',startDate,sep='')]
+	priorPL<-last(Portfolio$symbols[[Symbol]]$posPL)
 	
 	Txns <- Portfolio$symbols[[Symbol]]$txn[dateRange]
 	# if there are no transactions, get the last one before the current dateRange, we'll discard later
 	if(nrow(Txns)==0) {
 		Txns <- last(Portfolio$symbols[[Symbol]]$txn[paste('::',startDate,sep='')])
-		rmfirst=TRUE
 	} 
 	
 	#	 line up transaction with Dates list
-	tmpPL <- merge(Txns, Prices) # most Txn columns will get discarded later
-
+	tmpPL <- merge(Txns, priorPL, Prices) # most Txn columns will get discarded later, as will the rows from 'before' the startDate
+	
+	#browser()
+	
 	if(is.na(tmpPL$Prices[1])){
-		tmpPL$Prices[1] <- last(prices[paste('::',startDate,sep='')])
+		#first price is NA, it would be nice to fill it in with a previous last valid price
+		fprice <- last(prices[paste('::',startDate,sep='')])
+		if (length(fprice)==1) tmpPL$Prices[1] <- fprice 
 	}
-
+	
 	# na.locf any missing prices with last observation (this assumption seems the only rational one for vectorization)
 	tmpPL$Prices <- na.locf(tmpPL$Prices)
 
-	# na.locf Pos.Qty,Con.Mult,Pos.Avg.Cost to instantiate $posPL new rows
+	# na.locf Pos.Qty,Con.Mult,Pos.Avg.Cost to instantiate $posPL new rows	
+	#tmpPL$Pos.Qty.1 <- na.locf(tmpPL$Pos.Qty.1)
+	#lagPosQty<-Lag(tmpPL$Pos.Qty.1)
+	tmpPL$Pos.Qty <- ifelse(is.na(tmpPL$Pos.Qty) & !is.na(tmpPL$Pos.Qty.1), tmpPL$Pos.Qty.1, tmpPL$Pos.Qty)
+	#tmpPL$Pos.Qty <- ifelse(is.na(tmpPL$Pos.Qty) & !is.na(lagPosQty), tmpPL$Pos.Qty.1, tmpPL$Pos.Qty)
 	tmpPL$Pos.Qty <- na.locf(tmpPL$Pos.Qty)
-	tmpPL$Pos.Qty <- ifelse(is.na(tmpPL$Pos.Qty),0, tmpPL$Pos.Qty)
 
+	tmpPL$Con.Mult.1 <- na.locf(tmpPL$Con.Mult.1)
+	tmpPL$Con.Mult.1 <- ifelse(is.na(tmpPL$Con.Mult) & !is.na(tmpPL$Con.Mult.1) , tmpPL$Con.Mult.1, tmpPL$Con.Mult)
 	tmpPL$Con.Mult <- na.locf(tmpPL$Con.Mult)
 	tmpPL$Con.Mult <- ifelse(is.na(tmpPL$Con.Mult) ,1, tmpPL$Con.Mult)
 	
+	tmpPL$Pos.Avg.Cost.1 <- na.locf(tmpPL$Pos.Avg.Cost.1)
+	tmpPL$Pos.Avg.Cost <- ifelse(is.na(tmpPL$Pos.Avg.Cost) & !is.na(tmpPL$Pos.Avg.Cost.1) ,tmpPL$Pos.Avg.Cost.1, tmpPL$Pos.Avg.Cost)
 	tmpPL$Pos.Avg.Cost <- na.locf(tmpPL$Pos.Avg.Cost)
-	tmpPL$Pos.Avg.Cost <- ifelse(is.na(tmpPL$Pos.Avg.Cost),0, tmpPL$Pos.Avg.Cost)
 	
 	# zerofill Txn.Value, Txn.Fees
 	tmpPL$Txn.Value <- ifelse(is.na(tmpPL$Txn.Value),0, tmpPL$Txn.Value)
+	
 	tmpPL$Txn.Fees  <- ifelse(is.na(tmpPL$Txn.Fees) ,0, tmpPL$Txn.Fees)
 	
 	# matrix calc Pos.Qty * Price * Con.Mult to get Pos.Value
 	tmpPL$Pos.Value <- tmpPL$Pos.Qty * tmpPL$Con.Mult * tmpPL$Prices
 	
-	# matrix calc Unrealized.PL as Pos.Qty*(Price-Pos.Avg.Cost)*Con.Mult
-	tmpPL$Unrealized.PL <- round(tmpPL$Pos.Qty*(tmpPL$Prices-tmpPL$Pos.Avg.Cost)*tmpPL$Con.Mult,2)
-	
-	# matrix calc Gross.Trading.PL as Pos.Value-Lag(Pos.Value)-Txn.Value
 	LagValue<-Lag(tmpPL$Pos.Value)
 	LagValue<-ifelse(is.na(LagValue),0,LagValue) # needed to avoid a possible NA on the first value that would mess up the Gross.Trading.PL calc
 	tmpPL$Gross.Trading.PL <- tmpPL$Pos.Value- LagValue - tmpPL$Txn.Value
 	
-	# matrix calc Realized.PL as Gross.Trading.PL - Unrealized.PL
-	tmpPL$Realized.PL <- round(tmpPL$Gross.Trading.PL - tmpPL$Unrealized.PL,2)
 	
+	# alternate matrix calc for Realized&Unrealized PL that is only dependent on Txn PL and Gross.Trading.PL
+	tmpPL$Net.Txn.Realized.PL <- ifelse(is.na(tmpPL$Net.Txn.Realized.PL),0,tmpPL$Net.Txn.Realized.PL)
+	tmpPL$Gross.Txn.Realized.PL <- ifelse(is.na(tmpPL$Gross.Txn.Realized.PL),0,tmpPL$Gross.Txn.Realized.PL)
+	
+	#tmpPL$Gross.Trading.PL <- tmpPL$Pos.Value - (tmpPL$Pos.Qty*tmpPL$Pos.Avg.Cost) +  tmpPL$Gross.Txn.Realized.PL
+	tmpPL$Period.Realized.PL <- tmpPL$Net.Txn.Realized.PL
+	tmpPL$Period.Unrealized.PL <- round(tmpPL$Gross.Trading.PL - tmpPL$Period.Realized.PL,2)
+	
 	# matrix calc Net.Trading.PL as Gross.Trading.PL + Txn.Fees
 	tmpPL$Net.Trading.PL <- tmpPL$Gross.Trading.PL + tmpPL$Txn.Fees
 
@@ -101,10 +114,10 @@
 	tmpPL$Ccy.Mult<-rep(1,nrow(tmpPL))
 	
 	# reorder,discard  columns for insert into portfolio object
-	tmpPL <- tmpPL[,c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Pos.Avg.Cost', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')]
+	tmpPL <- tmpPL[,c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Pos.Avg.Cost', 'Txn.Value',  'Period.Realized.PL', 'Period.Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')]
 
 	# rbind to $posPL slot
-	if(isTRUE(rmfirst)) tmpPL<-tmpPL[-1,] #remove the constructed first row, so we don't insert dups in the table
+	tmpPL <- tmpPL[dateRange] #subset to get rid of any prior period Txn or PosPL rows we inserted
 	Portfolio$symbols[[Symbol]]$posPL<-rbind(Portfolio$symbols[[Symbol]]$posPL,tmpPL)
 		
 
@@ -160,7 +173,7 @@
 	}
 	
 	#multiply the correct columns    
-    columns<-c('Pos.Value', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
+    columns<-c('Pos.Value', 'Txn.Value',  'Period.Realized.PL', 'Period.Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
 #    for (column in columns){
 #        TmpPeriods[,column]<-TmpPeriods[,column]*CcyMult
 #    }

Modified: pkg/blotter/demo/turtles.R
===================================================================
--- pkg/blotter/demo/turtles.R	2010-09-27 13:03:51 UTC (rev 402)
+++ pkg/blotter/demo/turtles.R	2010-10-02 18:12:24 UTC (rev 403)
@@ -1,29 +1,4 @@
-updateStrat <- function(Portfolio, Symbol, TxnDate, PosUnitsQty, UnitSize, StopPrice, TxnPrice, TxnN)
-{ # @author Peter Carl
 
-    # DESCRIPTION:
-    # Adds transactions-related data to the STRATEGY timeseries.
-
-    # Inputs
-    # TxnDate: transaction date as ISO 8106, e.g., '2008-09-01'
-    # PosUnitsQty: total units (shares) of the transaction
-    # StopPrice: price at which the transaction was done
-    # TxnPrice: last trade price
-    # TxnN: calculated N for last transaction
-
-    # Outputs:
-    # No output.  Modifies STRATEGY in local namespace.
-
-    # FUNCTION
-    # Store the transaction and calculations, returns the portfolio
-    pname=Portfolio
-    NewTxn = xts(t(c(PosUnitsQty, UnitSize, StopPrice, TxnPrice, TxnN)), order.by=as.POSIXct(TxnDate))
-    colnames(NewTxn) = c('Pos.Units', 'Unit.Size', 'Stop.Price', 'Txn.Price', 'Txn.N')
-    Portfolio<-getPortfolio(Portfolio)
-    Portfolio[[Symbol]]$strat <- rbind(Portfolio[[Symbol]]$strat, NewTxn)
-    assign( paste("portfolio",pname,sep='.'), Portfolio, envir=.blotter )
-}
-
 # - Turtle System #1
 
 # required libraries
@@ -31,6 +6,11 @@
 require(TTR)
 require(blotter)
 
+# Try to clean up in case the demo was run previously
+try(rm("account.turtles","portfolio.turtles",pos=.blotter),silent=TRUE)
+try(rm("portfolio","account","N","symbol","symbols","ClosePrice","CurrentDate","equity","Units","maxUnits","size","Stop","equity","TxnPrice","initDate","initEq","Posn","verbose"),silent=TRUE)
+
+
 # Set initial values
 initDate="2008-01-01"
 initEq=100000
@@ -42,6 +22,33 @@
     stock(symbol, currency="USD",multiplier=1)
 }
 
+#set function for storing intermediate values
+updateStrat <- function(Portfolio, Symbol, TxnDate, PosUnitsQty, UnitSize, StopPrice, TxnPrice, TxnN)
+{ # @author Peter Carl
+	
+	# DESCRIPTION:
+	# Adds transactions-related data to the STRATEGY timeseries.
+	
+	# Inputs
+	# TxnDate: transaction date as ISO 8106, e.g., '2008-09-01'
+	# PosUnitsQty: total units (shares) of the transaction
+	# StopPrice: price at which the transaction was done
+	# TxnPrice: last trade price
+	# TxnN: calculated N for last transaction
+	
+	# Outputs:
+	# No output.  Modifies STRATEGY in local namespace.
+	
+	# FUNCTION
+	# Store the transaction and calculations, returns the portfolio
+	pname=Portfolio
+	NewTxn = xts(t(c(PosUnitsQty, UnitSize, StopPrice, TxnPrice, TxnN)), order.by=as.POSIXct(TxnDate))
+	colnames(NewTxn) = c('Pos.Units', 'Unit.Size', 'Stop.Price', 'Txn.Price', 'Txn.N')
+	Portfolio<-getPortfolio(Portfolio)
+	Portfolio[[Symbol]]$strat <- rbind(Portfolio[[Symbol]]$strat, NewTxn)
+	assign( paste("portfolio",pname,sep='.'), Portfolio, envir=.blotter )
+}
+
 getSymbols(symbols, index.class="POSIXct", from=initDate, source="yahoo")
 # getSymbols now defaults (as originally) to "Date" indexing.  We can change to use POSIXct here.
 # getSymbols(symbols, index.class=c("POSIXt","POSIXct"), from=initDate, source="yahoo")



More information about the Blotter-commits mailing list