Coding Technical Analysis Functions

April 23, 2013

Beginners, don’t worry if you don’t understand when you read this manual. We will explain how to code your technical analysis strategy in the “Code your strategy” section.

Technical Analysis

NEST Pulse provides many built-in Technical Analysis functions. Using only a single line of code you can calculate functions such as Moving Averages, Bollinger Bands, Japanese Candlesticks and so on. A complete list of technical analysis functions is covered here. The following is a simple example of how to use one of the most common technical analysis functions, the Simple Moving Average:

LAST >SimpleMovingAverage(CLOSE, 20)

The script will check if the last traded price is over the 20-day Moving Average of the close price.

The CLOSE variable is actually a vector of closing prices, not just the most recent close price. You can use OPEN, HIGH, LOW, CLOSE and VOLUME vectors to create your own calculated vectors using the “SET” keyword:

SET Median = (CLOSE + OPEN)/ 2

This code creates a vector containing the median price for each trading day.

We can use the Median vector inside any function that requires a vector:

LAST >SimpleMovingAverage(Median, 20)

This function evaluates to True when the last traded price is greater than the 20-day Moving Average of the Median price.

Because Functions return Vectors, Functions can also be used as valid arguments within other Functions like:

LAST >SimpleMovingAverage(SimpleMovingAverage(CLOSE, 30), 20)

This evaluates to True when the last price is greater than the 20-day moving average of the 30-day moving average of the close price.

Crossovers

You may be familiar with the term “crossover”, which is what happens when one series crosses over the top of another series as depicted in the image below:

Moving Average Crossover on a Google Finance chart

Many technical indicators such as the MACD for example, have a “signal line”. A buy or sell signal is generated when the signal line crosses over or under the technical indicator.

The CROSSOVER function helps you when one series has crossed over another.

For example, we can find the exact point in time when one moving average crossed over another by using the CROSSOVER function:

SET MA1 = SimpleMovingAverage(CLOSE, 28)
SET MA2 = SimpleMovingAverage(CLOSE, 14)
CROSSOVER(MA1, MA2) = TRUE

The script above will evaluate to true when the MA1 vector most recently crossed over the MA2 vector. And we can reverse the script to the MA1 vector crossed below the MA2 vector: CROSSOVER(MA2, MA1) = TRUE

Primitive functions and operators

Primitives

The built-in functions of NEST Pulse, are known as Primitives. These important functions define the NEST Pulse programming language and provide the basic framework required to build complex trading systems from the ground up.

Literally any type of trading system can be developed using the NEST Pulse programming language with minimal effort. If a system can be expressed in mathematical terms or programmed in any structured, procedural language such as C++, VB, or Java you can rest with the assurance that the same formulas can also be programmed using the NEST programming language.

Sometimes Technical Analysis formula can be very complex. For example, Technical Analysis functions exist that require recursive calculations and complicated IF-THEN-ELSE structures as part of their formula. These complex trading systems are traditionally developed in a low level programming language.

You can perform these calculations in a much  simpler way by means of vector operations and simulated control structure using NEST Pulse. Here’s more on it:

Conditional IF function

IF(Condition, True part, False part)

The conditional “IF” function allows you to design complex Boolean logic filters. If you paste the following script into the Script area in your trading Software Application, you will see a column of numbers that oscillate between 1 and -1, depending on when the closing price is greater than the opening price:

SET A = IF(CLOSE > OPEN, 1, -1)

The first argument of the “IF” function is a logical test. The second argument is the value that will be used if the condition evaluates to TRUE. Conversely, the third argument is the value that will be used if the condition evaluates to FALSE.

The logical test may be any value or expression that can be evaluated to TRUE or FALSE. For example, CLOSE = OPEN is a logical expression; if the close price is the same as the opening price, the expression evaluates to TRUE, otherwise, the expression evaluates to FALSE.

LOOP function

LOOP(Vector1, Vector2, Offset1, Offset2, Operator)

LOOP provides simulated control structure by means of a single function call.

Consider the following:

SET X = CLOSE
SET X = REF(X, 1) + X

