I would like to use some custom series - for example, split-unadjusted close and volume series - in a rotation script as additional filters for trade entry. The split-unadjusted series are calculated thus, as you know:
CODE:
Please log in to see this code.
I want to go long only if the split-unadj price on a bar was > 10 and the volume on the bar was > 500000.
Using an existing rotation script - such as "Weak-stock rotation" - can you show how to do this as I am unable to figure it out.
Size:
Color:
It's a DataSeries. Therefore, what is said and exemplified in the WealthScript Programming Guide, DataSeries > Accessing a Single Value from a DataSeries, applies to splitUnadjC and splitUnadjVol like to any data series.
Size:
Color:
Wish it were that simple.
Here's the problem:
In the rotation strategy, you have the symbol loop inside the bar loop. Since these are custom, not native, price series, they have to be created only after accessing the symbol via SetContext. But then the process gets repeated at each bar, which markedly slows down the script and for a large dataset may even choke up the memory.
Size:
Color:
Then one solution is to use caching for your custom indicators in the same way that's done for a "formal" indicator. See the Tech Indicators API Guide for a detailed example.
Another way could be to create an array of DataSeries indexed by the DataSetSymbol, but formalizing an indicator would be the right way to go.
Size:
Color:
I found this API in the wiki: Create an Indicator Library. I assume you meant that?
I read it but since I don't have Visual Studio the project is a non-starter. Besides, it seems overly complicated for the task at hand.
Isn't there some simple way to achieve this?
Size:
Color:
Re: array of DataSeries -- here's an example of creating a List of DataSeries:
CODE:
Please log in to see this code.
Size:
Color:
Here's an *incomplete* test script; not sure if I am going down the right path. Your code above was piggybacked on the Weak-stock rotation script:
CODE:
Please log in to see this code.
I meant to ask:
- are you supposed to give a unique description to each custom series (? native series also) so they don't get mixed up?
- do you create one dsHolder for each symbol that will hold all the series, or (as above) one dsHolder for every series?
- how do you retrieve a series, or its value at 'bar' from the dsHolder?
- and where do you place series based on external symbols (symbols that are not in the dataset)?
Can you please tweak this test script with the above points in mind, or suggest how to move forward? My brain (??) refuses to work anymore, sayz its overloaded!
Size:
Color:
QUOTE:
- do you create one dsHolder for each symbol that will hold all the series, or (as above) one dsHolder for every series?
One dsHolder per symbol, and stuff it with all the series or whatever you need (including the Bars object, for example).
QUOTE:
- how do you retrieve a series, or its value at 'bar' from the dsHolder?
See my PrintDebug line?
QUOTE:
- and where do you place series based on external symbols (symbols that are not in the dataset)?
Ain't you supposed to do a GetExternalSymbol(...).Close call?
Follow-up. Here's an illustration of another Robert's suggestion -- formalizing an indicator, taking your split-unadjusted code for example. Hope that this pattern will be easier for you to comprehend. Call/use the
splitUnadj series just like the RSI.Series in 'RSI rotation', the series has become formalized:
CODE:
Please log in to see this code.
Size:
Color:
P.S. Here, you're passing the Close series to unadjust (or whatever); leave "
this" as is:
CODE:
Please log in to see this code.
Size:
Color:
Thanks for the new technique, Eugene. Its quite elegant.
But I actually found the first one easier to understand - its short & sweet. If you don't mind, can you post an example how your first method can be used to access, say, 3-4 different series (say, one native - like the RSI - and 2-3 custom)? Think I should be all set after that.
Sorry to be such a bother.
Size:
Color:
Not sure what the problem is? It's identical to
DataSeries Series = Close;
Nonetheless, another example shows how to conveniently pass a bunch of DataSeries to a dsHolder instance:
CODE:
Please log in to see this code.
Size:
Color:
Correct me if I'm wrong, but for this to work you have to know the order in which the series were added? So if later you add/remove some series to/from being added, then you have to back and change each occurrence of dsList[n] to a new index value? What if I wanted to pull the rsi series w/o knowing in which order it was added?
Size:
Color:
Use IndexOf:
CODE:
Please log in to see this code.
Size:
Color:
Many thanks, Eugene.
Let me go back to the incomplete test script I posted above and apply these concepts there.
Size:
Color:
Unable to get IndexOf(reverseAdjustment); script throws error: CS0165 use of unassigned local variable 'reverseAdjustment'.
Relevant code block (full code available if needed):
CODE:
Please log in to see this code.
Size:
Color:
reverseAdjustment is not a formalized data series. Refer to my earlier example on creating a "formal" indicator.
Size:
Color:
Ok. [What's a formalized data series?]
BTW, of the 2 methods you posted above, which one do you think is more optimal or time/memory efficient?
In the same context, do I call ClearExternalSeries at some point in a bar loop while using either method?
Size:
Color:
Another difficulty...sorry!
To calculate splitUnadjVolume, one needs to divide Volume by rev adj factor, vs price series where you actually multiply.
Size:
Color:
QUOTE:
Ok. [What's a formalized data series?]
Formal indicator. See Cone's reply # 8/11/2010 4:26 PM.
Size:
Color:
Eugene, can you fix the calculation for split unadj vol for your method 2? When I add a
if (ds.Description.Contains("Volume"))...
statement to the method, I get an "Embedded statement cannot be a declaration or labeled statement" error.
Size:
Color:
Size:
Color:
It doesn't tell you how to fix the error.
Size:
Color:
Lets wrap this up. Here's the code for the test script:
CODE:
Please log in to see this code.
I would like your comments on:
1. I had to create a separate class splitUnadjV just for calculating the s_u_volume correctly. This creates some code duplicity. Any way to wrap both splitUnadj and splitUnadjV into one?
2. While creating data series in the symbol loop, there may sometimes be errors (insufficient data, whatever). Best way to tackle them?
Size:
Color:
QUOTE:
1. I had to create a separate class splitUnadjV just for calculating the s_u_volume correctly. This creates some code duplicity. Any way to wrap both splitUnadj and splitUnadjV into one?
This will solve your error, you may remove splitUnadj
V from the code:
CODE:
Please log in to see this code.
QUOTE:
2. While creating data series in the symbol loop, there may sometimes be errors (insufficient data, whatever). Best way to tackle them?
See the canned "RSI Rotation" strategy, in the beginning of it.
Size:
Color:
1. Many thanks, Eugene.
I had tried the if (...) argument but failed to modify the line above it, causing the error. Newbie mistake.
2. That code segment deals with updates whereas I was thinking about insufficient history - IPOs, new ETFs, etc. Guess I will fall back on the try/catch routine.
*/
One thing that still bothers me a bit is that most series names don't include symbol names. While not an issue for this script as series are stored in the symbol holder, I was wondering if at some time in a different context it won't come back to bite me if multiple series w/o a unique name are stored together in a List.
Lastly, can you please point me to some good websites discussing Lists. The ones I found are either too basic or geared towards the programmer; I need an intermediate level.
Size:
Color:
QUOTE:
Lastly, can you please point me to some good websites discussing Lists.
dotnetperls.com, though be prepared for occasional C# 3.0 snippets.
Size:
Color:
Thanks, Eugene! This has been a very helpful exchange!!
Size:
Color:
Running into problems retrieving some series, like RelativeStrength_MAM and fundamental ratios.
Following series were created and added as we discussed above:
CODE:
Please log in to see this code.
Retrieving these series however is throwing an "Index out of range..." error which I can see in the debug window using the try/catch routine. Here's the relevant code further doen:
CODE:
Please log in to see this code.
[Uncomment any line to test.]
Have tried many variations of IndexOf argument but fail each time. Really need some help.
Size:
Color:
You're not looking for an easy way, aren't you :)
CODE:
Please log in to see this code.
You're creating 3 objects for a symbol while could be only one. Simply devise a
dsHolder that would contain multiple series:
CODE:
Please log in to see this code.
Add it to the dsList (btw, what's seriesList? Looks like it's not required):
CODE:
Please log in to see this code.
And then retrieve them all by querying the properties of a
dsHolder found later:
CODE:
Please log in to see this code.
Size:
Color:
Thank you, Eugene.
>>You're not looking for an easy way...<<
I am *always* looking for the simplest solution to a problem.
But sometimes the solution cannot be simple, and sometimes my ignorance trips me up. :(
>>Simply devise a dsHolder that would contain multiple series<<
>>Add it to the dsList (btw, what's seriesList? Looks like it's not required)<<
Actually, Eugene, if you look at your reply above dated 8/16/10 9:10am, you had created a dsHolder with just a symbol and a List, and then you added all the series for a symbol to that List (which is the seriesList, btw) and then added that List alongwith the symbol to a dsHolder. I was following your example from there.
But perhaps this is simpler. Let me try to digest all that you wrote and check it out. May take a while...
Size:
Color:
Works great. Simple, too.
Thank you so much, Eugene!
Size:
Color: