Blotter example by kafka from R-bloggers
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