This script simply adds the previous close to the most current close, REF(X, 1) is evaluated once. This is expected behavior for a vector programming language; vectors are calculated independently in a stepwise fashion and are not recursive.

Now by changing CLOSE to 0, logically we would expect X to equal the previous X value plus one, and therefore expect REF(X, 1) to be evaluated once for each record in the vector:

SET X = 0
SET X = REF(X, 1) + X

Although we are looking at the exact same formula, because we are initializing X with a scalar and X is not related to any existing vector we would now expect X to be calculated as a series: 1,2,3,4,5,6,…n

We are now exceeding the limits of a vector programming language by requiring control structure. Anytime we assign a variable to itself such as SET X = F(X) we are expecting F(X) to be recursive. In the first example we write SET X = CLOSE. CLOSE is a variable, not a function and does not have any relationship with X. Our expectations change when we initialize X with anything other than an existing vector.

The LOOP function overcomes this inherent limitation by simulating a structured programming construct, the for-loop iteration:

LOOP(Vector1, Vector2, Offset1, Offset2, Operator)

Vector1 is the vector to initialize the calculation form. Offset1 is the offset where values are referenced in Vector1 for the incremental calculation, and Offset2 is the offset where values are referenced from in Vector2.

Example 1:

X (Vector1) is a series from 5.25 to 11.25.

If we write LOOP(X, 2, 1, 0, MULTIPLY) the vector returned will contain values initialized by X, offset by 1 and multiplied by 2.

Example 2:

In the case of SET X = REF(X, 1), Vector1 is X and Vector2 is 1. Since we’re adding the value of 1 (not a vector) to X in the following example, Offset2 is set to zero:

SET X = LOOP(X, 1, 1, 0, ADD)

And now X contains the series 1,2,3,4,5,6,…n

Example 3:

SET X = REF(CLOSE,1)
SET Y = (REF(Y, 3) - X) * 2

Because Y requires control structure we must instead write: SET X = REF(CLOSE,1)

SET Y = LOOP(Y, X, 3, 0, SUBTRACT) * 2

We could reduce that to:

SET Y = LOOP(Y, CLOSE, 3, 1, SUBTRACT) * 2

Valid operators are ADD, SUBTRACT, MULTIPLY and DIVIDE.

COUNTIF

COUNTIF(Condition): Returns a Vector representing the total number of times the specified condition evaluated to TRUE. Example: COUNTIF(CROSSOVER(SimpleMovingAverage(CLOSE, 14), CLOSE)) The script returns a vector with increasing values expressing the number of times the 14-day Simple Moving Average crossed over the closing price.

LASTIF

LASTIF(Condition): Similar to COUNTIF, except LASTIF returns a Vector containing the number of days since the last time the specified condition evaluated to TRUE. The count is reset to zero(0) each time the condition evaluates to TRUE.

Example: LASTIF(CLOSE < REF(CLOSE, 1)) The script returns a vector that increases in value for each bar where the closing price was not less than the previous closing price. When the condition evaluates to TRUE, meaning the closing price was less than the previous closing price, the reference count is reset to zero.

SUMIF

SUMIF(Condtion, Vector) Last in the “IF” function lineup is the SUMIF function. This function outputs a running sum of all values in the supplied Vector wherever the supplied condition evaluates to TRUE.

For example if we wanted a Vector containing the sum of Volume for all the days where the closing price closed up 5%, we could write:

SUMIF(CLOSE > REF(CLOSE,1) * 1.05, VOLUME)

The result will be a Vector containing a running sum of Volume for each day where the closing price closed up at by least 5%.

SUM

SUM(Vector, Periods): The SUM function (not to be confused with the SUMIF function) outputs a Vector containing a running sum, as specified by the Periods argument.

Example:

SUM(CLOSE, 10) The script returns a vector of sums based on a 10-period window.

AVG

AVERAGE(Vector, Periods)

AVG(Vector, Periods): Returns a vector containing a running average, as specified by the Periods argument. The AVERAGE function can also be referenced by AVG for short. Example: AVERAGE(CLOSE, 10) AVG(CLOSE, 10) Both scripts return a vector of averages based on a 10- period window.

MAX

MAX(Vector, Periods): Returns a vector containing a running maximum, as specified by the Periods argument. The values represent the maximum value for each window.

