[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