Synchronize Calculated DataSeries
Author: ronc
Creation Date: 10/9/2013 12:53 AM
profile picture

ronc

#1
To have all my data series ready at the start of my simulations, I initialize the DataSeries with;
DataSeries seriesName = new DataSeries(allDataBars, "seriesName");
and:
seriesName = Synchronize(seriesName);

Now I am creating a custom data series which is the integral of the area between 2 other series, and it resets to zero when the first 2 series cross. In essence, take Series1 and Series2, and for each bar, add the difference (divergence) between them to a running total to get the integral series, which increases with time, except that I reset the integral (area) to zero when Series1 and 2 crossover/under each other.

Since this integral series is calculated on the fly, by adding the difference between 2 other series to a running total, it always starts with a value of zero on Bar 1, since the running total at Bar 1 is zero. This is not realistic since it does not reflect the history of Series 1 and 2 prior to the simulation start date.

How can I get this calculated integral series to start "in the past" like the other series do when I use the above "Synchronize" trick?

Thanks,
Ron
profile picture

Eugene

#2
Is this close?

GetAllDataForSymbol
profile picture

ronc

#3
I am already using that. In essence I do this (abbreviated code):

CODE:
Please log in to see this code.


With this approach, myDivergenceIntegral always starts with a value of zero, because it is only calculated starting at at Bar 1.
How can I calculate and fill in the myDivergenceIntegral series prior to Bar 0?

This is analogous to summing the values of MACD Histogram to get the area under the curve. The challenge is the startup value.

Thanks
profile picture

Eugene

#4
I don't know what you're doing inside your abbreviated code, but my quick take shows that myDivergenceIntegral starts at bar 0 with a non-zero value.

CODE:
Please log in to see this code.
profile picture

ronc

#5
Hi Eugene,
In your sample code above, the "PlotSeries" function call is plotting myDivergence. If you change that to myDivergenceIntegral it seems to start with a zero value.
Thanks
Ron
profile picture

Eugene

#6
Hi Ron,

Oh I see it now. Sorry, my bad. However, it's quite reasonable to expect that zero value because your indicator is programmed to deliver it. Give it a little more thought: it's a blank new series computed with regard to Bars.Count, not allDataBars.
CODE:
Please log in to see this code.

How then should non-zero values on all the preceding history emerge?
profile picture

ronc

#7
Yes, agreed. So how can I do calculations before bar 0, in order to fill in dataseries values before bar 0? I understand that I can do a loop from bar = 0 to bar = Bars.Count - 1, and that allDataBars is some number larger than Bars.Count, so I suppose there are bars before bar 0, but how do I access them?
Thanks
Ron
profile picture

Eugene

#8
Loop by allDataBars, as this is the source of your complete data for that symbol.
profile picture

ronc

#9
Do you mean this:

CODE:
Please log in to see this code.


Doesn't this also start at Bar 0?
profile picture

Eugene

#10
At bar 1, according to your indicator's logic:
CODE:
Please log in to see this code.
profile picture

ronc

#11
Thanks!
Magically, it seems to work!
So.. exactly what is Bar 0? Assuming a daily time scale, is Bar 0 the bar on the first date that I select in the UI for the Date Range, or is it the bar corresponding to the earliest date in the data set?
Ron
profile picture

Eugene

#12
Bar 0 is the bar on the first date selected in the Data Range control for the Date Range.

To load the entire available history, GetAllDataForSymbol works around it by calling an internal method (some .NET Reflection magic).
profile picture

ronc

#13
I tried this in a different context and am hitting a wall. The following code keeps giving me an index out of range error. I want to do calculate/fill a data series based on OHLC data from previous bars. I want the new calculated series to have valid values starting at Bar 0, so I am doing the Synchronize trick. But no joy. What am I doing wrong? Also, shouldn't I be able to remove the "if (bar > period)" restriction?

CODE:
Please log in to see this code.
profile picture

Eugene

#14
No wonder that your code violates the boundaries. allDataBars and Bars have different bar counts.

Also no need in looping over allDataBars in this case:

CODE:
Please log in to see this code.
profile picture

ronc

#15
My goal is to find the high and low price values for a symbol within the last N bars (the "period") before the current bar. My code for that is shown below. This was the origin of the error above.

CODE:
Please log in to see this code.


Based on your post above, I can do this by creating new series that shifted to the right (into the future) by pivotPeriod, and the checking values from the current bar to current bar + period. But I am wondering if there is not a way to do this directly on the original unshifted bar object, i.e. to look back in time and check from (current Bar - period) to (current bar)? Is it ever possible to access a Bars object with an index less than 0? I assume not, in which case what is the "normal" way of doing this in Wealth Lab? Is it always to create new data series that is shifted to the right?
profile picture

Eugene