Example:

MAX(CLOSE, 10)

Returns a vector of maximum values based on a 10- period window.

MIN

MIN(Vector, Periods): Returns a vector containing a running minimum, as specified by the Periods argument. The values represent the minimum value for each window.

Example:

MIN(CLOSE, 10)

Returns a vector of minimum values based on a 10- period window.

MAXOF

MAXOF(Vector1, Vector2, [Vector3]..[Vector8]): Returns a vector containing a maximum value of all specified vectors, for up to eight vectors. Vector1 and Vector2 are required and vectors 3 through 8 are optional.

Example:

MAXOF(CLOSE, OPEN)

Returns a vector containing the maximum value for each bar, which is either the opening price or the closing price in this example.

MINOF

MINOF(Vector1, Vector2, [Vector3]..[Vector8]):Returns a vector containing a minimum value of all specified vectors, for up to eight vectors. Vector1 and Vector2 are required and vectors 3 through 8 are optional.

Example:

MINOF(CLOSE, OPEN)

Returns a vector containing the minimum value for each bar, which is either the opening price or the closing price in this example.

REF

REF(Vector, Periods)

By default all calculations are performed on the last, most recent value of a vector. The following script evaluates to true when the last open price (the current bar’s open price) is less than Rs.30:

OPEN < 30

By default OPEN is assumed to be the current bar’s open. You can reference a previous value of a vector by using the REF function: REF(OPEN, 1) < 30, and now the script will check if the previous bar’s open price was less than Rs.30. The number 1 (the second argument) tells the REF function to reference values as of one bar ago. To reference values two bars ago, simply use 2 instead of 1. The valid range for the Periods argument is 1- 250 unless otherwise noted.

TREND

TREND(Vector)

The TREND function can be used to determine if data is trending upwards, downwards, or sideways. This function can be used on the price (open, high, low, close), volume, or any other vector. The TREND function returns a constant of either UP, DOWN or SIDEWAYS. Example: TREND(CLOSE) = UP AND TREND(VOLUME) = DOWN

TREND is often the first function used as a means of filtering securities that are not trending in the desired direction.

CROSSOVER

Many technical indicators such as the MACD for example, have a “signal line”. Traditionally a buy or sell signal is generated when the signal line crosses over or under the technical indicator. The CROSSOVER function helps you one series has crossed over another. For example, we can find the exact point in time when one moving average crossed over another by using the CROSSOVER function: SET MA1 = SimpleMovingAverage(CLOSE, 28)

SET MA2 = SimpleMovingAverage(CLOSE, 14)
CROSSOVER(MA1, MA2) = TRUE

The script above will evaluate to true when the MA1 vector most recently crossed over the MA2 vector. And we can reverse the script to the MA1 vector crossed below the MA2 vector: CROSSOVER(MA2, MA1) = TRUE

Math Functions

Note that all math functions return a vector.

For example ABS(CLOSE – OPEN) returns a vector of the ABS value of CLOSE – OPEN (one record per bar). The RND function returns a vector of random values, one for each bar, and so forth.

ABS

The ABS function returns the absolute value for a number. Negative numbers become positive and positive numbers remain positive.

Example:

ABS(CLOSE - OPEN)

The script always evaluates to a positive number, even if the opening price is greater than the closing price.

SIN

The SIN function returns the sine of a number (angle).

Example:

SIN(45)

The script outputs 0.851

COS

COS returns the cosine of a number (angle).

Example:

COS(45)

The script outputs 0.525

TAN

The TAN function returns the tangent of a number (angle).

Example:

TAN(45)

The script outputs 1.619

ATN

Returns the arc tangent of a number.

Example:

ATN(45)

The script outputs 1.548

EXP

EXP raises “e” to the power of a number. The LOG function is the reverse of this function. Example: EXP(3.26)

The script outputs 26.28

LOG

Returns the natural logarithm of a positive number. The EXP function is the reverse of this function.

Example:

LOG(26.28)

The script outputs 3.26

LOG10

Returns the base 10 logarithm of a positive number.

Example: LOG10(26.28) The script outputs 1.42

RND

