The features in composited indicator formula parser

Recently I (almostly) finished my expression parser in my ftap system. The indicator formula parser parses a piece of code and evaluate the result as the indicator. Though the parser obeys the regular rules used in most expression parser, it has some difference with a normal mathematical expression parser. In this blog, I will explain the special features in my indicator formula parser.

Warm up, some simple examples

“pClose[0] + 1” gives an indicator that the values are the close price plus 1.
“(pClose[1] + pClose[0]) / 2” gives an indicator of the average of two bars' close.
“iRsi(14) @ iMa(10)” gives an indicator of 10 period EMA of 14 period RSI.

Feature 1, the "@" operator

The “@” operator is the special operator I introduce to the parser. The binary operator uses the values from the indicator on its left side to input to the indicator on its right side. So “iRsi(14) @ iMa(10)” can be read as, calculate the values of 14 period RSI, then feed the values to 10 period EMA.

The “@” operator is the most powerful feature in the parser. It brings the powerful capability to compsite two indicators together.

Some more examples,

10 period EMA on the average of 9 and 14 period RSIs.

((iRsi(9) + iRsi(14)) / 2) @ iMa(10)

14 period RSI on the average of high and low price.

((pHigh[0] + pLow[0]) / 2) @ iRsi(14)

The John Ehlers RSI smoothing.

((pClose[0] + 2 * pClose[1] + 2 * pClose[2] + pClose[3]) / 6) @ iRsi(14)

Feature 2, the "if" function

Liking the ternary conditional operator “:?” in C++, “if” is a function that accepts three arguments.
if(condition, trueExpression, falseExpression) If the condition is true, trueExpression is returned, otherwise, falseExpression is returned, and if falseExpression is omitted, null is returned.

The “if” function gives basic and powerful conditional branching ability. Here are some examples

# Turns a regluar RSI to a two-values indicator, which has values of either 100 or -100.
if(iRsi(14) > 50, 100, -100)
# Oh yeah, this is basic adaptive look back indicator!
if(iAtr(5) > iAtr(14), iMa(20), iMa(10))

Feature 3, the "while" function

Though I have added built-in functions such as aSum, aMax, aMin to execute actions on array, it's really good if we have some more powful flow control ability. So comes the “while” function.

a = 0, b = 0, while(a < 14, b = b + a, ++a)

Feature 4, recursion

Some indicator, such as EMA, uses its previous value in calculation, the is called recursion. To accomplish this, a variable “self” is added to represent current indicator. Then an EMA in formula looks like,

period = 20, m = 2.0 / (period + 1), pClose * m + self[1] * (1 - m)

A completed RSI indicator written in formula

Though it's not useful to repeat RSI algorithm in formula, below code of a full RSI indicator can show the power of the formula parser.

period = 14, price = pClose,
if(upList == null, upList = series()),
if(downList == null, downList = series()),
up = 0, down = 0,
diff = price[0] - price[1],
if(diff >= 0, up += diff, down -= diff),
upList[0] = (upList[1] * (period - 1) + up) / period,
downList[0] = (downList[1] * (period - 1) + down) / period,
upList[0] / (upList[0] + downList[0]) * 100.0

Discussion

Enter your comment. Wiki syntax is allowed:
QEUFB