[R-SIG-Finance] What are the requirements for instrument names in a blotter portfolio?
Brian G. Peterson
brian at braverock.com
Wed Apr 28 13:11:28 CEST 2010
Robert,
I looks to me like you're on the right track.
It looks like the line that is failing is in updatePosPL (called from updatePortf).
I think I mentioned in one of my earlier messages that you won't get cumulative
P&L unless you have historical market price data available. You're
downloading a list of transactions from your broker, and adding those via
addTxn(). That step is going fine. The failure is later, when you call
updatePortf().
Comment out this line:
portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
and the script should import all your transactions properly and calculate
transaction P&L on them. You'll be able to verify this via getPortfolio().
chart.Posn() will also fail without historical market price data available.
To 'mark the book' it should make sense that you need historical price data.
Any frequency is fine: tick, bars, daily close, etc. updatePortf() will go
find this data and calculate a 'mark' at each time point in your market data or
against some reference index. I typically run trades as irregular series, like
yours, and then mark the book on some periodic basis, like hourly or daily.
If historical market data isn't available, then there's no point in calling
updatePortf(), (and the Account and Equity functions) as there's nothing to
calculate at the portfolio level.
I'm not at my main development machine today, but tomorrow I'll wrap the call
to market data in a try() statement and add a more descriptive error so that
hopefully it will be clearer to others what is required.
I suppose eventually we could 'mark the book' based only on the trade data,
with no unrealized P&L changes not related to prices observed at the time of a
trade, but I'll need to think about that a little more: I'm not sure it's worth
the effort as I always have historical market data available.
Regards,
- Brian
Robert Nicholson wrote:
> After I made the following changes I still seem to get the same error
>
> [1] "2008-05-30 O24702R9GE 10 @ 0.35"
> Error in get(Symbol, envir = as.environment(.GlobalEnv)) :
> object 'O24702R9GE' not found
>
>
> The code prefixes any option that begins with a - with O and leaves equity stock symbols alone.
>
> library(quantmod)
> library(blotter)
> library(PerformanceAnalytics)
> Transactions <- as.xts(read.zoo("/Users/robert/Downloads/transactions.csv", header=FALSE, FUN=as.POSIXct, sep=",", format="%m/%d/%Y"))
> colnames(Transactions) <- c('Action', 'Symbol', 'SecurityDescription', 'Cash', 'Quantity', 'Price', 'Commission', 'Fees', 'Blank', 'Amount', 'SettlementDate')
>
> rm(list=ls(envir=.blotter),envir=.blotter)
> rm(list=ls(envir=.instrument),envir=.instrument)
>
> USD = currency('USD')
>
> Transactions$Symbol = sub('^[ ]','',Transactions$Symbol)
>
> for (symbol in unique(Transactions$Symbol))
> {
> print (symbol)
> if (regexpr('^$', symbol) != -1) {
> print("ignore")
> } else if (regexpr('^-', symbol) == -1) {
> print("stock")
> stock(primary_id=symbol, currency='USD', multiplier = 1, underlying_id = NULL)
> } else if (regexpr('^-', symbol) != -1) {
> option(primary_id=sub('^[-]', 'O', symbol), currency='USD', multiplier = 100, underlying_id = NULL)
> print ("option")
> } else {
> print ("ignore")
> }
> }
>
> Transactions$Symbol = sub('^[ -]+','O',Transactions$Symbol)
>
> symbols = unique(Transactions$Symbol)
>
> portfolioname = 'portfolio'
> accountname = 'account'
>
> portfolio <- initPortf(portfolioname, symbols=symbols)
> account = initAcct(accountname, portfolios=portfolioname)
> for (i in 1:NROW(Transactions)) {
> Transaction = Transactions[i]
> CurrentDate=time(Transaction)
> equity = getEndEq(account, CurrentDate)
> symbol = Transaction$Symbol
> price = as.numeric(Transaction$Price)
> quantity = as.numeric(Transaction$Quantity)
> if(is.na(Transaction$Fees)) {
> fees = 0
> } else {
> fees = as.numeric(Transaction$Fees)
> }
> if (is.na(Transaction$Commission)) {
> commission = 0
> } else {
> commission = as.numeric(Transaction$Commission)
> }
> multiplier = 1
> #if(substr(symbol,2,2) == '-') {
> # multiplier = 100
> #}
> addTxn(Portfolio=portfolio, Symbol=symbol, TxnDate=CurrentDate, TxnPrice=(price*multiplier), TxnQty=quantity, TxnFees=(commission + fees), verbose=TRUE, ConMult=1)
> portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
> }
> #portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
> #account = updateAcct(Account = account, Dates = CurrentDate)
> #account = updateEndEq(Account = account, Dates = CurrentDate)
>
> On Apr 26, 2010, at 9:11 AM, Brian G. Peterson wrote:
>
>> I'll reply in more detail later if required, after US and European markets close, and try to work through the issue for you, but I'll give you a hint/direction now.
>>
>> I would probably start by defining the currency:
>>
>> currency('USD')
>>
>> and then once you read the transaction data, you already define the symbols here:
>>
>> symbols = as.character((unique(Transactions$Symbol)))
>>
>>
>> You could then define the instruments:
>>
>> for (symbol in symbols) {
>> option(primary_id=symbol,currency='USD',multiplier='100')
>> # you'd need more sophistication if either of the two constants above aren't true
>> }
>>
>> Ideally, since you're dealing with option series, you'd also define the option_series information, but that probably isn't necessary for downloaded trade P&L. Jeff Ryan and I will likely do some work this spring on automatically defining the properties for options OSI symbology, but as I said, I don't think it is necessary in your case. I typically load the instrument metadata from our internal databases (I think this is the most likely use-case right now for non-stock portfolios).
>>
>> Incidentally, I'd see if your broker can or will provide you the data using OSI standard symbols. the symbols you've got in your data file don't contain a lot of information.
>>
>> updatePortf() will fail if you don't have market data for each symbol to mark the book on. This may very well not be a problem for your stated purpose, as calling getPortfolio should allow you to view the per-trade P&L, and chart.Posn should work (but will not display cumulative P&L)
>>
>> Regards,
>>
>> - Brian
>>
>> On 04/26/2010 08:49 AM, Robert Nicholson wrote:
>>> Sure here's an example
>>>
>>> Please bear I'm in mind I'm still learning R and blotter.
>>>
>>> The idea is to put transaction data thru and then look at the PnL ideally for each trade
>>>
>>> The transactions file looks like this for each row
>>>
>>> 05/30/2008, YOU BOUGHT OPENING TRANSACTION, -24702R9GE, CALL (DLQ) DELL INC JUL 25 (100 SHS),Cash,10,0.35,17.5,,,-367.5, 06/02/2008
>>> 06/12/2008, YOU SOLD CLOSING TRANSACTION, -24702R9GE, CALL (DLQ) DELL INC JUL 25 (100 SHS),Cash,-10,0.56,18.45,,,541.54, 06/13/2008
>>>
>>> library(quantmod)
>>> library(blotter)
>>> library(PerformanceAnalytics)
>>> Transactions<- as.xts(read.zoo("/Users/robert/Downloads/transactions.csv", header=FALSE, FUN=as.POSIXct, sep=",", format="%m/%d/%Y"))
>>> colnames(Transactions)<- c('Action', 'Symbol', 'SecurityDescription', 'Cash', 'Quantity', 'Price', 'Commission', 'Fees', 'Blank', 'Amount', 'SettlementDate')
>>>
>>> Transactions$Symbol = sub('[ -]*','INST',Transactions$Symbol)
>>>
>>> symbols = as.character((unique(Transactions$Symbol)))
>>> portfolioname = 'portfolio'
>>> accountname = 'account'
>>>
>>> rm(list=ls(envir=.blotter),envir=.blotter)
>>>
>>> portfolio<- initPortf(portfolioname, symbols=symbols)
>>> account = initAcct(accountname, portfolios=portfolioname)
>>> for (i in 1:NROW(Transactions)) {
>>> Transaction = Transactions[i]
>>> CurrentDate=time(Transaction)
>>> equity = getEndEq(account, CurrentDate)
>>> symbol = Transaction$Symbol
>>> price = as.numeric(Transaction$Price)
>>> quantity = as.numeric(Transaction$Quantity)
>>> if(is.na(Transaction$Fees)) {
>>> fees = 0
>>> } else {
>>> fees = as.numeric(Transaction$Fees)
>>> }
>>> if (is.na(Transaction$Commission)) {
>>> commission = 0
>>> } else {
>>> commission = as.numeric(Transaction$Commission)
>>> }
>>> multiplier = 1
>>> if(substr(symbol,2,2) == '-') {
>>> multiplier = 100
>>> }
>>> addTxn(Portfolio=portfolio, Symbol=symbol, TxnDate=CurrentDate, TxnPrice=(price*multiplier), TxnQty=quantity, TxnFees=(commission + fees), verbose=TRUE, ConMult=1)
>>> portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
>>> }
>>> #portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
>>> #account = updateAcct(Account = account, Dates = CurrentDate)
>>> #account = updateEndEq(Account = account, Dates = CurrentDate)
>>>
>>> On Apr 26, 2010, at 8:40 AM, Brian G. Peterson wrote:
>>>
>>>
>>>> As should be clear from the documentation and examples, we have followed the 'quantmod' convention of storing the market data as the symbol name.
>>>>
>>>> My presumtion is that as you could not possibly have stored your market data as '-24702R9GE' (as this is an illegal R variable name), you have likely also not stored it as 'INST24702R9GE'
>>>>
>>>> The call that is failing, however, suggests a different problem.
>>>>
>>>> This error:
>>>>
>>>> Error in get(x, pos = .instrument) : object 'INST24702R9GE' not found
>>>>
>>>> suggests that you haven't declared the instrument, with currency, multiplier, etc.
>>>>
>>>> it's not clear if the next error is directly related, or if it is simply the code falling back to try to find the instrument data in the global environment.
>>>>
>>>> Diagnosing this would be much easier if you provided a complete, reproducible example, per the posting guide. Then I wouldn't have to guess, I could simply run the code.
>>>>
>>>> Regards,
>>>>
>>>> - Brian
>>>>
>>>> On 04/26/2010 08:32 AM, Robert Nicholson wrote:
>>>>
>>>>> Why then do I get this?
>>>>>
>>>>> I added
>>>>>
>>>>> Transactions$Symbol = sub('[ -]*','INST',Transactions$Symbol)
>>>>>
>>>>> so this prefixes everything I had with INST presumably I can have digits in the name
>>>>>
>>>>> 1] "2008-05-30 INST24702R9GE 10 @ 0.35"
>>>>> Error in get(x, pos = .instrument) : object 'INST24702R9GE' not found
>>>>> Error in get(Symbol, envir = as.environment(.GlobalEnv)) :
>>>>> object 'INST24702R9GE' not found
>>>>>
>>>>>
>>>>> On Apr 26, 2010, at 5:01 AM, Brian G. Peterson wrote:
>>>>>
>>>>>
>>>>>
>>>>>> R variable names may not start with a number.
>>>>>>
>>>>>> instruments will be used to create R variables, so all normal naming rules for variables apply.
>>>>>>
>>>>>> Robert Nicholson wrote:
>>>>>>
>>>>>>
>>>>>>> Why when
>>>>>>> names(getPortfolio(portfolio))
>>>>>>> [1] " -24702R9GE"
>>>>>>> do I have
>>>>>>> [1] "2008-05-30 -24702R9GE 10 @ 35"
>>>>>>> Error in get(x, pos = .instrument) : object ' -24702R9GE' not found
>>>>>>> Error in get(Symbol, envir = as.environment(.GlobalEnv)) : object ' -24702R9GE' not found
>>>>>>> when I call
>>>>>>> portfolio = updatePortf(Portfolio = portfolio, Dates = CurrentDate)
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> Brian G. Peterson
>>>>>> http://braverock.com/brian/
>>>>>> Ph: 773-459-4973
>>>>>> IM: bgpbraverock
>>>>>>
>>>>>>
>>>> --
>>>> Brian G. Peterson
>>>> http://braverock.com/brian/
>>>> Ph: 773-459-4973
>>>> IM: bgpbraverock
>>>>
>>>>
>>>>
>>
>> --
>> Brian G. Peterson
>> http://braverock.com/brian/
>> Ph: 773-459-4973
>> IM: bgpbraverock
>>
>>
--
Brian G. Peterson
http://braverock.com/brian/
Ph: 773-459-4973
IM: bgpbraverock
More information about the R-SIG-Finance
mailing list