#16
If you start that loop at bar 1, not at pivotPeriod+1, an "index out of range" will be thrown if pivotPeriod is greater than 1:
CODE:
Please log in to see this code.


QUOTE:
Is it ever possible to access a Bars object with an index less than 0?

No, because the data does not exist beyond bar 0. As already suggested, loop through allDataBars, not Bars. GetAllDataForSymbol is here to help peek beyond bar #0 of your charted Bars object.
profile picture

ronc

#17
If I understand correctly, Bars starts at at the bar corresponding to the first time increment (e.g. day) selected in the UI, and allDataBars starts at the first bar (e.g. day) in the entire data set. So allDataBars starts earlier in time than Bars.

If I want to loop the actual simulation period (from Bars[0] to Bars[Bars.Count-1]) and look back in time N bars, then I should use allDataBars, since that has bars corresponding to "negative time". But if I am starting at Bar 0 in the Bars object (first day of the simulation) and I want to look back N bars (into allDataBars), how do I relate the indeces of Bars and allDataBars? In other words, what allDataBars index corresponds to Bars[0]?

I understand that I should loop on allDataBars to access prior to Bar 0 in the Bars object, but unless I am mistaken that can only apply to "set up" code, i.e operations done outside of the main program loop, such as filling in calculated series. The code I am interested in runs in the main loop and is calculating an indicator on-the-fly, and my understanding is that the main loop must loop on the Bars object since Bars corresponds to the time interval selected in the UI. If I've got this wrong please clarify for me.

Thanks,
Ron
profile picture

ronc

#18
Still stuck. Getting out of range errors, whether I loop on Bars or allDataBars.

To look back in time over "pivotPeriod" I created new series that are shifted forward in time. Then I check from the current bar forward through pivotPeriod.

I am just trying to do what must be done within the calculations of all indicators: look back over the span of bars just prior to the current bar and calculate some metric based on the values within that span. For example, just calculating the Simple Moving Average must do the same thing - it needs to access Bar values for the most recent N periods (N=SMA period). If my technique below is not the right way to do this, what is?

Thanks.

CODE:
Please log in to see this code.
profile picture

Eugene

#19
Getting IOOR (index out of range) after violating the upper bound now. To fix:

CODE:
Please log in to see this code.


Move both Synchronize clauses after having built the DataSeries in the loop, not before it:

CODE:
Please log in to see this code.
profile picture

ronc

#20
It works! Thanks.

Is my technique the same used by other indicators use to calculate values based on recent history before the current bar, or is there some simpler way (while using Synchronize to make sure the calculated series starts at Bar 0).

For example, the SMA indicator: SMA[bar] with SMA period = 20: the SMA code must be looking the current bar and 19 previous bars, and when using Synchronize SMA starts correctly at Bar 0. How is that being done?

Thanks,
Ron
profile picture

Eugene

#21
QUOTE:
How is that being done?


Synchronize() is explained in the WealthScript Programming Guide > DataSeries > Accessing Secondary Symbols > Secondary Series Synchronization.

GetAllDataForSymbol is documented int its online guide in the Wiki:

GetAllDataForSymbol

If you have any further questions on how it works, the library's source code is open for review.
profile picture

Eugene

#22
ronc asked this in an unnecessary new thread, and I appended it here to avoid fragmentation.
Hint: Consider bookmarking this thread if it's important to you to be able to find it easily.

---

This code produces a run-time error but I cannot figure out why...?
CODE:
Please log in to see this code.
profile picture

Eugene

#23
Nothing wrong with the code. Error might be thrown by some data providers the code is applied to and depending on selected data range. Switch to "All Data" and the error is gone. With Most Recent / Number of Bars selected, some providers will throw an error and some not (depending on their internals). Find a combination that works for you.
profile picture

ronc

#24
I have been using Fidelity data. I have On-Demand Updates off.
I tried many different time spans and symbols. All produce the same error. I have not been able to find any time span or symbol (other than "All Data") that does not produce the error.
I updated the Fidelity data, no change.
I created a new dataset using Yahoo data, same error.
I tried creating a dataset using Microsoft data provider but the update did not work ("Error: No data").
I created a new test strategy, using RSI instead of stochK/D - same error.

I can try larger time scales such as "All Data" to debug this issue but I can't use "All Data" for my actual work since the computation times would be infeasible for backtesting and optimization.

Using RSI instead of stochastics (this errors out):
CODE:
Please log in to see this code.

But if we replace the CrossOver/Under functions this does not produce an error:
CODE:
Please log in to see this code.

profile picture

Eugene

#25
Glad that you found the workaround. CrossOver & CrossUnder perform an internal validity check that for some reason cries wolf.
This website uses cookies to improve your experience. We'll assume you're ok with that, but you can opt-out if you wish (Read more).