Consider the following example. Initialise portfolio on day 1 with 100 USD, buy
stock ABC on day 2 at a price of 100, sell stock ABC on day 3 at a price of 100.
Now the End.Eq in getAccount is showing 200 USD.
library(blotter)
currency('USD')
stock('ABC', currency='USD', multiplier=1)
initPortf('portA', symbols="ABC", initDate='2010-01-01');
initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100);
#Buy on day 2
addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=100, TxnQty = 1,
TxnFees=0, verbose=TRUE)
currentPrice <- xts(100, order.by=as.Date('2010-01-02'))
updatePortf('portA', Dates = '2010-01-02', Prices=currentPrice)
updateAcct('accA', Dates = '2010-01-02')
updateEndEq('accA', Dates = '2010-01-02')
#Sell on day 3
addTxn("portA", Symbol='ABC', TxnDate='2010-01-03', TxnPrice=100, TxnQty = -1,
TxnFees=0, verbose=TRUE)
currentPrice <- xts(100, order.by=as.Date('2010-01-03'))
updatePortf('portA', Dates = '2010-01-03', Prices=currentPrice)
updateAcct('accA', Dates = '2010-01-03')
updateEndEq('accA', Dates = '2010-01-03')
#Equity wrong?
getPortfolio('portA')
getAccount('accA')
Wolfgang Wu
Possible bug in blotter
8 messages · Peter Carl, Wolfgang Wu, Brian G. Peterson
Wolfgang,
Your example is sending in prices in a way that blotter doesn't expect.
I've modified your example to construct the price series that blotter can
work with. We'll have to figure out a way to check the price series and
warn the user when it's mangled, so I appreciate the use case.
I've modified your script to construct a time series of prices for the
instrument being traded, ABC. blotter uses FinancialInstrument to
associate the prices with the instrument, so that you don't have to. I'd
refer you to the documentation, but we're still writing it...
library(blotter)
currency('USD')
stock('ABC', currency='USD', multiplier=1)
initPortf('portA', symbols="ABC", initDate='2010-01-01');
initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100);
#Buy on day 2
addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=100, TxnQty =
1, TxnFees=0, verbose=TRUE)
ABC <- xts(100, order.by=as.Date('2010-01-02'))
colnames(ABC) = "Close"
updatePortf('portA', Dates = '2010-01-02')
updateAcct('accA', Dates = '2010-01-02')
updateEndEq('accA', Dates = '2010-01-02')
#Sell on day 3
addTxn("portA", Symbol='ABC', TxnDate='2010-01-03', TxnPrice=100, TxnQty =
-1, TxnFees=0, verbose=TRUE)
ABC <- rbind(ABC, xts(100, order.by=as.Date('2010-01-03')))
updatePortf('portA', Dates = '2010-01-03')
updateAcct('accA', Dates = '2010-01-03')
updateEndEq('accA', Dates = '2010-01-03')
#Equity wrong?
getPortfolio('portA')
getAccount('accA')
That results in:
getAccount('accA')
$portfolios
$portfolios$portA
Long.Value Short.Value Net.Value Gross.Value Realized.PL
2010-01-01 0 0 0 0 0
2010-01-02 100 0 100 100 0
2010-01-03 0 0 0 0 0
Unrealized.PL Gross.Trading.PL Txn.Fees Net.Trading.PL
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 0 0 0 0
$summary
Additions Withdrawals Realized.PL Unrealized.PL Int.Income
2010-01-01 0 0 0 0 0
2010-01-02 0 0 0 0 0
2010-01-03 0 0 0 0 0
Gross.Trading.PL Txn.Fees Net.Trading.PL Advisory.Fees
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 0 0 0 0
Net.Performance End.Eq
2010-01-01 0 100
2010-01-02 0 100
2010-01-03 0 100
attr(,"currency")
[1] "USD"
attr(,"initEq")
[1] 100
attr(,"class")
[1] "portfolio_account" "account"
... which is, I think, what you're looking for.
pcc
Peter Carl http://www.braverock.com/~peter > Consider the following example. Initialise portfolio on day 1 with 100 > USD, buy > stock ABC on day 2 at a price of 100, sell stock ABC on day 3 at a price > of 100. > Now the End.Eq in getAccount is showing 200 USD. > > > library(blotter) > currency('USD') > stock('ABC', currency='USD', multiplier=1) > initPortf('portA', symbols="ABC", initDate='2010-01-01'); > initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100); > #Buy on day 2 > addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=100, TxnQty = > 1, > TxnFees=0, verbose=TRUE) > currentPrice <- xts(100, order.by=as.Date('2010-01-02')) > updatePortf('portA', Dates = '2010-01-02', Prices=currentPrice) > updateAcct('accA', Dates = '2010-01-02') > updateEndEq('accA', Dates = '2010-01-02') > #Sell on day 3 > addTxn("portA", Symbol='ABC', TxnDate='2010-01-03', TxnPrice=100, TxnQty = > -1, > TxnFees=0, verbose=TRUE) > currentPrice <- xts(100, order.by=as.Date('2010-01-03')) > updatePortf('portA', Dates = '2010-01-03', Prices=currentPrice) > updateAcct('accA', Dates = '2010-01-03') > updateEndEq('accA', Dates = '2010-01-03') > #Equity wrong? > getPortfolio('portA') > getAccount('accA') > > Wolfgang Wu > > > > > _______________________________________________ > R-SIG-Finance at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-sig-finance > -- Subscriber-posting only. If you want to post, subscribe first. > -- Also note that this is not the r-help list where general R questions > should go. >
Peter,
thank you for the explanation. I understand this now. However consider a
different example where the security is now a futures contract with a multiplier
of 2. Then blotter will produce a wrong End.Eq. (See example code) I suspect the
Con.Mult column in the first row of the portfolio object is set wrongly and is
causing the problem. Would you agree?
library(blotter)
currency('USD')
future('ABC', currency='USD', multiplier=2, tick_size=1)
initPortf('portA', symbols="ABC", initDate='2010-01-01');
initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100);
#Buy on day 2
addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=100, TxnQty =1,
TxnFees=0, verbose=TRUE)
ABC <- xts(100, order.by=as.Date('2010-01-02'))
colnames(ABC) = "Close"
updatePortf('portA', Dates = '2010-01-02')
updateAcct('accA', Dates = '2010-01-02')
updateEndEq('accA', Dates = '2010-01-02')
#Sell on day 3
addTxn("portA", Symbol='ABC', TxnDate='2010-01-03', TxnPrice=100, TxnQty =-1,
TxnFees=0, verbose=TRUE)
ABC <- rbind(ABC, xts(100, order.by=as.Date('2010-01-03')))
updatePortf('portA', Dates = '2010-01-03')
updateAcct('accA', Dates = '2010-01-03')
updateEndEq('accA', Dates = '2010-01-03')
#Equity wrong?
getPortfolio('portA')
getAccount('accA')
I then get the following result
getPortfolio('portA')
$symbols
$symbols$ABC
$symbols$ABC$txn
Txn.Qty Txn.Price Txn.Value Txn.Avg.Cost Pos.Qty Pos.Avg.Cost
2010-01-01 0 0 0 0 0 0
2010-01-02 1 100 200 100 1 100
2010-01-03 -1 100 -200 100 0 0
Gross.Txn.Realized.PL Txn.Fees Net.Txn.Realized.PL Con.Mult
2010-01-01 0 0 0 0
2010-01-02 0 0 0 2
2010-01-03 0 0 0 2
$symbols$ABC$posPL
Pos.Qty Con.Mult Ccy.Mult Pos.Value Pos.Avg.Cost Txn.Value
2010-01-01 0 1 1 0 0 0
2010-01-02 1 2 1 200 100 200
2010-01-03 0 2 1 0 0 -200
Period.Realized.PL Period.Unrealized.PL Gross.Trading.PL Txn.Fees
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 0 100 100 0
Net.Trading.PL
2010-01-01 0
2010-01-02 0
2010-01-03 100
$symbols$ABC$posPL.USD
Pos.Qty Con.Mult Ccy.Mult Pos.Value Pos.Avg.Cost Txn.Value
2010-01-01 0 1 1 0 0 0
2010-01-02 1 2 1 200 100 200
2010-01-03 0 2 1 0 0 -200
Period.Realized.PL Period.Unrealized.PL Gross.Trading.PL Txn.Fees
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 0 100 100 0
Net.Trading.PL
2010-01-01 0
2010-01-02 0
2010-01-03 100
$summary
Long.Value Short.Value Net.Value Gross.Value Period.Realized.PL
2010-01-03 0 0 0 0 0
Period.Unrealized.PL Gross.Trading.PL Txn.Fees Net.Trading.PL
2010-01-03 100 100 0 100
attr(,"class")
[1] "blotter_portfolio" "portfolio"
attr(,"currency")
[1] "USD"
attr(,"initDate")
[1] "2010-01-01"
getAccount('accA')
$portfolios
$portfolios$portA
Long.Value Short.Value Net.Value Gross.Value Realized.PL
2010-01-01 0 0 0 0 0
2010-01-02 200 0 200 200 0
2010-01-03 0 0 0 0 0
Unrealized.PL Gross.Trading.PL Txn.Fees Net.Trading.PL
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 100 100 0 100
$summary
Additions Withdrawals Realized.PL Unrealized.PL Int.Income
2010-01-01 0 0 0 0 0
2010-01-02 0 0 0 0 0
2010-01-03 0 0 0 100 0
Gross.Trading.PL Txn.Fees Net.Trading.PL Advisory.Fees
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 100 0 100 0
Net.Performance End.Eq
2010-01-01 0 100
2010-01-02 0 100
2010-01-03 100 200
attr(,"currency")
[1] "USD"
attr(,"initEq")
[1] 100
attr(,"class")
[1] "portfolio_account" "account"
Thank you!
Regards, Wolfgang Wu
On 12/22/2010 04:30 AM, Wolfgang Wu wrote:
thank you for the explanation. I understand this now. However consider a different example where the security is now a futures contract with a multiplier of 2. Then blotter will produce a wrong End.Eq. (See example code) I suspect the Con.Mult column in the first row of the portfolio object is set wrongly and is causing the problem. Would you agree?
The first row doesn't have anything to do with it. That row has a zero value, and is only there to initialize things. It does appear that your example highlights a problem in the multiplier being applied to one of the Avg.Cost columns in the $posPL slot. We'll investigate and fix. Thanks for the report. Regards, - Brian
Brian G. Peterson http://braverock.com/brian/ Ph: 773-459-4973 IM: bgpbraverock
I don't fully understand the code but the following patch fixes the problem for me. 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 <- na.locf(tmpPL$Con.Mult, fromLast=TRUE) tmpPL$Con.Mult <- ifelse(is.na(tmpPL$Con.Mult) ,1, tmpPL$Con.Mult) There might be a more elegant solution however as I think it might be this bit of code quickly assumes that the multiplier is 1 when is.na == true tmpPL$Con.Mult <- ifelse(is.na(tmpPL$Con.Mult) ,1, tmpPL$Con.Mult) Wolfgang Wu ----- Urspr?ngliche Mail ---- Von: Brian G. Peterson <brian at braverock.com> An: r-sig-finance at r-project.org Gesendet: Mittwoch, den 22. Dezember 2010, 13:43:24 Uhr Betreff: Re: [R-SIG-Finance] Possible bug in blotter
On 12/22/2010 04:30 AM, Wolfgang Wu wrote:
thank you for the explanation. I understand this now. However consider a different example where the security is now a futures contract with a multiplier of 2. Then blotter will produce a wrong End.Eq. (See example code) I suspect the Con.Mult column in the first row of the portfolio object is set wrongly and is causing the problem. Would you agree?
The first row doesn't have anything to do with it. That row has a zero value, and is only there to initialize things. It does appear that your example highlights a problem in the multiplier being applied to one of the Avg.Cost columns in the $posPL slot. We'll investigate and fix. Thanks for the report. Regards, - Brian -- Brian G. Peterson http://braverock.com/brian/ Ph: 773-459-4973 IM: bgpbraverock _______________________________________________ R-SIG-Finance at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. If you want to post, subscribe first. -- Also note that this is not the r-help list where general R questions should go. -------------- next part -------------- A non-text attachment was scrubbed... Name: updatePosPL.patch Type: application/octet-stream Size: 571 bytes Desc: not available URL: <https://stat.ethz.ch/pipermail/r-sig-finance/attachments/20101222/e196a0de/attachment.obj>
On 12/22/2010 08:06 AM, Wolfgang Wu wrote:
+ tmpPL$Con.Mult<- na.locf(tmpPL$Con.Mult, fromLast=TRUE)
I've applied this patch in R-Forge SVN r506. The 'better' method of NA handling would be to first check the contract multiplier in the instrument, but that will take more work to incorporate than your one-line patch. As always, thanks for the report, test case, and patch. I will try to incorporate your test case directly into the 'tests' for blotter soon so we can catch any regression or changes. Regards, - Brian
Brian G. Peterson http://braverock.com/brian/ Ph: 773-459-4973 IM: bgpbraverock
1 day later
I am still bumping into problems trying to implement some of our trading
strategies using blotter. So here is another one that seems to go wrong using
r511.
library(blotter)
dateRange <- as.Date(as.Date('2010-01-02'):as.Date('2010-01-05'))
currency('USD')
stock('ABC', currency='USD')
ABC <- xts(102:105, order.by=dateRange)
colnames(ABC) = "Close"
initPortf('portA', symbols="ABC", initDate='2010-01-01');
initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100);
addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=102, TxnQty =1,
TxnFees=0, verbose=TRUE)
updatePortf('portA', Dates = dateRange)
updateAcct('accA', Dates = dateRange)
updateEndEq('accA', Dates = dateRange)
#Equity wrong?
getAccount('accA')
I get the following result with the End.Eq staying at 101 where I am expecting
it to increase as the stock increases in value.
$portfolios
$portfolios$portA
Long.Value Short.Value Net.Value Gross.Value Realized.PL
2010-01-01 0 0 0 0 0
2010-01-02 102 0 102 102 0
2010-01-03 103 0 103 103 0
2010-01-04 104 0 104 104 0
2010-01-05 105 0 105 105 0
Unrealized.PL Gross.Trading.PL Txn.Fees Net.Trading.PL
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 1 1 0 1
2010-01-04 1 1 0 1
2010-01-05 1 1 0 1
$summary
Additions Withdrawals Realized.PL Unrealized.PL Int.Income
2010-01-01 0 0 0 0 0
2010-01-02 0 0 0 0 0
2010-01-03 0 0 0 1 0
2010-01-04 0 0 0 1 0
2010-01-05 0 0 0 1 0
Gross.Trading.PL Txn.Fees Net.Trading.PL Advisory.Fees
2010-01-01 0 0 0 0
2010-01-02 0 0 0 0
2010-01-03 1 0 1 0
2010-01-04 1 0 1 0
2010-01-05 1 0 1 0
Net.Performance End.Eq
2010-01-01 0 100
2010-01-02 0 100
2010-01-03 1 101
2010-01-04 1 101
2010-01-05 1 101
attr(,"currency")
[1] "USD"
attr(,"initEq")
[1] 100
attr(,"class")
[1] "portfolio_account" "account"
Regards, Wolfgang Wu
On 12/24/2010 03:35 AM, Wolfgang Wu wrote:
I am still bumping into problems trying to implement some of our trading
strategies using blotter. So here is another one that seems to go wrong using
r511.
library(blotter)
dateRange<- as.Date(as.Date('2010-01-02'):as.Date('2010-01-05'))
currency('USD')
stock('ABC', currency='USD')
ABC<- xts(102:105, order.by=dateRange)
colnames(ABC) = "Close"
initPortf('portA', symbols="ABC", initDate='2010-01-01');
initAcct('accA',portfolios='portA', initDate='2010-01-01', initEq=100);
addTxn("portA", Symbol='ABC', TxnDate='2010-01-02', TxnPrice=102, TxnQty =1,
TxnFees=0, verbose=TRUE)
updatePortf('portA', Dates = dateRange)
updateAcct('accA', Dates = dateRange)
updateEndEq('accA', Dates = dateRange)
#Equity wrong?
getAccount('accA')
I get the following result with the End.Eq staying at 101 where I am expecting
it to increase as the stock increases in value.
This looks like a bug. Looks like for some reason updateEndEq isn't accumulating the Trading.PL. It's showing properly in the $posPL slot as Unrealized.PL and Trading.PL, so we'll have to sort out what's wrong with the equity calculation. Thanks for the report, should be fixed at the latest early next week. As always, thank you for the reproducible test case, these always make debugging easier. Also, for 'bug reports', it's generally considered best to email the maintainer of the package first, to not bother the list. For 'help' or 'support' requests, the list may be a better outlet, as others will likely have relevant experience and all benefit from sharing. Regards, - Brian
Brian G. Peterson http://braverock.com/brian/ Ph: 773-459-4973 IM: bgpbraverock