DataSeries returning zero
Author: fritz
Creation Date: 2/21/2010 5:45 PM
profile picture

fritz

#1
I'm writing a strategy that calls EMA.Series several times -- sometimes picking out a particular value, e.g.:
CODE:
Please log in to see this code.

...and sometimes returning the entire series.

I've been tearing my hair out trying to debug this script and I finally realized these EMAs are returning zero. Sometimes. I tried switching back and forth between Modern and Legacy calculation, and it seemed that switching one EMA to Modern was causing ALL the EMAs to return zero.

Then hazy memories of WL4 started to come back. I suspect my problem is that I'm calling EMA.Series inside the bar loop while I'm still filling the Port series. If I remember right, in WL4, series math happened once at the start of the script (regardless of where you reference it) and then you just picked out elements of the pre-calculated EMA series. I suspect WL5 is doing the same -- except maybe it does the series math when the EMA series is constructed.

What is the right way to fill a series (Port) bar-by-bar, and then get an EMA of Port[bar-AvgLength+1] through Port[bar] ? I can calculate the EMA by hand if I have to, but I want to know the right general answer for this question. I remember running into it frequently with WL4.

Thanks,
Gary
profile picture

Cone

#2
It's generally a mistake to use a variable length/period when referring to a Indicator.Series method. Each time the variable changes, you create an entirely new series - very inefficient.

Some indicators support a .Value method. This is akin to v4's SingleCalcMode, but since EMA is an unstable indicator (it generally takes 3x the period for an EMA to return stable values), the .Value method is not supported for it.

QUOTE:
What is the right way to fill a series (Port) bar-by-bar, and then get an EMA ...
As I said, EMA probably shouldn't be used this way, so I'd recommend a Gaussian or Kalman for smoothing splines. But if you insist on using the EMA, you can recreate it's calculation yourself (you can find it in a forum search). Once you do, you'll probably see why it doesn't really make sense for your application of it.
profile picture

fritz

#3
I'm not using a variable length. I'm using the same length all the time but I need to calculate the EMA inside the bar loop. I would calculate it outside the loop in one series calc if I could, but I'm filling the series bar-by-bar inside the loop -- and then I need to get a smoothed average of the last N bars including the just-calculated most-recent value:
CODE:
Please log in to see this code.

So I'm just picking off the EMA value on the current bar, including the value of Port[bar] I just calculated.

EMA works fine in this application. I'm currently calculating it by hand. But this applies to any series calculation, not just EMA. This "fill bar X of a series then do a series calculation using the new bar info" issue came up frequently when I was coding for WL4, for EMAs and for other series calculations. Maybe I'm not doing it the "right WL way" and all series should be filled in & calculated ahead of time, but I really don't see how to do that in all cases. I want to be able to calculate this stuff like I would in any other language I've used. Is WL5 unable to do that with series?
profile picture

Cone

#4
The WL way is the way any other app would do it. You need to completely fill your series with values first and then apply EMA.Series to it. Use two separate loops. In other apps, those loops are hidden.
profile picture

fritz

#5
I don't agree other apps do it the same way. I'm well aware of the hidden loops in e.g. Tradestation code, and I and friends of mine have written our own code in C / C++ / C# that had no hidden loops.

But if that's the way WL does it, I'll work with it.
profile picture

Cone

#6
If you calculate the EMA yourself, then sure, you can calculate it as you're adding values to another series; not a very extendable architecture.

Being a programmer, note that you're passing a series reference to the EMA.Series method. In other words, early in your loop you're passing a series filled with zeroes and that's why you get one back (GIGO). The reason the result doesn't change after you start filling the parameter series is due to caching so that your script can continually refer to the same series without having to recalculate it over and over.
profile picture

fritz

#7
Yes, I understand the hows & whys of the caching idea. (But I didn't remember WL worked that way until I'd spent several hours pounding my head on the screen!)

It's just a different approach than I'm used to. For example Tradestation has no such concept; they just use a rolling window of history and you can refer back to any variable within that history window. So rather than computing the series ahead of time, the series information is calculated as you go, bar-by-bar. Since bar-by-bar is often when/where you want to be able to calculate and use those values, I find that works well. The platforms my friends and I have written use a similar bar-by-bar approach, but without TS's "magic" history model. Maybe the WL pre-calculated approach is more efficient, but (at least for my mindset) I find it forces a very non-intuitive and often clunky programming style. Maybe you're used to using it so it seems very natural, but I'm not there yet.
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).