This tutorial assumes you are already familiar with the basics of the TSL language.
Most of the features described here are also useful to make trading systems.
Here is the code of the SMA (Simple Moving Average) indicator:
""" Simple Moving Average """ return average(Price)
Let's look at each part individually.
""" Simple Moving Average """
|The text inside the quotes appears in the the Description column of the list-view when you browse indicators.|
|This computes the average of the current Price data.|
|The return keyword sends the value to be displayed in charts or to be used in the stock screener.|
A TSL indicator is automatically translated to a Python function similar to the following:
def SMA_Fun(): """ Simple Moving Average """ return average(Price)
This function is called every-time the value of the indicator is needed, for different stock tickers and different dates1). For example, the moving average curve in a stock chart is made of the return values of SMA at every bar.
In any indicator, price and volume data can be accessed with the  operator. Here is an example:
Val = Close
Close means: the last (or “close”) price of the current time period (of today in an EOD chart).
Close would mean the last price of the time period before (of yesterday in an EOD chart), and so on.
Here are the price and volume data which can be used in a similar way:
|Open||The first price of the time period.|
|High||The highest price of the time period.|
|Low||The lowest price of the time period.|
|Close||The last price of the time period.|
|Volume||The volume of transaction during the whole time period.|
Like with price and volume data, you can access information about time:
|Name||Sample value||Data returned|
|Date||20100812||The date of the time period.|
|DateYear||2010||The year of the time period.|
|DateMonth||8||The month of the time period (from 1 to 12).|
|DateDay||12||The day of the time period (from 1 to 31).|
|WeekDay||3||The day of the week (from 0: monday to 6:sunday).|
|Time||2010\08\12 - 0:00:00||The date and hour of the time period.|
There is not a unique moving average used in all contexts. Depending on the situation, you may use a SMA(14), a SMA(21), a SMA(200) or other variants that you see fit. What changes is the number of time-periods covered by the indicator.
In TSL, this number is stored in the Periods variable. For example, the following indicators return the same value:
return average(Price[i] for i in range(Periods))
The Periods variable may be needed, for example, when computing an average.
return sum(Price) / Periods
The First variable is always equal to Period minus 1. It makes it easy to access data at one extremity of the period covered by an indicator.
return (Close[First] + Close) / 2
The moving average is generally computed based on close prices. Nonetheless, it is sometimes useful to apply it to other data like the highest prices, the open prices, or even technical indicators.
By default, Price behaves just like Close. However, it is possible to replace it with any other data.
return SMA(14, Price=High)
The code above returns the average of the last 14 highest prices.
The param keyword enables the use of parameters that can be changed later, for example when an indicator is added to a chart.
""" Fast %D """ param(FastD = 3) return average(FastStoK[0:FastD])
The call to param will not be included in the final translated function. Instead, once parameters are set from SystemTrader's GUI, their names are textually replaced by their values.
def FastStoD_Fun(): """ Fast %D """ return average(FastStoK[0:3])
Indicator values in a stock chart are always computed from left to right. The Init value allows you to know when the first call (at the left extremity) is taking place.
The value is typically used in conjunction with the Save object, in order to pre-compute values or to make the indicator “recursive”, like in the Exponential Moving Average.
""" Exponential Moving Average (EMA) """ param(Smoothing = 2.0) if Init: Save.LastEMA = average(Price) Save.K = Smoothing / (Periods + 1) Save.LastEMA = Save.K * Price + (1-Save.K) * Save.LastEMA return Save.LastEMA