[R-SIG-Finance] Blotter example by kafka from R-bloggers

Stephen Choularton stephen at organicfoodmarkets.com.au
Tue Dec 28 20:28:54 CET 2010


My apologies.

I did not realize the script worked so slowly.  I reduced the time scale 
it covered so it commenced at the beginning of the year and it did run 
to completion.  I will try the full term and see if it produces the same 
graphs as the original example.

I'm always a bit worried about warnings as they often mean something is 
going wrong and it might be useful if kafta had warned one not to worry 
about them.  Mind you I think he did say it all took a long time ;-)

I can assure you I do try and read man before I ask for help but dealing 
with other people's code is not always easy particularly when working 
with a programming system that uses a different paradigm like R with its 
emphasis on operations on vectors and the like. and the extensive use of 
calls to functions each of which often require a wet towel and cup of 
coffee to understand.

I added the parameter definitions you suggest:

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

and the warnings reduced to one:

Warning messages:
1: In updatePortf(ltportfolio, Dates = currentDate) :
   Incompatible methods ("Ops.Date", "Ops.POSIXt") for ">="

updatePortf goes:

updatePortf
function (Portfolio, Symbols = NULL, Dates = NULL, Prices = NULL,
     ...)
{
     pname <- Portfolio
     Portfolio <- getPortfolio(pname)
     if (is.null(Symbols)) {
         Symbols = names(Portfolio$symbols)
     }
     for (symbol in Symbols) {
         tmp_instr <- try(getInstrument(symbol))
         .updatePosPL(Portfolio = pname, Symbol = as.character(symbol),
             Dates = Dates, Prices = Prices, ... = ...)
     }
     Portfolio <- getPortfolio(pname)
     if (is.null(Dates))
         Dates <- time(Portfolio$symbols[[1]]$posPL)
     Attributes = c("Long.Value", "Short.Value", "Net.Value",
         "Gross.Value", "Period.Realized.PL", "Period.Unrealized.PL",
         "Gross.Trading.PL", "Txn.Fees", "Net.Trading.PL")
     summary = NULL
     tmp.attr = NULL
     for (attribute in Attributes) {
         result = NULL
         switch(attribute, Net.Value = , Gross.Value = , Long.Value = ,
             Short.Value = , {
                 if (is.null(tmp.attr)) {
                   table = .getBySymbol(Portfolio = Portfolio,
                     Attribute = "Pos.Value", Dates = Dates, Symbols = 
Symbols)
                   tmp.attr = "Pos.Value"
                 }
                 switch(attribute, Gross.Value = {
                   result = xts(rowSums(abs(table), na.rm = TRUE),
                     order.by = index(table))
                 }, Long.Value = {
                   tmat = apply(table, MARGIN = c(1, 2), FUN = max,
                     0)
                   result = xts(rowSums(tmat, na.rm = TRUE), order.by = 
index(table))
                 }, Short.Value = {
                   tmat = apply(table, MARGIN = c(1, 2), FUN = min,
                     0)
                   result = xts(rowSums(tmat, na.rm = TRUE), order.by = 
index(table))
                 }, Net.Value = {
                   result = xts(rowSums(table, na.rm = TRUE),
                     order.by = index(table))
                 })
             }, Period.Realized.PL = , Period.Unrealized.PL = ,
             Gross.Trading.PL = , Txn.Fees = , Net.Trading.PL = {
                 table = .getBySymbol(Portfolio = Portfolio, Attribute = 
attribute,
                   Dates = Dates, Symbols = Symbols)
                 tmp.attr = NULL
                 result = xts(rowSums(table, na.rm = TRUE), order.by = 
index(table))
             })
         colnames(result) = attribute
         if (is.null(summary)) {
             summary = result
         }
         else {
             summary = cbind(summary, result)
         }
     }
     if (!is.timeBased(Dates))
         Dates = time(Portfolio$symbols[[1]][Dates])
     startDate = first(xts:::.parseISO8601(Dates))$first.time -
         1
     if (attr(Portfolio, "initDate") >= startDate | 
length(Portfolio$summary) ==
         0) {
         Portfolio$summary <- summary
     }
     else {
         Portfolio$summary <- rbind(Portfolio$summary[paste("::",
             startDate, sep = "")], summary)
     }
     assign(paste("portfolio", pname, sep = "."), Portfolio, envir = 
.blotter)
     return(pname)
}
<environment: namespace:blotter>
 >

