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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Apr 1 22:07:39 CEST 2010


Author: braverock
Date: 2010-04-01 22:07:39 +0200 (Thu, 01 Apr 2010)
New Revision: 320

Modified:
   pkg/blotter/DESCRIPTION
   pkg/blotter/R/updatePosPL.R
Log:
- multi-currency support for portfolio as another 'table' in $posPL

Modified: pkg/blotter/DESCRIPTION
===================================================================
--- pkg/blotter/DESCRIPTION	2010-03-31 20:33:25 UTC (rev 319)
+++ pkg/blotter/DESCRIPTION	2010-04-01 20:07:39 UTC (rev 320)
@@ -1,7 +1,7 @@
 Package: blotter
 Type: Package
 Title: Tools for transaction-oriented trading systems development.
-Version: 0.4
+Version: 0.5
 Date: $Date$
 Author: Peter Carl, Brian G. Peterson
 Maintainer: Brian G. Peterson <brian at braverock.com>

Modified: pkg/blotter/R/updatePosPL.R
===================================================================
--- pkg/blotter/R/updatePosPL.R	2010-03-31 20:33:25 UTC (rev 319)
+++ pkg/blotter/R/updatePosPL.R	2010-04-01 20:07:39 UTC (rev 320)
@@ -41,14 +41,16 @@
     if(is.null(ConMult) | !hasArg(ConMult)){
         tmp_instr<-try(getInstrument(Symbol))
         if(inherits(tmp_instr,"try-error") | !is.instrument(tmp_instr)){
-            warning("Instrument",Symbol," not found, using contract multiplier of 1")
+            warning(paste("Instrument",Symbol," not found, using contract multiplier of 1"))
             ConMult<-1
         } else {
-            ConMult<-tmp_instr$multiplier # TODO ultimately this needs to be time series aware
+            ConMult<-tmp_instr$multiplier
         }  
     }
-    CcyMult = NULL 
-    FXrate = NULL
+    PrevConMult = 1 ## @TODO: Change this to look up the value from instrument?
+
+    CcyMult = NA 
+    FXrate = NA
     invert=FALSE
     if(!is.null(attr(Portfolio,'currency'))) {
         p.ccy.str<-attr(Portfolio,'currency')
@@ -75,10 +77,9 @@
             }
         }
     } else {
-        message("no currency multiplier set on portfolio, using currency multiplier of 1")
+        message("no currency set on portfolio, using currency multiplier of 1")
         CcyMult =1
     }
