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.
This blog contains short examples that demonstrate how to perform common, basic tasks such as identifying securities within a specific price range, increase in volatility, crossing over of an indicator, and so forth. You can cut and paste many of these examples right into the NEST Pulse’s programming area on Zerodha Trader.
Also this blog contains a reference of functions, properties, and constants supported by the NEST Pulse language as well as hands-on trading system examples. This method of organization allows the beginning programmer to see results immediately while learning at his or her own pace. NEST Pulse is the engine that drives the scripting language in your trading software. It is a non-procedural scientific vector programming language that was designed specifically for developing trading systems. A script is simply a set of instructions that tells the NEST Pulse engine to do something useful, such as provide an alert when the price of one stock reaches a new high, crosses over a moving average, or drops by a certain percentage. There are many uses.
Introduction: Important Concepts
NEST Pulse is a powerful and versatile programming language for traders.
The language provides the framework required to build sophisticated trading programs piece by piece without extensive training or programming experience.
The following script is a very simple example that identifies markets that are trading higher than the opening price:
LAST > OPEN
It almost goes without saying that the purpose of this script is to identify when the last price is trading higher than the open price. It is nearly as plain as English language.
Just as a spoken language gives you many ways to express each idea, the NEST Pulse programming language provides a wide variety of ways to program a Trading System. Scripts can be very simple as just shown or extremely complex, consisting of many hundreds of lines of instructions. But for most systems, scripts usually consist of just a few lines of code.
The examples outlined in the first section of this blog are relatively short and simple but provide a foundation for the development of more complex scripts.
The scripts shown in this first section may be linked together using Boolean logic just by adding the AND or the OR keyword, for example:
Script 1 evaluates to true when the last price is higher than the open price:
LAST > OPEN
Script 2 evaluates to true when volume is two times the previous day’s volume:
VOLUME >REF(VOLUME, 1) * 2
You can aggregate scripts so that your script returns results for securities that are higher than the open and with the volume two times the previous volume:
LAST > OPEN AND VOLUME >REF(VOLUME, 1) * 2
Likewise, you can change the AND into an OR to find securities that are either trading higher than the open or have a volume two times the previous volume:
LAST > OPEN OR VOLUME >REF(VOLUME, 1) * 2
Once again, the instructions are nearly is plain as the English language. The use of Boolean logic with the AND and OR keywords is a very important concept that is used extensively by the NEST Pulse programming language.
It does not matter if your code is all on a single line or on multiple lines. It is often easier to read a script where the code is broken into multiple lines. The following script will work exactly as the previous example, but is somewhat easier to read:
LAST > OPEN OR VOLUME >REF(VOLUME, 1) * 2
It is good practice to structure your scripts to make them as intuitive as possible for future reference. In some cases it may be useful to add comments to a very complex script. A comment is used to include explanatory remarks in a script.
Whenever the pound sign is placed at the beginning of a line, the script will ignore the words that follow. The words will only serve as a comment or note to make the script more understandable:
# Evaluates to true when the last price is higher than the open or the volume is 2 X’s the previous volume:
LAST > OPEN OR VOLUME >REF(VOLUME, 1) * 2
The script runs just as it did before with the only difference being that you can more easily understand the design and purpose of the script.
The NEST Pulse language provides many built-in functions that make programming easier. When functions are built into the core of a programming language they are referred to as primitives. The TREND function is one example:
TREND(CLOSE, 30) = UP
In this example, the TREND function tells NEST Pulse to identify trades where the closing price is in a 30-day uptrend.
The values that are contained inside a function (such as the REF function or the TREND function) are called arguments. Here there are two arguments in the TREND function. Argument #1 is the closing price, and argument #2 is 30, as in “30 days” or “30 periods”
Only one of two things will occur if you use a function incorrectly will automatically fix the problem and the script will still run, or NEST Pulse will report an error, tell you what’s wrong with the script, and then allow you to fix the problem and try again.
In other words, user input errors will never cause NEST Pulse to break or return erroneous results without first warning you about a potential problem.
Let’s take CLOSE out of the TREND function and then try to run the script again:
TREND(30) = UP
The following error occurs:
Error: argument of “TREND” function not optional.
We are given the option to fix the script and try again.
Vector programming languages (also known as array or multidimensional languages) generalize operations on scalars to apply transparently to vectors, matrices, and higher dimensional arrays.
The fundamental idea behind vector programming is that operations apply at once to an entire set of values (a vector or field). This allows you to think and operate on whole aggregates of data, without having to resort to explicit loops of individual scalar operations.
As an example, to calculate a simple moving average based on the median price of a stock over 30 days, in a traditional programming language such as BASIC you would be required to write a program similar to this:
For each symbol For bar = 30 to max Average = 0 For n = bar - 30 to bar median = (CLOSE + OPEN) / 2 Average = Average + median Next MedianAverages(bar) = Average / 30 Next bar Next symbol
Nine to ten lines of code would be required to create the â€œMedianAveragesâ€ vector. But with NEST Pulse, you can effectively accomplish the same thing using only one line:
SET MedianAverage = SimpleMovingAverage((CLOSE + OPEN) / 2, 30)
And now MedianAverage is actually a new vector that contains the 30-period simple moving average of the median price of the stock at each point.
It is not uncommon to find array programming language “one-liners” that require more than a couple of pages of BASIC, Java or C++ code.
The REF Function
At this point you may be wondering what “REF” and “TREND” are. These are two of the very useful primitives that are built into the NEST Pulse language.
The REF function is used whenever you want to reference a value at any specific point in a vector. Assume the MedianAverage vector contains the average median price of a stock. In order to access a particular element in the vector using a traditional programming language, you would write:
SET A = MedianAverage[n]
Using NestPulse you would write:
SET A = REF(MedianAverage, n)
The main difference other than a variation in syntax is that traditional languages reference the points in a vector starting from the beginning, or 0 if the vectors are zero-based. NEST Pulse on the other hand references values backwards, from the end. This is most convenient since the purpose of NEST Pulse is of course, to develop trading systems. It is always the last, most recent value that is of most importance. To get the most recent value in the MedianAverage vector we could write:
SET A = REF(MedianAverage, 0)
Which is the same as not using the REF function at all. Therefore the preferred way to get the last value (the most recent value) in a vector is to simply write:
SET A = MedianAverage
The last value of a vector is always assumed when the REF function is absent.
To get the value as of one bar ago, we would write:
SET A = REF(MedianAverage, 1)
Or two bars ago:
SET A = REF(MedianAverage, 2)
The TREND Function
Stock traders often refer to “trending” as a state when the price of a stock has been increasing (up-trending) or decreasing (down-trending) for several days, weeks, months, or years. The typical investor or trader would avoid opening a new long position of a stock that has been in a downtrend for many months.
NEST Pulse provides a primitive function aptly named TREND especially for detecting trends in stock price, volume, or indicators: TREND(CLOSE, 30) = UP
This tells NEST Pulse to identify trades where the closing price is in a 30-day uptrend. Similarly, you could also use the TREND function to find trends in volume or technical indicators:
# The volume has been in a downtrend for at least 10 days:
TREND(VOLUME, 10) = DOWN
# The 14-day CMO indicator has been up-trending for at least 20 days:
TREND(CMO(CLOSE, 14), 20) = UP
It is useful to use the TREND function for confirming a trading system signal.
Suppose we have a trading system that buys when the close price crosses above a 20-day Simple Moving Average. The script may look similar to this:
# Gives a buy signal when the close price crosses above the 20-day SMA
CROSSOVER(CLOSE, SimpleMovingAverage(CLOSE, 20)) = TRUE
It would be helpful in this case to narrow the script down to only the securities that have been in a general downtrend for some time. We can add the following line of code to achieve this:
AND TREND(CLOSE, 40) = DOWN
TREND tells us if a vector has been trending upwards, downwards, or sideways, but does not tell us the degree of which it has been trending. We can use the REF function in order to determine the range in which the data has been trending. To find the change from the most current price and the price 40 bars ago, we could write:
SET A = LAST - REF(CLOSE, 40)
Price Gaps and Volatility
Although the TREND function can be used for identifying trends and the REF function can be used for determining the degree in which a stock has moved, it is often very useful to identify gaps in prices and extreme volume changes, which may be early indications of a change in trend.
We can achieve this by writing:
# Returns true when the price has gapped up
LOW >REF(HIGH, 1)
# Returns true when the price has gapped down
HIGH <REF(LOW, 1)
You can further specify a minimum percentage for the price gap:
# Returns true when the price has gapped up at least 1%
LOW >REF(HIGH, 1) * 1.01
And with a slight variation we can also the volume is either up or down by a large margin:
# the volume is up 1000%
VOLUME >REF(VOLUME, 1) * 10
Or by the average volume:
# the volume is up 1000% over average volume
VOLUME >SimpleMovingAverage(VOLUME, 30) * 10
We can also measure volatility in price or volume by using any one of the built-in technical indicators such as the Volume Oscillator, Chaikin Volatility Index, Coefficient of Determination,Price Rate of Change, Historical Volatility Index, etc.
This blog is a user manual for algoZ and is continued here.