JBlohm
JBlohm

Reputation: 13

Trying to understand blotter account Unrealized.PL and End.Eq calculation

While programming a strategy in blotter, I came across the problem that the End.Eq after my trades did not match my expected results from manual calculation. So I have written some simple R code to better understand how blotter works. Also here the results differ from what I have expected.

Maybe someone with better insight can help me out with an explanation.

# R version 3.2.1 (2015-06-18)
# Platform: x86_64-pc-linux-gnu (64-bit)
# blotter: 0.9.1666
require(blotter)
Sys.setenv(TZ="UTC")
rm(list =ls(envir=.blotter), envir=.blotter) 

initDate <- '2008-01-01'
initEq <- 1000

currency("USD")
stock("MDY", currency = "USD", multiplier = 1)

getSymbols("MDY", from='2008-01-01', to='2008-06-30', index.class="POSIXct", adjust=T)

b.strategy <- "b.test"
initPortf(name = b.strategy, symbols = "MDY", initDate = initDate)
initAcct(name = b.strategy, portfolios = b.strategy, initDate = initDate, initEq = initEq)

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-04-30",
   TxnPrice = as.numeric(Cl(MDY["2008-04-30"])), TxnQty = 1, TxnFees = 0)
updatePortf(b.strategy, Dates = "2008-04-30")
updateAcct(b.strategy, Dates = "2008-04-30")
updateEndEq(b.strategy, Dates = "2008-04-30")

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-05-30",
   TxnPrice = as.numeric(Cl(MDY["2008-05-30"])), TxnQty = -1, TxnFees = 0)
updatePortf(b.strategy, Dates = "2008-05-30")
updateAcct(b.strategy, Dates = "2008-05-30")
updateEndEq(b.strategy, Dates = "2008-05-30")

perTradeStats(b.strategy, "MDY")
tradeStats(b.strategy)
getAccount(b.strategy)$summary

The code above initializes a portfolio with $1000 cash. I buy 1 "MDY" at the closing price on "2008-04-30". Then I close the position a month later at the closing price on "2008-05-30".

[1] "2008-04-30 00:00:00 MDY 1 @ 151.920844224256"
[1] "2008-05-30 00:00:00 MDY -1 @ 160.178061444191"

Since the portfolio contains no open positions anymore, I expect a gain in End.Eq of 1000+8.257217 = 1008.257217, but what I see is a much lower result because of Unrealized.PL = -6.72.

But where does that come from? All positions are closed, so I expect Unrealized.PL = 0. Though the transaction still seems to give me the expected result of Net.Trading.PL = 8.257217.

> perTradeStats(b.strategy, "MDY")
       Start        End Init.Pos Max.Pos Num.Txns Max.Notional.Cost Net.Trading.PL MAE      MFE
1 2008-04-30 2008-05-30        1       1        2          151.9208       8.257217   0 8.257217
  Pct.Net.Trading.PL Pct.MAE   Pct.MFE tick.Net.Trading.PL tick.MAE tick.MFE
1          0.0543521       0 0.0543521            825.7217        0 825.7217

Looking into the portfolio account, I find Unrealized.PL = -6.72 which I am unable to explain, but which clearly also leads to the unexpected End.Eq result.

> getAccount(b.strategy)$summary
           Additions Withdrawals Realized.PL Unrealized.PL Interest          Gross.Trading.PL Txn.Fees Net.Trading.PL
2008-01-01         0           0    0.000000          0.00        0         0.000000        0       0.000000
2008-04-30         0           0    0.000000          0.00        0         0.000000        0       0.000000
2008-05-30         0           0    8.257217         -6.72        0         1.535756        0       1.535756
           Advisory.Fees Net.Performance   End.Eq
2008-01-01             0        0.000000 1000.000
2008-04-30             0        0.000000 1000.000
2008-05-30             0        1.535756 1001.536

To summarize, my two questions are:

  1. Seeking an explanation how the Unrealized.PL came about?
  2. How I can avoid that, if possible?

Upvotes: 1

Views: 515

Answers (1)

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

First, you should only call the update* functions when you need to mark the book. It's inefficient to call them after every transaction if you don't actually need to use some of the values they calculate.

Second, you're calling the update* functions with a single date, which (usually) does not make sense. That causes the book to be marked for that single date only, which isn't particularly helpful. It would make more sense to use a date range like "2008-04-30/2008-05-30".

The non-zero Unrealized.PL is because your position-closing transaction occurs at the end of 2008-05-30, which means you have unrealized P&L for that day.

The modified version of your code below should give the results you expect.

require(blotter)
Sys.setenv(TZ="UTC")
rm(list =ls(envir=.blotter), envir=.blotter) 

initDate <- '2008-01-01'
initEq <- 1000

currency("USD")
stock("MDY", currency = "USD", multiplier = 1)
getSymbols("MDY", from='2008-01-01', to='2008-06-30', index.class="POSIXct", adjust=T)

b.strategy <- "b.test"
initPortf(name = b.strategy, symbols = "MDY", initDate = initDate)
initAcct(name = b.strategy, portfolios = b.strategy, initDate = initDate, initEq = initEq)

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-04-30",
  TxnPrice = as.numeric(Cl(MDY["2008-04-30"])), TxnQty = 1, TxnFees = 0)
addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-05-30",
  TxnPrice = as.numeric(Cl(MDY["2008-05-30"])), TxnQty = -1, TxnFees = 0)

updatePortf(b.strategy, Dates = "2008-04-30/2008-05-30")
updateAcct(b.strategy, Dates = "2008-04-30/2008-05-30")
updateEndEq(b.strategy, Dates = "2008-04-30/2008-05-30")

perTradeStats(b.strategy, "MDY")
tradeStats(b.strategy)
getAccount(b.strategy)$summary
getPortfolio(b.strategy)$summary

Upvotes: 1

Related Questions