[R-SIG-Finance] quantstrat & custom indicators

Brian G. Peterson brian at braverock.com
Tue May 3 02:42:32 CEST 2011


On Mon, 2011-05-02 at 16:10 -0700, algotr8der wrote:
> I have read through the documentation for quantstrat and gone through some
> examples (RSI, MACD, Faber) but am a bit lost as to whether I can creatively
> use the features of this package to create a custom indicator as follows:
> 
> -I have N securities 
> -I want to pass each of those N securities along with N+1 constants to a
> user created function called myfunction().
> -the user created function myfunction() performs some arithmetic operations
> and returns a single time series.
> 
> In this example, lets say N = 4
> 
> c1 <- 1
> c2 <- 2
> c3 <- 3
> c4 <- 4
> c5 <- 5
> 
> myStrat <- strategy("myStrat")
> myStrat <- add.indicator(strategy = myStrat, name = "myfunction", arguments
> = list(symbols[1], symbols[2], symbols[3], symbols[4], c1, c2, c3, c4, c5))
> 
> I have tried this and when I call applyStrategy I get multiple errors -
> 
> a) c1 is not found
> b) when I removed c1-c5 and defined them in myfunction instead, I got:
> 
> Error in .Internal(get(x, envir, mode, inherits)) : 'x' is missing
> 
> It seems its expecting arguments in the form x=quote(Cl(mktdata)). I'm not
> sure I can use that as my argument to myfunction as this user created
> function needs to treat each individual time series in a unique way i.e. it
> is performing a proprietary arithmetic operation.
> 
> Any guidance would be greatly appreciated.

You're being (deliberately) a little unclear.  I'll try to unpack it
anyway...

We routinely write custom indicator and signal functions.

You can do that with either little or much work required on your end.

'mktdata' is constructed inside quantstrat in the applyRules loop
(currently the loop over symbols, though this may change if was add a
'portfolio' evaluation mode this summer during GSoC).  If it mktdata is
not passed in, it is created by get()'ing the variable named for the
symbol.  I believe this is precisely as described in the documentation.
Cases where you may want to pass mktdata would include some complex
portfolio-based or basket-based approach.

In typical usage, an indicator or signal function will return either an
xts time series with the same index as mktdata, or a vector of the same
length as nrow(mktdata).  I believe this is also described in the
documentation.  The indicator function may also retrieve any information
known to the calling environment (the applyStrategy and applyRules
functions), including the symbol that is currently being evaluated.  If
you need custom logic per symbol, you can do that based on some
proprietary lookup function.

In your calling logic, 'myfunction' is *both* the name= argument to
add.indicator *and* the name of a function you do not define.  All of
the name= arguments in quantstrat refer to named functions.  This too
is, I believe, spelled out in the documentation.  I would assume that
c1,c2,c3,c4,c5 are arguments to the function.  The largest problem is
that you need to NAME the arguments in your arguments=list().  These are
used for argument matching to your function.  Since you do not name
them, they are in the list slots as [[1]],[[2]],[[3]], etc.  We can't
magically match from that.  the documentation for add.indicator says
"arguments and parameters are named lists".  Note that we say *named*
lists...

There is no problem whatsoever with your 'proprietary arithmetic
operation'. I do it all the time.  You just need to be explicit about
where and how quantstrat is to match your (named) arguments list up with
the named function parameters of your custom proprietary indicator.

Now, if you want to make things more difficult on yourself, you don't
*need* to return a time series or a proper-length vector.  You can
return any object at all.  In that case, your returned object will be
stuck in the $indicators slot.  All good so far.  The difficulty lies in
the fact that your signal and rule functions will need to know precisely
what you've stuck there and how to act on that data.  So, I typically
(though not always), make things easy on myself and return time series
indicators and boolean signal time series, even with proprietary
indicator and signal logic.  I don't always do that, which is why the
framework can handle arbitrary returns, but do realize that it makes
things harder.

Regards,

   - Brian


-- 
Brian G. Peterson
http://braverock.com/brian/
Ph: 773-459-4973
IM: bgpbraverock



More information about the R-SIG-Finance mailing list