Navigation: Realtest Script Language > Script Sections > Data Section > One-Pass Exponential Series

A regular data section item formula is calculated by looping through all the dates of the symbol and evaluating the formula for each date. If the formula includes a rolling bar function with a long lookback, this can take some time to accomplish, since it has to "roll back" that many bars from each bar of each symbol.

For most types of formulas, this can't be avoided, and fortunately RealTest already performs these calculations as quickly as possible, using multiple threads.

Exponential functions and indicators are a special case because of their definition. In theory, every past bar is present in an exponential average, no matter how "short" the length. (The length of an EMA is not actually a bar count, rather, it is a divisor in the calculation of each bar's value.)

Exponential moving averages were popular with pre-computer-age market technicians like Welles Wilder because they are much faster to calculate by hand than arithmetic averages. RealTest can take advantage of this fact and radically speed up the calculation of exponential functions and indicators when they are expressed simply enough.

An exponential function is automatically calculated in a single pass if the following conditions apply:

it is in a Data Section item

it is the only thing in the item

It literally has to be Function(arguments) with no other forumla terms before or after it.

Arguments to the functions can be as complex as you like, but to get the one-pass speed advantage, a data item must consist of nothing but a single exponential function definition.

Here are a few examples to illustrate this distinction: (Note that each of the second set of examples could still be calculated as one-pass formulas by dividing them into multiple data items.)

The exponential functions and indicators in RealTest that can benefit from this optimization are:

ADX - Wilder's average directional index

ATR - Wilder's average true range

KBBOT - Keltner band bottom

KBTOP - Keltner band top

MACD - MACD = EMA(C,len1) - EMA(C,len2)

MACDH - MACDH = MACD(len1,len2) - MACDS(len1, len2, len3)

MACDS - MACDS = MACD(len1,len2) - EMA(MACD(len1,len2),len3)

MDI - Wilder's negative directional index

PDI - Wilder's positive directional index

RRSI - reverse RSI (price required for RSI to reach level)

RSI - Wilder's relative strength index

RsiF - RSI as a function

XAvg or EMA - exponential moving average

Avg or MA - simple moving average (though more tricky internally, these are also calculated in one pass when the above conditions are met)

As explained in the self-referential items topic, one-pass calculation of exponential functions can introduce some interesting problems with regard to stock splits. In nearly every possible way, RealTest makes it unnecessary to worry about splits. In the usual (slower) way to calculate data items, the rolling bar function result for each bar is an "as traded" value for that bar, but is calculated in split-adjusted fashion relative to that bar (as if you had been using split-adjusted data on that date).

For most of the indicators and functions on the above list, this kind of automatic split handing is still provided in one-pass calculations. The exceptions are the last two,  EMA and MA. In their case, splits are still handled for you if your function has the simplest possible form, e.g. EMA(C, 100) or EMA(V, 100). In these cases, RealTest can infer whether to multiply or divide by the split factor depending on whether the first argument is a price or a volume element.

The trouble starts when this becomes a complex expression. EMA(C*V, 100), for example, would be "100-period exponential turnover". Here the split always cancels out because price and volume are multiplied, so the fact that no split adjustments are applied is not a problem. As argument expressions get more complex, however, it quickly becomes impossible to infer how to apply split factors during the calculation, so they are simply not applied.

If you see results that don't seem right from a complex one-pass EMA calculation, consider breaking it into multiple simpler one-pass items. If you don't want to do that and prefer to force an item to be calculated the old way, just add a meaningless extra term, e.g. 0 + EMA(SQR(H^2-L^2),20). (No idea what this indicator might be. Just felt like making up something absurd.)

Copyright © 2020-2021 Systematic Solutions, LLC