"Ops.Date", "Ops.POSIXt" don't appear in the function call so they must 
be somewhere deeper.  I'm afraid I'm currently a windows user so grep is 
not available and the windows native text search didn't reveal much.  
However, I did find some references in the documentation (Date-Time 
Classes, Operators on the Date Class & S3 Group Generic Functions) but 
Ops.POSIXt doesn't appear therein only POSIXlt and Ops.POSIXct.  Is 
there a typo somewhere ?

It would be nice to get rid of the warnings.

Stephen Choularton Ph.D., FIoD


On 28/12/2010 9:56 PM, Brian G. Peterson wrote:
> On Tue, 28 Dec 2010 18:14:09 +1100, Stephen Choularton
> <stephen at organicfoodmarkets.com.au>  wrote:
>> I'm still not winning with this.
>
> Really, does the script fail?
> No: these are warnings.
>
> Alternately: Does it produce incorrect results?  Does it replicate the
> charts on his blog?  It does when I run it (warnings aside).
>
>
>> I  installed blotter again from
>> https://r-forge.r-project.org/R/?group_id=316 but now I am getting  this
>> inside the loop:
>
> Please at least attempt to read the documentation before posting.
>
> Failing that, please try to figure out what a given *Warning* (these are
> not Errors!) is telling you.
>
>
> I've trimmed the following to keep only unique warnings.
>
>
>> There were 50 or more warnings (use warnings() to see the first 50)
>>   >  warnings()
>> Warning messages:
>> 1: In getInstrument(symbol) : Instrument SPY  not found, please create
>> it first.
>> 2: In getInstrument(Symbol) : Instrument SPY  not found, please create
>> it first.
>> 3: In .updatePosPL(Portfolio = pname, Symbol = as.character(symbol),
> ... :
>>     Instrument SPY  not found, things may break
>
> getInstrument is called by all sorts of things.  The warning is saying
> that you don't have an instrument definition, and things may be wonky.  Per
> the documentation, we'll *attempt* to assume USD for the currency, and a
> multiplier of 1, but this may not work everywhere, and per one comment in
> the documentation which you apparently haven't read and Warnings
> 3,11,15,19, etc. from your output, "things may break".
>
> adding this somewhere near the beginning of the script (after loading
> blotter) should eliminate all of the warnings related to the lack of an
> instrument:
>
> currency("USD")
> stock("SPY",currency="USD",multiplier=1)
>
> but they are Warnings, and are there to inform you that something unhappy
> might be going on.  Errors actually stop R in most cases, because it can't
> continue.
>
> <...>
>
>> 8: In updatePortf(ltportfolio, Dates = currentDate) :
>>     Incompatible methods ("Ops.Date", "Ops.POSIXt") for ">="
>
> I've never seen this one before in blotter, even when running the script
> you are using to test this, which works for me.  It may have something to
> do with the script, as I know it has a loop on Dates with an updatePortf
> after every day in order to do position sizing (which is a lot of heavy
> lifting for the computer to do, and you likely won't want to do something
> like this for most strategies when backtesting, though obviously running
> once a day or even once an hour on real portfolios wouldn't be a problem.)
>
>
> <...>
>
>> 50: In addTxn(ltportfolio, Symbol = symbols[1], TxnDate = currentDate,
>> ... :
>>     Instrument SPY  not found, using contract multiplier of 1
>
> See my earlier comments about assuming a multiplier of 1 ...  your
> computer told you that before I re-highlighted it.
>
>
>> getInstrument doesn't even appear in the code so I'm not sure where this
>> is going wrong.
> .../blotter/R$ grep -c getInstrument *.R | grep -v 0
> addTxn.R:3
> chart.Spread.R:1
> updateAcct.R:1
> updatePortf.R:1
> updatePosPL.R:2
>
> The code you're running calls every file/function in the output above
> except for chart.Spread, so getInstrument does 'appear in the code' (which
> you have always had available to you for inspection)
>
>    - Brian
>



More information about the R-SIG-Finance mailing list