-    #PrevCcyMult =1 ## @TODO: Change this to look up the value from instrument?
     
     # For each date, calculate realized and unrealized P&L
     for(i in 1:length(Dates)){ ##
@@ -97,31 +98,13 @@
         PrevSpan = paste(PriorPrevDateLast, PrevDate, sep="::")
         if(length(PrevDate)==0)
              PrevDate = NA
-
-        if(is.null(CcyMult) & !is.null(FXrate)) {
-            if(inherits(FXrate,'xts')){
-                CcyMult<-as.numeric(last(FXrate[paste('::',as.character(CurrentDate),sep='')]))
-                PrevCcyMult<-as.numeric(last(FXrate[paste('::',as.character(PrevDateLast),sep='')]))
-            } else {
-                CcyMult<-as.numeric(FXrate)
-                PrevCcyMult<-CcyMult
-            }
-        } else {
-            CcyMult<-1
-            PrevCcyMult<-CcyMult
-        }
-        if(isTRUE(invert)){
-            # portfolio and instrument have different currencies, and FXrate was in the wrong direction
-            CcyMult<-1/CcyMult
-            PrevCcyMult<-1/PrevCcyMult
-        }
         
         #TODO write a single getTxn and use the values instead of these lines
-        TxnValue = getTxnValue(pname, Symbol, CurrentSpan)*CcyMult
-        TxnFees = getTxnFees(pname, Symbol, CurrentSpan)*CcyMult
+        TxnValue = getTxnValue(pname, Symbol, CurrentSpan)
+        TxnFees = getTxnFees(pname, Symbol, CurrentSpan)
         PosQty = getPosQty(pname, Symbol, as.character(CurrentDate))
         
-        ClosePrice = as.numeric(last(Prices[CurrentDate, grep("Close", colnames(Prices))]))*CcyMult
+        ClosePrice = as.numeric(last(Prices[CurrentDate, grep("Close", colnames(Prices))])) #not necessary
         PosValue = calcPosValue(PosQty, ClosePrice, ConMult)
 
         if(is.na(PrevDate))
@@ -132,19 +115,50 @@
         if(PrevPosQty==0)
             PrevClosePrice = 0
         else
-            PrevClosePrice = as.numeric(Cl(Prices)[as.character(PrevDate)])*PrevCcyMult
+            PrevClosePrice = as.numeric(Cl(Prices)[as.character(PrevDate)])
 
         PrevPosValue = calcPosValue(PrevPosQty, PrevClosePrice, ConMult) ### @TODO: PrevConMult?
         GrossTradingPL = PosValue - PrevPosValue - TxnValue
         NetTradingPL = GrossTradingPL + TxnFees # Fees are assumed to have negative values
+
+        UnrealizedPL = PosQty*(ClosePrice-getPosAvgCost(Portfolio=pname, Symbol, CurrentDate))*ConMult
+
+        RealizedPL = round(GrossTradingPL - UnrealizedPL,2)
         #$unrealized_gl    = $end_return['calc_position'] * ($end_return['last_price'] - $end_return['average_cost']);
-        UnrealizedPL = PosQty*(ClosePrice-(getPosAvgCost(Portfolio=pname, Symbol, CurrentDate)*CcyMult))*ConMult
-        RealizedPL = round(GrossTradingPL - UnrealizedPL,2)
 
         NewPeriod = as.xts(t(c(PosQty, ConMult, CcyMult, PosValue, TxnValue, RealizedPL, UnrealizedPL, GrossTradingPL, TxnFees, NetTradingPL)), order.by=CurrentDate) #, format=tformat
-        colnames(NewPeriod) = c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
+        colnames(NewPeriod) =  c('Pos.Qty', 'Con.Mult', 'Ccy.Mult', 'Pos.Value', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
         Portfolio[[Symbol]]$posPL <- rbind(Portfolio[[Symbol]]$posPL, NewPeriod) 
     }
+    
+    # now do the currency conversions for the whole date range
+    startDate = xts:::.parseISO8601(first(Dates))$first.time-1
+    endDate   = xts:::.parseISO8601(last(Dates))$last.time
+    dateRange = paste(startDate,endDate,sep='::')
+    TmpPeriods<-Portfolio[[Symbol]]$posPL[dateRange]
+    if(is.na(CcyMult) & !is.na(FXrate)) {
+        if(inherits(FXrate,'xts')){
+            CcyMult <- FXrate[dateRange]
+            CcyMult <- na.locf(merge(CcyMult,index(TmpPeriods)))
+            CcyMult <- CcyMult[index(TmpPeriods)]
+        } else {
+            CcyMult<-as.numeric(FXrate)
+        }
+    } else {
+        CcyMult<-1
+    }
+    if(isTRUE(invert)){
+        # portfolio and instrument have different currencies, and FXrate was in the wrong direction
+        CcyMult<-1/CcyMult
+    }
+    #multiply the correct columns, (probably one at a time?)    
+    columns<-c('Pos.Value', 'Txn.Value',  'Realized.PL', 'Unrealized.PL','Gross.Trading.PL', 'Txn.Fees', 'Net.Trading.PL')
+    for (column in columns){
+        TmpPeriods[,column]<-TmpPeriods[,column]*CcyMult
+    }
+    TmpPeriods[,'Ccy.Mult']<-CcyMult
+    #stick it in posPL.ccy
+    Portfolio[[Symbol]][[paste('posPL',p.ccy.str,sep='.')]]<-rbind(Portfolio[[Symbol]][[paste('posPL',p.ccy.str,sep='.')]],TmpPeriods)
     # return(Portfolio)
     assign( paste("portfolio",pname,sep='.'), Portfolio, envir=.blotter )
 }



More information about the Blotter-commits mailing list