On 5/2/11 8:42 PM, Brian G. Peterson wrote:
> 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...
>
Apologies for the vague description. Let me elaborate further inline
(please see below).
> 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.
My strategy is actually portfolio based but the indicator is computed
based on time series data of all N components. So, the indicator applied
to any one particular security is meaningless. The indicator is to be
used in a portfolio sense.

i.e.

if the indicator > X {then buy the portfolio}
if the indicator < Y {then sell the portfolio}

The portfolio will consist of long and short positions in the N
components (i.e. subset of the N will be short and subset will be long).
This should be driven by the signal/rule and both would need to be
written in a way that would not apply the indicator to a symbol (since
it is meaningless for an individual security).

I am a bit confused about your comment re: 'portfolio' evaluation mode
as I'm not sure if this refers to functionality that I would need to
implement my portfolio based strategy.

> 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.  
myfunction() is a function I created and is saved in a .R file which I
source in my code via source('myfunction'). Is this okay?
> 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.  
Yes c1 through c5 are arguments to the function. I corrected the code to
accommodate named lists.
> 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...
Yes - I just re-read the add.indicator notes in the documentation.
Apologies for the miss on 'named lists' - I am trying to do way too many
things at once and as a result getting distracted. Thank you for all
your help.

<begin snippet>
arguments and parameters are named lists that describe the arguments to
be passed to the indicator function. arguments is for defining any
non-default arguments to be passed to the function named in the name of
the indicator. For example, the x argument to a moving average function
may be defined as x=quote(Cl(mktdata)).
<end snippet>
> 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


	[[alternative HTML version deleted]]