The RND function returns a random number from 0 to a maximum value. Example: RND(100) Outputs a random number from 0 to 100.

Operators

Equal (=)

The equal operator is used to assign a value to a variable or vector, or to compare values. When used for assignment, a single variable or vector on the left side of the = operator is given the value determined by one or more variables, vectors, and/or expressions on the right side. Also, the SET keyword must precede the variable name when the = operator is used for an assignment:

SET A = 123
SET B = 123
A = B = TRUE

Greater Than (>)

The > operator determines if the first expression is greater-than the second expression. Example:

SET A = 124
SET B = 123
A > B = TRUE

Less Than (<)

The < operator determines if the first expression is less-than the second expression. Example: SET A = 123

SET B = 124
A > B = TRUE

Greater Than Or Equal To (>=)

The >= operator determines if the first expression is greater-than or equal to the second expression. Example:

SET A = 123
SET B = 123
A >= B = TRUE

And:

SET A = 124
SET B = 123
A >= B = TRUE

Less Than Or Equal To (<=)

The <= operator determines if the first expression is less-than or equal to the second expression. Example:

SET A = 123
SET B = 123
A <= B = TRUE

And:

SET A = 123 SET B = 124 A <= B = TRUE

Not Equal (<>or !=)

Both the != and the <> inequality operators determine if the first expression is not equal to the second expression. Example:

SET A = 123
SET B = 124
A = B = TRUE

AND

The AND operator is used to perform a logical conjunction on two expressions, where the expressions are Null, or are of Boolean subtype and have a value of True or False. The AND operator can also be used a bitwise operator to make a bit-by-bit comparison of two integers. If both bits in the comparison are 1, then a 1 is returned. Otherwise, a 0 is returned. When using the AND to compare Boolean expressions, the order of the expressions is not important. Example:

(TRUE = TRUE AND FALSE = FALSE) = TRUE

And:

(TRUE = TRUE AND FALSE = TRUE) = FALSE

OR

The OR operator is used to perform a logical disjunction on two expressions, where the expressions are Null, or are of Boolean subtype and have a value of True or False.

The OR operator can also be used a “bitwise operator” to make a bit-by-bit comparison of two integers. If one or both bits in the comparison are 1, then a 1 is returned. Otherwise, a 0 is returned.

When using the OR to compare Boolean expressions, the order of the expressions is important.

Example:

(TRUE = TRUE OR TRUE = FALSE) = TRUE

And:

(FALSE = TRUE OR TRUE = FALSE) = FALSE

XOR

The XOR operator is used to perform a logical exclusion on two expressions, where the expressions are Null, or are of Boolean subtype and have a value of “True” or “False”.

The XOR operator can also be used a “bitwise operator” to make a bit-by-bit comparison of two integers. If both bits are the same in the comparison (both are 0’s or 1’s), then a 0 is returned. Otherwise, 1 is returned.

Example:

(TRUE XOR FALSE) = TRUE

And:

(FALSE XOR FALSE) = FALSE

NOT

The NOT operator is used to perform a logical negation on an expression. The expression must be of Boolean subtype and have a value of True or False. This operator causes a True expression to become False, and a False expression to become True.

Example:

NOT (TRUE = FALSE) = TRUE

And:

NOT (TRUE = TRUE) = FALSE

EQV

The EQV operator is used to perform a logical comparison on two expressions (I.e., are the two expressions identical), where the expressions are Null, or are of Boolean subtype and have a value of True or False.

The EQV operator can also be used a “bitwise operator” to make a bit-by-bit comparison of two integers. If both bits in the comparison are the same (both are 0’s or 1’s), then a 1 is returned. Otherwise, 0 is returned.

The order of the expressions in the comparison is not important.

Example:

TRUE EQV TRUE = TRUE

And:

TRUE EQV FALSE = FALSE

MOD

The MOD operator divides two numbers and returns the remainder. In the example below, 5 divides into 21, 4 times with a remainder of 1.

Example:

21 MOD 5 = 1

Happy Trading.

This blog is an antecedent to the Trading Systems blog which is continued here.

Zerodha

Your friendly neighborhood discount brokerage

Comments are closed.